@stacksjs/components 0.2.27 → 0.2.53
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/dist/Accordion-19x8q4rj.stx +88 -0
- package/dist/{Audio-vdmg1258.stx → Audio-hjywk3qc.stx} +4 -4
- package/dist/{Avatar-365cvrh4.stx → Avatar-h3jmwcq0.stx} +23 -34
- package/dist/{Badge-8m3qete4.stx → Badge-k8dy3d53.stx} +11 -19
- package/dist/{Button-3tt4vsqt.stx → Button-1vknasy3.stx} +18 -33
- package/dist/Calendar-reny0et7.stx +189 -0
- package/dist/{Card-6wdbexqr.stx → Card-c1g1fd1w.stx} +27 -33
- package/dist/{Checkbox-p3q3e3nf.stx → Checkbox-zgdmy3p5.stx} +36 -44
- package/dist/{Checkout-e4037tyy.stx → Checkout-agt0ngpw.stx} +8 -16
- package/dist/Combobox-fdkr6cdq.stx +96 -0
- package/dist/{ComboboxButton-8gxwkhdx.stx → ComboboxButton-g76stp1e.stx} +14 -2
- package/dist/{ComboboxInput-mk99z65n.stx → ComboboxInput-z1293bbh.stx} +12 -5
- package/dist/ComboboxOption-hmxt3gte.stx +49 -0
- package/dist/{ListboxOptions-8kqvfp7z.stx → ComboboxOptions-sq5360ae.stx} +2 -2
- package/dist/CommandPalette-36mxf05w.stx +81 -0
- package/dist/CommandPaletteItem-mvk6q7a2.stx +27 -0
- package/dist/Dialog-hczpexs4.stx +37 -0
- package/dist/{Drawer-p7m351bn.stx → Drawer-xhevp5cw.stx} +29 -49
- package/dist/Dropdown-vvhemtc0.stx +82 -0
- package/dist/{DropdownButton-9w8zkfwj.stx → DropdownButton-wcz67dxy.stx} +12 -6
- package/dist/DropdownItem-c7rz08e5.stx +35 -0
- package/dist/{DropdownItems-aygjpxkx.stx → DropdownItems-1sxnd5qn.stx} +2 -2
- package/dist/EmailInput-vak3kkmk.stx +30 -0
- package/dist/Form-mas630hy.stx +95 -0
- package/dist/{Image-jhkm6w1f.stx → Image-yhxcvgzs.stx} +68 -100
- package/dist/Listbox-q49tnr90.stx +101 -0
- package/dist/{ListboxButton-spwx7513.stx → ListboxButton-keb8gm0q.stx} +12 -1
- package/dist/ListboxOption-e0dtv1gc.stx +49 -0
- package/dist/{ComboboxOptions-6b5ywc5x.stx → ListboxOptions-ejkatcfg.stx} +7 -3
- package/dist/{Login-rx9gyqhx.stx → Login-gepemsth.stx} +17 -19
- package/dist/Navigator-rk2a5wvk.stx +113 -0
- package/dist/Notification-tb9b525s.stx +78 -0
- package/dist/{NumberInput-nzpkx1ry.stx → NumberInput-drnvtqej.stx} +40 -53
- package/dist/{Pagination-h61eq390.stx → Pagination-n3d31cns.stx} +73 -108
- package/dist/PasswordInput-n02x6053.stx +142 -0
- package/dist/{PaymentMethods-j42jsk5x.stx → PaymentMethods-x4vrx9yb.stx} +21 -30
- package/dist/Popover-et2q44m7.stx +60 -0
- package/dist/{PopoverButton-fnaqc77g.stx → PopoverButton-mffzc9pr.stx} +12 -6
- package/dist/{PopoverPanel-y0vtf5w9.stx → PopoverPanel-054yh38h.stx} +6 -6
- package/dist/{Portal-s2q37yp0.stx → Portal-1vf14s4x.stx} +20 -37
- package/dist/{Progress-vmdkm06p.stx → Progress-yxcntr4x.stx} +36 -48
- package/dist/{Radio-04bs3d21.stx → Radio-cgjv2hb2.stx} +29 -34
- package/dist/RadioGroup-qxmnm3xm.stx +60 -0
- package/dist/RadioGroupOption-s1d6r221.stx +58 -0
- package/dist/SearchInput-pdx7agn0.stx +44 -0
- package/dist/{Select-g4mmvfv8.stx → Select-28y0pg83.stx} +23 -31
- package/dist/Sidebar-73vc78as.stx +236 -0
- package/dist/SidebarFooter-zsfsgcxb.stx +109 -0
- package/dist/SidebarHeader-7v174a9c.stx +122 -0
- package/dist/SidebarItem-3y3e8g2t.stx +92 -0
- package/dist/SidebarSection-z5ey6awe.stx +113 -0
- package/dist/{Signup-c4dyv6f3.stx → Signup-hxm5hwkr.stx} +26 -28
- package/dist/{StepperStep-en4r00zv.stx → StepperStep-wxgembat.stx} +9 -5
- package/dist/{SubscriptionCheckout-gawjzf3q.stx → SubscriptionCheckout-zy2ycrmw.stx} +99 -129
- package/dist/Switch-r5t5w04w.stx +70 -0
- package/dist/{TableHeader-ydys9rzz.stx → TableHeader-0eyzbqpz.stx} +10 -3
- package/dist/Tabs-bzvvn4ke.stx +126 -0
- package/dist/Teleport-tsx4bt4n.stx +65 -0
- package/dist/{TextInput-k2kfkgy1.stx → TextInput-kf084763.stx} +42 -59
- package/dist/{Textarea-szad57dz.stx → Textarea-xg4rr2xz.stx} +42 -54
- package/dist/{Tooltip-em7t551n.stx → Tooltip-m0tqd72e.stx} +34 -40
- package/dist/Transition-7smenaz8.stx +102 -0
- package/dist/{TwoFactorChallenge-an9yvxvq.stx → TwoFactorChallenge-y5m3nk79.stx} +49 -63
- package/dist/{Video-crxva65p.stx → Video-84j4pv6h.stx} +4 -4
- package/dist/VirtualList-fa7v5a3h.stx +67 -0
- package/dist/VirtualTable-f9crbfjr.stx +103 -0
- package/dist/components/CodeBlock.stx +1 -6
- package/dist/index.js +13 -13
- package/dist/ui/accordion/Accordion.stx +1 -3
- package/dist/ui/auth/Login.stx +0 -1
- package/dist/ui/auth/Signup.stx +0 -1
- package/dist/ui/auth/TwoFactorChallenge.stx +1 -3
- package/dist/ui/avatar/Avatar.stx +0 -2
- package/dist/ui/badge/Badge.stx +0 -1
- package/dist/ui/button/Button.stx +1 -2
- package/dist/ui/calendar/Calendar.stx +12 -2
- package/dist/ui/card/Card.stx +0 -2
- package/dist/ui/checkbox/Checkbox.stx +2 -2
- package/dist/ui/combobox/Combobox.stx +2 -1
- package/dist/ui/combobox/ComboboxButton.stx +1 -0
- package/dist/ui/combobox/ComboboxInput.stx +1 -4
- package/dist/ui/combobox/ComboboxOption.stx +2 -9
- package/dist/ui/combobox/ComboboxOptions.stx +1 -1
- package/dist/ui/command-palette/CommandPalette.stx +3 -6
- package/dist/ui/command-palette/CommandPaletteItem.stx +2 -7
- package/dist/ui/dialog/Dialog.stx +1 -3
- package/dist/ui/drawer/Drawer.stx +1 -3
- package/dist/ui/dropdown/Dropdown.stx +2 -5
- package/dist/ui/dropdown/DropdownButton.stx +1 -3
- package/dist/ui/dropdown/DropdownItem.stx +2 -7
- package/dist/ui/dropdown/DropdownItems.stx +1 -1
- package/dist/ui/form/Form.stx +0 -5
- package/dist/ui/image/Image.stx +1 -6
- package/dist/ui/input/EmailInput.stx +1 -1
- package/dist/ui/input/NumberInput.stx +0 -1
- package/dist/ui/input/PasswordInput.stx +1 -4
- package/dist/ui/input/SearchInput.stx +2 -2
- package/dist/ui/input/TextInput.stx +1 -2
- package/dist/ui/listbox/Listbox.stx +2 -1
- package/dist/ui/listbox/ListboxButton.stx +1 -0
- package/dist/ui/listbox/ListboxOption.stx +2 -9
- package/dist/ui/listbox/ListboxOptions.stx +1 -1
- package/dist/ui/navigator/Navigator.stx +4 -4
- package/dist/ui/notification/Notification.stx +1 -5
- package/dist/ui/pagination/Pagination.stx +1 -2
- package/dist/ui/payment/Checkout.stx +0 -4
- package/dist/ui/payment/PaymentMethods.stx +15 -2
- package/dist/ui/payment/SubscriptionCheckout.stx +3 -184
- package/dist/ui/popover/Popover.stx +2 -5
- package/dist/ui/popover/PopoverButton.stx +1 -3
- package/dist/ui/popover/PopoverPanel.stx +1 -1
- package/dist/ui/portal/Portal.stx +1 -0
- package/dist/ui/progress/Progress.stx +6 -1
- package/dist/ui/radio/Radio.stx +1 -1
- package/dist/ui/radio-group/RadioGroup.stx +2 -1
- package/dist/ui/radio-group/RadioGroupOption.stx +2 -9
- package/dist/ui/select/Select.stx +1 -1
- package/dist/ui/sidebar/Sidebar.stx +9 -26
- package/dist/ui/sidebar/SidebarFooter.stx +6 -21
- package/dist/ui/sidebar/SidebarHeader.stx +7 -18
- package/dist/ui/sidebar/SidebarItem.stx +4 -20
- package/dist/ui/sidebar/SidebarSection.stx +5 -18
- package/dist/ui/sidebar/index.d.ts +13 -1
- package/dist/ui/stepper/StepperStep.stx +1 -5
- package/dist/ui/switch/Switch.stx +4 -10
- package/dist/ui/table/TableHeader.stx +1 -1
- package/dist/ui/tabs/Tabs.stx +0 -1
- package/dist/ui/teleport/Teleport.stx +1 -0
- package/dist/ui/textarea/Textarea.stx +1 -1
- package/dist/ui/tooltip/Tooltip.stx +1 -2
- package/dist/ui/transition/Transition.stx +9 -16
- package/dist/ui/virtual-list/VirtualList.stx +2 -4
- package/dist/ui/virtual-table/VirtualTable.stx +1 -1
- package/package.json +3 -3
- package/src/components/CodeBlock.stx +26 -29
- package/src/components/Footer.stx +1 -1
- package/src/components/Hero.stx +1 -1
- package/src/components/Installation.stx +5 -7
- package/src/ui/accordion/Accordion.stx +48 -68
- package/src/ui/audio/Audio.stx +4 -4
- package/src/ui/auth/Login.stx +17 -19
- package/src/ui/auth/Signup.stx +26 -28
- package/src/ui/auth/TwoFactorChallenge.stx +49 -63
- package/src/ui/avatar/Avatar.stx +23 -34
- package/src/ui/badge/Badge.stx +11 -19
- package/src/ui/button/Button.stx +18 -33
- package/src/ui/calendar/Calendar.stx +93 -136
- package/src/ui/card/Card.stx +27 -33
- package/src/ui/checkbox/Checkbox.stx +36 -44
- package/src/ui/combobox/Combobox.stx +87 -4
- package/src/ui/combobox/ComboboxButton.stx +14 -2
- package/src/ui/combobox/ComboboxInput.stx +12 -5
- package/src/ui/combobox/ComboboxOption.stx +29 -32
- package/src/ui/combobox/ComboboxOptions.stx +7 -3
- package/src/ui/command-palette/CommandPalette.stx +70 -28
- package/src/ui/command-palette/CommandPaletteItem.stx +15 -20
- package/src/ui/dialog/Dialog.stx +28 -10
- package/src/ui/drawer/Drawer.stx +29 -49
- package/src/ui/dropdown/Dropdown.stx +69 -11
- package/src/ui/dropdown/DropdownButton.stx +12 -6
- package/src/ui/dropdown/DropdownItem.stx +18 -26
- package/src/ui/dropdown/DropdownItems.stx +2 -2
- package/src/ui/form/Form.stx +50 -164
- package/src/ui/heatmap/Heatmap.stx +16 -37
- package/src/ui/image/Image.stx +68 -100
- package/src/ui/input/EmailInput.stx +16 -27
- package/src/ui/input/NumberInput.stx +40 -53
- package/src/ui/input/PasswordInput.stx +64 -77
- package/src/ui/input/SearchInput.stx +27 -46
- package/src/ui/input/TextInput.stx +42 -59
- package/src/ui/listbox/Listbox.stx +91 -4
- package/src/ui/listbox/ListboxButton.stx +12 -1
- package/src/ui/listbox/ListboxOption.stx +30 -38
- package/src/ui/listbox/ListboxOptions.stx +2 -2
- package/src/ui/navigator/Navigator.stx +52 -77
- package/src/ui/notification/Notification.stx +46 -39
- package/src/ui/pagination/Pagination.stx +73 -108
- package/src/ui/payment/Checkout.stx +8 -16
- package/src/ui/payment/PaymentMethods.stx +21 -30
- package/src/ui/payment/SubscriptionCheckout.stx +99 -129
- package/src/ui/popover/Popover.stx +50 -14
- package/src/ui/popover/PopoverButton.stx +12 -6
- package/src/ui/popover/PopoverPanel.stx +6 -6
- package/src/ui/portal/Portal.stx +20 -37
- package/src/ui/progress/Progress.stx +36 -48
- package/src/ui/radio/Radio.stx +29 -34
- package/src/ui/radio-group/RadioGroup.stx +51 -4
- package/src/ui/radio-group/RadioGroupOption.stx +37 -30
- package/src/ui/select/Select.stx +23 -31
- package/src/ui/sidebar/Sidebar.stx +136 -188
- package/src/ui/sidebar/SidebarFooter.stx +49 -35
- package/src/ui/sidebar/SidebarHeader.stx +52 -30
- package/src/ui/sidebar/SidebarItem.stx +52 -78
- package/src/ui/sidebar/SidebarSection.stx +56 -51
- package/src/ui/sidebar/index.ts +21 -1
- package/src/ui/stepper/StepperStep.stx +9 -5
- package/src/ui/switch/Switch.stx +38 -42
- package/src/ui/table/TableHeader.stx +10 -3
- package/src/ui/tabs/Tabs.stx +68 -87
- package/src/ui/teleport/Teleport.stx +23 -59
- package/src/ui/textarea/Textarea.stx +42 -54
- package/src/ui/tooltip/Tooltip.stx +34 -40
- package/src/ui/transition/Transition.stx +76 -148
- package/src/ui/video/Video.stx +4 -4
- package/src/ui/virtual-list/VirtualList.stx +45 -61
- package/src/ui/virtual-table/VirtualTable.stx +62 -72
- package/dist/Accordion-sbfra0mz.stx +0 -108
- package/dist/Calendar-58nnkdh8.stx +0 -232
- package/dist/Combobox-th5ebw62.stx +0 -13
- package/dist/ComboboxOption-an9zyan6.stx +0 -52
- package/dist/CommandPalette-kwmdf2np.stx +0 -39
- package/dist/CommandPaletteItem-zx2fbpts.stx +0 -32
- package/dist/Dialog-rgmj8q2j.stx +0 -19
- package/dist/Dropdown-jz4jy0n3.stx +0 -24
- package/dist/DropdownItem-wagdspb8.stx +0 -43
- package/dist/EmailInput-ajsp9vw6.stx +0 -41
- package/dist/Form-1mdmx9b6.stx +0 -209
- package/dist/Listbox-pqqh72g8.stx +0 -14
- package/dist/ListboxOption-7nxzaexq.stx +0 -57
- package/dist/Navigator-aay8bjab.stx +0 -138
- package/dist/Notification-gk33gv7b.stx +0 -71
- package/dist/PasswordInput-zv4hm43j.stx +0 -155
- package/dist/Popover-469gbt6r.stx +0 -24
- package/dist/RadioGroup-bvb1mrhd.stx +0 -13
- package/dist/RadioGroupOption-cpdwgnhw.stx +0 -51
- package/dist/SearchInput-2521m475.stx +0 -63
- package/dist/Sidebar-40ckbzh8.stx +0 -288
- package/dist/SidebarFooter-hnth56mg.stx +0 -95
- package/dist/SidebarHeader-3wrte2p2.stx +0 -100
- package/dist/SidebarItem-zqtvvzpc.stx +0 -118
- package/dist/SidebarSection-3etwnbjr.stx +0 -108
- package/dist/Switch-036j9vm1.stx +0 -74
- package/dist/Tabs-svh721m0.stx +0 -145
- package/dist/Teleport-qfch3w0b.stx +0 -101
- package/dist/Transition-0hmr6zxb.stx +0 -174
- package/dist/VirtualList-cndhjejh.stx +0 -83
- package/dist/VirtualTable-ng0b48yp.stx +0 -113
|
@@ -1,219 +1,189 @@
|
|
|
1
1
|
<script server>
|
|
2
|
-
/**
|
|
3
|
-
* Sidebar Component - macOS Native Style
|
|
4
|
-
*
|
|
5
|
-
* A native-feeling sidebar component that integrates with Craft for true native rendering
|
|
6
|
-
* when running in a Craft desktop environment, with beautiful macOS Tahoe-style fallback
|
|
7
|
-
* for web environments.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* <Sidebar
|
|
11
|
-
* :sections="sections"
|
|
12
|
-
* :collapsed="false"
|
|
13
|
-
* :width="240"
|
|
14
|
-
* variant="tahoe"
|
|
15
|
-
* >
|
|
16
|
-
* <template #header>
|
|
17
|
-
* <SidebarHeader title="My App" />
|
|
18
|
-
* </template>
|
|
19
|
-
* <template #footer>
|
|
20
|
-
* <SidebarFooter />
|
|
21
|
-
* </template>
|
|
22
|
-
* </Sidebar>
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
// Props
|
|
26
2
|
export const sections = $props.sections || []
|
|
27
3
|
export const collapsed = $props.collapsed ?? false
|
|
28
4
|
export const collapsible = $props.collapsible ?? true
|
|
29
5
|
export const width = $props.width || 240
|
|
30
6
|
export const minWidth = $props.minWidth || 64
|
|
31
|
-
export const variant = $props.variant || 'tahoe'
|
|
32
|
-
export const position = $props.position || 'left'
|
|
7
|
+
export const variant = $props.variant || 'tahoe'
|
|
8
|
+
export const position = $props.position || 'left'
|
|
9
|
+
export const placement = $props.placement || 'fixed'
|
|
33
10
|
export const bordered = $props.bordered ?? true
|
|
34
11
|
export const className = $props.className || ''
|
|
35
|
-
export const onCollapse = $props.onCollapse
|
|
36
|
-
export const onSectionToggle = $props.onSectionToggle
|
|
37
|
-
export const onItemClick = $props.onItemClick
|
|
38
|
-
|
|
39
|
-
// Internal state
|
|
40
|
-
let isHovered = false
|
|
41
|
-
let nativeSidebarId = null
|
|
42
|
-
|
|
43
|
-
// Check if running in Craft environment with native sidebar enabled
|
|
44
|
-
// When Craft uses --native-sidebar, it sets these flags and we should NOT render the web sidebar
|
|
45
|
-
const hasNativeSidebar = typeof window !== 'undefined' && (
|
|
46
|
-
window.__craftNativeSidebar === true ||
|
|
47
|
-
window.craft?.hasNativeSidebar?.() ||
|
|
48
|
-
(window.webkit?.messageHandlers?.craft && document.body?.dataset?.nativeSidebar === 'true')
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
// Check if running in Craft environment (may not have native sidebar)
|
|
52
|
-
const isCraft = typeof window !== 'undefined' && window.craft?.isCraft?.()
|
|
53
12
|
|
|
54
|
-
// Variant styles - macOS Tahoe inspired
|
|
55
|
-
// Native macOS sidebars use vibrancy where desktop background shines through
|
|
56
13
|
const variantStyles = {
|
|
57
14
|
tahoe: {
|
|
58
|
-
// Translucent with warm tint overlay - desktop shows through
|
|
59
15
|
bg: 'bg-white/70 dark:bg-black/50',
|
|
60
16
|
border: 'border-black/5 dark:border-white/10',
|
|
61
17
|
backdrop: 'backdrop-blur-2xl backdrop-saturate-180',
|
|
62
|
-
|
|
63
|
-
tint: true
|
|
18
|
+
tint: true,
|
|
64
19
|
},
|
|
65
20
|
vibrancy: {
|
|
66
21
|
bg: 'bg-white/50 dark:bg-black/40',
|
|
67
22
|
border: 'border-white/20 dark:border-white/10',
|
|
68
23
|
backdrop: 'backdrop-blur-3xl backdrop-saturate-200',
|
|
69
|
-
tint: false
|
|
24
|
+
tint: false,
|
|
70
25
|
},
|
|
71
26
|
solid: {
|
|
72
27
|
bg: 'bg-stone-100 dark:bg-neutral-900',
|
|
73
28
|
border: 'border-stone-200 dark:border-neutral-800',
|
|
74
29
|
backdrop: '',
|
|
75
|
-
tint: false
|
|
30
|
+
tint: false,
|
|
76
31
|
},
|
|
77
32
|
transparent: {
|
|
78
33
|
bg: 'bg-transparent',
|
|
79
34
|
border: 'border-transparent',
|
|
80
35
|
backdrop: '',
|
|
81
|
-
tint: false
|
|
82
|
-
}
|
|
36
|
+
tint: false,
|
|
37
|
+
},
|
|
38
|
+
workspace: {
|
|
39
|
+
bg: 'bg-[#f4f4f3] dark:bg-neutral-950',
|
|
40
|
+
border: 'border-transparent',
|
|
41
|
+
backdrop: '',
|
|
42
|
+
tint: false,
|
|
43
|
+
nav: 'px-5 py-5 space-y-1',
|
|
44
|
+
slot: 'px-5 py-5',
|
|
45
|
+
},
|
|
46
|
+
desktop: {
|
|
47
|
+
bg: 'bg-white/42 dark:bg-black/32',
|
|
48
|
+
border: 'border-white/30 dark:border-white/10',
|
|
49
|
+
backdrop: 'backdrop-blur-3xl backdrop-saturate-200',
|
|
50
|
+
tint: false,
|
|
51
|
+
shimmer: true,
|
|
52
|
+
nav: 'px-4 py-4 space-y-1',
|
|
53
|
+
slot: 'px-4 py-4',
|
|
54
|
+
},
|
|
83
55
|
}
|
|
84
56
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
57
|
+
const style = variantStyles[variant] || variantStyles.tahoe
|
|
58
|
+
export const variantTint = style.tint
|
|
59
|
+
export const variantShimmer = style.shimmer
|
|
60
|
+
const borderSide = position === 'left' ? 'border-r' : 'border-l'
|
|
61
|
+
const borderClasses = bordered ? `${borderSide} ${style.border}` : ''
|
|
62
|
+
const positionClass = position === 'left' ? 'left-0' : 'right-0'
|
|
63
|
+
const placementClasses = {
|
|
64
|
+
fixed: `fixed inset-y-0 z-50 ${positionClass}`,
|
|
65
|
+
sticky: 'sticky top-0 h-screen',
|
|
66
|
+
static: 'relative h-full',
|
|
88
67
|
}
|
|
89
68
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
69
|
+
export const containerClasses = [
|
|
70
|
+
placementClasses[placement] || placementClasses.fixed,
|
|
71
|
+
'flex flex-col',
|
|
72
|
+
'transition-all duration-300 ease-out',
|
|
73
|
+
'overflow-hidden',
|
|
74
|
+
style.bg,
|
|
75
|
+
style.backdrop,
|
|
76
|
+
borderClasses,
|
|
77
|
+
className,
|
|
78
|
+
].filter(Boolean).join(' ')
|
|
97
79
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
80
|
+
export const collapseBtnPosition = position === 'left' ? 'right-2' : 'left-2'
|
|
81
|
+
export const navClasses = style.nav || 'px-3 py-2 space-y-1'
|
|
82
|
+
export const slotClasses = style.slot || 'px-3 py-2'
|
|
83
|
+
</script>
|
|
102
84
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
sections: sections.map(section => ({
|
|
113
|
-
id: section.id,
|
|
114
|
-
label: section.label,
|
|
115
|
-
items: section.items?.map(item => ({
|
|
116
|
-
id: item.id,
|
|
117
|
-
label: item.label,
|
|
118
|
-
icon: item.icon,
|
|
119
|
-
href: item.href,
|
|
120
|
-
badge: item.badge
|
|
121
|
-
}))
|
|
122
|
-
}))
|
|
123
|
-
}
|
|
124
|
-
nativeSidebarId = await window.craft.components.createSidebar(config)
|
|
125
|
-
} catch (err) {
|
|
126
|
-
console.warn('[Sidebar] Failed to create native sidebar, using web fallback:', err)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
85
|
+
<script client>
|
|
86
|
+
const emit = defineEmits()
|
|
87
|
+
const collapsedProp = {{ collapsed }}
|
|
88
|
+
const collapsibleProp = {{ collapsible }}
|
|
89
|
+
const widthProp = {{ width }}
|
|
90
|
+
const minWidthProp = {{ minWidth }}
|
|
91
|
+
const sectionsProp = {{ sections }}
|
|
92
|
+
const positionProp = {{ position }}
|
|
93
|
+
const variantProp = {{ variant }}
|
|
130
94
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
onCollapse(!collapsed)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
95
|
+
const collapsed = state(collapsedProp)
|
|
96
|
+
const isHovered = state(false)
|
|
97
|
+
const hasNativeSidebar = state(false)
|
|
137
98
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (collapsed &&
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
99
|
+
const showExpanded = derived(() => !collapsed() || isHovered())
|
|
100
|
+
const sidebarWidth = derived(() => {
|
|
101
|
+
if (collapsed() && !isHovered()) return `${minWidthProp}px`
|
|
102
|
+
return `${widthProp}px`
|
|
103
|
+
})
|
|
104
|
+
const collapseAriaLabel = derived(() => collapsed() ? 'Expand sidebar' : 'Collapse sidebar')
|
|
105
|
+
const collapseIconClass = derived(() => collapsed() ? 'i-hugeicons-sidebar-right' : 'i-hugeicons-sidebar-left')
|
|
144
106
|
|
|
145
|
-
function
|
|
146
|
-
|
|
107
|
+
function onMouseEnter() {
|
|
108
|
+
if (collapsed() && collapsibleProp) isHovered.set(true)
|
|
147
109
|
}
|
|
148
110
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (onSectionToggle) {
|
|
152
|
-
onSectionToggle(sectionId)
|
|
153
|
-
}
|
|
111
|
+
function onMouseLeave() {
|
|
112
|
+
isHovered.set(false)
|
|
154
113
|
}
|
|
155
114
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
onItemClick(item, event)
|
|
160
|
-
}
|
|
115
|
+
function toggleCollapse() {
|
|
116
|
+
collapsed.set(!collapsed())
|
|
117
|
+
emit('collapse', collapsed())
|
|
161
118
|
}
|
|
162
119
|
|
|
163
|
-
|
|
164
|
-
|
|
120
|
+
function onSectionToggle(sectionId) {
|
|
121
|
+
emit('sectionToggle', sectionId)
|
|
122
|
+
}
|
|
165
123
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (!bordered) return ''
|
|
169
|
-
const borderSide = position === 'left' ? 'border-r' : 'border-l'
|
|
170
|
-
return `${borderSide} ${style.border}`
|
|
124
|
+
function onItemClick(event) {
|
|
125
|
+
emit('itemClick', event.detail)
|
|
171
126
|
}
|
|
172
127
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
128
|
+
onMount(async () => {
|
|
129
|
+
hasNativeSidebar.set(
|
|
130
|
+
window.__craftNativeSidebar === true
|
|
131
|
+
|| window.craft?.hasNativeSidebar?.()
|
|
132
|
+
|| (window.webkit?.messageHandlers?.craft && document.body?.dataset?.nativeSidebar === 'true'),
|
|
133
|
+
)
|
|
134
|
+
if (window.craft?.isCraft?.() && window.craft?.components?.createSidebar) {
|
|
135
|
+
try {
|
|
136
|
+
await window.craft.components.createSidebar({
|
|
137
|
+
position: positionProp,
|
|
138
|
+
width: widthProp,
|
|
139
|
+
minWidth: minWidthProp,
|
|
140
|
+
collapsible: collapsibleProp,
|
|
141
|
+
variant: variantProp,
|
|
142
|
+
material: variantProp === 'desktop' ? 'sidebar' : undefined,
|
|
143
|
+
backgroundEffect: variantProp === 'desktop' ? 'shimmer' : undefined,
|
|
144
|
+
allowsVibrancy: variantProp === 'desktop' || variantProp === 'vibrancy' || variantProp === 'tahoe',
|
|
145
|
+
sections: sectionsProp.map(s => ({
|
|
146
|
+
id: s.id,
|
|
147
|
+
label: s.label,
|
|
148
|
+
items: s.items?.map(i => ({ id: i.id, label: i.label, icon: i.icon, href: i.href, badge: i.badge })),
|
|
149
|
+
})),
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
console.warn('[Sidebar] Failed to create native sidebar, using web fallback:', err)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
})
|
|
183
157
|
|
|
184
|
-
|
|
185
|
-
if (typeof window !== 'undefined') {
|
|
186
|
-
initNativeSidebar()
|
|
187
|
-
}
|
|
158
|
+
defineExpose({ collapsed, toggle: toggleCollapse })
|
|
188
159
|
</script>
|
|
189
160
|
|
|
190
|
-
<!-- Only render web sidebar when NOT running in Craft native sidebar mode -->
|
|
191
|
-
@if(!hasNativeSidebar)
|
|
192
161
|
<aside
|
|
162
|
+
:show="!hasNativeSidebar()"
|
|
193
163
|
class="{{ containerClasses }} sidebar-container"
|
|
194
|
-
style="width: {
|
|
195
|
-
@mouseenter="
|
|
196
|
-
@mouseleave="
|
|
164
|
+
:style="`width: ${sidebarWidth()}`"
|
|
165
|
+
@mouseenter="onMouseEnter()"
|
|
166
|
+
@mouseleave="onMouseLeave()"
|
|
197
167
|
role="navigation"
|
|
198
168
|
aria-label="Sidebar navigation"
|
|
199
169
|
>
|
|
200
|
-
|
|
201
|
-
@if(style.tint)
|
|
170
|
+
@if(variantTint)
|
|
202
171
|
<div class="absolute inset-0 pointer-events-none bg-gradient-to-b from-amber-50/30 via-orange-50/20 to-stone-100/30 dark:from-neutral-800/20 dark:via-neutral-900/10 dark:to-neutral-800/20 mix-blend-overlay"></div>
|
|
203
172
|
@endif
|
|
173
|
+
@if(variantShimmer)
|
|
174
|
+
<div class="absolute inset-0 pointer-events-none bg-[radial-gradient(circle_at_18%_12%,rgba(255,255,255,0.46),transparent_28%),linear-gradient(120deg,rgba(255,255,255,0.22),rgba(255,255,255,0.04)_42%,rgba(255,255,255,0.18))] dark:bg-[radial-gradient(circle_at_18%_12%,rgba(255,255,255,0.12),transparent_30%),linear-gradient(120deg,rgba(255,255,255,0.10),rgba(255,255,255,0.02)_45%,rgba(255,255,255,0.08))]"></div>
|
|
175
|
+
@endif
|
|
204
176
|
|
|
205
|
-
<!-- Header slot -->
|
|
206
177
|
@if($slots.header)
|
|
207
178
|
<div class="flex-shrink-0 relative z-10">
|
|
208
179
|
<slot name="header" />
|
|
209
180
|
</div>
|
|
210
181
|
@endif
|
|
211
182
|
|
|
212
|
-
<!-- Main content area with sections -->
|
|
213
183
|
<div class="flex-1 overflow-y-auto overflow-x-hidden relative z-10">
|
|
214
184
|
@if(sections.length > 0)
|
|
215
|
-
<nav class="
|
|
216
|
-
@foreach(
|
|
185
|
+
<nav class="{{ navClasses }}">
|
|
186
|
+
@foreach(section in sections)
|
|
217
187
|
<SidebarSection
|
|
218
188
|
:id="section.id"
|
|
219
189
|
:label="section.label"
|
|
@@ -222,67 +192,45 @@ if (typeof window !== 'undefined') {
|
|
|
222
192
|
:expanded="section.expanded !== false"
|
|
223
193
|
:collapsible="section.collapsible !== false"
|
|
224
194
|
:showLabel="showExpanded()"
|
|
225
|
-
|
|
226
|
-
@
|
|
195
|
+
:variant="variant"
|
|
196
|
+
@toggle="onSectionToggle(section.id)"
|
|
197
|
+
@itemClick="onItemClick($event)"
|
|
227
198
|
/>
|
|
228
199
|
@endforeach
|
|
229
200
|
</nav>
|
|
230
201
|
@else
|
|
231
|
-
|
|
232
|
-
<div class="px-3 py-2">
|
|
202
|
+
<div class="{{ slotClasses }}">
|
|
233
203
|
<slot />
|
|
234
204
|
</div>
|
|
235
205
|
@endif
|
|
236
206
|
</div>
|
|
237
207
|
|
|
238
|
-
<!-- Footer slot -->
|
|
239
208
|
@if($slots.footer)
|
|
240
209
|
<div class="flex-shrink-0 relative z-10">
|
|
241
210
|
<slot name="footer" />
|
|
242
211
|
</div>
|
|
243
212
|
@endif
|
|
244
213
|
|
|
245
|
-
|
|
246
|
-
@if(collapsible && showExpanded())
|
|
214
|
+
@if(collapsible)
|
|
247
215
|
<button
|
|
216
|
+
:show="showExpanded()"
|
|
248
217
|
type="button"
|
|
249
|
-
class="absolute top-4 {{
|
|
250
|
-
@click="
|
|
251
|
-
aria-label="
|
|
218
|
+
class="absolute top-4 {{ collapseBtnPosition }} p-1.5 rounded-lg text-stone-400 hover:text-stone-600 hover:bg-black/5 dark:hover:text-neutral-300 dark:hover:bg-white/10 transition-colors z-20"
|
|
219
|
+
@click="toggleCollapse()"
|
|
220
|
+
:aria-label="collapseAriaLabel()"
|
|
252
221
|
>
|
|
253
|
-
<div class="{
|
|
222
|
+
<div :class="`${collapseIconClass()} w-5 h-5`"></div>
|
|
254
223
|
</button>
|
|
255
224
|
@endif
|
|
256
225
|
</aside>
|
|
257
|
-
@endif
|
|
258
226
|
|
|
259
227
|
<style scoped>
|
|
260
|
-
|
|
261
|
-
.overflow-y-auto::-webkit-scrollbar {
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
.overflow-y-auto::-webkit-scrollbar-track {
|
|
266
|
-
background: transparent;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
.overflow-y-auto::-webkit-scrollbar-thumb {
|
|
270
|
-
background-color: rgba(0, 0, 0, 0.15);
|
|
271
|
-
border-radius: 3px;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
.overflow-y-auto::-webkit-scrollbar-thumb:hover {
|
|
275
|
-
background-color: rgba(0, 0, 0, 0.25);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/* Dark mode scrollbar */
|
|
228
|
+
.overflow-y-auto::-webkit-scrollbar { width: 6px; }
|
|
229
|
+
.overflow-y-auto::-webkit-scrollbar-track { background: transparent; }
|
|
230
|
+
.overflow-y-auto::-webkit-scrollbar-thumb { background-color: rgba(0, 0, 0, 0.15); border-radius: 3px; }
|
|
231
|
+
.overflow-y-auto::-webkit-scrollbar-thumb:hover { background-color: rgba(0, 0, 0, 0.25); }
|
|
279
232
|
@media (prefers-color-scheme: dark) {
|
|
280
|
-
.overflow-y-auto::-webkit-scrollbar-thumb {
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
.overflow-y-auto::-webkit-scrollbar-thumb:hover {
|
|
285
|
-
background-color: rgba(255, 255, 255, 0.25);
|
|
286
|
-
}
|
|
233
|
+
.overflow-y-auto::-webkit-scrollbar-thumb { background-color: rgba(255, 255, 255, 0.15); }
|
|
234
|
+
.overflow-y-auto::-webkit-scrollbar-thumb:hover { background-color: rgba(255, 255, 255, 0.25); }
|
|
287
235
|
}
|
|
288
236
|
</style>
|
|
@@ -1,40 +1,54 @@
|
|
|
1
1
|
<script server>
|
|
2
|
-
/**
|
|
3
|
-
* SidebarFooter Component
|
|
4
|
-
*
|
|
5
|
-
* A footer component for the sidebar with quick actions and settings.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* <SidebarFooter
|
|
9
|
-
* :showSettings="true"
|
|
10
|
-
* :showThemeToggle="true"
|
|
11
|
-
* settingsHref="/settings"
|
|
12
|
-
* />
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
// Props
|
|
16
2
|
export const showSettings = $props.showSettings ?? true
|
|
17
3
|
export const showThemeToggle = $props.showThemeToggle ?? true
|
|
18
4
|
export const settingsHref = $props.settingsHref || '/settings'
|
|
19
5
|
export const settingsLabel = $props.settingsLabel || 'Settings'
|
|
20
6
|
export const collapsed = $props.collapsed ?? false
|
|
21
|
-
export const onThemeToggle = $props.onThemeToggle
|
|
22
|
-
|
|
23
|
-
// Quick action items
|
|
24
7
|
export const actions = $props.actions || []
|
|
8
|
+
export const variant = $props.variant || 'tahoe'
|
|
9
|
+
|
|
10
|
+
const footerVariants = {
|
|
11
|
+
workspace: {
|
|
12
|
+
container: 'p-5 space-y-2',
|
|
13
|
+
action: 'flex-1 flex items-center gap-3 rounded-[18px] px-4 py-3 text-[17px] text-zinc-700 transition-colors hover:bg-[#ececea] hover:text-zinc-950 dark:text-zinc-300 dark:hover:bg-white/10',
|
|
14
|
+
icon: 'w-5 h-5 text-zinc-500 dark:text-zinc-400',
|
|
15
|
+
},
|
|
16
|
+
desktop: {
|
|
17
|
+
container: 'p-4 space-y-2',
|
|
18
|
+
action: 'flex-1 flex items-center gap-3 rounded-[16px] px-3.5 py-2.5 text-[15px] text-zinc-700 transition-colors hover:bg-white/34 hover:text-zinc-950 dark:text-zinc-300 dark:hover:bg-white/10',
|
|
19
|
+
icon: 'w-5 h-5 text-zinc-500 dark:text-zinc-400',
|
|
20
|
+
},
|
|
21
|
+
default: {
|
|
22
|
+
container: 'border-t border-black/5 dark:border-white/10 p-3 space-y-2',
|
|
23
|
+
action: 'flex-1 flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-black/70 dark:text-white/70 hover:bg-black/5 dark:hover:bg-white/10 transition-colors',
|
|
24
|
+
icon: 'w-4 h-4',
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const footerStyle = footerVariants[variant] || footerVariants.default
|
|
29
|
+
export const footerClasses = footerStyle.container
|
|
30
|
+
export const actionClasses = footerStyle.action
|
|
31
|
+
export const footerIconClasses = footerStyle.icon
|
|
32
|
+
export const settingsIconClasses = `i-hugeicons-settings-02 ${footerStyle.icon}`
|
|
33
|
+
export const themeButtonClasses = variant === 'workspace' || variant === 'desktop'
|
|
34
|
+
? 'p-3 rounded-[16px] text-zinc-500 hover:text-zinc-900 hover:bg-white/50 dark:text-zinc-400 dark:hover:text-white dark:hover:bg-white/10 transition-colors'
|
|
35
|
+
: 'p-2 rounded-lg text-black/50 hover:text-black/80 hover:bg-black/5 dark:text-white/50 dark:hover:text-white/80 dark:hover:bg-white/10 transition-colors'
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<script client>
|
|
39
|
+
const emit = defineEmits()
|
|
40
|
+
|
|
41
|
+
function onThemeToggle() {
|
|
42
|
+
document.documentElement.classList.toggle('dark')
|
|
43
|
+
emit('themeToggle')
|
|
44
|
+
}
|
|
25
45
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (onThemeToggle) {
|
|
29
|
-
onThemeToggle()
|
|
30
|
-
} else {
|
|
31
|
-
// Default theme toggle behavior
|
|
32
|
-
document.documentElement.classList.toggle('dark')
|
|
33
|
-
}
|
|
46
|
+
function onActionClick(index) {
|
|
47
|
+
emit('actionClick', index)
|
|
34
48
|
}
|
|
35
49
|
</script>
|
|
36
50
|
|
|
37
|
-
<div class="
|
|
51
|
+
<div class="{{ footerClasses }}">
|
|
38
52
|
<!-- Custom actions slot -->
|
|
39
53
|
<slot />
|
|
40
54
|
|
|
@@ -45,21 +59,21 @@ function handleThemeToggle() {
|
|
|
45
59
|
@if(action.href)
|
|
46
60
|
<a
|
|
47
61
|
href="{{ action.href }}"
|
|
48
|
-
class="
|
|
62
|
+
class="{{ actionClasses }}"
|
|
49
63
|
>
|
|
50
64
|
@if(action.icon)
|
|
51
|
-
<div class="{{ action.icon }}
|
|
65
|
+
<div class="{{ action.icon }} {{ footerIconClasses }}"></div>
|
|
52
66
|
@endif
|
|
53
67
|
<span>{{ action.label }}</span>
|
|
54
68
|
</a>
|
|
55
69
|
@else
|
|
56
70
|
<button
|
|
57
71
|
type="button"
|
|
58
|
-
class="
|
|
59
|
-
@click="
|
|
72
|
+
class="{{ actionClasses }}"
|
|
73
|
+
@click="onActionClick({{ $loop.index }})"
|
|
60
74
|
>
|
|
61
75
|
@if(action.icon)
|
|
62
|
-
<div class="{{ action.icon }}
|
|
76
|
+
<div class="{{ action.icon }} {{ footerIconClasses }}"></div>
|
|
63
77
|
@endif
|
|
64
78
|
<span>{{ action.label }}</span>
|
|
65
79
|
</button>
|
|
@@ -69,8 +83,8 @@ function handleThemeToggle() {
|
|
|
69
83
|
@if(showThemeToggle)
|
|
70
84
|
<button
|
|
71
85
|
type="button"
|
|
72
|
-
class="
|
|
73
|
-
@click="
|
|
86
|
+
class="{{ themeButtonClasses }}"
|
|
87
|
+
@click="onThemeToggle()"
|
|
74
88
|
aria-label="Toggle dark mode"
|
|
75
89
|
>
|
|
76
90
|
<div class="i-hugeicons-moon-02 w-4 h-4 dark:hidden"></div>
|
|
@@ -84,9 +98,9 @@ function handleThemeToggle() {
|
|
|
84
98
|
@if(showSettings)
|
|
85
99
|
<a
|
|
86
100
|
href="{{ settingsHref }}"
|
|
87
|
-
class="
|
|
101
|
+
class="{{ actionClasses }}"
|
|
88
102
|
>
|
|
89
|
-
<div class="
|
|
103
|
+
<div class="{{ settingsIconClasses }}"></div>
|
|
90
104
|
@if(!collapsed)
|
|
91
105
|
<span>{{ settingsLabel }}</span>
|
|
92
106
|
@endif
|