svelte-comp 1.3.3 → 1.3.6
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/LICENSE.md +21 -21
- package/README.md +101 -100
- package/dist/App.svelte +507 -507
- package/dist/Container.svelte +59 -59
- package/dist/app.css +234 -235
- package/dist/app.d.ts +10 -0
- package/dist/lib/Accordion.svelte +155 -155
- package/dist/lib/Badge.svelte +44 -44
- package/dist/lib/Button.svelte +185 -170
- package/dist/lib/Calendar.svelte +384 -384
- package/dist/lib/Card.svelte +103 -103
- package/dist/lib/Carousel.svelte +293 -293
- package/dist/lib/Carousel.svelte.d.ts +1 -1
- package/dist/lib/CheckBox.svelte +210 -210
- package/dist/lib/CodeView.svelte +308 -307
- package/dist/lib/ColorPicker.svelte +159 -159
- package/dist/lib/ContextMenu.svelte +328 -322
- package/dist/lib/DatePicker.svelte +246 -246
- package/dist/lib/Dialog.svelte +233 -233
- package/dist/lib/Field.svelte +299 -299
- package/dist/lib/FilePicker.svelte +295 -240
- package/dist/lib/FilePicker.svelte.d.ts +6 -1
- package/dist/lib/Form.svelte +438 -438
- package/dist/lib/Hamburger.svelte +217 -217
- package/dist/lib/InstallPWA.svelte +94 -94
- package/dist/lib/Menu.svelte +623 -623
- package/dist/lib/NoticeBase.svelte +140 -140
- package/dist/lib/PaginatedCard.svelte +73 -73
- package/dist/lib/Pagination.svelte +119 -119
- package/dist/lib/PrimaryColorSelect.svelte +111 -111
- package/dist/lib/ProgressBar.svelte +141 -141
- package/dist/lib/ProgressCircle.svelte +190 -190
- package/dist/lib/Radio.svelte +189 -189
- package/dist/lib/SearchInput.svelte +104 -104
- package/dist/lib/Select.svelte +524 -524
- package/dist/lib/Slider.svelte +253 -253
- package/dist/lib/Splitter.svelte +159 -150
- package/dist/lib/Switch.svelte +168 -167
- package/dist/lib/Table.svelte +299 -299
- package/dist/lib/Tabs.svelte +213 -213
- package/dist/lib/ThemeToggle.svelte +128 -127
- package/dist/lib/TimePicker.svelte +312 -312
- package/dist/lib/TimePickerNew.svelte +634 -0
- package/dist/lib/TimePickerNew.svelte.d.ts +49 -0
- package/dist/lib/Toast.svelte +123 -123
- package/dist/lib/Tooltip.svelte +110 -110
- package/dist/lib/Topbar.svelte +107 -107
- package/dist/lib/__tests__/Accordion.test.d.ts +1 -0
- package/dist/lib/__tests__/Accordion.test.js +171 -0
- package/dist/lib/__tests__/Badge.test.d.ts +1 -0
- package/dist/lib/__tests__/Badge.test.js +41 -0
- package/dist/lib/__tests__/Button.test.d.ts +1 -0
- package/dist/lib/__tests__/Button.test.js +269 -0
- package/dist/lib/__tests__/Calendar.test.d.ts +1 -0
- package/dist/lib/__tests__/Calendar.test.js +171 -0
- package/dist/lib/__tests__/Card.test.d.ts +1 -0
- package/dist/lib/__tests__/Card.test.js +148 -0
- package/dist/lib/__tests__/Carousel.test.d.ts +1 -0
- package/dist/lib/__tests__/Carousel.test.js +439 -0
- package/dist/lib/__tests__/CheckBox.test.d.ts +1 -0
- package/dist/lib/__tests__/CheckBox.test.js +152 -0
- package/dist/lib/__tests__/CodeView.test.d.ts +1 -0
- package/dist/lib/__tests__/CodeView.test.js +157 -0
- package/dist/lib/__tests__/ColorPicker.test.d.ts +1 -0
- package/dist/lib/__tests__/ColorPicker.test.js +93 -0
- package/dist/lib/__tests__/ContextMenu.test.d.ts +1 -0
- package/dist/lib/__tests__/ContextMenu.test.js +67 -0
- package/dist/lib/__tests__/DatePicker.test.d.ts +1 -0
- package/dist/lib/__tests__/DatePicker.test.js +108 -0
- package/dist/lib/__tests__/Dialog.test.d.ts +1 -0
- package/dist/lib/__tests__/Dialog.test.js +183 -0
- package/dist/lib/__tests__/Field.test.d.ts +1 -0
- package/dist/lib/__tests__/Field.test.js +190 -0
- package/dist/lib/__tests__/FilePicker.test.d.ts +1 -0
- package/dist/lib/__tests__/FilePicker.test.js +179 -0
- package/dist/lib/__tests__/Form.integration.test.d.ts +1 -0
- package/dist/lib/__tests__/Form.integration.test.js +158 -0
- package/dist/lib/__tests__/Form.test.d.ts +1 -0
- package/dist/lib/__tests__/Form.test.js +463 -0
- package/dist/lib/__tests__/Hamburger.test.d.ts +1 -0
- package/dist/lib/__tests__/Hamburger.test.js +161 -0
- package/dist/lib/__tests__/InstallPWA.test.d.ts +1 -0
- package/dist/lib/__tests__/InstallPWA.test.js +15 -0
- package/dist/lib/__tests__/Menu.test.d.ts +1 -0
- package/dist/lib/__tests__/Menu.test.js +285 -0
- package/dist/lib/__tests__/NoticeBase.test.d.ts +1 -0
- package/dist/lib/__tests__/NoticeBase.test.js +60 -0
- package/dist/lib/__tests__/PaginatedCard.test.d.ts +1 -0
- package/dist/lib/__tests__/PaginatedCard.test.js +89 -0
- package/dist/lib/__tests__/Pagination.test.d.ts +1 -0
- package/dist/lib/__tests__/Pagination.test.js +168 -0
- package/dist/lib/__tests__/PrimaryColorSelect.test.d.ts +1 -0
- package/dist/lib/__tests__/PrimaryColorSelect.test.js +92 -0
- package/dist/lib/__tests__/ProgressBar.test.d.ts +1 -0
- package/dist/lib/__tests__/ProgressBar.test.js +69 -0
- package/dist/lib/__tests__/ProgressCircle.test.d.ts +1 -0
- package/dist/lib/__tests__/ProgressCircle.test.js +71 -0
- package/dist/lib/__tests__/Radio.test.d.ts +1 -0
- package/dist/lib/__tests__/Radio.test.js +127 -0
- package/dist/lib/__tests__/SearchInput.test.d.ts +1 -0
- package/dist/lib/__tests__/SearchInput.test.js +80 -0
- package/dist/lib/__tests__/Select.test.d.ts +1 -0
- package/dist/lib/__tests__/Select.test.js +408 -0
- package/dist/lib/__tests__/Slider.test.d.ts +1 -0
- package/dist/lib/__tests__/Slider.test.js +213 -0
- package/dist/lib/__tests__/Splitter.test.d.ts +1 -0
- package/dist/lib/__tests__/Splitter.test.js +87 -0
- package/dist/lib/__tests__/Switch.test.d.ts +1 -0
- package/dist/lib/__tests__/Switch.test.js +97 -0
- package/dist/lib/__tests__/Table.test.d.ts +1 -0
- package/dist/lib/__tests__/Table.test.js +349 -0
- package/dist/lib/__tests__/Tabs.test.d.ts +1 -0
- package/dist/lib/__tests__/Tabs.test.js +262 -0
- package/dist/lib/__tests__/ThemeToggle.test.d.ts +1 -0
- package/dist/lib/__tests__/ThemeToggle.test.js +84 -0
- package/dist/lib/__tests__/TimePicker.test.d.ts +1 -0
- package/dist/lib/__tests__/TimePicker.test.js +146 -0
- package/dist/lib/__tests__/TimePickerNew.test.d.ts +1 -0
- package/dist/lib/__tests__/TimePickerNew.test.js +322 -0
- package/dist/lib/__tests__/Toast.test.d.ts +1 -0
- package/dist/lib/__tests__/Toast.test.js +135 -0
- package/dist/lib/__tests__/Tooltip.test.d.ts +1 -0
- package/dist/lib/__tests__/Tooltip.test.js +171 -0
- package/dist/lib/__tests__/Topbar.test.d.ts +1 -0
- package/dist/lib/__tests__/Topbar.test.js +25 -0
- package/dist/lib/__tests__/setupLangContext.d.ts +1 -0
- package/dist/lib/__tests__/setupLangContext.js +65 -0
- package/dist/lib/__tests__/storage.test.d.ts +1 -0
- package/dist/lib/__tests__/storage.test.js +124 -0
- package/dist/lib/__tests__/utils.test.d.ts +1 -0
- package/dist/lib/__tests__/utils.test.js +11 -0
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +1 -0
- package/dist/lib/lang.d.ts +4 -0
- package/dist/lib/lang.js +4 -0
- package/dist/styles.css +234 -232
- package/dist/utils/index.js +15 -4
- package/package.json +52 -52
package/dist/App.svelte
CHANGED
|
@@ -37,102 +37,102 @@
|
|
|
37
37
|
import Topbar from "./lib/Topbar.svelte";
|
|
38
38
|
import type { FieldSchema, MenuAction, MenuItem, SizeKey, ToastVariant } from "./lib/types";
|
|
39
39
|
import Container from "./Container.svelte";
|
|
40
|
-
|
|
41
|
-
const tabs = [
|
|
42
|
-
{ id: "overview", label: "Overview" },
|
|
43
|
-
{ id: "team", label: "Team" },
|
|
44
|
-
{ id: "table", label: "Data" },
|
|
45
|
-
];
|
|
46
|
-
let activeTab = $state(tabs[0].id);
|
|
47
|
-
|
|
48
|
-
let sliderValue = $state(68);
|
|
49
|
-
let autoplay = $state(true);
|
|
50
|
-
|
|
51
|
-
const planOptions = [
|
|
52
|
-
{ label: "Starter", value: "starter" },
|
|
53
|
-
{ label: "Pro", value: "pro" },
|
|
54
|
-
{ label: "Enterprise", value: "enterprise" },
|
|
55
|
-
];
|
|
56
|
-
|
|
57
|
-
let selectedPlan = $state(planOptions[1].value);
|
|
58
|
-
let featureName = $state("Dashboard 2.0");
|
|
59
|
-
let contactEmail = $state("team@studio.dev");
|
|
60
|
-
let dateValue = $state<string | null>(null);
|
|
61
|
-
let timeValue = $state<string | null>(null);
|
|
62
|
-
let accentColor = $state<string | null>("#7c3aed");
|
|
63
|
-
|
|
64
|
-
const accordionItems = [
|
|
65
|
-
{
|
|
66
|
-
title: "Composition",
|
|
67
|
-
content:
|
|
68
|
-
"Card, Tabs, Table and Carousel let you assemble complex screens without extra layout work.",
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
title: "Forms",
|
|
72
|
-
content:
|
|
73
|
-
"Field, Select, DatePicker, TimePicker and ColorPicker share spacing, tokens and state handling.",
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
title: "Feedback",
|
|
77
|
-
content:
|
|
78
|
-
"ProgressBar, ProgressCircle, Toast and Dialog keep users informed without noise.",
|
|
79
|
-
},
|
|
80
|
-
];
|
|
81
|
-
|
|
82
|
-
const carouselItems = [
|
|
83
|
-
{
|
|
84
|
-
title: "Smooth forms",
|
|
85
|
-
content:
|
|
86
|
-
"Clean fields, tight spacing and built-in hints help ship surveys in minutes.",
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
title: "Smart navigation",
|
|
90
|
-
content:
|
|
91
|
-
"Tabs and Accordion keep content nearby while Carousel saves horizontal space.",
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
title: "Status signals",
|
|
95
|
-
content:
|
|
96
|
-
"Toast and progress indicators deliver context quickly without blocking flows.",
|
|
97
|
-
},
|
|
98
|
-
];
|
|
99
|
-
|
|
100
|
-
const tableColumns = [
|
|
101
|
-
{ key: "name", label: "Feature", width: "42%" },
|
|
102
|
-
{ key: "owner", label: "Owner" },
|
|
103
|
-
{ key: "status", label: "Status" },
|
|
104
|
-
{ key: "eta", label: "ETA", align: "end" },
|
|
105
|
-
] as const;
|
|
106
|
-
|
|
107
|
-
const tableRows = [
|
|
108
|
-
{ id: 1, name: "Onboarding", owner: "Anna", status: "Ready", eta: "Today" },
|
|
109
|
-
{ id: 2, name: "Theming", owner: "Mark", status: "In progress", eta: "Fri" },
|
|
110
|
-
{ id: 3, name: "Notifications", owner: "Oleg", status: "Testing", eta: "Thu" },
|
|
111
|
-
{ id: 4, name: "Data tables", owner: "Ira", status: "In progress", eta: "Next week" },
|
|
112
|
-
{ id: 5, name: "Carousel", owner: "Anton", status: "Design", eta: "In two weeks" },
|
|
113
|
-
{ id: 6, name: "Accessibility", owner: "Sasha", status: "Review", eta: "Today" },
|
|
114
|
-
];
|
|
115
|
-
|
|
116
|
-
const pageSize = 4;
|
|
117
|
-
let tablePage = $state(1);
|
|
118
|
-
const totalPages = $derived(
|
|
119
|
-
Math.max(1, Math.ceil(tableRows.length / pageSize))
|
|
120
|
-
);
|
|
121
|
-
const pagedRows = $derived(
|
|
122
|
-
tableRows.slice((tablePage - 1) * pageSize, tablePage * pageSize)
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
$effect(() => {
|
|
126
|
-
if (tablePage > totalPages) tablePage = totalPages;
|
|
127
|
-
if (tablePage < 1) tablePage = 1;
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
const quality = [
|
|
131
|
-
{ label: "UI polish", value: 86 },
|
|
132
|
-
{ label: "Accessibility", value: 72 },
|
|
133
|
-
{ label: "Performance", value: 64 },
|
|
134
|
-
];
|
|
135
|
-
|
|
40
|
+
|
|
41
|
+
const tabs = [
|
|
42
|
+
{ id: "overview", label: "Overview" },
|
|
43
|
+
{ id: "team", label: "Team" },
|
|
44
|
+
{ id: "table", label: "Data" },
|
|
45
|
+
];
|
|
46
|
+
let activeTab = $state(tabs[0].id);
|
|
47
|
+
|
|
48
|
+
let sliderValue = $state(68);
|
|
49
|
+
let autoplay = $state(true);
|
|
50
|
+
|
|
51
|
+
const planOptions = [
|
|
52
|
+
{ label: "Starter", value: "starter" },
|
|
53
|
+
{ label: "Pro", value: "pro" },
|
|
54
|
+
{ label: "Enterprise", value: "enterprise" },
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
let selectedPlan = $state(planOptions[1].value);
|
|
58
|
+
let featureName = $state("Dashboard 2.0");
|
|
59
|
+
let contactEmail = $state("team@studio.dev");
|
|
60
|
+
let dateValue = $state<string | null>(null);
|
|
61
|
+
let timeValue = $state<string | null>(null);
|
|
62
|
+
let accentColor = $state<string | null>("#7c3aed");
|
|
63
|
+
|
|
64
|
+
const accordionItems = [
|
|
65
|
+
{
|
|
66
|
+
title: "Composition",
|
|
67
|
+
content:
|
|
68
|
+
"Card, Tabs, Table and Carousel let you assemble complex screens without extra layout work.",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
title: "Forms",
|
|
72
|
+
content:
|
|
73
|
+
"Field, Select, DatePicker, TimePicker and ColorPicker share spacing, tokens and state handling.",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
title: "Feedback",
|
|
77
|
+
content:
|
|
78
|
+
"ProgressBar, ProgressCircle, Toast and Dialog keep users informed without noise.",
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
const carouselItems = [
|
|
83
|
+
{
|
|
84
|
+
title: "Smooth forms",
|
|
85
|
+
content:
|
|
86
|
+
"Clean fields, tight spacing and built-in hints help ship surveys in minutes.",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
title: "Smart navigation",
|
|
90
|
+
content:
|
|
91
|
+
"Tabs and Accordion keep content nearby while Carousel saves horizontal space.",
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
title: "Status signals",
|
|
95
|
+
content:
|
|
96
|
+
"Toast and progress indicators deliver context quickly without blocking flows.",
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
const tableColumns = [
|
|
101
|
+
{ key: "name", label: "Feature", width: "42%" },
|
|
102
|
+
{ key: "owner", label: "Owner" },
|
|
103
|
+
{ key: "status", label: "Status" },
|
|
104
|
+
{ key: "eta", label: "ETA", align: "end" },
|
|
105
|
+
] as const;
|
|
106
|
+
|
|
107
|
+
const tableRows = [
|
|
108
|
+
{ id: 1, name: "Onboarding", owner: "Anna", status: "Ready", eta: "Today" },
|
|
109
|
+
{ id: 2, name: "Theming", owner: "Mark", status: "In progress", eta: "Fri" },
|
|
110
|
+
{ id: 3, name: "Notifications", owner: "Oleg", status: "Testing", eta: "Thu" },
|
|
111
|
+
{ id: 4, name: "Data tables", owner: "Ira", status: "In progress", eta: "Next week" },
|
|
112
|
+
{ id: 5, name: "Carousel", owner: "Anton", status: "Design", eta: "In two weeks" },
|
|
113
|
+
{ id: 6, name: "Accessibility", owner: "Sasha", status: "Review", eta: "Today" },
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
const pageSize = 4;
|
|
117
|
+
let tablePage = $state(1);
|
|
118
|
+
const totalPages = $derived(
|
|
119
|
+
Math.max(1, Math.ceil(tableRows.length / pageSize))
|
|
120
|
+
);
|
|
121
|
+
const pagedRows = $derived(
|
|
122
|
+
tableRows.slice((tablePage - 1) * pageSize, tablePage * pageSize)
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
$effect(() => {
|
|
126
|
+
if (tablePage > totalPages) tablePage = totalPages;
|
|
127
|
+
if (tablePage < 1) tablePage = 1;
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const quality = [
|
|
131
|
+
{ label: "UI polish", value: 86 },
|
|
132
|
+
{ label: "Accessibility", value: 72 },
|
|
133
|
+
{ label: "Performance", value: 64 },
|
|
134
|
+
];
|
|
135
|
+
|
|
136
136
|
const team = [
|
|
137
137
|
{ name: "Anna", role: "Product", focus: "UX flows" },
|
|
138
138
|
{ name: "Mark", role: "Frontend", focus: "Components" },
|
|
@@ -211,28 +211,28 @@
|
|
|
211
211
|
type ToastItem = { id: number; title?: string; message: string; variant: ToastVariant };
|
|
212
212
|
let toasts = $state<ToastItem[]>([]);
|
|
213
213
|
let toastId = 0;
|
|
214
|
-
|
|
215
|
-
function pushToast(variant: ToastVariant) {
|
|
216
|
-
const messageMap: Record<ToastVariant, string> = {
|
|
217
|
-
success: "Changes saved and ready to roll out.",
|
|
218
|
-
info: "Components share tokens, typography, and behavior.",
|
|
219
|
-
warning: "Double-check disabled, focus, and hover states.",
|
|
220
|
-
danger: "Tests caught a blocking issue. Investigate.",
|
|
221
|
-
};
|
|
222
|
-
const titleMap: Record<ToastVariant, string> = {
|
|
223
|
-
success: "Success",
|
|
224
|
-
info: "Heads up",
|
|
225
|
-
warning: "Warning",
|
|
226
|
-
danger: "Error",
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
const id = ++toastId;
|
|
230
|
-
toasts = [
|
|
231
|
-
...toasts,
|
|
232
|
-
{ id, variant, title: titleMap[variant], message: messageMap[variant] },
|
|
233
|
-
];
|
|
234
|
-
}
|
|
235
|
-
|
|
214
|
+
|
|
215
|
+
function pushToast(variant: ToastVariant) {
|
|
216
|
+
const messageMap: Record<ToastVariant, string> = {
|
|
217
|
+
success: "Changes saved and ready to roll out.",
|
|
218
|
+
info: "Components share tokens, typography, and behavior.",
|
|
219
|
+
warning: "Double-check disabled, focus, and hover states.",
|
|
220
|
+
danger: "Tests caught a blocking issue. Investigate.",
|
|
221
|
+
};
|
|
222
|
+
const titleMap: Record<ToastVariant, string> = {
|
|
223
|
+
success: "Success",
|
|
224
|
+
info: "Heads up",
|
|
225
|
+
warning: "Warning",
|
|
226
|
+
danger: "Error",
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const id = ++toastId;
|
|
230
|
+
toasts = [
|
|
231
|
+
...toasts,
|
|
232
|
+
{ id, variant, title: titleMap[variant], message: messageMap[variant] },
|
|
233
|
+
];
|
|
234
|
+
}
|
|
235
|
+
|
|
236
236
|
function removeToast(id: number) {
|
|
237
237
|
toasts = toasts.filter((t) => t.id !== id);
|
|
238
238
|
}
|
|
@@ -258,7 +258,7 @@
|
|
|
258
258
|
pushToast(variant);
|
|
259
259
|
}
|
|
260
260
|
</script>
|
|
261
|
-
|
|
261
|
+
|
|
262
262
|
<Topbar
|
|
263
263
|
title="svelte-comp"
|
|
264
264
|
showHamburger={true}
|
|
@@ -268,387 +268,387 @@
|
|
|
268
268
|
|
|
269
269
|
<Container>
|
|
270
270
|
<div class="relative mx-auto max-w-6xl space-y-8 px-6 pb-10 pt-24">
|
|
271
|
-
<section
|
|
272
|
-
class="relative rounded-[28px] border border-[var(--border-color-default)] bg-gradient-to-br from-[var(--color-bg-surface)] via-white/70 to-[var(--color-bg-muted)] shadow-[0_20px_60px_-25px_var(--shadow-color)] dark:from-[var(--color-bg-surface)] dark:via-slate-900/70 dark:to-slate-900/50"
|
|
273
|
-
>
|
|
274
|
-
<div
|
|
275
|
-
class="absolute inset-0 bg-[radial-gradient(circle_at_20%_20%,rgba(99,102,241,0.18),transparent_35%),radial-gradient(circle_at_80%_0%,rgba(16,185,129,0.14),transparent_25%)]"
|
|
276
|
-
></div>
|
|
277
|
-
|
|
278
|
-
<div class="relative grid gap-8 p-8 md:p-10 lg:grid-cols-[1.1fr_0.9fr]">
|
|
279
|
-
<div class="space-y-4">
|
|
280
|
-
<p class="text-xs uppercase tracking-[0.25em] text-[var(--color-text-muted)]">
|
|
281
|
-
svelte-comp
|
|
282
|
-
</p>
|
|
283
|
-
<h1 class="text-3xl font-bold leading-tight md:text-4xl">
|
|
284
|
-
Component showcase
|
|
285
|
-
</h1>
|
|
286
|
-
<p class="text-[var(--color-text-muted)] md:w-3/4">
|
|
287
|
-
Toggle theme, tweak the primary color, and try the main lib components in a cohesive layout.
|
|
288
|
-
</p>
|
|
289
|
-
|
|
290
|
-
<div class="flex flex-wrap gap-3">
|
|
291
|
-
<Button variant="primary" onClick={() => pushToast("info")} sz="lg">
|
|
292
|
-
Launch interactive
|
|
293
|
-
</Button>
|
|
294
|
-
<Button variant="ghost" onClick={() => pushToast("warning")} sz="lg">
|
|
295
|
-
Remind to review
|
|
296
|
-
</Button>
|
|
297
|
-
</div>
|
|
298
|
-
|
|
299
|
-
<div class="flex flex-wrap gap-3 text-sm text-[var(--color-text-muted)]">
|
|
300
|
-
<span
|
|
301
|
-
class="inline-flex items-center gap-2 rounded-full border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] px-3 py-2"
|
|
302
|
-
>
|
|
303
|
-
<span class="h-2 w-2 animate-pulse rounded-full bg-[var(--color-bg-primary)]"></span>
|
|
304
|
-
Live preview is on
|
|
305
|
-
</span>
|
|
306
|
-
<span
|
|
307
|
-
class="inline-flex items-center gap-2 rounded-full border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] px-3 py-2"
|
|
308
|
-
>
|
|
309
|
-
<span class="h-2 w-2 rounded-full bg-[var(--color-bg-secondary)]"></span>
|
|
310
|
-
{tabs.length} sections below
|
|
311
|
-
</span>
|
|
312
|
-
</div>
|
|
313
|
-
</div>
|
|
314
|
-
|
|
315
|
-
<div
|
|
316
|
-
class="space-y-4 rounded-2xl border border-[var(--border-color-default)] bg-white/70 p-5 shadow-lg dark:bg-slate-900/60"
|
|
317
|
-
>
|
|
318
|
-
<div class="flex items-start justify-between gap-3">
|
|
319
|
-
<div>
|
|
320
|
-
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
321
|
-
Theme
|
|
322
|
-
</p>
|
|
323
|
-
<p class="text-lg font-semibold">Mode and accent</p>
|
|
324
|
-
</div>
|
|
325
|
-
|
|
326
|
-
<Tooltip text="Toggles document-level theme" position="bottom">
|
|
327
|
-
<ThemeToggle class="relative shadow-sm" sz="sm" />
|
|
328
|
-
</Tooltip>
|
|
329
|
-
</div>
|
|
330
|
-
|
|
331
|
-
<PrimaryColorSelect class="w-full" />
|
|
332
|
-
|
|
333
|
-
<div
|
|
334
|
-
class="flex items-center justify-between rounded-xl border border-[var(--border-color-default)] bg-[var(--color-bg-muted)]/70 px-4 py-3"
|
|
335
|
-
>
|
|
336
|
-
<div>
|
|
337
|
-
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
338
|
-
Autoplay
|
|
339
|
-
</p>
|
|
340
|
-
<p class="text-sm font-medium">Carousel</p>
|
|
341
|
-
</div>
|
|
342
|
-
<Switch
|
|
343
|
-
checked={autoplay}
|
|
344
|
-
onChange={(v) => (autoplay = v)}
|
|
345
|
-
sz="sm"
|
|
346
|
-
rightLabel={autoplay ? "On" : "Off"}
|
|
347
|
-
/>
|
|
348
|
-
</div>
|
|
349
|
-
|
|
350
|
-
<div class="grid gap-3 md:grid-cols-2">
|
|
351
|
-
<ProgressCircle value={sliderValue} label="Readiness" />
|
|
352
|
-
<ProgressBar value={sliderValue} label="Sprint focus" />
|
|
353
|
-
</div>
|
|
354
|
-
</div>
|
|
355
|
-
</div>
|
|
356
|
-
</section>
|
|
357
|
-
|
|
358
|
-
{#snippet controlsHeader()}
|
|
359
|
-
<div class="flex items-center justify-between gap-2">
|
|
360
|
-
<div>
|
|
361
|
-
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
362
|
-
Actions
|
|
363
|
-
</p>
|
|
364
|
-
<h2 class="text-lg font-semibold leading-tight">Quick triggers</h2>
|
|
365
|
-
</div>
|
|
366
|
-
<Tooltip text="Buttons use the full variant set" position="left">
|
|
367
|
-
<span
|
|
368
|
-
class="inline-flex h-9 w-9 items-center justify-center rounded-full bg-[var(--color-bg-muted)] text-sm font-semibold text-[var(--color-text-default)]"
|
|
369
|
-
>
|
|
370
|
-
?
|
|
371
|
-
</span>
|
|
372
|
-
</Tooltip>
|
|
373
|
-
</div>
|
|
374
|
-
{/snippet}
|
|
375
|
-
|
|
376
|
-
{#snippet formHeader()}
|
|
377
|
-
<div class="flex items-center justify-between">
|
|
378
|
-
<div>
|
|
379
|
-
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
380
|
-
Form
|
|
381
|
-
</p>
|
|
382
|
-
<h2 class="text-lg font-semibold leading-tight">Mini brief</h2>
|
|
383
|
-
</div>
|
|
384
|
-
<Tooltip text="Field, Select, DatePicker, TimePicker and ColorPicker" position="left">
|
|
385
|
-
<span
|
|
386
|
-
class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-[var(--color-bg-muted)] text-sm font-semibold text-[var(--color-text-default)]"
|
|
387
|
-
>
|
|
388
|
-
i
|
|
389
|
-
</span>
|
|
390
|
-
</Tooltip>
|
|
391
|
-
</div>
|
|
392
|
-
{/snippet}
|
|
393
|
-
|
|
394
|
-
<div class="grid gap-6 lg:grid-cols-2">
|
|
395
|
-
<Card header={controlsHeader}>
|
|
396
|
-
<div class="space-y-4">
|
|
397
|
-
<div class="flex flex-wrap gap-2">
|
|
398
|
-
<Button variant="primary" onClick={() => pushToast("success")}>Primary</Button>
|
|
399
|
-
<Button variant="secondary">Secondary</Button>
|
|
400
|
-
<Button variant="ghost">Ghost</Button>
|
|
401
|
-
<Button variant="pill">Pill</Button>
|
|
402
|
-
<Button variant="danger" onClick={() => pushToast("danger")}>Danger</Button>
|
|
403
|
-
</div>
|
|
404
|
-
|
|
405
|
-
<div
|
|
406
|
-
class="flex items-center justify-between gap-3 rounded-xl border border-[var(--border-color-default)] px-4 py-3"
|
|
407
|
-
>
|
|
408
|
-
<div class="space-y-1">
|
|
409
|
-
<p class="text-sm font-medium">Live mode</p>
|
|
410
|
-
<p class="text-xs text-[var(--color-text-muted)]">
|
|
411
|
-
Keep autoplay and progress linked across the page
|
|
412
|
-
</p>
|
|
413
|
-
</div>
|
|
414
|
-
<Switch checked={autoplay} onChange={(v) => (autoplay = v)} sz="sm" />
|
|
415
|
-
</div>
|
|
416
|
-
|
|
417
|
-
<div class="space-y-2">
|
|
418
|
-
<div class="flex items-center justify-between text-sm">
|
|
419
|
-
<span class="text-[var(--color-text-muted)]">Drag to refresh progress</span>
|
|
420
|
-
<span class="font-mono text-[var(--color-text-default)]">{sliderValue}%</span>
|
|
421
|
-
</div>
|
|
422
|
-
<Slider
|
|
423
|
-
value={sliderValue}
|
|
424
|
-
min={0}
|
|
425
|
-
max={100}
|
|
426
|
-
onInput={(v) => (sliderValue = v)}
|
|
427
|
-
showValue={false}
|
|
428
|
-
/>
|
|
429
|
-
</div>
|
|
430
|
-
|
|
431
|
-
<div class="grid gap-3 md:grid-cols-2">
|
|
432
|
-
<ProgressBar value={sliderValue} label="Iteration" />
|
|
433
|
-
<ProgressCircle value={sliderValue} label="Readiness" />
|
|
434
|
-
</div>
|
|
435
|
-
|
|
436
|
-
<div class="flex flex-wrap gap-2">
|
|
437
|
-
<Button variant="success" onClick={() => pushToast("success")} sz="sm">
|
|
438
|
-
Success toast
|
|
439
|
-
</Button>
|
|
440
|
-
<Button variant="warning" onClick={() => pushToast("warning")} sz="sm">
|
|
441
|
-
Warning toast
|
|
442
|
-
</Button>
|
|
443
|
-
<Button variant="info" onClick={() => pushToast("info")} sz="sm">
|
|
444
|
-
Info toast
|
|
445
|
-
</Button>
|
|
446
|
-
</div>
|
|
447
|
-
</div>
|
|
448
|
-
</Card>
|
|
449
|
-
|
|
450
|
-
<Card header={formHeader}>
|
|
451
|
-
<div class="space-y-4">
|
|
452
|
-
<div class="grid gap-3 md:grid-cols-2">
|
|
453
|
-
<Field
|
|
454
|
-
label="Name"
|
|
455
|
-
value={featureName}
|
|
456
|
-
onChange={(v) => (featureName = String(v))}
|
|
457
|
-
/>
|
|
458
|
-
<Field
|
|
459
|
-
label="Contact email"
|
|
460
|
-
type="email"
|
|
461
|
-
value={contactEmail}
|
|
462
|
-
onChange={(v) => (contactEmail = String(v))}
|
|
463
|
-
/>
|
|
464
|
-
</div>
|
|
465
|
-
|
|
466
|
-
<Select
|
|
467
|
-
label="Plan"
|
|
468
|
-
options={planOptions}
|
|
469
|
-
value={selectedPlan}
|
|
470
|
-
placeholder="Choose a plan"
|
|
471
|
-
onChange={(v) => (selectedPlan = v)}
|
|
472
|
-
/>
|
|
473
|
-
|
|
474
|
-
<div class="grid gap-3 md:grid-cols-3">
|
|
475
|
-
<DatePicker
|
|
476
|
-
label="Launch date"
|
|
477
|
-
value={dateValue}
|
|
478
|
-
onChange={(v) => (dateValue = v)}
|
|
479
|
-
/>
|
|
480
|
-
<TimePicker
|
|
481
|
-
label="Release time"
|
|
482
|
-
value={timeValue}
|
|
483
|
-
onChange={(v) => (timeValue = v)}
|
|
484
|
-
/>
|
|
485
|
-
<ColorPicker
|
|
486
|
-
label="Accent"
|
|
487
|
-
value={accentColor}
|
|
488
|
-
onChange={(v) => (accentColor = v)}
|
|
489
|
-
/>
|
|
490
|
-
</div>
|
|
491
|
-
|
|
492
|
-
<div class="flex justify-end gap-3">
|
|
493
|
-
<Button
|
|
494
|
-
variant="ghost"
|
|
495
|
-
onClick={() => {
|
|
496
|
-
featureName = "Dashboard 2.0";
|
|
497
|
-
selectedPlan = planOptions[1].value;
|
|
498
|
-
contactEmail = "team@studio.dev";
|
|
499
|
-
dateValue = null;
|
|
500
|
-
timeValue = null;
|
|
501
|
-
accentColor = "#7c3aed";
|
|
502
|
-
}}
|
|
503
|
-
>
|
|
504
|
-
Reset
|
|
505
|
-
</Button>
|
|
506
|
-
<Button variant="primary" onClick={() => pushToast("success")}>
|
|
507
|
-
Save
|
|
508
|
-
</Button>
|
|
509
|
-
</div>
|
|
510
|
-
</div>
|
|
511
|
-
</Card>
|
|
512
|
-
</div>
|
|
513
|
-
|
|
514
|
-
{#snippet dataHeader()}
|
|
515
|
-
<div class="flex items-center justify-between gap-3">
|
|
516
|
-
<div>
|
|
517
|
-
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
518
|
-
Data
|
|
519
|
-
</p>
|
|
520
|
-
<h2 class="text-lg font-semibold leading-tight">Sprint snapshot</h2>
|
|
521
|
-
</div>
|
|
522
|
-
<Button variant="secondary" sz="sm" onClick={() => pushToast("info")}>
|
|
523
|
-
Refresh
|
|
524
|
-
</Button>
|
|
525
|
-
</div>
|
|
526
|
-
{/snippet}
|
|
527
|
-
|
|
528
|
-
{#snippet accordionHeader()}
|
|
529
|
-
<div class="flex items-center justify-between gap-3">
|
|
530
|
-
<div>
|
|
531
|
-
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
532
|
-
Details
|
|
533
|
-
</p>
|
|
534
|
-
<h3 class="text-lg font-semibold leading-tight">Sections</h3>
|
|
535
|
-
</div>
|
|
536
|
-
</div>
|
|
537
|
-
{/snippet}
|
|
538
|
-
|
|
539
|
-
{#snippet carouselHeader()}
|
|
540
|
-
<div class="flex items-center justify-between gap-3">
|
|
541
|
-
<div>
|
|
542
|
-
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
543
|
-
Carousel
|
|
544
|
-
</p>
|
|
545
|
-
<h3 class="text-lg font-semibold leading-tight">Stories</h3>
|
|
546
|
-
</div>
|
|
547
|
-
<span class="text-xs text-[var(--color-text-muted)]">
|
|
548
|
-
Autoplay {autoplay ? "on" : "off"}
|
|
549
|
-
</span>
|
|
550
|
-
</div>
|
|
551
|
-
{/snippet}
|
|
552
|
-
|
|
271
|
+
<section
|
|
272
|
+
class="relative rounded-[28px] border border-[var(--border-color-default)] bg-gradient-to-br from-[var(--color-bg-surface)] via-white/70 to-[var(--color-bg-muted)] shadow-[0_20px_60px_-25px_var(--shadow-color)] dark:from-[var(--color-bg-surface)] dark:via-slate-900/70 dark:to-slate-900/50"
|
|
273
|
+
>
|
|
274
|
+
<div
|
|
275
|
+
class="absolute inset-0 bg-[radial-gradient(circle_at_20%_20%,rgba(99,102,241,0.18),transparent_35%),radial-gradient(circle_at_80%_0%,rgba(16,185,129,0.14),transparent_25%)]"
|
|
276
|
+
></div>
|
|
277
|
+
|
|
278
|
+
<div class="relative grid gap-8 p-8 md:p-10 lg:grid-cols-[1.1fr_0.9fr]">
|
|
279
|
+
<div class="space-y-4">
|
|
280
|
+
<p class="text-xs uppercase tracking-[0.25em] text-[var(--color-text-muted)]">
|
|
281
|
+
svelte-comp
|
|
282
|
+
</p>
|
|
283
|
+
<h1 class="text-3xl font-bold leading-tight md:text-4xl">
|
|
284
|
+
Component showcase
|
|
285
|
+
</h1>
|
|
286
|
+
<p class="text-[var(--color-text-muted)] md:w-3/4">
|
|
287
|
+
Toggle theme, tweak the primary color, and try the main lib components in a cohesive layout.
|
|
288
|
+
</p>
|
|
289
|
+
|
|
290
|
+
<div class="flex flex-wrap gap-3">
|
|
291
|
+
<Button variant="primary" onClick={() => pushToast("info")} sz="lg">
|
|
292
|
+
Launch interactive
|
|
293
|
+
</Button>
|
|
294
|
+
<Button variant="ghost" onClick={() => pushToast("warning")} sz="lg">
|
|
295
|
+
Remind to review
|
|
296
|
+
</Button>
|
|
297
|
+
</div>
|
|
298
|
+
|
|
299
|
+
<div class="flex flex-wrap gap-3 text-sm text-[var(--color-text-muted)]">
|
|
300
|
+
<span
|
|
301
|
+
class="inline-flex items-center gap-2 rounded-full border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] px-3 py-2"
|
|
302
|
+
>
|
|
303
|
+
<span class="h-2 w-2 animate-pulse rounded-full bg-[var(--color-bg-primary)]"></span>
|
|
304
|
+
Live preview is on
|
|
305
|
+
</span>
|
|
306
|
+
<span
|
|
307
|
+
class="inline-flex items-center gap-2 rounded-full border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] px-3 py-2"
|
|
308
|
+
>
|
|
309
|
+
<span class="h-2 w-2 rounded-full bg-[var(--color-bg-secondary)]"></span>
|
|
310
|
+
{tabs.length} sections below
|
|
311
|
+
</span>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
|
|
315
|
+
<div
|
|
316
|
+
class="space-y-4 rounded-2xl border border-[var(--border-color-default)] bg-white/70 p-5 shadow-lg dark:bg-slate-900/60"
|
|
317
|
+
>
|
|
318
|
+
<div class="flex items-start justify-between gap-3">
|
|
319
|
+
<div>
|
|
320
|
+
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
321
|
+
Theme
|
|
322
|
+
</p>
|
|
323
|
+
<p class="text-lg font-semibold">Mode and accent</p>
|
|
324
|
+
</div>
|
|
325
|
+
|
|
326
|
+
<Tooltip text="Toggles document-level theme" position="bottom">
|
|
327
|
+
<ThemeToggle class="relative shadow-sm" sz="sm" />
|
|
328
|
+
</Tooltip>
|
|
329
|
+
</div>
|
|
330
|
+
|
|
331
|
+
<PrimaryColorSelect class="w-full" />
|
|
332
|
+
|
|
333
|
+
<div
|
|
334
|
+
class="flex items-center justify-between rounded-xl border border-[var(--border-color-default)] bg-[var(--color-bg-muted)]/70 px-4 py-3"
|
|
335
|
+
>
|
|
336
|
+
<div>
|
|
337
|
+
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
338
|
+
Autoplay
|
|
339
|
+
</p>
|
|
340
|
+
<p class="text-sm font-medium">Carousel</p>
|
|
341
|
+
</div>
|
|
342
|
+
<Switch
|
|
343
|
+
checked={autoplay}
|
|
344
|
+
onChange={(v) => (autoplay = v)}
|
|
345
|
+
sz="sm"
|
|
346
|
+
rightLabel={autoplay ? "On" : "Off"}
|
|
347
|
+
/>
|
|
348
|
+
</div>
|
|
349
|
+
|
|
350
|
+
<div class="grid gap-3 md:grid-cols-2">
|
|
351
|
+
<ProgressCircle value={sliderValue} label="Readiness" />
|
|
352
|
+
<ProgressBar value={sliderValue} label="Sprint focus" />
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
</section>
|
|
357
|
+
|
|
358
|
+
{#snippet controlsHeader()}
|
|
359
|
+
<div class="flex items-center justify-between gap-2">
|
|
360
|
+
<div>
|
|
361
|
+
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
362
|
+
Actions
|
|
363
|
+
</p>
|
|
364
|
+
<h2 class="text-lg font-semibold leading-tight">Quick triggers</h2>
|
|
365
|
+
</div>
|
|
366
|
+
<Tooltip text="Buttons use the full variant set" position="left">
|
|
367
|
+
<span
|
|
368
|
+
class="inline-flex h-9 w-9 items-center justify-center rounded-full bg-[var(--color-bg-muted)] text-sm font-semibold text-[var(--color-text-default)]"
|
|
369
|
+
>
|
|
370
|
+
?
|
|
371
|
+
</span>
|
|
372
|
+
</Tooltip>
|
|
373
|
+
</div>
|
|
374
|
+
{/snippet}
|
|
375
|
+
|
|
376
|
+
{#snippet formHeader()}
|
|
377
|
+
<div class="flex items-center justify-between">
|
|
378
|
+
<div>
|
|
379
|
+
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
380
|
+
Form
|
|
381
|
+
</p>
|
|
382
|
+
<h2 class="text-lg font-semibold leading-tight">Mini brief</h2>
|
|
383
|
+
</div>
|
|
384
|
+
<Tooltip text="Field, Select, DatePicker, TimePicker and ColorPicker" position="left">
|
|
385
|
+
<span
|
|
386
|
+
class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-[var(--color-bg-muted)] text-sm font-semibold text-[var(--color-text-default)]"
|
|
387
|
+
>
|
|
388
|
+
i
|
|
389
|
+
</span>
|
|
390
|
+
</Tooltip>
|
|
391
|
+
</div>
|
|
392
|
+
{/snippet}
|
|
393
|
+
|
|
394
|
+
<div class="grid gap-6 lg:grid-cols-2">
|
|
395
|
+
<Card header={controlsHeader}>
|
|
396
|
+
<div class="space-y-4">
|
|
397
|
+
<div class="flex flex-wrap gap-2">
|
|
398
|
+
<Button variant="primary" onClick={() => pushToast("success")}>Primary</Button>
|
|
399
|
+
<Button variant="secondary">Secondary</Button>
|
|
400
|
+
<Button variant="ghost">Ghost</Button>
|
|
401
|
+
<Button variant="pill">Pill</Button>
|
|
402
|
+
<Button variant="danger" onClick={() => pushToast("danger")}>Danger</Button>
|
|
403
|
+
</div>
|
|
404
|
+
|
|
405
|
+
<div
|
|
406
|
+
class="flex items-center justify-between gap-3 rounded-xl border border-[var(--border-color-default)] px-4 py-3"
|
|
407
|
+
>
|
|
408
|
+
<div class="space-y-1">
|
|
409
|
+
<p class="text-sm font-medium">Live mode</p>
|
|
410
|
+
<p class="text-xs text-[var(--color-text-muted)]">
|
|
411
|
+
Keep autoplay and progress linked across the page
|
|
412
|
+
</p>
|
|
413
|
+
</div>
|
|
414
|
+
<Switch checked={autoplay} onChange={(v) => (autoplay = v)} sz="sm" />
|
|
415
|
+
</div>
|
|
416
|
+
|
|
417
|
+
<div class="space-y-2">
|
|
418
|
+
<div class="flex items-center justify-between text-sm">
|
|
419
|
+
<span class="text-[var(--color-text-muted)]">Drag to refresh progress</span>
|
|
420
|
+
<span class="font-mono text-[var(--color-text-default)]">{sliderValue}%</span>
|
|
421
|
+
</div>
|
|
422
|
+
<Slider
|
|
423
|
+
value={sliderValue}
|
|
424
|
+
min={0}
|
|
425
|
+
max={100}
|
|
426
|
+
onInput={(v) => (sliderValue = v)}
|
|
427
|
+
showValue={false}
|
|
428
|
+
/>
|
|
429
|
+
</div>
|
|
430
|
+
|
|
431
|
+
<div class="grid gap-3 md:grid-cols-2">
|
|
432
|
+
<ProgressBar value={sliderValue} label="Iteration" />
|
|
433
|
+
<ProgressCircle value={sliderValue} label="Readiness" />
|
|
434
|
+
</div>
|
|
435
|
+
|
|
436
|
+
<div class="flex flex-wrap gap-2">
|
|
437
|
+
<Button variant="success" onClick={() => pushToast("success")} sz="sm">
|
|
438
|
+
Success toast
|
|
439
|
+
</Button>
|
|
440
|
+
<Button variant="warning" onClick={() => pushToast("warning")} sz="sm">
|
|
441
|
+
Warning toast
|
|
442
|
+
</Button>
|
|
443
|
+
<Button variant="info" onClick={() => pushToast("info")} sz="sm">
|
|
444
|
+
Info toast
|
|
445
|
+
</Button>
|
|
446
|
+
</div>
|
|
447
|
+
</div>
|
|
448
|
+
</Card>
|
|
449
|
+
|
|
450
|
+
<Card header={formHeader}>
|
|
451
|
+
<div class="space-y-4">
|
|
452
|
+
<div class="grid gap-3 md:grid-cols-2">
|
|
453
|
+
<Field
|
|
454
|
+
label="Name"
|
|
455
|
+
value={featureName}
|
|
456
|
+
onChange={(v) => (featureName = String(v))}
|
|
457
|
+
/>
|
|
458
|
+
<Field
|
|
459
|
+
label="Contact email"
|
|
460
|
+
type="email"
|
|
461
|
+
value={contactEmail}
|
|
462
|
+
onChange={(v) => (contactEmail = String(v))}
|
|
463
|
+
/>
|
|
464
|
+
</div>
|
|
465
|
+
|
|
466
|
+
<Select
|
|
467
|
+
label="Plan"
|
|
468
|
+
options={planOptions}
|
|
469
|
+
value={selectedPlan}
|
|
470
|
+
placeholder="Choose a plan"
|
|
471
|
+
onChange={(v) => (selectedPlan = v)}
|
|
472
|
+
/>
|
|
473
|
+
|
|
474
|
+
<div class="grid gap-3 md:grid-cols-3">
|
|
475
|
+
<DatePicker
|
|
476
|
+
label="Launch date"
|
|
477
|
+
value={dateValue}
|
|
478
|
+
onChange={(v) => (dateValue = v)}
|
|
479
|
+
/>
|
|
480
|
+
<TimePicker
|
|
481
|
+
label="Release time"
|
|
482
|
+
value={timeValue}
|
|
483
|
+
onChange={(v) => (timeValue = v)}
|
|
484
|
+
/>
|
|
485
|
+
<ColorPicker
|
|
486
|
+
label="Accent"
|
|
487
|
+
value={accentColor}
|
|
488
|
+
onChange={(v) => (accentColor = v)}
|
|
489
|
+
/>
|
|
490
|
+
</div>
|
|
491
|
+
|
|
492
|
+
<div class="flex justify-end gap-3">
|
|
493
|
+
<Button
|
|
494
|
+
variant="ghost"
|
|
495
|
+
onClick={() => {
|
|
496
|
+
featureName = "Dashboard 2.0";
|
|
497
|
+
selectedPlan = planOptions[1].value;
|
|
498
|
+
contactEmail = "team@studio.dev";
|
|
499
|
+
dateValue = null;
|
|
500
|
+
timeValue = null;
|
|
501
|
+
accentColor = "#7c3aed";
|
|
502
|
+
}}
|
|
503
|
+
>
|
|
504
|
+
Reset
|
|
505
|
+
</Button>
|
|
506
|
+
<Button variant="primary" onClick={() => pushToast("success")}>
|
|
507
|
+
Save
|
|
508
|
+
</Button>
|
|
509
|
+
</div>
|
|
510
|
+
</div>
|
|
511
|
+
</Card>
|
|
512
|
+
</div>
|
|
513
|
+
|
|
514
|
+
{#snippet dataHeader()}
|
|
515
|
+
<div class="flex items-center justify-between gap-3">
|
|
516
|
+
<div>
|
|
517
|
+
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
518
|
+
Data
|
|
519
|
+
</p>
|
|
520
|
+
<h2 class="text-lg font-semibold leading-tight">Sprint snapshot</h2>
|
|
521
|
+
</div>
|
|
522
|
+
<Button variant="secondary" sz="sm" onClick={() => pushToast("info")}>
|
|
523
|
+
Refresh
|
|
524
|
+
</Button>
|
|
525
|
+
</div>
|
|
526
|
+
{/snippet}
|
|
527
|
+
|
|
528
|
+
{#snippet accordionHeader()}
|
|
529
|
+
<div class="flex items-center justify-between gap-3">
|
|
530
|
+
<div>
|
|
531
|
+
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
532
|
+
Details
|
|
533
|
+
</p>
|
|
534
|
+
<h3 class="text-lg font-semibold leading-tight">Sections</h3>
|
|
535
|
+
</div>
|
|
536
|
+
</div>
|
|
537
|
+
{/snippet}
|
|
538
|
+
|
|
539
|
+
{#snippet carouselHeader()}
|
|
540
|
+
<div class="flex items-center justify-between gap-3">
|
|
541
|
+
<div>
|
|
542
|
+
<p class="text-xs uppercase tracking-[0.15em] text-[var(--color-text-muted)]">
|
|
543
|
+
Carousel
|
|
544
|
+
</p>
|
|
545
|
+
<h3 class="text-lg font-semibold leading-tight">Stories</h3>
|
|
546
|
+
</div>
|
|
547
|
+
<span class="text-xs text-[var(--color-text-muted)]">
|
|
548
|
+
Autoplay {autoplay ? "on" : "off"}
|
|
549
|
+
</span>
|
|
550
|
+
</div>
|
|
551
|
+
{/snippet}
|
|
552
|
+
|
|
553
553
|
<div class="grid gap-6 lg:grid-cols-[1.2fr_0.8fr]">
|
|
554
554
|
<Card header={dataHeader} class="h-full">
|
|
555
|
-
<Tabs
|
|
556
|
-
tabs={tabs}
|
|
557
|
-
activeTab={activeTab}
|
|
558
|
-
onChange={(id) => (activeTab = id)}
|
|
559
|
-
variant="underline"
|
|
560
|
-
fitted={true}
|
|
561
|
-
>
|
|
562
|
-
{#if activeTab === "overview"}
|
|
563
|
-
<div class="grid gap-4 md:grid-cols-3">
|
|
564
|
-
<div
|
|
565
|
-
class="rounded-xl border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] p-4"
|
|
566
|
-
>
|
|
567
|
-
<p class="text-xs uppercase tracking-[0.1em] text-[var(--color-text-muted)]">
|
|
568
|
-
Readiness
|
|
569
|
-
</p>
|
|
570
|
-
<p class="text-2xl font-bold">{sliderValue}%</p>
|
|
571
|
-
<p class="text-sm text-[var(--color-text-muted)]">
|
|
572
|
-
Synced with the slider above
|
|
573
|
-
</p>
|
|
574
|
-
</div>
|
|
575
|
-
|
|
576
|
-
<div
|
|
577
|
-
class="rounded-xl border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] p-4"
|
|
578
|
-
>
|
|
579
|
-
<p class="text-xs uppercase tracking-[0.1em] text-[var(--color-text-muted)]">
|
|
580
|
-
Plan
|
|
581
|
-
</p>
|
|
582
|
-
<p class="text-lg font-semibold">{selectedPlan}</p>
|
|
583
|
-
<p class="text-sm text-[var(--color-text-muted)]">
|
|
584
|
-
Contact: {contactEmail}
|
|
585
|
-
</p>
|
|
586
|
-
</div>
|
|
587
|
-
|
|
588
|
-
<div
|
|
589
|
-
class="rounded-xl border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] p-4"
|
|
590
|
-
>
|
|
591
|
-
<p class="text-xs uppercase tracking-[0.1em] text-[var(--color-text-muted)]">
|
|
592
|
-
Release window
|
|
593
|
-
</p>
|
|
594
|
-
<p class="text-lg font-semibold">
|
|
595
|
-
{dateValue ?? "Not selected yet"}
|
|
596
|
-
</p>
|
|
597
|
-
<p class="text-sm text-[var(--color-text-muted)]">
|
|
598
|
-
{timeValue ?? "Time is being planned"}
|
|
599
|
-
</p>
|
|
600
|
-
</div>
|
|
601
|
-
</div>
|
|
602
|
-
|
|
603
|
-
<div class="mt-4 grid gap-3 md:grid-cols-3">
|
|
604
|
-
{#each quality as metric (metric.label)}
|
|
605
|
-
<ProgressBar value={metric.value} label={metric.label} sz="sm" />
|
|
606
|
-
{/each}
|
|
607
|
-
</div>
|
|
608
|
-
{:else if activeTab === "team"}
|
|
609
|
-
<div class="space-y-3">
|
|
610
|
-
{#each team as person (person.name)}
|
|
611
|
-
<div
|
|
612
|
-
class="flex items-center justify-between rounded-xl border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] px-4 py-3"
|
|
613
|
-
>
|
|
614
|
-
<div>
|
|
615
|
-
<p class="font-semibold">{person.name}</p>
|
|
616
|
-
<p class="text-sm text-[var(--color-text-muted)]">{person.role}</p>
|
|
617
|
-
</div>
|
|
618
|
-
<span
|
|
619
|
-
class="rounded-full bg-[var(--color-bg-muted)] px-3 py-1 text-xs text-[var(--color-text-default)]"
|
|
620
|
-
>
|
|
621
|
-
{person.focus}
|
|
622
|
-
</span>
|
|
623
|
-
</div>
|
|
624
|
-
{/each}
|
|
625
|
-
</div>
|
|
626
|
-
{:else}
|
|
627
|
-
<Table
|
|
628
|
-
columns={tableColumns}
|
|
629
|
-
rows={pagedRows}
|
|
630
|
-
variant="zebra"
|
|
631
|
-
pagination={{ currentPage: tablePage, totalPages, onPageChange: (p) => (tablePage = p) }}
|
|
632
|
-
/>
|
|
633
|
-
{/if}
|
|
634
|
-
</Tabs>
|
|
635
|
-
</Card>
|
|
636
|
-
|
|
637
|
-
<div class="grid gap-6">
|
|
638
|
-
<Card header={accordionHeader}>
|
|
639
|
-
<Accordion items={accordionItems} multiple={true} defaultOpen={[0]} />
|
|
640
|
-
</Card>
|
|
641
|
-
|
|
642
|
-
<Card header={carouselHeader}>
|
|
643
|
-
<Carousel
|
|
644
|
-
items={carouselItems}
|
|
645
|
-
autoplay={autoplay}
|
|
646
|
-
interval={4200}
|
|
647
|
-
showDots={true}
|
|
648
|
-
showArrows={true}
|
|
649
|
-
sz="sm"
|
|
650
|
-
/>
|
|
651
|
-
</Card>
|
|
555
|
+
<Tabs
|
|
556
|
+
tabs={tabs}
|
|
557
|
+
activeTab={activeTab}
|
|
558
|
+
onChange={(id) => (activeTab = id)}
|
|
559
|
+
variant="underline"
|
|
560
|
+
fitted={true}
|
|
561
|
+
>
|
|
562
|
+
{#if activeTab === "overview"}
|
|
563
|
+
<div class="grid gap-4 md:grid-cols-3">
|
|
564
|
+
<div
|
|
565
|
+
class="rounded-xl border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] p-4"
|
|
566
|
+
>
|
|
567
|
+
<p class="text-xs uppercase tracking-[0.1em] text-[var(--color-text-muted)]">
|
|
568
|
+
Readiness
|
|
569
|
+
</p>
|
|
570
|
+
<p class="text-2xl font-bold">{sliderValue}%</p>
|
|
571
|
+
<p class="text-sm text-[var(--color-text-muted)]">
|
|
572
|
+
Synced with the slider above
|
|
573
|
+
</p>
|
|
574
|
+
</div>
|
|
575
|
+
|
|
576
|
+
<div
|
|
577
|
+
class="rounded-xl border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] p-4"
|
|
578
|
+
>
|
|
579
|
+
<p class="text-xs uppercase tracking-[0.1em] text-[var(--color-text-muted)]">
|
|
580
|
+
Plan
|
|
581
|
+
</p>
|
|
582
|
+
<p class="text-lg font-semibold">{selectedPlan}</p>
|
|
583
|
+
<p class="text-sm text-[var(--color-text-muted)]">
|
|
584
|
+
Contact: {contactEmail}
|
|
585
|
+
</p>
|
|
586
|
+
</div>
|
|
587
|
+
|
|
588
|
+
<div
|
|
589
|
+
class="rounded-xl border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] p-4"
|
|
590
|
+
>
|
|
591
|
+
<p class="text-xs uppercase tracking-[0.1em] text-[var(--color-text-muted)]">
|
|
592
|
+
Release window
|
|
593
|
+
</p>
|
|
594
|
+
<p class="text-lg font-semibold">
|
|
595
|
+
{dateValue ?? "Not selected yet"}
|
|
596
|
+
</p>
|
|
597
|
+
<p class="text-sm text-[var(--color-text-muted)]">
|
|
598
|
+
{timeValue ?? "Time is being planned"}
|
|
599
|
+
</p>
|
|
600
|
+
</div>
|
|
601
|
+
</div>
|
|
602
|
+
|
|
603
|
+
<div class="mt-4 grid gap-3 md:grid-cols-3">
|
|
604
|
+
{#each quality as metric (metric.label)}
|
|
605
|
+
<ProgressBar value={metric.value} label={metric.label} sz="sm" />
|
|
606
|
+
{/each}
|
|
607
|
+
</div>
|
|
608
|
+
{:else if activeTab === "team"}
|
|
609
|
+
<div class="space-y-3">
|
|
610
|
+
{#each team as person (person.name)}
|
|
611
|
+
<div
|
|
612
|
+
class="flex items-center justify-between rounded-xl border border-[var(--border-color-default)] bg-[var(--color-bg-surface)] px-4 py-3"
|
|
613
|
+
>
|
|
614
|
+
<div>
|
|
615
|
+
<p class="font-semibold">{person.name}</p>
|
|
616
|
+
<p class="text-sm text-[var(--color-text-muted)]">{person.role}</p>
|
|
617
|
+
</div>
|
|
618
|
+
<span
|
|
619
|
+
class="rounded-full bg-[var(--color-bg-muted)] px-3 py-1 text-xs text-[var(--color-text-default)]"
|
|
620
|
+
>
|
|
621
|
+
{person.focus}
|
|
622
|
+
</span>
|
|
623
|
+
</div>
|
|
624
|
+
{/each}
|
|
625
|
+
</div>
|
|
626
|
+
{:else}
|
|
627
|
+
<Table
|
|
628
|
+
columns={tableColumns}
|
|
629
|
+
rows={pagedRows}
|
|
630
|
+
variant="zebra"
|
|
631
|
+
pagination={{ currentPage: tablePage, totalPages, onPageChange: (p) => (tablePage = p) }}
|
|
632
|
+
/>
|
|
633
|
+
{/if}
|
|
634
|
+
</Tabs>
|
|
635
|
+
</Card>
|
|
636
|
+
|
|
637
|
+
<div class="grid gap-6">
|
|
638
|
+
<Card header={accordionHeader}>
|
|
639
|
+
<Accordion items={accordionItems} multiple={true} defaultOpen={[0]} />
|
|
640
|
+
</Card>
|
|
641
|
+
|
|
642
|
+
<Card header={carouselHeader}>
|
|
643
|
+
<Carousel
|
|
644
|
+
items={carouselItems}
|
|
645
|
+
autoplay={autoplay}
|
|
646
|
+
interval={4200}
|
|
647
|
+
showDots={true}
|
|
648
|
+
showArrows={true}
|
|
649
|
+
sz="sm"
|
|
650
|
+
/>
|
|
651
|
+
</Card>
|
|
652
652
|
</div>
|
|
653
653
|
</div>
|
|
654
654
|
|
|
@@ -1035,12 +1035,12 @@
|
|
|
1035
1035
|
</div>
|
|
1036
1036
|
|
|
1037
1037
|
{#each toasts as toast (toast.id)}
|
|
1038
|
-
<Toast
|
|
1039
|
-
title={toast.title}
|
|
1040
|
-
message={toast.message}
|
|
1041
|
-
variant={toast.variant}
|
|
1042
|
-
onClose={() => removeToast(toast.id)}
|
|
1043
|
-
timeout={3500}
|
|
1044
|
-
/>
|
|
1045
|
-
{/each}
|
|
1046
|
-
</Container>
|
|
1038
|
+
<Toast
|
|
1039
|
+
title={toast.title}
|
|
1040
|
+
message={toast.message}
|
|
1041
|
+
variant={toast.variant}
|
|
1042
|
+
onClose={() => removeToast(toast.id)}
|
|
1043
|
+
timeout={3500}
|
|
1044
|
+
/>
|
|
1045
|
+
{/each}
|
|
1046
|
+
</Container>
|