refactor: icon and download button use button component

This commit is contained in:
2026-09-02 18:37:43 +05:00
parent 3d0f8ebb10
commit 8a6f87938d
16 changed files with 85 additions and 167 deletions
+1 -1
View File
@@ -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 -1
View File
@@ -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>
+1 -12
View File
@@ -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>
+3 -3
View File
@@ -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">
+10
View File
@@ -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",
+14 -16
View File
@@ -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} />