@runwisp/ui 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +39 -47
- package/src/astro/CTABand.astro +19 -12
- package/src/astro/Hero.astro +3 -3
- package/src/astro/SiteFooter.astro +4 -4
- package/src/astro/SiteHeader.astro +4 -4
- package/src/lib/actions/portal.ts +0 -3
- package/src/lib/assets/runwisp-logo.svg +1 -8
- package/src/lib/components/AccordionItem.svelte +4 -10
- package/src/lib/components/Alert.svelte +11 -11
- package/src/lib/components/Avatar.svelte +1 -1
- package/src/lib/components/Badge.svelte +13 -13
- package/src/lib/components/Breadcrumb.svelte +3 -3
- package/src/lib/components/Button.svelte +2 -2
- package/src/lib/components/Card.svelte +4 -4
- package/src/lib/components/Checkbox.svelte +12 -10
- package/src/lib/components/CodeBlock.svelte +7 -13
- package/src/lib/components/CronInput.svelte +12 -15
- package/src/lib/components/DataGrid.svelte +14 -13
- package/src/lib/components/Drawer.svelte +9 -9
- package/src/lib/components/Dropdown.svelte +12 -20
- package/src/lib/components/DurationInput.svelte +10 -14
- package/src/lib/components/EmptyState.svelte +1 -1
- package/src/lib/components/ErrorState.svelte +4 -4
- package/src/lib/components/FeatureCard.svelte +4 -4
- package/src/lib/components/FormField.svelte +4 -6
- package/src/lib/components/Heading.svelte +4 -1
- package/src/lib/components/Input.svelte +10 -12
- package/src/lib/components/Kbd.svelte +1 -1
- package/src/lib/components/Link.svelte +2 -3
- package/src/lib/components/LinkButton.svelte +2 -2
- package/src/lib/components/LogConsole.svelte +22 -21
- package/src/lib/components/Logo.svelte +3 -1
- package/src/lib/components/Modal.svelte +9 -11
- package/src/lib/components/PageContainer.svelte +1 -1
- package/src/lib/components/PageHeader.svelte +1 -1
- package/src/lib/components/Pagination.svelte +4 -4
- package/src/lib/components/Popover.svelte +5 -7
- package/src/lib/components/Progress.svelte +6 -4
- package/src/lib/components/Prose.svelte +4 -4
- package/src/lib/components/Radio.svelte +11 -10
- package/src/lib/components/RadioGroup.svelte +3 -5
- package/src/lib/components/Select.svelte +23 -36
- package/src/lib/components/Separator.svelte +4 -1
- package/src/lib/components/Skeleton.svelte +6 -6
- package/src/lib/components/StatusIndicator.svelte +7 -18
- package/src/lib/components/Table.svelte +1 -1
- package/src/lib/components/TableCell.svelte +1 -1
- package/src/lib/components/TableRow.svelte +1 -5
- package/src/lib/components/Tabs.svelte +10 -13
- package/src/lib/components/TaskCard.svelte +7 -4
- package/src/lib/components/Textarea.svelte +10 -11
- package/src/lib/components/ThemeToggle.svelte +1 -1
- package/src/lib/components/ToastContainer.svelte +3 -8
- package/src/lib/components/Toggle.svelte +2 -3
- package/src/lib/components/Tooltip.svelte +12 -10
- package/src/lib/components/button-styles.ts +17 -18
- package/src/lib/components/dashboard/RunDetailPanel.svelte +160 -249
- package/src/lib/components/dashboard/RunFilterPopover.svelte +31 -25
- package/src/lib/components/dashboard/RunsList.svelte +55 -50
- package/src/lib/components/dashboard/run-filters.test.ts +31 -33
- package/src/lib/components/dashboard/run-filters.ts +33 -33
- package/src/lib/components/dashboard/run-helpers.test.ts +42 -17
- package/src/lib/components/dashboard/run-helpers.ts +53 -17
- package/src/lib/components/dashboard/status-config.ts +9 -8
- package/src/lib/theme-tokens.css +179 -114
- package/src/lib/theme.css +49 -35
- package/src/lib/utils/error.ts +0 -3
- package/src/lib/utils/format.test.ts +2 -6
- package/src/lib/utils/format.ts +28 -3
|
@@ -5,13 +5,7 @@
|
|
|
5
5
|
import { fade } from "svelte/transition";
|
|
6
6
|
|
|
7
7
|
type Status =
|
|
8
|
-
| "
|
|
9
|
-
| "success"
|
|
10
|
-
| "failed"
|
|
11
|
-
| "pending"
|
|
12
|
-
| "paused"
|
|
13
|
-
| "scheduled"
|
|
14
|
-
| "cancelled";
|
|
8
|
+
"running" | "success" | "failed" | "pending" | "paused" | "scheduled" | "cancelled";
|
|
15
9
|
type Size = "sm" | "md" | "lg";
|
|
16
10
|
|
|
17
11
|
interface Props {
|
|
@@ -32,28 +26,25 @@
|
|
|
32
26
|
class: className = "",
|
|
33
27
|
}: Props = $props();
|
|
34
28
|
|
|
35
|
-
// Status configuration lookup
|
|
36
29
|
const STATUS_CONFIG: Record<Status, { label: string; classes: string; iconColor: string }> = {
|
|
37
30
|
running: {
|
|
38
31
|
label: "Running",
|
|
39
|
-
classes: "bg-info-soft text-info-soft-text border-info-soft
|
|
32
|
+
classes: "bg-info-soft text-info-soft-text border-info-soft-border",
|
|
40
33
|
iconColor: "text-info-surface",
|
|
41
34
|
},
|
|
42
35
|
success: {
|
|
43
36
|
label: "Success",
|
|
44
|
-
classes:
|
|
45
|
-
"bg-success-soft text-success-soft-text border-success-soft ring-1 ring-success-soft/50",
|
|
37
|
+
classes: "bg-success-soft text-success-soft-text border-success-soft-border",
|
|
46
38
|
iconColor: "text-success-surface",
|
|
47
39
|
},
|
|
48
40
|
failed: {
|
|
49
41
|
label: "Failed",
|
|
50
|
-
classes:
|
|
51
|
-
"bg-danger-soft text-danger-soft-text border-danger-soft ring-1 ring-danger-soft/50",
|
|
42
|
+
classes: "bg-danger-soft text-danger-soft-text border-danger-soft-border",
|
|
52
43
|
iconColor: "text-danger-surface",
|
|
53
44
|
},
|
|
54
45
|
pending: {
|
|
55
46
|
label: "Pending",
|
|
56
|
-
classes: "bg-warning-soft text-warning-soft-text border-warning-soft",
|
|
47
|
+
classes: "bg-warning-soft text-warning-soft-text border-warning-soft-border",
|
|
57
48
|
iconColor: "text-warning-surface",
|
|
58
49
|
},
|
|
59
50
|
paused: {
|
|
@@ -63,7 +54,7 @@
|
|
|
63
54
|
},
|
|
64
55
|
scheduled: {
|
|
65
56
|
label: "Scheduled",
|
|
66
|
-
classes: "bg-primary-soft text-primary-soft-text border-primary-soft",
|
|
57
|
+
classes: "bg-primary-soft text-primary-soft-text border-primary-soft-border",
|
|
67
58
|
iconColor: "text-primary",
|
|
68
59
|
},
|
|
69
60
|
cancelled: {
|
|
@@ -73,7 +64,6 @@
|
|
|
73
64
|
},
|
|
74
65
|
};
|
|
75
66
|
|
|
76
|
-
// Size configuration lookup
|
|
77
67
|
const SIZE_CONFIG: Record<Size, { classes: string; iconSize: number }> = {
|
|
78
68
|
sm: { classes: "px-2 py-0.5 text-2xs gap-1.5", iconSize: 10 },
|
|
79
69
|
md: { classes: "px-2.5 py-0.5 text-xs gap-1.5", iconSize: 12 },
|
|
@@ -85,11 +75,10 @@
|
|
|
85
75
|
</script>
|
|
86
76
|
|
|
87
77
|
<div
|
|
88
|
-
class="
|
|
78
|
+
class="inline-flex items-center justify-center rounded-full border font-mono tracking-wide {config.classes} {sizeConfig.classes} {className}"
|
|
89
79
|
role="status"
|
|
90
80
|
in:fade={{ duration: 150 }}
|
|
91
81
|
>
|
|
92
|
-
<!-- Icon Container -->
|
|
93
82
|
<span class="flex shrink-0 items-center justify-center {config.iconColor}">
|
|
94
83
|
{#if status === "running" || pulse}
|
|
95
84
|
<svg
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
let { children, class: className = "" }: Props = $props();
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
|
-
<div class="overflow-x-auto rounded-
|
|
15
|
+
<div class="overflow-x-auto rounded-[4px] border border-outline {className}">
|
|
16
16
|
<table class="w-full text-sm">
|
|
17
17
|
{@render children()}
|
|
18
18
|
</table>
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
<svelte:element
|
|
28
28
|
this={tag}
|
|
29
29
|
class="px-4 py-3 {alignClasses[align]} {header
|
|
30
|
-
? 'text-xs
|
|
30
|
+
? 'font-mono text-xs tracking-wide text-on-surface-faint uppercase'
|
|
31
31
|
: 'text-on-surface'} {className}"
|
|
32
32
|
>
|
|
33
33
|
{@render children()}
|
|
@@ -13,10 +13,6 @@
|
|
|
13
13
|
let { children, hoverable = false, class: className = "" }: Props = $props();
|
|
14
14
|
</script>
|
|
15
15
|
|
|
16
|
-
<tr
|
|
17
|
-
class="border-b border-outline-faint {hoverable
|
|
18
|
-
? 'duration-fast transition-colors hover:bg-surface-sunken'
|
|
19
|
-
: ''} {className}"
|
|
20
|
-
>
|
|
16
|
+
<tr class="border-b border-outline {hoverable ? 'hover:bg-surface-sunken' : ''} {className}">
|
|
21
17
|
{@render children()}
|
|
22
18
|
</tr>
|
|
@@ -53,9 +53,8 @@
|
|
|
53
53
|
const baseClasses = `
|
|
54
54
|
${fullWidth ? "flex-1" : ""}
|
|
55
55
|
inline-flex items-center justify-center gap-2 px-4 py-2.5
|
|
56
|
-
text-sm font-
|
|
57
|
-
|
|
58
|
-
disabled:cursor-not-allowed disabled:opacity-50
|
|
56
|
+
text-sm font-mono
|
|
57
|
+
disabled:cursor-not-allowed disabled:opacity-50
|
|
59
58
|
`;
|
|
60
59
|
|
|
61
60
|
const isActive = activeTab === tab.id;
|
|
@@ -63,16 +62,16 @@
|
|
|
63
62
|
if (variant === "underline") {
|
|
64
63
|
return `${baseClasses} -mb-px border-b-2 ${
|
|
65
64
|
isActive
|
|
66
|
-
? "border-primary text-primary
|
|
67
|
-
: "border-transparent text-on-surface-muted hover:border-outline-hover hover:text-
|
|
65
|
+
? "border-primary text-primary"
|
|
66
|
+
: "border-transparent text-on-surface-muted hover:border-outline-hover hover:text-primary"
|
|
68
67
|
}`;
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
if (variant === "pills" || variant === "enclosed") {
|
|
72
|
-
return `${baseClasses} rounded-
|
|
71
|
+
return `${baseClasses} rounded-[3px] ${
|
|
73
72
|
isActive
|
|
74
|
-
? "bg-
|
|
75
|
-
: "text-on-surface-muted hover:text-
|
|
73
|
+
? "bg-primary-soft text-primary-soft-text"
|
|
74
|
+
: "text-on-surface-muted hover:text-primary"
|
|
76
75
|
}`;
|
|
77
76
|
}
|
|
78
77
|
|
|
@@ -81,12 +80,11 @@
|
|
|
81
80
|
</script>
|
|
82
81
|
|
|
83
82
|
<div class={className}>
|
|
84
|
-
<!-- Tab list -->
|
|
85
83
|
<div
|
|
86
84
|
class="
|
|
87
85
|
{variant === 'underline' ? 'border-b border-outline' : ''}
|
|
88
|
-
{variant === 'pills' ? 'rounded-
|
|
89
|
-
{variant === 'enclosed' ? 'rounded-
|
|
86
|
+
{variant === 'pills' ? 'rounded-[4px] bg-surface-sunken p-1' : ''}
|
|
87
|
+
{variant === 'enclosed' ? 'rounded-[4px] border border-outline bg-surface-sunken p-1' : ''}
|
|
90
88
|
"
|
|
91
89
|
role="tablist"
|
|
92
90
|
>
|
|
@@ -120,7 +118,7 @@
|
|
|
120
118
|
{#if tab.badge || tab.badge === 0}
|
|
121
119
|
<span
|
|
122
120
|
class="
|
|
123
|
-
rounded-
|
|
121
|
+
rounded-[3px] px-1.5 py-0.5 font-mono text-xs
|
|
124
122
|
{activeTab === tab.id
|
|
125
123
|
? 'bg-primary-soft text-primary-soft-text'
|
|
126
124
|
: 'bg-surface-sunken text-on-surface-muted'}
|
|
@@ -134,7 +132,6 @@
|
|
|
134
132
|
</nav>
|
|
135
133
|
</div>
|
|
136
134
|
|
|
137
|
-
<!-- Tab panels -->
|
|
138
135
|
{#if children && renderedActiveTab}
|
|
139
136
|
<div
|
|
140
137
|
id="tabpanel-{renderedActiveTab}"
|
|
@@ -15,16 +15,19 @@
|
|
|
15
15
|
|
|
16
16
|
let { accent = "wisp", onclick, children, class: className = "" }: Props = $props();
|
|
17
17
|
|
|
18
|
+
// Each accent maps to a left keyline in the matching semantic colour. The
|
|
19
|
+
// other three sides stay a neutral hairline (set per-side so the shorthand
|
|
20
|
+
// never overrides the accent left-colour), and hover lifts the surface.
|
|
18
21
|
const accentClasses: Record<TaskCardAccent, string> = {
|
|
19
|
-
danger: "
|
|
20
|
-
wisp: "
|
|
21
|
-
aurora: "
|
|
22
|
+
danger: "border-l-danger-surface",
|
|
23
|
+
wisp: "border-l-primary",
|
|
24
|
+
aurora: "border-l-info",
|
|
22
25
|
};
|
|
23
26
|
</script>
|
|
24
27
|
|
|
25
28
|
<button
|
|
26
29
|
type="button"
|
|
27
|
-
class="group w-full rounded-
|
|
30
|
+
class="group w-full rounded-[4px] border border-l-2 border-t-outline border-r-outline border-b-outline bg-surface-raised p-3 text-left hover:bg-surface-sunken {accentClasses[
|
|
28
31
|
accent
|
|
29
32
|
]} {className}"
|
|
30
33
|
{onclick}
|
|
@@ -34,21 +34,21 @@
|
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
const textareaClasses = `
|
|
37
|
-
w-full px-3.5 py-2.5 rounded-
|
|
37
|
+
w-full px-3.5 py-2.5 rounded-[3px] border font-mono
|
|
38
38
|
text-sm bg-surface-raised text-on-surface placeholder:text-on-surface-faint
|
|
39
|
-
focus:outline-none focus:ring-2 focus:ring-offset-
|
|
39
|
+
focus:outline-none focus:ring-2 focus:ring-offset-2
|
|
40
40
|
disabled:bg-surface-sunken disabled:text-on-surface-muted disabled:cursor-not-allowed
|
|
41
|
-
|
|
42
|
-
`;
|
|
41
|
+
`;
|
|
43
42
|
|
|
44
43
|
const normalBorder =
|
|
45
|
-
"border-outline hover:border-outline-hover focus:border-ring focus:ring-ring
|
|
46
|
-
const errorBorder =
|
|
44
|
+
"border-outline hover:border-outline-hover shadow-sm focus:border-ring focus:ring-ring";
|
|
45
|
+
const errorBorder =
|
|
46
|
+
"border-danger-surface focus:border-danger-surface focus:ring-danger-surface";
|
|
47
47
|
</script>
|
|
48
48
|
|
|
49
49
|
<div class="space-y-1.5 {className}">
|
|
50
50
|
{#if label}
|
|
51
|
-
<label class="block text-
|
|
51
|
+
<label class="block font-mono text-xs font-medium text-on-surface-muted" for={id}>
|
|
52
52
|
{label}
|
|
53
53
|
</label>
|
|
54
54
|
{/if}
|
|
@@ -63,8 +63,7 @@
|
|
|
63
63
|
{disabled}
|
|
64
64
|
{id}
|
|
65
65
|
bind:value
|
|
66
|
-
{...restProps}
|
|
67
|
-
></textarea>
|
|
66
|
+
{...restProps}></textarea>
|
|
68
67
|
|
|
69
68
|
{#if error}
|
|
70
69
|
<div class="pointer-events-none absolute top-3 right-3 text-danger-soft-text">
|
|
@@ -74,8 +73,8 @@
|
|
|
74
73
|
</div>
|
|
75
74
|
|
|
76
75
|
{#if error}
|
|
77
|
-
<p class="text-
|
|
76
|
+
<p class="font-sans text-xs text-danger-soft-text">{error}</p>
|
|
78
77
|
{:else if hint}
|
|
79
|
-
<p class="text-
|
|
78
|
+
<p class="font-sans text-xs text-on-surface-muted">{hint}</p>
|
|
80
79
|
{/if}
|
|
81
80
|
</div>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
aria-pressed={isDark}
|
|
38
38
|
aria-label={isDark ? "Switch to light theme" : "Switch to dark theme"}
|
|
39
39
|
title={isDark ? "Switch to light theme" : "Switch to dark theme"}
|
|
40
|
-
class="inline-flex h-9 w-9 items-center justify-center rounded-
|
|
40
|
+
class="inline-flex h-9 w-9 items-center justify-center rounded-[3px] border border-outline bg-surface-raised text-on-surface-muted hover:border-outline-hover hover:text-on-surface {className}"
|
|
41
41
|
>
|
|
42
42
|
{#if mounted && isDark}
|
|
43
43
|
<Sun size={16} />
|
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
<!-- SPDX-License-Identifier: Apache-2.0 -->
|
|
3
3
|
|
|
4
4
|
<script lang="ts">
|
|
5
|
-
/**
|
|
6
|
-
* Toast notification component
|
|
7
|
-
* Displays toast notifications for user feedback
|
|
8
|
-
*/
|
|
9
5
|
import { fly, fade } from "svelte/transition";
|
|
10
6
|
import { CircleCheck, CircleX, Info, TriangleAlert, X } from "@lucide/svelte";
|
|
11
7
|
import { toast, type Toast } from "../utils/toast.svelte.js";
|
|
@@ -50,7 +46,6 @@
|
|
|
50
46
|
}
|
|
51
47
|
</script>
|
|
52
48
|
|
|
53
|
-
<!-- Toast Container -->
|
|
54
49
|
<div
|
|
55
50
|
class="pointer-events-none fixed bottom-4 left-1/2 z-[100] flex -translate-x-1/2 flex-col gap-2"
|
|
56
51
|
role="region"
|
|
@@ -62,7 +57,7 @@
|
|
|
62
57
|
<div
|
|
63
58
|
in:fly={{ y: 20, duration: 300 }}
|
|
64
59
|
out:fade={{ duration: 200 }}
|
|
65
|
-
class="pointer-events-auto isolate flex max-w-md min-w-[320px] items-start gap-3 rounded-
|
|
60
|
+
class="pointer-events-auto isolate flex max-w-md min-w-[320px] items-start gap-3 rounded-[4px] border bg-surface-overlay px-4 py-3 shadow-lg {getColorClasses(
|
|
66
61
|
toastItem.type,
|
|
67
62
|
)}"
|
|
68
63
|
role="alert"
|
|
@@ -79,14 +74,14 @@
|
|
|
79
74
|
action.onClick();
|
|
80
75
|
toast.remove(toastItem.id);
|
|
81
76
|
}}
|
|
82
|
-
class="flex-shrink-0 rounded-
|
|
77
|
+
class="flex-shrink-0 rounded-[3px] px-2 py-1 font-mono text-xs font-semibold text-on-surface underline-offset-2 hover:bg-surface-sunken hover:underline"
|
|
83
78
|
>
|
|
84
79
|
{action.label}
|
|
85
80
|
</button>
|
|
86
81
|
{/if}
|
|
87
82
|
<button
|
|
88
83
|
onclick={() => toast.remove(toastItem.id)}
|
|
89
|
-
class="flex-shrink-0 rounded-
|
|
84
|
+
class="flex-shrink-0 rounded-[3px] p-1 text-on-surface-muted hover:bg-surface-sunken hover:text-on-surface"
|
|
90
85
|
aria-label="Close notification"
|
|
91
86
|
>
|
|
92
87
|
<X class="h-4 w-4" aria-hidden="true" />
|
|
@@ -55,7 +55,6 @@
|
|
|
55
55
|
class="
|
|
56
56
|
relative inline-flex shrink-0 items-center rounded-full
|
|
57
57
|
{sizeConfig.track}
|
|
58
|
-
transition-colors duration-200
|
|
59
58
|
focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
|
|
60
59
|
{checked ? 'bg-primary' : 'bg-outline-hover'}
|
|
61
60
|
{disabled ? 'cursor-not-allowed' : 'cursor-pointer'}
|
|
@@ -65,7 +64,7 @@
|
|
|
65
64
|
class="
|
|
66
65
|
inline-block rounded-full bg-surface-raised shadow-sm
|
|
67
66
|
{sizeConfig.thumb}
|
|
68
|
-
transform transition-transform duration-
|
|
67
|
+
transform transition-transform duration-[120ms]
|
|
69
68
|
{checked ? sizeConfig.translate : 'translate-x-0.5'}
|
|
70
69
|
"
|
|
71
70
|
></span>
|
|
@@ -74,7 +73,7 @@
|
|
|
74
73
|
{#if label || description}
|
|
75
74
|
<div class="flex flex-col gap-0.5">
|
|
76
75
|
{#if label}
|
|
77
|
-
<span class="{sizeConfig.text} font-medium text-on-surface">{label}</span>
|
|
76
|
+
<span class="{sizeConfig.text} font-mono font-medium text-on-surface">{label}</span>
|
|
78
77
|
{/if}
|
|
79
78
|
{#if description}
|
|
80
79
|
<span class="text-sm text-on-surface-muted">{description}</span>
|
|
@@ -31,26 +31,28 @@
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
const arrowClasses: Record<TooltipPosition, string> = {
|
|
34
|
-
top: "top-full left-1/2 -translate-x-1/2 border-t-
|
|
35
|
-
bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-
|
|
36
|
-
left: "left-full top-1/2 -translate-y-1/2 border-l-
|
|
37
|
-
right: "right-full top-1/2 -translate-y-1/2 border-r-
|
|
34
|
+
top: "top-full left-1/2 -translate-x-1/2 border-t-outline border-x-transparent border-b-transparent",
|
|
35
|
+
bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-outline border-x-transparent border-t-transparent",
|
|
36
|
+
left: "left-full top-1/2 -translate-y-1/2 border-l-outline border-y-transparent border-r-transparent",
|
|
37
|
+
right: "right-full top-1/2 -translate-y-1/2 border-r-outline border-y-transparent border-l-transparent",
|
|
38
38
|
};
|
|
39
39
|
</script>
|
|
40
40
|
|
|
41
41
|
<div class="group relative inline-block {className}">
|
|
42
42
|
{@render children()}
|
|
43
43
|
|
|
44
|
+
<!-- Hover intent: 100ms before it appears, so sweeping the pointer across a
|
|
45
|
+
dense row doesn't flash a trail of bubbles. Still no fade — `duration-0`
|
|
46
|
+
keeps the appearance instant once the delay is served, per DESIGN.md. -->
|
|
44
47
|
<div
|
|
45
48
|
class="
|
|
46
49
|
absolute z-50 {positionClasses[position]}
|
|
47
|
-
pointer-events-none invisible rounded-
|
|
48
|
-
bg-
|
|
49
|
-
|
|
50
|
+
pointer-events-none invisible rounded-[3px]
|
|
51
|
+
border border-outline bg-surface-overlay px-2.5 py-1.5 font-sans
|
|
52
|
+
text-xs
|
|
50
53
|
{wide ? 'w-max max-w-xs whitespace-normal' : 'whitespace-nowrap'}
|
|
51
|
-
text-
|
|
52
|
-
duration-
|
|
53
|
-
group-hover:opacity-100
|
|
54
|
+
text-on-surface opacity-0 transition-[opacity,visibility]
|
|
55
|
+
delay-100 duration-0 group-hover:visible group-hover:opacity-100
|
|
54
56
|
"
|
|
55
57
|
role="tooltip"
|
|
56
58
|
>
|
|
@@ -7,45 +7,44 @@ export type ButtonSize = "xs" | "sm" | "md" | "lg";
|
|
|
7
7
|
export const BUTTON_BASE = `
|
|
8
8
|
group
|
|
9
9
|
inline-flex items-center justify-center gap-2
|
|
10
|
-
font-
|
|
11
|
-
|
|
12
|
-
focus-visible:outline-none focus-visible:ring-
|
|
10
|
+
font-mono font-medium tracking-normal
|
|
11
|
+
cursor-pointer select-none border
|
|
12
|
+
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
|
|
13
13
|
disabled:opacity-50 disabled:cursor-not-allowed
|
|
14
|
-
|
|
15
|
-
active:scale-[0.98]
|
|
14
|
+
active:translate-y-px
|
|
16
15
|
`;
|
|
17
16
|
|
|
18
17
|
export const BUTTON_VARIANTS: Record<ButtonVariant, string> = {
|
|
19
18
|
primary: `
|
|
20
|
-
bg-primary text-on-primary
|
|
21
|
-
hover:bg-primary-hover
|
|
19
|
+
bg-primary text-on-primary border-transparent
|
|
20
|
+
hover:bg-primary-hover
|
|
22
21
|
active:bg-primary-active
|
|
23
22
|
`,
|
|
24
23
|
secondary: `
|
|
25
|
-
bg-surface-raised text-on-surface
|
|
26
|
-
hover:
|
|
24
|
+
bg-surface-raised text-on-surface border-outline
|
|
25
|
+
hover:border-outline-hover hover:text-primary
|
|
27
26
|
active:bg-surface-sunken
|
|
28
27
|
`,
|
|
29
28
|
ghost: `
|
|
30
|
-
bg-transparent text-on-surface-muted
|
|
29
|
+
bg-transparent text-on-surface-muted border-transparent
|
|
31
30
|
hover:bg-surface-sunken hover:text-on-surface
|
|
32
31
|
active:bg-surface-sunken
|
|
33
32
|
`,
|
|
34
33
|
danger: `
|
|
35
|
-
bg-danger-surface text-on-danger
|
|
36
|
-
hover:bg-danger-hover
|
|
34
|
+
bg-danger-surface text-on-danger border-transparent
|
|
35
|
+
hover:bg-danger-hover
|
|
37
36
|
active:bg-danger-active
|
|
38
37
|
`,
|
|
39
38
|
success: `
|
|
40
|
-
bg-success-surface text-on-success
|
|
41
|
-
hover:bg-success-hover
|
|
39
|
+
bg-success-surface text-on-success border-transparent
|
|
40
|
+
hover:bg-success-hover
|
|
42
41
|
active:bg-success-surface
|
|
43
42
|
`,
|
|
44
43
|
};
|
|
45
44
|
|
|
46
45
|
export const BUTTON_SIZES: Record<ButtonSize, string> = {
|
|
47
|
-
xs: "text-xs px-2 py-1 rounded-
|
|
48
|
-
sm: "text-sm px-3 py-1.5 rounded-
|
|
49
|
-
md: "text-sm px-4 py-2 rounded-
|
|
50
|
-
lg: "text-base px-6 py-
|
|
46
|
+
xs: "text-xs px-2.5 py-1 rounded-[3px]",
|
|
47
|
+
sm: "text-sm px-3 py-1.5 rounded-[3px]",
|
|
48
|
+
md: "text-sm px-4 py-2 rounded-[3px]",
|
|
49
|
+
lg: "text-base px-6 py-2.5 rounded-[3px]",
|
|
51
50
|
};
|