@stacksjs/components 0.2.35 → 0.2.54
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 +5 -5
- 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,7 +1,5 @@
|
|
|
1
1
|
<script server>
|
|
2
2
|
export const value = $props.value || ''
|
|
3
|
-
export const onChange = $props.onChange || (() => {})
|
|
4
|
-
export const onSearch = $props.onSearch || (() => {})
|
|
5
3
|
export const placeholder = $props.placeholder || 'Search...'
|
|
6
4
|
export const disabled = $props.disabled || false
|
|
7
5
|
export const size = $props.size || 'md'
|
|
@@ -11,53 +9,36 @@ export const helperText = $props.helperText || ''
|
|
|
11
9
|
export const loading = $props.loading || false
|
|
12
10
|
export const className = $props.className || ''
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
// Loading spinner SVG
|
|
18
|
-
const spinnerIcon = '<svg class="animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><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></svg>'
|
|
19
|
-
|
|
20
|
-
export const rightIcon = loading ? spinnerIcon : undefined
|
|
12
|
+
export const searchIcon = '<svg fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>'
|
|
13
|
+
export const spinnerIcon = '<svg class="animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><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></svg>'
|
|
14
|
+
export const rightIcon = loading ? spinnerIcon : ''
|
|
21
15
|
</script>
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
onChange,
|
|
26
|
-
placeholder,
|
|
27
|
-
disabled,
|
|
28
|
-
size,
|
|
29
|
-
error,
|
|
30
|
-
label,
|
|
31
|
-
helperText,
|
|
32
|
-
leftIcon: searchIcon,
|
|
33
|
-
rightIcon,
|
|
34
|
-
clearable: !loading,
|
|
35
|
-
className,
|
|
36
|
-
inputClassName: 'pr-20'
|
|
37
|
-
})
|
|
38
|
-
@endcomponent
|
|
39
|
-
|
|
40
|
-
<script>
|
|
41
|
-
// Debounce search to avoid excessive calls
|
|
17
|
+
<script client>
|
|
18
|
+
const emit = defineEmits()
|
|
42
19
|
let searchTimeout = null
|
|
43
20
|
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
// Debounce the onSearch callback
|
|
50
|
-
if (searchTimeout) {
|
|
51
|
-
clearTimeout(searchTimeout)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
searchTimeout = setTimeout(() => {
|
|
55
|
-
if (onSearch) {
|
|
56
|
-
onSearch(newValue)
|
|
57
|
-
}
|
|
58
|
-
}, 300) // 300ms debounce
|
|
21
|
+
function onSearchInput(event) {
|
|
22
|
+
const target = event.target
|
|
23
|
+
const value = target?.value ?? event.detail
|
|
24
|
+
if (searchTimeout) clearTimeout(searchTimeout)
|
|
25
|
+
searchTimeout = setTimeout(() => emit('search', value), 300)
|
|
59
26
|
}
|
|
60
|
-
|
|
61
|
-
// Expose enhanced onChange handler
|
|
62
|
-
export const enhancedOnChange = handleSearchInput
|
|
63
27
|
</script>
|
|
28
|
+
|
|
29
|
+
<div @input="onSearchInput($event)">
|
|
30
|
+
<TextInput
|
|
31
|
+
:value="value"
|
|
32
|
+
:placeholder="placeholder"
|
|
33
|
+
:disabled="disabled"
|
|
34
|
+
:size="size"
|
|
35
|
+
:error="error"
|
|
36
|
+
:label="label"
|
|
37
|
+
:helperText="helperText"
|
|
38
|
+
:leftIcon="searchIcon"
|
|
39
|
+
:rightIcon="rightIcon"
|
|
40
|
+
:clearable="!loading"
|
|
41
|
+
:className="className"
|
|
42
|
+
inputClassName="pr-20"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script server>
|
|
2
2
|
export const value = $props.value || ''
|
|
3
|
-
export const onChange = $props.onChange || (() => {})
|
|
4
3
|
export const placeholder = $props.placeholder || ''
|
|
5
4
|
export const disabled = $props.disabled || false
|
|
6
5
|
export const readonly = $props.readonly || false
|
|
@@ -17,45 +16,51 @@ export const showCount = $props.showCount || false
|
|
|
17
16
|
export const className = $props.className || ''
|
|
18
17
|
export const inputClassName = $props.inputClassName || ''
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
sm: 'px-3 py-1.5 text-sm h-8',
|
|
23
|
-
md: 'px-4 py-2 text-base h-10',
|
|
24
|
-
lg: 'px-5 py-3 text-lg h-12',
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Icon size classes
|
|
28
|
-
const iconSizeClasses = {
|
|
29
|
-
sm: 'h-4 w-4',
|
|
30
|
-
md: 'h-5 w-5',
|
|
31
|
-
lg: 'h-6 w-6',
|
|
32
|
-
}
|
|
19
|
+
const sizeClasses = { sm: 'px-3 py-1.5 text-sm h-8', md: 'px-4 py-2 text-base h-10', lg: 'px-5 py-3 text-lg h-12' }
|
|
20
|
+
const iconSizeClasses = { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6' }
|
|
33
21
|
|
|
34
|
-
// Base and state classes
|
|
35
22
|
const baseClasses = 'block w-full border-0 rounded-md shadow-sm ring-1 ring-inset transition-colors duration-200 focus:ring-2 focus:ring-inset dark:bg-blue-gray-700 dark:text-gray-100'
|
|
36
|
-
|
|
37
23
|
const stateClasses = error
|
|
38
24
|
? 'ring-red-300 dark:ring-red-600 text-red-900 dark:text-red-300 placeholder-red-300 dark:placeholder-red-500 focus:ring-red-500 dark:focus:ring-red-400'
|
|
39
25
|
: 'ring-gray-300 dark:ring-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-indigo-600 dark:focus:ring-indigo-400'
|
|
40
|
-
|
|
41
26
|
const disabledClasses = disabled
|
|
42
27
|
? 'opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-800'
|
|
43
28
|
: readonly
|
|
44
29
|
? 'bg-gray-50 dark:bg-gray-800 cursor-default'
|
|
45
30
|
: 'bg-white dark:bg-blue-gray-700'
|
|
46
|
-
|
|
47
31
|
const paddingClasses = leftIcon ? 'pl-10' : rightIcon || clearable ? 'pr-10' : ''
|
|
48
32
|
|
|
49
33
|
export const inputClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses} ${paddingClasses} ${inputClassName}`.trim()
|
|
50
34
|
export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-900 dark:text-gray-100'}`.trim()
|
|
51
35
|
export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
|
|
52
36
|
export const iconClasses = iconSizeClasses[size]
|
|
53
|
-
export const
|
|
37
|
+
export const inputId = `input-${label}`
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<script client>
|
|
41
|
+
const emit = defineEmits()
|
|
42
|
+
const inputValue = state({{ value }})
|
|
43
|
+
|
|
44
|
+
function onInput(event) {
|
|
45
|
+
inputValue.set(event.target.value)
|
|
46
|
+
emit('input', inputValue())
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function onClear() {
|
|
50
|
+
inputValue.set('')
|
|
51
|
+
emit('input', '')
|
|
52
|
+
emit('clear')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const hasValue = derived(() => inputValue().length > 0)
|
|
56
|
+
const charCount = derived(() => `${inputValue().length} / {{ maxLength || 0 }}`)
|
|
57
|
+
|
|
58
|
+
defineExpose({ value: inputValue, clear: onClear })
|
|
54
59
|
</script>
|
|
55
60
|
|
|
56
61
|
<div class="w-full {{ className }}">
|
|
57
62
|
@if(label)
|
|
58
|
-
<label for="
|
|
63
|
+
<label for="{{ inputId }}" class="{{ labelClasses }}">
|
|
59
64
|
{{ label }}
|
|
60
65
|
@if(required)
|
|
61
66
|
<span class="text-red-500 ml-1">*</span>
|
|
@@ -65,33 +70,31 @@ export const hasValue = value && value.length > 0
|
|
|
65
70
|
|
|
66
71
|
<div class="relative">
|
|
67
72
|
@if(leftIcon)
|
|
68
|
-
<!-- Left icon -->
|
|
69
73
|
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
|
70
|
-
<span class="{{ iconClasses }} text-gray-400 dark:text-gray-500"
|
|
74
|
+
<span class="{{ iconClasses }} text-gray-400 dark:text-gray-500">{!! leftIcon !!}</span>
|
|
71
75
|
</div>
|
|
72
76
|
@endif
|
|
73
77
|
|
|
74
78
|
<input
|
|
75
79
|
type="text"
|
|
76
|
-
id="
|
|
80
|
+
id="{{ inputId }}"
|
|
77
81
|
class="{{ inputClasses }}"
|
|
78
|
-
value="
|
|
82
|
+
:value="inputValue()"
|
|
79
83
|
placeholder="{{ placeholder }}"
|
|
80
|
-
disabled
|
|
81
|
-
readonly
|
|
82
|
-
required
|
|
84
|
+
@if(disabled)disabled@endif
|
|
85
|
+
@if(readonly)readonly@endif
|
|
86
|
+
@if(required)required@endif
|
|
83
87
|
@if(maxLength)maxlength="{{ maxLength }}"@endif
|
|
84
|
-
|
|
85
|
-
aria-invalid="{{ error ? 'true' : 'false' }}"
|
|
88
|
+
@input="onInput($event)"
|
|
89
|
+
:aria-invalid="{{ error ? 'true' : 'false' }}"
|
|
86
90
|
@if(helperText)aria-describedby="helper-text"@endif
|
|
87
91
|
/>
|
|
88
92
|
|
|
89
|
-
@if(clearable
|
|
90
|
-
|
|
91
|
-
<div class="absolute inset-y-0 right-0 flex items-center pr-3">
|
|
93
|
+
@if(clearable)
|
|
94
|
+
<div :show="hasValue() && !{{ disabled }} && !{{ readonly }}" class="absolute inset-y-0 right-0 flex items-center pr-3">
|
|
92
95
|
<button
|
|
93
96
|
type="button"
|
|
94
|
-
@click="
|
|
97
|
+
@click="onClear()"
|
|
95
98
|
class="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 focus:outline-none"
|
|
96
99
|
aria-label="Clear input"
|
|
97
100
|
>
|
|
@@ -100,13 +103,11 @@ export const hasValue = value && value.length > 0
|
|
|
100
103
|
</svg>
|
|
101
104
|
</button>
|
|
102
105
|
</div>
|
|
103
|
-
@
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
</div>
|
|
109
|
-
@endif
|
|
106
|
+
@endif
|
|
107
|
+
@if(rightIcon && !clearable)
|
|
108
|
+
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
|
|
109
|
+
<span class="{{ iconClasses }} text-gray-400 dark:text-gray-500">{!! rightIcon !!}</span>
|
|
110
|
+
</div>
|
|
110
111
|
@endif
|
|
111
112
|
</div>
|
|
112
113
|
|
|
@@ -121,26 +122,8 @@ export const hasValue = value && value.length > 0
|
|
|
121
122
|
@endif
|
|
122
123
|
|
|
123
124
|
@if(showCount && maxLength)
|
|
124
|
-
<p class="text-sm text-gray-500 dark:text-gray-400">
|
|
125
|
-
{{ value.length }} / {{ maxLength }}
|
|
126
|
-
</p>
|
|
125
|
+
<p class="text-sm text-gray-500 dark:text-gray-400" x-text="charCount()"></p>
|
|
127
126
|
@endif
|
|
128
127
|
</div>
|
|
129
128
|
@endif
|
|
130
129
|
</div>
|
|
131
|
-
|
|
132
|
-
<script>
|
|
133
|
-
function handleInput(event) {
|
|
134
|
-
const newValue = event.target.value
|
|
135
|
-
|
|
136
|
-
if (onChange) {
|
|
137
|
-
onChange(newValue)
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function handleClear() {
|
|
142
|
-
if (onChange) {
|
|
143
|
-
onChange('')
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
</script>
|
|
@@ -1,14 +1,101 @@
|
|
|
1
1
|
<script server>
|
|
2
2
|
export const value = $props.value
|
|
3
|
-
export const onChange = $props.onChange
|
|
4
3
|
export const multiple = $props.multiple || false
|
|
5
4
|
export const className = $props.className || ''
|
|
6
5
|
export const as = $props.as || 'div'
|
|
7
6
|
|
|
8
7
|
const baseClasses = 'relative'
|
|
9
|
-
const listboxClasses = `${baseClasses} ${className}`.trim()
|
|
8
|
+
export const listboxClasses = `${baseClasses} ${className}`.trim()
|
|
9
|
+
export const listboxInstanceId = `stx-lb-${Math.random().toString(36).slice(2, 11)}`
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
|
-
<
|
|
13
|
-
|
|
12
|
+
<script client>
|
|
13
|
+
const emit = defineEmits()
|
|
14
|
+
const listboxInstanceId = {{ listboxInstanceId }}
|
|
15
|
+
const multiple = {{ multiple }}
|
|
16
|
+
const initialValue = {{ value === undefined ? 'null' : value }}
|
|
17
|
+
|
|
18
|
+
const isOpen = state(false)
|
|
19
|
+
const selected = state(initialValue)
|
|
20
|
+
let rootEl = null
|
|
21
|
+
let outsideHandler = null
|
|
22
|
+
|
|
23
|
+
function isSelectedValue(v) {
|
|
24
|
+
const cur = selected()
|
|
25
|
+
if (multiple && Array.isArray(cur)) return cur.includes(v)
|
|
26
|
+
return cur === v
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function selectValue(v) {
|
|
30
|
+
if (multiple) {
|
|
31
|
+
const cur = Array.isArray(selected()) ? selected() : []
|
|
32
|
+
selected.set(cur.includes(v) ? cur.filter(x => x !== v) : [...cur, v])
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
selected.set(v)
|
|
36
|
+
isOpen.set(false)
|
|
37
|
+
}
|
|
38
|
+
syncOptionStates()
|
|
39
|
+
emit('change', selected())
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function syncOptionStates() {
|
|
43
|
+
if (!rootEl) return
|
|
44
|
+
const options = rootEl.querySelectorAll('[data-stx-listbox-option]')
|
|
45
|
+
for (const opt of options) {
|
|
46
|
+
const raw = opt.dataset.optionValue
|
|
47
|
+
let v
|
|
48
|
+
try { v = JSON.parse(raw ?? 'null') }
|
|
49
|
+
catch { v = raw }
|
|
50
|
+
const sel = isSelectedValue(v)
|
|
51
|
+
opt.setAttribute('aria-selected', sel ? 'true' : 'false')
|
|
52
|
+
opt.setAttribute('data-selected', sel ? 'true' : 'false')
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function open() { if (!isOpen()) { isOpen.set(true); emit('change', selected()) } }
|
|
57
|
+
function close() { if (isOpen()) { isOpen.set(false) } }
|
|
58
|
+
function toggle() { isOpen() ? close() : open() }
|
|
59
|
+
|
|
60
|
+
function onToggle(event) { event.stopPropagation(); toggle() }
|
|
61
|
+
function onSelect(event) {
|
|
62
|
+
event.stopPropagation()
|
|
63
|
+
selectValue(event.detail)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
onMount(() => {
|
|
67
|
+
rootEl = document.querySelector(`[data-listbox-id="${listboxInstanceId}"]`)
|
|
68
|
+
syncOptionStates()
|
|
69
|
+
outsideHandler = (event) => {
|
|
70
|
+
if (!isOpen()) return
|
|
71
|
+
if (rootEl && !rootEl.contains(event.target)) close()
|
|
72
|
+
}
|
|
73
|
+
document.addEventListener('click', outsideHandler, true)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
onDestroy(() => {
|
|
77
|
+
if (outsideHandler) document.removeEventListener('click', outsideHandler, true)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
const dataState = derived(() => isOpen() ? 'open' : 'closed')
|
|
81
|
+
|
|
82
|
+
defineExpose({ isOpen, selected, toggle, open, close, selectValue })
|
|
83
|
+
</script>
|
|
84
|
+
|
|
85
|
+
<component
|
|
86
|
+
:is="{{ as }}"
|
|
87
|
+
class="{{ listboxClasses }}"
|
|
88
|
+
data-stx-listbox
|
|
89
|
+
data-listbox-id="{{ listboxInstanceId }}"
|
|
90
|
+
:data-state="dataState()"
|
|
91
|
+
@stx:listbox-toggle="onToggle($event)"
|
|
92
|
+
@stx:listbox-select="onSelect($event)"
|
|
93
|
+
>
|
|
94
|
+
<slot />
|
|
14
95
|
</component>
|
|
96
|
+
|
|
97
|
+
<style>
|
|
98
|
+
[data-stx-listbox][data-state="closed"] [data-stx-listbox-options] {
|
|
99
|
+
display: none;
|
|
100
|
+
}
|
|
101
|
+
</style>
|
|
@@ -5,13 +5,24 @@ export const disabled = $props.disabled || false
|
|
|
5
5
|
|
|
6
6
|
const baseClasses = 'relative w-full cursor-pointer rounded-lg bg-white dark:bg-neutral-800 py-2 pl-3 pr-10 text-left shadow-md focus:outline-none focus-visible:border-blue-500 focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-blue-300'
|
|
7
7
|
const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : ''
|
|
8
|
-
const buttonClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
|
|
8
|
+
export const buttonClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<script client>
|
|
12
|
+
const isDisabled = {{ disabled }}
|
|
13
|
+
|
|
14
|
+
function onClick(event) {
|
|
15
|
+
if (isDisabled) return
|
|
16
|
+
event.currentTarget.dispatchEvent(new CustomEvent('stx:listbox-toggle', { bubbles: true }))
|
|
17
|
+
}
|
|
9
18
|
</script>
|
|
10
19
|
|
|
11
20
|
<component
|
|
12
21
|
:is="{{ as }}"
|
|
13
22
|
class="{{ buttonClasses }}"
|
|
23
|
+
data-stx-listbox-button
|
|
14
24
|
@if(disabled)disabled aria-disabled="true"@endif
|
|
25
|
+
@click="onClick($event)"
|
|
15
26
|
>
|
|
16
27
|
<slot />
|
|
17
28
|
</component>
|
|
@@ -3,55 +3,47 @@ export const value = $props.value
|
|
|
3
3
|
export const disabled = $props.disabled || false
|
|
4
4
|
export const className = $props.className || ''
|
|
5
5
|
export const as = $props.as || 'li'
|
|
6
|
-
export const currentValue = $props.currentValue
|
|
7
|
-
export const onChange = $props.onChange
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const baseClasses = 'relative cursor-pointer select-none py-2 pl-10 pr-4'
|
|
15
|
-
const stateClasses = active
|
|
16
|
-
? 'bg-blue-100 text-blue-900 dark:bg-blue-900 dark:text-blue-100'
|
|
17
|
-
: 'text-neutral-900 dark:text-neutral-100'
|
|
18
|
-
const disabledClasses = disabled
|
|
19
|
-
? 'opacity-50 cursor-not-allowed'
|
|
20
|
-
: ''
|
|
21
|
-
|
|
22
|
-
const optionClasses = `${baseClasses} ${stateClasses} ${disabledClasses} ${className}`.trim()
|
|
23
|
-
|
|
24
|
-
export function handleClick() {
|
|
25
|
-
if (disabled) return
|
|
26
|
-
onChange?.(value)
|
|
27
|
-
}
|
|
7
|
+
const baseClasses = 'relative cursor-pointer select-none py-2 pl-10 pr-4 text-neutral-900 dark:text-neutral-100 hover:bg-blue-100 dark:hover:bg-blue-900'
|
|
8
|
+
const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : ''
|
|
9
|
+
export const optionClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
|
|
10
|
+
export const valueJson = JSON.stringify(value === undefined ? null : value)
|
|
11
|
+
</script>
|
|
28
12
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
13
|
+
<script client>
|
|
14
|
+
const isDisabled = {{ disabled }}
|
|
15
|
+
const optionValue = {{ value === undefined ? 'null' : value }}
|
|
32
16
|
|
|
33
|
-
|
|
34
|
-
|
|
17
|
+
function onClick(event) {
|
|
18
|
+
if (isDisabled) return
|
|
19
|
+
event.currentTarget.dispatchEvent(
|
|
20
|
+
new CustomEvent('stx:listbox-select', { bubbles: true, detail: optionValue }),
|
|
21
|
+
)
|
|
35
22
|
}
|
|
36
23
|
</script>
|
|
37
24
|
|
|
38
25
|
<component
|
|
39
26
|
:is="{{ as }}"
|
|
40
27
|
class="{{ optionClasses }}"
|
|
28
|
+
data-stx-listbox-option
|
|
29
|
+
data-option-value="{{ valueJson }}"
|
|
41
30
|
role="option"
|
|
42
|
-
aria-selected="
|
|
31
|
+
aria-selected="false"
|
|
43
32
|
@if(disabled)aria-disabled="true"@endif
|
|
44
|
-
@click="
|
|
45
|
-
@mouseenter="handleMouseEnter"
|
|
46
|
-
@mouseleave="handleMouseLeave"
|
|
33
|
+
@click="onClick($event)"
|
|
47
34
|
>
|
|
48
|
-
|
|
49
|
-
<
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
</span>
|
|
54
|
-
@endif
|
|
35
|
+
<span class="absolute inset-y-0 left-0 flex items-center pl-3 text-blue-600 dark:text-blue-400" data-stx-listbox-check>
|
|
36
|
+
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
|
37
|
+
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
|
|
38
|
+
</svg>
|
|
39
|
+
</span>
|
|
55
40
|
|
|
56
|
-
<slot :
|
|
41
|
+
<slot :disabled="disabled" />
|
|
57
42
|
</component>
|
|
43
|
+
|
|
44
|
+
<style>
|
|
45
|
+
[data-stx-listbox-option][data-selected="false"] [data-stx-listbox-check],
|
|
46
|
+
[data-stx-listbox-option]:not([data-selected]) [data-stx-listbox-check] {
|
|
47
|
+
display: none;
|
|
48
|
+
}
|
|
49
|
+
</style>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<script server>
|
|
2
2
|
export const className = $props.className || ''
|
|
3
3
|
export const as = $props.as || 'ul'
|
|
4
|
-
export const static_ = $props.static || false
|
|
5
4
|
|
|
6
5
|
const baseClasses = 'absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white dark:bg-neutral-800 py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none'
|
|
7
|
-
const optionsClasses = `${baseClasses} ${className}`.trim()
|
|
6
|
+
export const optionsClasses = `${baseClasses} ${className}`.trim()
|
|
8
7
|
</script>
|
|
9
8
|
|
|
10
9
|
<component
|
|
11
10
|
:is="{{ as }}"
|
|
12
11
|
class="{{ optionsClasses }}"
|
|
12
|
+
data-stx-listbox-options
|
|
13
13
|
role="listbox"
|
|
14
14
|
>
|
|
15
15
|
<slot />
|