refactor: icon and download button use button component
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Copy } from "@lucide/svelte";
|
||||
import IconButton from "./IconButton.svelte";
|
||||
import IconButton from "./ui/IconButton.svelte";
|
||||
|
||||
interface Props {
|
||||
code: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { Component, Snippet } from "svelte";
|
||||
import Icon from "./Icon.svelte";
|
||||
import Icon from "./ui/Icon.svelte";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { Component } from "svelte";
|
||||
import Icon from "./Icon.svelte";
|
||||
|
||||
interface Props {
|
||||
icon: Component<{ size?: number; class?: string }>;
|
||||
label: string;
|
||||
onclick?: () => void;
|
||||
variant?: "ghost" | "solid" | "accent" | "bare";
|
||||
size?: number;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
let {
|
||||
icon,
|
||||
label,
|
||||
onclick,
|
||||
variant = "ghost",
|
||||
size = 16,
|
||||
disabled = false,
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="icon-btn icon-btn--{variant}"
|
||||
aria-label={label}
|
||||
{disabled}
|
||||
onclick={() => onclick?.()}
|
||||
>
|
||||
<Icon {icon} {size} />
|
||||
</button>
|
||||
|
||||
<style>
|
||||
.icon-btn {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius);
|
||||
background: transparent;
|
||||
color: var(--muted);
|
||||
cursor: pointer;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
border: 0;
|
||||
background: 0 0;
|
||||
border: 0;
|
||||
place-items: center;
|
||||
padding: 6px;
|
||||
display: grid;
|
||||
}
|
||||
.icon-btn:hover:not(:disabled) {
|
||||
color: var(--foreground);
|
||||
border-color: var(--blue);
|
||||
}
|
||||
.icon-btn--solid {
|
||||
background: var(--blue);
|
||||
color: #fff;
|
||||
border-color: var(--blue);
|
||||
}
|
||||
.icon-btn--accent {
|
||||
background: var(--cyan);
|
||||
color: #042;
|
||||
border-color: var(--cyan);
|
||||
}
|
||||
.icon-btn--bare {
|
||||
padding: 6px;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
color: var(--muted);
|
||||
}
|
||||
.icon-btn--bare:hover:not(:disabled) {
|
||||
color: var(--foreground);
|
||||
border-color: transparent;
|
||||
}
|
||||
.icon-btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.icon-btn--ghost {
|
||||
padding: 6px;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
color: var(--muted);
|
||||
}
|
||||
</style>
|
||||
@@ -2,7 +2,7 @@
|
||||
import { resolve } from "$app/paths";
|
||||
import { ArrowUpRight } from "@lucide/svelte";
|
||||
import type { Component } from "svelte";
|
||||
import Icon from "./Icon.svelte";
|
||||
import Icon from "./ui/Icon.svelte";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
@@ -73,15 +73,4 @@
|
||||
color: var(--muted);
|
||||
align-self: start;
|
||||
}
|
||||
.tool-arrow {
|
||||
color: var(--blue);
|
||||
opacity: 0;
|
||||
transition:
|
||||
opacity 0.12s ease,
|
||||
transform 0.12s ease;
|
||||
}
|
||||
.tool-card:hover .tool-arrow {
|
||||
opacity: 1;
|
||||
transform: translate(2px, -2px);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from "$app/paths";
|
||||
import { CircleQuestionMark, Moon, Sun } from "@lucide/svelte";
|
||||
import IconButton from "./IconButton.svelte";
|
||||
import StatusDot from "./StatusDot.svelte";
|
||||
import IconButton from "./ui/IconButton.svelte";
|
||||
|
||||
interface Props {
|
||||
theme: "light" | "dark";
|
||||
@@ -35,13 +35,13 @@
|
||||
<IconButton
|
||||
icon={CircleQuestionMark}
|
||||
label="Help"
|
||||
variant="bare"
|
||||
variant="clear"
|
||||
onclick={() => {}}
|
||||
/>
|
||||
<IconButton
|
||||
icon={theme === "light" ? Moon : Sun}
|
||||
label="Toggle theme"
|
||||
variant="bare"
|
||||
variant="clear"
|
||||
onclick={ontoggle}
|
||||
/>
|
||||
<div class="lang" role="group" aria-label="Language">
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
export const ButtonVariantDefine = {
|
||||
PRIMARY: "primary",
|
||||
OUTLINE: "outline",
|
||||
ACCENT: "accent",
|
||||
DANGER: "danger",
|
||||
CLEAR: "clear",
|
||||
} as const;
|
||||
|
||||
export type ButtonVariant =
|
||||
(typeof ButtonVariantDefine)[keyof typeof ButtonVariantDefine];
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { Check } from "@lucide/svelte";
|
||||
|
||||
// TODO: сделать эти типы общими для кнопок \ бейджей \ етц???
|
||||
const ToneVariantDefine = {
|
||||
DEFAULT: "default",
|
||||
ACCENT: "accent",
|
||||
|
||||
@@ -1,26 +1,19 @@
|
||||
<script lang="ts">
|
||||
import type { Component, Snippet } from "svelte";
|
||||
import Icon from "../Icon.svelte";
|
||||
|
||||
const ButtonVariantDefine = {
|
||||
PRIMARY: "primary",
|
||||
OUTLINE: "outline",
|
||||
ACCENT: "accent",
|
||||
DANGER: "danger",
|
||||
} as const;
|
||||
|
||||
type ButtonVariant =
|
||||
(typeof ButtonVariantDefine)[keyof typeof ButtonVariantDefine];
|
||||
import type { Component } from "svelte";
|
||||
import { ButtonVariantDefine, type ButtonVariant } from "../define";
|
||||
import Icon from "./Icon.svelte";
|
||||
|
||||
interface Props {
|
||||
children: Snippet;
|
||||
label: string;
|
||||
ariaLabel?: string;
|
||||
onclick?: () => void;
|
||||
variant?: ButtonVariant;
|
||||
icon?: Component<{ size?: number; class?: string }>;
|
||||
disabled?: boolean;
|
||||
}
|
||||
let {
|
||||
children,
|
||||
label,
|
||||
ariaLabel = label,
|
||||
onclick,
|
||||
variant = ButtonVariantDefine.PRIMARY,
|
||||
icon,
|
||||
@@ -28,9 +21,14 @@
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<button class="btn btn--{variant}" {disabled} onclick={() => onclick?.()}>
|
||||
<button
|
||||
class="btn btn--{variant}"
|
||||
{disabled}
|
||||
aria-label={ariaLabel}
|
||||
onclick={() => onclick?.()}
|
||||
>
|
||||
{#if icon}<Icon {icon} size={14} />{/if}
|
||||
<span class="btn-label">{@render children()}</span>
|
||||
<span class="btn-label">{label}</span>
|
||||
</button>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { ArrowDownToLine, Download } from "@lucide/svelte";
|
||||
import { Download } from "@lucide/svelte";
|
||||
import Button from "./Button.svelte";
|
||||
|
||||
interface Props {
|
||||
label: string;
|
||||
@@ -8,29 +9,4 @@
|
||||
let { label, onclick }: Props = $props();
|
||||
</script>
|
||||
|
||||
<button class="download-btn" type="button" onclick={() => onclick?.()}>
|
||||
<Download size={16} />
|
||||
{label}
|
||||
<ArrowDownToLine size={14} />
|
||||
</button>
|
||||
|
||||
<style>
|
||||
.download-btn {
|
||||
background: var(--color-main);
|
||||
color: var(--color-background);
|
||||
width: 100%;
|
||||
height: calc(5 * var(--space-m));
|
||||
font-size: var(--font-button);
|
||||
font-family: var(--font-mono);
|
||||
border: 0;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: var(--space-m);
|
||||
margin-top: var(--space-xl);
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.download-btn:hover {
|
||||
background: var(--color-main-tint);
|
||||
}
|
||||
</style>
|
||||
<Button icon={Download} {label} {onclick} />
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
import type { Component } from "svelte";
|
||||
import { ButtonVariantDefine, type ButtonVariant } from "../define";
|
||||
import Button from "./Button.svelte";
|
||||
|
||||
interface Props {
|
||||
icon: Component<{ size?: number; class?: string }>;
|
||||
label: string;
|
||||
onclick?: () => void;
|
||||
variant?: ButtonVariant;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
let {
|
||||
icon,
|
||||
label,
|
||||
onclick,
|
||||
variant = ButtonVariantDefine.PRIMARY,
|
||||
disabled = false,
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<Button label="" {onclick} {variant} {disabled} {icon} ariaLabel={label} />
|
||||
Reference in New Issue
Block a user