@stacksjs/components 0.2.3
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/README.md +477 -0
- package/dist/Accordion-x2gjedap.stx +108 -0
- package/dist/Audio-0fk6p9tn.stx +50 -0
- package/dist/Avatar-5m0v0s4x.stx +88 -0
- package/dist/Badge-ynes82vv.stx +70 -0
- package/dist/Breadcrumb-h9n427sk.stx +79 -0
- package/dist/Button-7xtrzn14.stx +89 -0
- package/dist/Calendar-egvx1pma.stx +232 -0
- package/dist/Card-r9w7vy1a.stx +74 -0
- package/dist/Checkbox-m8v46pmx.stx +92 -0
- package/dist/Checkout-vcnnr176.stx +39 -0
- package/dist/CodeBlock-mwex82cm.stx +57 -0
- package/dist/Combobox-npb08vkp.stx +13 -0
- package/dist/ComboboxButton-vcdyq4zw.stx +13 -0
- package/dist/ComboboxInput-c9d2p02m.stx +25 -0
- package/dist/ComboboxOption-7d0h9ash.stx +52 -0
- package/dist/ComboboxOptions-4dtqc0qa.stx +12 -0
- package/dist/CommandPalette-ah00bf8v.stx +39 -0
- package/dist/CommandPaletteItem-2yx0gvtj.stx +32 -0
- package/dist/DefaultPaymentMethod-emw5fg8s.stx +62 -0
- package/dist/Dialog-1w4rz7x0.stx +19 -0
- package/dist/DialogBackdrop-qbm3y5ab.stx +9 -0
- package/dist/DialogDescription-01w5j74b.stx +11 -0
- package/dist/DialogPanel-brsszrrs.stx +16 -0
- package/dist/DialogTitle-3rxhwg21.stx +11 -0
- package/dist/Drawer-yfaz8q7f.stx +137 -0
- package/dist/Dropdown-ng7nx556.stx +24 -0
- package/dist/DropdownButton-vc4zpyrb.stx +23 -0
- package/dist/DropdownItem-z491y23c.stx +43 -0
- package/dist/DropdownItems-7ykf29sj.stx +18 -0
- package/dist/EmailInput-bfshpj92.stx +41 -0
- package/dist/Footer-xdaf02nr.stx +66 -0
- package/dist/Form-z4f7w6r1.stx +209 -0
- package/dist/Hero-9vvp7pxf.stx +25 -0
- package/dist/Image-ktk0451c.stx +197 -0
- package/dist/Installation-33bj4rm7.stx +39 -0
- package/dist/Listbox-xcejcmyc.stx +14 -0
- package/dist/ListboxButton-nx5kmw19.stx +17 -0
- package/dist/ListboxLabel-aky8a73n.stx +11 -0
- package/dist/ListboxOption-6h4hsdz5.stx +57 -0
- package/dist/ListboxOptions-2sacdtm5.stx +16 -0
- package/dist/Login-s2jkvd9y.stx +163 -0
- package/dist/Navigator-tqqdgdkw.stx +138 -0
- package/dist/Notification-sry8egea.stx +71 -0
- package/dist/NumberInput-zm93ddfw.stx +138 -0
- package/dist/Pagination-yza9v4qw.stx +183 -0
- package/dist/PasswordInput-4xnndp5y.stx +155 -0
- package/dist/PaymentMethods-jxba6kek.stx +113 -0
- package/dist/Popover-scbqatjq.stx +24 -0
- package/dist/PopoverButton-rbxhzj4k.stx +23 -0
- package/dist/PopoverPanel-9ng1rm6e.stx +23 -0
- package/dist/Portal-j111yvqp.stx +74 -0
- package/dist/Progress-gbmw3akr.stx +142 -0
- package/dist/Radio-1n9qamv1.stx +81 -0
- package/dist/RadioGroup-12dw2vhk.stx +13 -0
- package/dist/RadioGroupDescription-bjm3mdht.stx +11 -0
- package/dist/RadioGroupLabel-aky8a73n.stx +11 -0
- package/dist/RadioGroupOption-9pcxgwmd.stx +51 -0
- package/dist/SearchInput-g240e2nq.stx +63 -0
- package/dist/Select-p9f94b20.stx +89 -0
- package/dist/Sidebar-gwxw8q38.stx +288 -0
- package/dist/SidebarFooter-887kxret.stx +95 -0
- package/dist/SidebarHeader-qjeyx0hv.stx +100 -0
- package/dist/SidebarItem-4dpwtmb4.stx +118 -0
- package/dist/SidebarSection-kh92fk4m.stx +108 -0
- package/dist/Signup-3nxq5zag.stx +161 -0
- package/dist/Skeleton-g0nx1njm.stx +48 -0
- package/dist/Spinner-w4zj58xp.stx +109 -0
- package/dist/Stepper-rwc5actp.stx +17 -0
- package/dist/StepperStep-h0k657nm.stx +53 -0
- package/dist/SubscriptionCheckout-4cbxdg7w.stx +353 -0
- package/dist/Switch-kjq8qd2p.stx +74 -0
- package/dist/Table-59j9qwp0.stx +14 -0
- package/dist/TableBody-reka2gwv.stx +10 -0
- package/dist/TableCell-j7nh4sgr.stx +10 -0
- package/dist/TableHead-ecbrwpqm.stx +10 -0
- package/dist/TableHeader-jn2shwsv.stx +13 -0
- package/dist/TableRow-xz8rrxhc.stx +11 -0
- package/dist/Tabs-kb6ex6m7.stx +145 -0
- package/dist/Teleport-819cg9zm.stx +101 -0
- package/dist/TextInput-zx9kgr79.stx +146 -0
- package/dist/Textarea-5xvmrb0z.stx +119 -0
- package/dist/Tooltip-5ehqsy49.stx +76 -0
- package/dist/Transition-2j39s044.stx +174 -0
- package/dist/TwoFactorChallenge-2q4gg89m.stx +125 -0
- package/dist/Video-6aq4shh4.stx +45 -0
- package/dist/VirtualList-weh5qtm1.stx +83 -0
- package/dist/VirtualTable-59a1eskc.stx +113 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/composables/index.d.ts +4 -0
- package/dist/composables/index.js +3 -0
- package/dist/composables/useCopyCode.d.ts +19 -0
- package/dist/composables/useDarkMode.d.ts +25 -0
- package/dist/composables/useSEO.d.ts +36 -0
- package/dist/composables/utilities/index.d.ts +5 -0
- package/dist/composables/utilities/useClickOutside.d.ts +28 -0
- package/dist/composables/utilities/useFocusTrap.d.ts +34 -0
- package/dist/composables/utilities/useKeyboard.d.ts +55 -0
- package/dist/composables/utilities/useLocalStorage.d.ts +33 -0
- package/dist/composables/utilities/useMediaQuery.d.ts +64 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +19 -0
- package/dist/ui/accordion/index.d.ts +12 -0
- package/dist/ui/audio/index.d.ts +12 -0
- package/dist/ui/auth/index.d.ts +29 -0
- package/dist/ui/avatar/index.d.ts +11 -0
- package/dist/ui/badge/index.d.ts +9 -0
- package/dist/ui/breadcrumb/index.d.ts +13 -0
- package/dist/ui/button/index.d.ts +45 -0
- package/dist/ui/calendar/index.d.ts +13 -0
- package/dist/ui/card/index.d.ts +12 -0
- package/dist/ui/checkbox/index.d.ts +15 -0
- package/dist/ui/combobox/index.d.ts +35 -0
- package/dist/ui/command-palette/index.d.ts +13 -0
- package/dist/ui/dialog/index.d.ts +27 -0
- package/dist/ui/drawer/index.d.ts +8 -0
- package/dist/ui/dropdown/index.d.ts +25 -0
- package/dist/ui/form/index.d.ts +48 -0
- package/dist/ui/image/index.d.ts +21 -0
- package/dist/ui/input/index.d.ts +73 -0
- package/dist/ui/listbox/index.d.ts +34 -0
- package/dist/ui/navigator/index.d.ts +18 -0
- package/dist/ui/notification/index.d.ts +11 -0
- package/dist/ui/pagination/index.d.ts +10 -0
- package/dist/ui/payment/index.d.ts +53 -0
- package/dist/ui/popover/index.d.ts +19 -0
- package/dist/ui/portal/index.d.ts +5 -0
- package/dist/ui/progress/index.d.ts +11 -0
- package/dist/ui/radio/index.d.ts +14 -0
- package/dist/ui/radio-group/index.d.ts +26 -0
- package/dist/ui/select/index.d.ts +19 -0
- package/dist/ui/sidebar/index.d.ts +129 -0
- package/dist/ui/skeleton/index.d.ts +10 -0
- package/dist/ui/spinner/index.d.ts +8 -0
- package/dist/ui/stepper/index.d.ts +17 -0
- package/dist/ui/storage/index.d.ts +40 -0
- package/dist/ui/switch/index.d.ts +9 -0
- package/dist/ui/table/index.d.ts +29 -0
- package/dist/ui/tabs/index.d.ts +14 -0
- package/dist/ui/teleport/index.d.ts +6 -0
- package/dist/ui/textarea/index.d.ts +19 -0
- package/dist/ui/tooltip/index.d.ts +9 -0
- package/dist/ui/transition/index.d.ts +24 -0
- package/dist/ui/video/index.d.ts +15 -0
- package/dist/ui/virtual-list/index.d.ts +9 -0
- package/dist/ui/virtual-table/index.d.ts +19 -0
- package/dist/utils/accessibility.d.ts +285 -0
- package/dist/utils/animation/easing.d.ts +112 -0
- package/dist/utils/animation/helpers.d.ts +119 -0
- package/dist/utils/animation/index.d.ts +3 -0
- package/dist/utils/animation/keyframes.d.ts +334 -0
- package/dist/utils/error-handling.d.ts +182 -0
- package/dist/utils/highlighter.d.ts +27 -0
- package/dist/utils/highlighter.js +2 -0
- package/dist/utils/i18n.d.ts +245 -0
- package/dist/utils/keep-alive.d.ts +171 -0
- package/dist/utils/lazy-loading.d.ts +174 -0
- package/dist/utils/prop-validation.d.ts +106 -0
- package/dist/utils/theme.d.ts +234 -0
- package/package.json +69 -0
- package/src/components/CodeBlock.stx +57 -0
- package/src/components/Footer.stx +66 -0
- package/src/components/Hero.stx +25 -0
- package/src/components/Installation.stx +39 -0
- package/src/components/index.ts +4 -0
- package/src/composables/index.ts +4 -0
- package/src/composables/useCopyCode.ts +73 -0
- package/src/composables/useDarkMode.ts +100 -0
- package/src/composables/useSEO.ts +229 -0
- package/src/composables/utilities/index.ts +7 -0
- package/src/composables/utilities/useClickOutside.ts +72 -0
- package/src/composables/utilities/useFocusTrap.ts +159 -0
- package/src/composables/utilities/useKeyboard.ts +124 -0
- package/src/composables/utilities/useLocalStorage.ts +132 -0
- package/src/composables/utilities/useMediaQuery.ts +118 -0
- package/src/index.ts +99 -0
- package/src/stx.d.ts +4 -0
- package/src/ui/accordion/Accordion.stx +108 -0
- package/src/ui/accordion/index.ts +14 -0
- package/src/ui/audio/Audio.stx +50 -0
- package/src/ui/audio/README.md +42 -0
- package/src/ui/audio/index.ts +13 -0
- package/src/ui/auth/Login.stx +163 -0
- package/src/ui/auth/README.md +145 -0
- package/src/ui/auth/Signup.stx +161 -0
- package/src/ui/auth/TwoFactorChallenge.stx +125 -0
- package/src/ui/auth/index.ts +32 -0
- package/src/ui/avatar/Avatar.stx +88 -0
- package/src/ui/avatar/index.ts +12 -0
- package/src/ui/badge/Badge.stx +70 -0
- package/src/ui/badge/index.ts +10 -0
- package/src/ui/breadcrumb/Breadcrumb.stx +79 -0
- package/src/ui/breadcrumb/index.ts +15 -0
- package/src/ui/button/Button.stx +89 -0
- package/src/ui/button/README.md +100 -0
- package/src/ui/button/index.ts +85 -0
- package/src/ui/calendar/Calendar.stx +232 -0
- package/src/ui/calendar/README.md +254 -0
- package/src/ui/calendar/index.ts +14 -0
- package/src/ui/card/Card.stx +74 -0
- package/src/ui/card/index.ts +13 -0
- package/src/ui/checkbox/Checkbox.stx +92 -0
- package/src/ui/checkbox/index.ts +16 -0
- package/src/ui/combobox/Combobox.stx +13 -0
- package/src/ui/combobox/ComboboxButton.stx +13 -0
- package/src/ui/combobox/ComboboxInput.stx +25 -0
- package/src/ui/combobox/ComboboxOption.stx +52 -0
- package/src/ui/combobox/ComboboxOptions.stx +12 -0
- package/src/ui/combobox/README.md +154 -0
- package/src/ui/combobox/index.ts +40 -0
- package/src/ui/command-palette/CommandPalette.stx +39 -0
- package/src/ui/command-palette/CommandPaletteItem.stx +32 -0
- package/src/ui/command-palette/README.md +42 -0
- package/src/ui/command-palette/index.ts +15 -0
- package/src/ui/dialog/Dialog.stx +19 -0
- package/src/ui/dialog/DialogBackdrop.stx +9 -0
- package/src/ui/dialog/DialogDescription.stx +11 -0
- package/src/ui/dialog/DialogPanel.stx +16 -0
- package/src/ui/dialog/DialogTitle.stx +11 -0
- package/src/ui/dialog/README.md +133 -0
- package/src/ui/dialog/index.ts +32 -0
- package/src/ui/drawer/Drawer.stx +137 -0
- package/src/ui/drawer/README.md +110 -0
- package/src/ui/drawer/index.ts +9 -0
- package/src/ui/dropdown/Dropdown.stx +24 -0
- package/src/ui/dropdown/DropdownButton.stx +23 -0
- package/src/ui/dropdown/DropdownItem.stx +43 -0
- package/src/ui/dropdown/DropdownItems.stx +18 -0
- package/src/ui/dropdown/README.md +142 -0
- package/src/ui/dropdown/index.ts +29 -0
- package/src/ui/form/Form.stx +209 -0
- package/src/ui/form/index.ts +67 -0
- package/src/ui/heatmap/Heatmap.stx +315 -0
- package/src/ui/image/Image.stx +197 -0
- package/src/ui/image/README.md +171 -0
- package/src/ui/image/index.ts +22 -0
- package/src/ui/input/EmailInput.stx +41 -0
- package/src/ui/input/NumberInput.stx +138 -0
- package/src/ui/input/PasswordInput.stx +155 -0
- package/src/ui/input/SearchInput.stx +63 -0
- package/src/ui/input/TextInput.stx +146 -0
- package/src/ui/input/index.ts +180 -0
- package/src/ui/listbox/Listbox.stx +14 -0
- package/src/ui/listbox/ListboxButton.stx +17 -0
- package/src/ui/listbox/ListboxLabel.stx +11 -0
- package/src/ui/listbox/ListboxOption.stx +57 -0
- package/src/ui/listbox/ListboxOptions.stx +16 -0
- package/src/ui/listbox/README.md +143 -0
- package/src/ui/listbox/index.ts +39 -0
- package/src/ui/navigator/Navigator.stx +138 -0
- package/src/ui/navigator/README.md +352 -0
- package/src/ui/navigator/index.ts +20 -0
- package/src/ui/notification/Notification.stx +71 -0
- package/src/ui/notification/README.md +118 -0
- package/src/ui/notification/index.ts +12 -0
- package/src/ui/pagination/Pagination.stx +183 -0
- package/src/ui/pagination/index.ts +11 -0
- package/src/ui/payment/Checkout.stx +39 -0
- package/src/ui/payment/DefaultPaymentMethod.stx +62 -0
- package/src/ui/payment/PaymentMethods.stx +113 -0
- package/src/ui/payment/README.md +427 -0
- package/src/ui/payment/SubscriptionCheckout.stx +353 -0
- package/src/ui/payment/index.ts +59 -0
- package/src/ui/popover/Popover.stx +24 -0
- package/src/ui/popover/PopoverButton.stx +23 -0
- package/src/ui/popover/PopoverPanel.stx +23 -0
- package/src/ui/popover/README.md +95 -0
- package/src/ui/popover/index.ts +22 -0
- package/src/ui/portal/Portal.stx +74 -0
- package/src/ui/portal/index.ts +6 -0
- package/src/ui/progress/Progress.stx +142 -0
- package/src/ui/progress/index.ts +12 -0
- package/src/ui/radio/Radio.stx +81 -0
- package/src/ui/radio/index.ts +15 -0
- package/src/ui/radio-group/README.md +145 -0
- package/src/ui/radio-group/RadioGroup.stx +13 -0
- package/src/ui/radio-group/RadioGroupDescription.stx +11 -0
- package/src/ui/radio-group/RadioGroupLabel.stx +11 -0
- package/src/ui/radio-group/RadioGroupOption.stx +51 -0
- package/src/ui/radio-group/index.ts +30 -0
- package/src/ui/select/README.md +204 -0
- package/src/ui/select/Select.stx +89 -0
- package/src/ui/select/index.ts +21 -0
- package/src/ui/sidebar/Sidebar.stx +288 -0
- package/src/ui/sidebar/SidebarFooter.stx +95 -0
- package/src/ui/sidebar/SidebarHeader.stx +100 -0
- package/src/ui/sidebar/SidebarItem.stx +118 -0
- package/src/ui/sidebar/SidebarSection.stx +108 -0
- package/src/ui/sidebar/index.ts +175 -0
- package/src/ui/skeleton/Skeleton.stx +48 -0
- package/src/ui/skeleton/index.ts +11 -0
- package/src/ui/spinner/Spinner.stx +109 -0
- package/src/ui/spinner/index.ts +9 -0
- package/src/ui/stepper/README.md +36 -0
- package/src/ui/stepper/Stepper.stx +17 -0
- package/src/ui/stepper/StepperStep.stx +53 -0
- package/src/ui/stepper/index.ts +19 -0
- package/src/ui/storage/README.md +193 -0
- package/src/ui/storage/index.ts +347 -0
- package/src/ui/switch/README.md +133 -0
- package/src/ui/switch/Switch.stx +74 -0
- package/src/ui/switch/index.ts +10 -0
- package/src/ui/table/README.md +39 -0
- package/src/ui/table/Table.stx +14 -0
- package/src/ui/table/TableBody.stx +10 -0
- package/src/ui/table/TableCell.stx +10 -0
- package/src/ui/table/TableHead.stx +10 -0
- package/src/ui/table/TableHeader.stx +13 -0
- package/src/ui/table/TableRow.stx +11 -0
- package/src/ui/table/index.ts +35 -0
- package/src/ui/tabs/Tabs.stx +145 -0
- package/src/ui/tabs/index.ts +16 -0
- package/src/ui/teleport/Teleport.stx +101 -0
- package/src/ui/teleport/index.ts +7 -0
- package/src/ui/textarea/Textarea.stx +119 -0
- package/src/ui/textarea/index.ts +20 -0
- package/src/ui/tooltip/Tooltip.stx +76 -0
- package/src/ui/tooltip/index.ts +10 -0
- package/src/ui/transition/README.md +30 -0
- package/src/ui/transition/Transition.stx +174 -0
- package/src/ui/transition/index.ts +25 -0
- package/src/ui/video/README.md +48 -0
- package/src/ui/video/Video.stx +45 -0
- package/src/ui/video/index.ts +16 -0
- package/src/ui/virtual-list/VirtualList.stx +83 -0
- package/src/ui/virtual-list/index.ts +10 -0
- package/src/ui/virtual-table/VirtualTable.stx +113 -0
- package/src/ui/virtual-table/index.ts +21 -0
- package/src/utils/PROP_VALIDATION.md +458 -0
- package/src/utils/THEME_SYSTEM.md +702 -0
- package/src/utils/accessibility.ts +841 -0
- package/src/utils/animation/easing.ts +368 -0
- package/src/utils/animation/helpers.ts +223 -0
- package/src/utils/animation/index.ts +5 -0
- package/src/utils/animation/keyframes.ts +230 -0
- package/src/utils/error-handling.ts +473 -0
- package/src/utils/highlighter.ts +93 -0
- package/src/utils/i18n.ts +634 -0
- package/src/utils/keep-alive.ts +818 -0
- package/src/utils/lazy-loading.ts +530 -0
- package/src/utils/prop-validation.ts +478 -0
- package/src/utils/theme.ts +626 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
/**
|
|
3
|
+
* SidebarSection Component
|
|
4
|
+
*
|
|
5
|
+
* A collapsible section within the sidebar containing navigation items.
|
|
6
|
+
* Follows macOS Finder sidebar conventions.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* <SidebarSection
|
|
10
|
+
* id="favorites"
|
|
11
|
+
* label="Favorites"
|
|
12
|
+
* icon="i-hugeicons-star"
|
|
13
|
+
* :items="favoriteItems"
|
|
14
|
+
* :expanded="true"
|
|
15
|
+
* />
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// Props
|
|
19
|
+
export const id = $props.id || ''
|
|
20
|
+
export const label = $props.label || ''
|
|
21
|
+
export const icon = $props.icon || ''
|
|
22
|
+
export const items = $props.items || []
|
|
23
|
+
export const expanded = $props.expanded ?? true
|
|
24
|
+
export const collapsible = $props.collapsible ?? true
|
|
25
|
+
export const showLabel = $props.showLabel ?? true
|
|
26
|
+
export const onToggle = $props.onToggle
|
|
27
|
+
export const onItemClick = $props.onItemClick
|
|
28
|
+
|
|
29
|
+
// Handle section header click
|
|
30
|
+
function handleHeaderClick() {
|
|
31
|
+
if (collapsible && onToggle) {
|
|
32
|
+
onToggle(id)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Handle item click
|
|
37
|
+
function handleItemClick(item, event) {
|
|
38
|
+
if (onItemClick) {
|
|
39
|
+
onItemClick(item, event)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Section header classes - macOS Finder style
|
|
44
|
+
const headerClasses = [
|
|
45
|
+
'w-full flex items-center gap-2.5 px-2.5 py-1.5 rounded-md text-left',
|
|
46
|
+
'transition-all duration-150',
|
|
47
|
+
'text-black/60 dark:text-white/60',
|
|
48
|
+
collapsible ? 'hover:bg-black/5 dark:hover:bg-white/10 cursor-pointer' : ''
|
|
49
|
+
].filter(Boolean).join(' ')
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<div class="py-1">
|
|
53
|
+
<!-- Section header -->
|
|
54
|
+
@if(collapsible)
|
|
55
|
+
<button
|
|
56
|
+
type="button"
|
|
57
|
+
class="{{ headerClasses }}"
|
|
58
|
+
@click="handleHeaderClick"
|
|
59
|
+
aria-expanded="{{ expanded }}"
|
|
60
|
+
aria-controls="sidebar-section-{{ id }}"
|
|
61
|
+
>
|
|
62
|
+
@if(icon)
|
|
63
|
+
<div class="{{ icon }} w-4 h-4 flex-shrink-0 opacity-70"></div>
|
|
64
|
+
@endif
|
|
65
|
+
@if(showLabel)
|
|
66
|
+
<span class="flex-1 text-[13px] font-semibold tracking-tight truncate">
|
|
67
|
+
{{ label }}
|
|
68
|
+
</span>
|
|
69
|
+
<div class="i-hugeicons-arrow-right-01 w-3 h-3 transition-transform duration-200 opacity-50 {{ expanded ? 'rotate-90' : '' }}"></div>
|
|
70
|
+
@endif
|
|
71
|
+
</button>
|
|
72
|
+
@else
|
|
73
|
+
<div class="{{ headerClasses }}">
|
|
74
|
+
@if(icon)
|
|
75
|
+
<div class="{{ icon }} w-4 h-4 flex-shrink-0 opacity-70"></div>
|
|
76
|
+
@endif
|
|
77
|
+
@if(showLabel)
|
|
78
|
+
<span class="flex-1 text-[13px] font-semibold tracking-tight truncate">
|
|
79
|
+
{{ label }}
|
|
80
|
+
</span>
|
|
81
|
+
@endif
|
|
82
|
+
</div>
|
|
83
|
+
@endif
|
|
84
|
+
|
|
85
|
+
<!-- Section items -->
|
|
86
|
+
@if(expanded && showLabel && items.length > 0)
|
|
87
|
+
<div
|
|
88
|
+
id="sidebar-section-{{ id }}"
|
|
89
|
+
class="mt-1 space-y-0.5 overflow-hidden"
|
|
90
|
+
role="group"
|
|
91
|
+
aria-label="{{ label }}"
|
|
92
|
+
>
|
|
93
|
+
@foreach(items as item)
|
|
94
|
+
<SidebarItem
|
|
95
|
+
:id="item.id"
|
|
96
|
+
:label="item.label"
|
|
97
|
+
:icon="item.icon"
|
|
98
|
+
:href="item.href"
|
|
99
|
+
:badge="item.badge"
|
|
100
|
+
:active="item.active"
|
|
101
|
+
:disabled="item.disabled"
|
|
102
|
+
:indent="true"
|
|
103
|
+
@click="handleItemClick(item, $event)"
|
|
104
|
+
/>
|
|
105
|
+
@endforeach
|
|
106
|
+
</div>
|
|
107
|
+
@endif
|
|
108
|
+
</div>
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const headingText = $props.headingText || 'Sign up for Stacks'
|
|
3
|
+
export const showSocialSignup = $props.showSocialSignup ?? true
|
|
4
|
+
export const onSubmit = $props.onSubmit || (() => {})
|
|
5
|
+
export const className = $props.className || ''
|
|
6
|
+
|
|
7
|
+
export const containerClasses = `min-h-full flex flex-col justify-center py-12 lg:px-8 sm:px-6 dark:bg-blue-gray-900 ${className}`.trim()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<div class="{{ containerClasses }}">
|
|
11
|
+
<div class="sm:mx-auto sm:max-w-md sm:w-full">
|
|
12
|
+
<h2 class="mt-6 text-center text-2xl text-gray-900 dark:text-gray-100 font-bold leading-9 tracking-tight">
|
|
13
|
+
{{ headingText }}
|
|
14
|
+
</h2>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div class="mt-10 sm:mx-auto sm:max-w-[480px] sm:w-full">
|
|
18
|
+
<div class="bg-white dark:bg-blue-gray-800 px-6 py-12 shadow sm:rounded-lg sm:px-12">
|
|
19
|
+
<form class="space-y-6" onsubmit="event.preventDefault(); handleSubmit(event)">
|
|
20
|
+
<div>
|
|
21
|
+
<label for="name" class="block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
|
|
22
|
+
Full Name
|
|
23
|
+
</label>
|
|
24
|
+
<div class="mt-2">
|
|
25
|
+
<input
|
|
26
|
+
id="name"
|
|
27
|
+
name="name"
|
|
28
|
+
type="text"
|
|
29
|
+
autocomplete="name"
|
|
30
|
+
required
|
|
31
|
+
class="block w-full border-0 rounded-md p-2 py-1.5 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset sm:text-sm placeholder:text-gray-400 dark:placeholder:text-gray-500 sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div>
|
|
37
|
+
<label for="email" class="block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
|
|
38
|
+
Email address
|
|
39
|
+
</label>
|
|
40
|
+
<div class="mt-2">
|
|
41
|
+
<input
|
|
42
|
+
id="email"
|
|
43
|
+
name="email"
|
|
44
|
+
type="email"
|
|
45
|
+
autocomplete="email"
|
|
46
|
+
required
|
|
47
|
+
class="block w-full border-0 rounded-md p-2 py-1.5 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset sm:text-sm placeholder:text-gray-400 dark:placeholder:text-gray-500 sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div>
|
|
53
|
+
<label for="confirm_email" class="block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
|
|
54
|
+
Confirm Email
|
|
55
|
+
</label>
|
|
56
|
+
<div class="mt-2">
|
|
57
|
+
<input
|
|
58
|
+
id="confirm_email"
|
|
59
|
+
name="confirm_email"
|
|
60
|
+
type="email"
|
|
61
|
+
autocomplete="email"
|
|
62
|
+
required
|
|
63
|
+
class="block w-full border-0 rounded-md p-2 py-1.5 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset sm:text-sm placeholder:text-gray-400 dark:placeholder:text-gray-500 sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<div>
|
|
69
|
+
<label for="password" class="block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
|
|
70
|
+
Password
|
|
71
|
+
</label>
|
|
72
|
+
<div class="mt-2">
|
|
73
|
+
<input
|
|
74
|
+
id="password"
|
|
75
|
+
name="password"
|
|
76
|
+
type="password"
|
|
77
|
+
autocomplete="new-password"
|
|
78
|
+
required
|
|
79
|
+
class="block w-full border-0 rounded-md p-2 py-1.5 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset sm:text-sm placeholder:text-gray-400 dark:placeholder:text-gray-500 sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<div>
|
|
85
|
+
<button
|
|
86
|
+
type="submit"
|
|
87
|
+
class="w-full flex justify-center rounded-md bg-teal-600 px-3 py-1.5 text-sm text-white font-semibold leading-6 shadow-sm hover:bg-teal-500 focus-visible:outline-2 focus-visible:outline-teal-600 focus-visible:outline-offset-2 focus-visible:outline"
|
|
88
|
+
>
|
|
89
|
+
Sign up
|
|
90
|
+
</button>
|
|
91
|
+
</div>
|
|
92
|
+
</form>
|
|
93
|
+
|
|
94
|
+
@if(showSocialSignup)
|
|
95
|
+
<div>
|
|
96
|
+
<div class="relative mt-10">
|
|
97
|
+
<div class="absolute inset-0 flex items-center" aria-hidden="true">
|
|
98
|
+
<div class="w-full border-t border-gray-200 dark:border-gray-600"></div>
|
|
99
|
+
</div>
|
|
100
|
+
<div class="relative flex justify-center text-sm font-medium leading-6">
|
|
101
|
+
<span class="bg-white dark:bg-blue-gray-800 px-6 text-gray-900 dark:text-gray-100">
|
|
102
|
+
Or signup with
|
|
103
|
+
</span>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div class="grid grid-cols-2 mt-6 gap-4">
|
|
108
|
+
<a
|
|
109
|
+
href="#"
|
|
110
|
+
class="w-full flex items-center justify-center gap-3 rounded-md bg-white dark:bg-blue-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-gray-100 font-semibold shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:ring-transparent"
|
|
111
|
+
>
|
|
112
|
+
<svg class="h-5 w-5" viewBox="0 0 24 24" aria-hidden="true">
|
|
113
|
+
<path d="M12.0003 4.75C13.7703 4.75 15.3553 5.36002 16.6053 6.54998L20.0303 3.125C17.9502 1.19 15.2353 0 12.0003 0C7.31028 0 3.25527 2.69 1.28027 6.60998L5.27028 9.70498C6.21525 6.86002 8.87028 4.75 12.0003 4.75Z" fill="#EA4335" />
|
|
114
|
+
<path d="M23.49 12.275C23.49 11.49 23.415 10.73 23.3 10H12V14.51H18.47C18.18 15.99 17.34 17.25 16.08 18.1L19.945 21.1C22.2 19.01 23.49 15.92 23.49 12.275Z" fill="#4285F4" />
|
|
115
|
+
<path d="M5.26498 14.2949C5.02498 13.5699 4.88501 12.7999 4.88501 11.9999C4.88501 11.1999 5.01998 10.4299 5.26498 9.7049L1.275 6.60986C0.46 8.22986 0 10.0599 0 11.9999C0 13.9399 0.46 15.7699 1.28 17.3899L5.26498 14.2949Z" fill="#FBBC05" />
|
|
116
|
+
<path d="M12.0004 24.0001C15.2404 24.0001 17.9654 22.935 19.9454 21.095L16.0804 18.095C15.0054 18.82 13.6204 19.245 12.0004 19.245C8.8704 19.245 6.21537 17.135 5.2654 14.29L1.27539 17.385C3.25539 21.31 7.3104 24.0001 12.0004 24.0001Z" fill="#34A853" />
|
|
117
|
+
</svg>
|
|
118
|
+
<span class="text-sm font-semibold leading-6">Google</span>
|
|
119
|
+
</a>
|
|
120
|
+
|
|
121
|
+
<a
|
|
122
|
+
href="#"
|
|
123
|
+
class="w-full flex items-center justify-center gap-3 rounded-md bg-white dark:bg-blue-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-gray-100 font-semibold shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:ring-transparent"
|
|
124
|
+
>
|
|
125
|
+
<svg class="h-5 w-5 fill-[#24292F] dark:fill-white" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
|
126
|
+
<path fill-rule="evenodd" d="M10 0C4.477 0 0 4.484 0 10.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0110 4.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.203 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.942.359.31.678.921.678 1.856 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0020 10.017C20 4.484 15.522 0 10 0z" clip-rule="evenodd" />
|
|
127
|
+
</svg>
|
|
128
|
+
<span class="text-sm font-semibold leading-6">GitHub</span>
|
|
129
|
+
</a>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
@endif
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<script>
|
|
138
|
+
function handleSubmit(event) {
|
|
139
|
+
const formData = new FormData(event.target)
|
|
140
|
+
const name = formData.get('name')
|
|
141
|
+
const email = formData.get('email')
|
|
142
|
+
const confirmEmail = formData.get('confirm_email')
|
|
143
|
+
const password = formData.get('password')
|
|
144
|
+
|
|
145
|
+
// Basic email confirmation validation
|
|
146
|
+
if (email !== confirmEmail) {
|
|
147
|
+
alert('Emails do not match!')
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (onSubmit) {
|
|
152
|
+
onSubmit({ name, email, password })
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Clear sensitive fields after submission
|
|
156
|
+
setTimeout(() => {
|
|
157
|
+
event.target.querySelector('#password').value = ''
|
|
158
|
+
event.target.querySelector('#confirm_email').value = ''
|
|
159
|
+
}, 1000)
|
|
160
|
+
}
|
|
161
|
+
</script>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const variant = $props.variant || 'text'
|
|
3
|
+
export const count = $props.count || 1
|
|
4
|
+
export const width = $props.width || ''
|
|
5
|
+
export const height = $props.height || ''
|
|
6
|
+
export const circle = $props.circle || false
|
|
7
|
+
export const className = $props.className || ''
|
|
8
|
+
export const animate = $props.animate ?? true
|
|
9
|
+
|
|
10
|
+
// Variant classes
|
|
11
|
+
const variantClasses = {
|
|
12
|
+
text: 'h-4 rounded',
|
|
13
|
+
title: 'h-8 rounded',
|
|
14
|
+
avatar: 'w-10 h-10 rounded-full',
|
|
15
|
+
thumbnail: 'w-24 h-24 rounded-md',
|
|
16
|
+
button: 'h-10 w-32 rounded-md',
|
|
17
|
+
card: 'h-64 rounded-lg',
|
|
18
|
+
rect: 'rounded-md',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Animation classes
|
|
22
|
+
const animationClasses = animate ? 'animate-pulse' : ''
|
|
23
|
+
|
|
24
|
+
// Build base classes
|
|
25
|
+
const baseClasses = circle ? 'rounded-full' : variantClasses[variant]
|
|
26
|
+
|
|
27
|
+
// Build style object
|
|
28
|
+
let styleString = ''
|
|
29
|
+
if (width) {
|
|
30
|
+
styleString += `width: ${typeof width === 'number' ? width + 'px' : width};`
|
|
31
|
+
}
|
|
32
|
+
if (height) {
|
|
33
|
+
styleString += `height: ${typeof height === 'number' ? height + 'px' : height};`
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const skeletonClasses = `bg-gray-200 dark:bg-gray-700 ${baseClasses} ${animationClasses} ${className}`.trim()
|
|
37
|
+
export const containerClasses = count > 1 ? 'space-y-3' : ''
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
@if(count > 1)
|
|
41
|
+
<div class="{{ containerClasses }}">
|
|
42
|
+
@for(i = 0; i < count; i++)
|
|
43
|
+
<div class="{{ skeletonClasses }}" style="{{ styleString }}" aria-busy="true" aria-live="polite"></div>
|
|
44
|
+
@endfor
|
|
45
|
+
</div>
|
|
46
|
+
@else
|
|
47
|
+
<div class="{{ skeletonClasses }}" style="{{ styleString }}" aria-busy="true" aria-live="polite"></div>
|
|
48
|
+
@endif
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const variant = $props.variant || 'circle'
|
|
3
|
+
export const size = $props.size || 'md'
|
|
4
|
+
export const color = $props.color || 'primary'
|
|
5
|
+
export const label = $props.label || ''
|
|
6
|
+
export const className = $props.className || ''
|
|
7
|
+
|
|
8
|
+
// Size classes
|
|
9
|
+
const sizeClasses = {
|
|
10
|
+
xs: 'w-3 h-3',
|
|
11
|
+
sm: 'w-4 h-4',
|
|
12
|
+
md: 'w-6 h-6',
|
|
13
|
+
lg: 'w-8 h-8',
|
|
14
|
+
xl: 'w-12 h-12',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Color classes
|
|
18
|
+
const colorClasses = {
|
|
19
|
+
primary: 'text-blue-600 dark:text-blue-500',
|
|
20
|
+
secondary: 'text-purple-600 dark:text-purple-500',
|
|
21
|
+
success: 'text-green-600 dark:text-green-500',
|
|
22
|
+
warning: 'text-yellow-600 dark:text-yellow-500',
|
|
23
|
+
danger: 'text-red-600 dark:text-red-500',
|
|
24
|
+
info: 'text-cyan-600 dark:text-cyan-500',
|
|
25
|
+
white: 'text-white',
|
|
26
|
+
gray: 'text-gray-600 dark:text-gray-400',
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const containerClasses = `inline-flex flex-col items-center gap-2 ${className}`.trim()
|
|
30
|
+
export const spinnerClasses = `${sizeClasses[size]} ${colorClasses[color]} animate-spin`.trim()
|
|
31
|
+
export const labelClasses = `text-sm font-medium text-gray-700 dark:text-gray-300`.trim()
|
|
32
|
+
|
|
33
|
+
// Dots size classes
|
|
34
|
+
const dotsSizeClasses = {
|
|
35
|
+
xs: 'w-1 h-1',
|
|
36
|
+
sm: 'w-1.5 h-1.5',
|
|
37
|
+
md: 'w-2 h-2',
|
|
38
|
+
lg: 'w-2.5 h-2.5',
|
|
39
|
+
xl: 'w-3 h-3',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const dotsColorClasses = {
|
|
43
|
+
primary: 'bg-blue-600 dark:bg-blue-500',
|
|
44
|
+
secondary: 'bg-purple-600 dark:bg-purple-500',
|
|
45
|
+
success: 'bg-green-600 dark:bg-green-500',
|
|
46
|
+
warning: 'bg-yellow-600 dark:bg-yellow-500',
|
|
47
|
+
danger: 'bg-red-600 dark:bg-red-500',
|
|
48
|
+
info: 'bg-cyan-600 dark:bg-cyan-500',
|
|
49
|
+
white: 'bg-white',
|
|
50
|
+
gray: 'bg-gray-600 dark:bg-gray-400',
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const dotClasses = `${dotsSizeClasses[size]} ${dotsColorClasses[color]} rounded-full`.trim()
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<div class="{{ containerClasses }}" role="status" aria-live="polite" aria-busy="true">
|
|
57
|
+
@if(variant === 'circle')
|
|
58
|
+
<!-- Circle spinner (default) -->
|
|
59
|
+
<svg class="{{ spinnerClasses }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
60
|
+
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
61
|
+
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
62
|
+
</svg>
|
|
63
|
+
@elseif(variant === 'dots')
|
|
64
|
+
<!-- Dots spinner -->
|
|
65
|
+
<div class="flex items-center gap-1">
|
|
66
|
+
<div class="{{ dotClasses }}" style="animation: bounce 1.4s infinite ease-in-out both; animation-delay: -0.32s"></div>
|
|
67
|
+
<div class="{{ dotClasses }}" style="animation: bounce 1.4s infinite ease-in-out both; animation-delay: -0.16s"></div>
|
|
68
|
+
<div class="{{ dotClasses }}" style="animation: bounce 1.4s infinite ease-in-out both"></div>
|
|
69
|
+
</div>
|
|
70
|
+
@elseif(variant === 'bars')
|
|
71
|
+
<!-- Bars spinner -->
|
|
72
|
+
<div class="flex items-center gap-1">
|
|
73
|
+
<div class="w-1 bg-current rounded-full" style="height: {{ size === 'xs' ? '8px' : size === 'sm' ? '12px' : size === 'md' ? '16px' : size === 'lg' ? '20px' : '24px' }}; animation: bars 1.2s infinite ease-in-out; animation-delay: -0.24s"></div>
|
|
74
|
+
<div class="w-1 bg-current rounded-full" style="height: {{ size === 'xs' ? '8px' : size === 'sm' ? '12px' : size === 'md' ? '16px' : size === 'lg' ? '20px' : '24px' }}; animation: bars 1.2s infinite ease-in-out; animation-delay: -0.12s"></div>
|
|
75
|
+
<div class="w-1 bg-current rounded-full" style="height: {{ size === 'xs' ? '8px' : size === 'sm' ? '12px' : size === 'md' ? '16px' : size === 'lg' ? '20px' : '24px' }}; animation: bars 1.2s infinite ease-in-out"></div>
|
|
76
|
+
</div>
|
|
77
|
+
@elseif(variant === 'ring')
|
|
78
|
+
<!-- Ring spinner -->
|
|
79
|
+
<div class="{{ spinnerClasses }}" style="border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%;"></div>
|
|
80
|
+
@endif
|
|
81
|
+
|
|
82
|
+
@if(label)
|
|
83
|
+
<span class="{{ labelClasses }}">{{ label }}</span>
|
|
84
|
+
@endif
|
|
85
|
+
|
|
86
|
+
<span class="sr-only">{{ label || 'Loading...' }}</span>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<style>
|
|
90
|
+
@keyframes bounce {
|
|
91
|
+
0%, 80%, 100% {
|
|
92
|
+
transform: scale(0);
|
|
93
|
+
opacity: 0.5;
|
|
94
|
+
}
|
|
95
|
+
40% {
|
|
96
|
+
transform: scale(1);
|
|
97
|
+
opacity: 1;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@keyframes bars {
|
|
102
|
+
0%, 40%, 100% {
|
|
103
|
+
transform: scaleY(0.4);
|
|
104
|
+
}
|
|
105
|
+
20% {
|
|
106
|
+
transform: scaleY(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
</style>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const currentStep = $props.currentStep || 0
|
|
3
|
+
export const orientation = $props.orientation || 'horizontal'
|
|
4
|
+
export const className = $props.className || ''
|
|
5
|
+
export const as = $props.as || 'div'
|
|
6
|
+
|
|
7
|
+
const orientationClasses = orientation === 'horizontal'
|
|
8
|
+
? 'flex flex-row'
|
|
9
|
+
: 'flex flex-col'
|
|
10
|
+
|
|
11
|
+
const baseClasses = 'w-full'
|
|
12
|
+
const stepperClasses = `${baseClasses} ${orientationClasses} ${className}`.trim()
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<component :is="{{ as }}" class="{{ stepperClasses }}">
|
|
16
|
+
<slot :currentStep="currentStep" />
|
|
17
|
+
</component>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const stepNumber = $props.stepNumber
|
|
3
|
+
export const currentStep = $props.currentStep || 0
|
|
4
|
+
export const label = $props.label || ''
|
|
5
|
+
export const description = $props.description || ''
|
|
6
|
+
export const className = $props.className || ''
|
|
7
|
+
export const as = $props.as || 'div'
|
|
8
|
+
export const onClick = $props.onClick
|
|
9
|
+
|
|
10
|
+
export const isComplete = stepNumber < currentStep
|
|
11
|
+
export const isCurrent = stepNumber === currentStep
|
|
12
|
+
export const isUpcoming = stepNumber > currentStep
|
|
13
|
+
|
|
14
|
+
const baseClasses = 'flex items-center'
|
|
15
|
+
const stepClasses = `${baseClasses} ${className}`.trim()
|
|
16
|
+
|
|
17
|
+
export function handleClick() {
|
|
18
|
+
onClick?.(stepNumber)
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<component :is="{{ as }}" class="{{ stepClasses }}">
|
|
23
|
+
<button
|
|
24
|
+
type="button"
|
|
25
|
+
@click="handleClick"
|
|
26
|
+
class="flex items-center gap-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 rounded-lg p-2"
|
|
27
|
+
>
|
|
28
|
+
<div class="{{ isComplete ? 'bg-blue-600 dark:bg-blue-500' : isCurrent ? 'bg-blue-600 dark:bg-blue-500 ring-4 ring-blue-200 dark:ring-blue-800' : 'bg-neutral-300 dark:bg-neutral-600' }} w-10 h-10 rounded-full flex items-center justify-center text-white font-semibold transition-all">
|
|
29
|
+
@if(isComplete)
|
|
30
|
+
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
31
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
|
32
|
+
</svg>
|
|
33
|
+
@else
|
|
34
|
+
{{ stepNumber + 1 }}
|
|
35
|
+
@endif
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
@if(label)
|
|
39
|
+
<div class="text-left">
|
|
40
|
+
<div class="text-sm font-medium {{ isCurrent ? 'text-blue-600 dark:text-blue-400' : 'text-neutral-900 dark:text-white' }}">
|
|
41
|
+
{{ label }}
|
|
42
|
+
</div>
|
|
43
|
+
@if(description)
|
|
44
|
+
<div class="text-xs text-neutral-500 dark:text-neutral-400">
|
|
45
|
+
{{ description }}
|
|
46
|
+
</div>
|
|
47
|
+
@endif
|
|
48
|
+
</div>
|
|
49
|
+
@endif
|
|
50
|
+
</button>
|
|
51
|
+
|
|
52
|
+
<slot :isComplete="isComplete" :isCurrent="isCurrent" :isUpcoming="isUpcoming" />
|
|
53
|
+
</component>
|