@stacksjs/components 0.2.93 → 0.2.94
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/index.js +4 -4
- package/package.json +5 -6
- package/src/components/CodeBlock.stx +0 -54
- package/src/components/Footer.stx +0 -66
- package/src/components/Hero.stx +0 -25
- package/src/components/Installation.stx +0 -37
- package/src/components/index.ts +0 -4
- package/src/composables/index.ts +0 -4
- package/src/composables/useCopyCode.ts +0 -73
- package/src/composables/useDarkMode.ts +0 -100
- package/src/composables/useSEO.ts +0 -230
- package/src/composables/utilities/index.ts +0 -7
- package/src/composables/utilities/useClickOutside.ts +0 -72
- package/src/composables/utilities/useFocusTrap.ts +0 -159
- package/src/composables/utilities/useKeyboard.ts +0 -124
- package/src/composables/utilities/useLocalStorage.ts +0 -132
- package/src/composables/utilities/useMediaQuery.ts +0 -118
- package/src/index.ts +0 -99
- package/src/stx.d.ts +0 -4
- package/src/ui/accordion/Accordion.stx +0 -146
- package/src/ui/accordion/AccordionItem.stx +0 -37
- package/src/ui/accordion/index.ts +0 -47
- package/src/ui/audio/Audio.stx +0 -50
- package/src/ui/audio/README.md +0 -41
- package/src/ui/audio/index.ts +0 -13
- package/src/ui/auth/Login.stx +0 -161
- package/src/ui/auth/README.md +0 -142
- package/src/ui/auth/Signup.stx +0 -159
- package/src/ui/auth/TwoFactorChallenge.stx +0 -111
- package/src/ui/auth/index.ts +0 -32
- package/src/ui/avatar/Avatar.stx +0 -77
- package/src/ui/avatar/index.ts +0 -12
- package/src/ui/badge/Badge.stx +0 -62
- package/src/ui/badge/index.ts +0 -10
- package/src/ui/breadcrumb/Breadcrumb.stx +0 -79
- package/src/ui/breadcrumb/index.ts +0 -15
- package/src/ui/button/Button.stx +0 -74
- package/src/ui/button/README.md +0 -80
- package/src/ui/button/index.ts +0 -85
- package/src/ui/calendar/Calendar.stx +0 -189
- package/src/ui/calendar/README.md +0 -254
- package/src/ui/calendar/index.ts +0 -14
- package/src/ui/card/Card.stx +0 -68
- package/src/ui/card/index.ts +0 -13
- package/src/ui/checkbox/Checkbox.stx +0 -86
- package/src/ui/checkbox/index.ts +0 -16
- package/src/ui/combobox/Combobox.stx +0 -96
- package/src/ui/combobox/ComboboxButton.stx +0 -25
- package/src/ui/combobox/ComboboxInput.stx +0 -32
- package/src/ui/combobox/ComboboxOption.stx +0 -49
- package/src/ui/combobox/ComboboxOptions.stx +0 -16
- package/src/ui/combobox/README.md +0 -150
- package/src/ui/combobox/index.ts +0 -40
- package/src/ui/command-palette/CommandPalette.stx +0 -81
- package/src/ui/command-palette/CommandPaletteItem.stx +0 -27
- package/src/ui/command-palette/README.md +0 -42
- package/src/ui/command-palette/index.ts +0 -15
- package/src/ui/dialog/Dialog.stx +0 -41
- package/src/ui/dialog/DialogBackdrop.stx +0 -9
- package/src/ui/dialog/DialogDescription.stx +0 -11
- package/src/ui/dialog/DialogPanel.stx +0 -16
- package/src/ui/dialog/DialogTitle.stx +0 -11
- package/src/ui/dialog/README.md +0 -121
- package/src/ui/dialog/index.ts +0 -32
- package/src/ui/drawer/Drawer.stx +0 -120
- package/src/ui/drawer/README.md +0 -90
- package/src/ui/drawer/index.ts +0 -9
- package/src/ui/dropdown/Dropdown.stx +0 -82
- package/src/ui/dropdown/DropdownButton.stx +0 -29
- package/src/ui/dropdown/DropdownItem.stx +0 -35
- package/src/ui/dropdown/DropdownItems.stx +0 -18
- package/src/ui/dropdown/README.md +0 -114
- package/src/ui/dropdown/index.ts +0 -29
- package/src/ui/form/Form.stx +0 -95
- package/src/ui/form/index.ts +0 -67
- package/src/ui/heatmap/Heatmap.stx +0 -294
- package/src/ui/image/Image.stx +0 -165
- package/src/ui/image/README.md +0 -164
- package/src/ui/image/index.ts +0 -22
- package/src/ui/input/EmailInput.stx +0 -30
- package/src/ui/input/NumberInput.stx +0 -126
- package/src/ui/input/PasswordInput.stx +0 -143
- package/src/ui/input/SearchInput.stx +0 -44
- package/src/ui/input/TextInput.stx +0 -132
- package/src/ui/input/index.ts +0 -180
- package/src/ui/listbox/Listbox.stx +0 -101
- package/src/ui/listbox/ListboxButton.stx +0 -28
- package/src/ui/listbox/ListboxLabel.stx +0 -11
- package/src/ui/listbox/ListboxOption.stx +0 -49
- package/src/ui/listbox/ListboxOptions.stx +0 -16
- package/src/ui/listbox/README.md +0 -135
- package/src/ui/listbox/index.ts +0 -39
- package/src/ui/navigator/Navigator.stx +0 -113
- package/src/ui/navigator/README.md +0 -352
- package/src/ui/navigator/index.ts +0 -20
- package/src/ui/notification/Notification.stx +0 -117
- package/src/ui/notification/README.md +0 -114
- package/src/ui/notification/index.ts +0 -12
- package/src/ui/pagination/Pagination.stx +0 -150
- package/src/ui/pagination/index.ts +0 -11
- package/src/ui/payment/Checkout.stx +0 -31
- package/src/ui/payment/DefaultPaymentMethod.stx +0 -62
- package/src/ui/payment/PaymentMethods.stx +0 -104
- package/src/ui/payment/README.md +0 -345
- package/src/ui/payment/SubscriptionCheckout.stx +0 -323
- package/src/ui/payment/index.ts +0 -59
- package/src/ui/popover/Popover.stx +0 -60
- package/src/ui/popover/PopoverButton.stx +0 -29
- package/src/ui/popover/PopoverPanel.stx +0 -23
- package/src/ui/popover/README.md +0 -91
- package/src/ui/popover/index.ts +0 -22
- package/src/ui/portal/Portal.stx +0 -57
- package/src/ui/portal/index.ts +0 -6
- package/src/ui/progress/Progress.stx +0 -131
- package/src/ui/progress/index.ts +0 -12
- package/src/ui/radio/Radio.stx +0 -77
- package/src/ui/radio/index.ts +0 -15
- package/src/ui/radio-group/README.md +0 -139
- package/src/ui/radio-group/RadioGroup.stx +0 -60
- package/src/ui/radio-group/RadioGroupDescription.stx +0 -11
- package/src/ui/radio-group/RadioGroupLabel.stx +0 -11
- package/src/ui/radio-group/RadioGroupOption.stx +0 -58
- package/src/ui/radio-group/index.ts +0 -30
- package/src/ui/select/README.md +0 -180
- package/src/ui/select/Select.stx +0 -82
- package/src/ui/select/index.ts +0 -21
- package/src/ui/sidebar/Sidebar.stx +0 -476
- package/src/ui/sidebar/SidebarFooter.stx +0 -71
- package/src/ui/sidebar/SidebarHeader.stx +0 -103
- package/src/ui/sidebar/SidebarItem.stx +0 -86
- package/src/ui/sidebar/SidebarSection.stx +0 -83
- package/src/ui/sidebar/index.ts +0 -153
- package/src/ui/sidebar/themes.ts +0 -240
- package/src/ui/skeleton/Skeleton.stx +0 -48
- package/src/ui/skeleton/index.ts +0 -11
- package/src/ui/spinner/Spinner.stx +0 -109
- package/src/ui/spinner/index.ts +0 -9
- package/src/ui/stepper/README.md +0 -36
- package/src/ui/stepper/Stepper.stx +0 -17
- package/src/ui/stepper/StepperStep.stx +0 -57
- package/src/ui/stepper/index.ts +0 -19
- package/src/ui/storage/README.md +0 -193
- package/src/ui/storage/index.ts +0 -347
- package/src/ui/switch/README.md +0 -114
- package/src/ui/switch/Switch.stx +0 -72
- package/src/ui/switch/index.ts +0 -10
- package/src/ui/table/README.md +0 -39
- package/src/ui/table/Table.stx +0 -14
- package/src/ui/table/TableBody.stx +0 -10
- package/src/ui/table/TableCell.stx +0 -10
- package/src/ui/table/TableHead.stx +0 -10
- package/src/ui/table/TableHeader.stx +0 -20
- package/src/ui/table/TableRow.stx +0 -11
- package/src/ui/table/index.ts +0 -35
- package/src/ui/tabs/TabPanel.stx +0 -25
- package/src/ui/tabs/Tabs.stx +0 -202
- package/src/ui/tabs/index.ts +0 -50
- package/src/ui/teleport/Teleport.stx +0 -65
- package/src/ui/teleport/index.ts +0 -7
- package/src/ui/textarea/Textarea.stx +0 -108
- package/src/ui/textarea/index.ts +0 -20
- package/src/ui/tooltip/Tooltip.stx +0 -71
- package/src/ui/tooltip/index.ts +0 -10
- package/src/ui/transition/README.md +0 -30
- package/src/ui/transition/Transition.stx +0 -102
- package/src/ui/transition/index.ts +0 -25
- package/src/ui/video/README.md +0 -47
- package/src/ui/video/Video.stx +0 -45
- package/src/ui/video/index.ts +0 -16
- package/src/ui/virtual-list/VirtualList.stx +0 -67
- package/src/ui/virtual-list/index.ts +0 -10
- package/src/ui/virtual-table/VirtualTable.stx +0 -103
- package/src/ui/virtual-table/index.ts +0 -21
- package/src/utils/PROP_VALIDATION.md +0 -458
- package/src/utils/THEME_SYSTEM.md +0 -702
- package/src/utils/accessibility.ts +0 -841
- package/src/utils/animation/easing.ts +0 -368
- package/src/utils/animation/helpers.ts +0 -223
- package/src/utils/animation/index.ts +0 -5
- package/src/utils/animation/keyframes.ts +0 -230
- package/src/utils/error-handling.ts +0 -475
- package/src/utils/highlighter.ts +0 -93
- package/src/utils/i18n.ts +0 -634
- package/src/utils/keep-alive.ts +0 -819
- package/src/utils/lazy-loading.ts +0 -530
- package/src/utils/prop-validation.ts +0 -478
- package/src/utils/theme.ts +0 -626
package/src/ui/dialog/Dialog.stx
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const open = $props.open || false
|
|
3
|
-
export const className = $props.className || ''
|
|
4
|
-
|
|
5
|
-
const baseClasses = 'relative z-50'
|
|
6
|
-
export const dialogClasses = `${baseClasses} ${className}`.trim()
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<script client>
|
|
10
|
-
const emit = defineEmits()
|
|
11
|
-
// useReactiveProp wires `:open="parentSignal()"` from the parent into our
|
|
12
|
-
// local `isOpen` signal — when the parent's signal changes, bindAttr
|
|
13
|
-
// updates the root's `open` attribute, our MutationObserver picks it up,
|
|
14
|
-
// and isOpen flips. See stacksjs/stx#1704.
|
|
15
|
-
const isOpen = useReactiveProp('open', {{ open }})
|
|
16
|
-
|
|
17
|
-
function close() {
|
|
18
|
-
isOpen.set(false)
|
|
19
|
-
emit('close')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function onBackdropKey(event) {
|
|
23
|
-
if (event.key === 'Escape') close()
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
defineExpose({
|
|
27
|
-
open: () => isOpen.set(true),
|
|
28
|
-
close,
|
|
29
|
-
isOpen,
|
|
30
|
-
})
|
|
31
|
-
</script>
|
|
32
|
-
|
|
33
|
-
<div
|
|
34
|
-
:show="isOpen()"
|
|
35
|
-
class="{{ dialogClasses }}"
|
|
36
|
-
role="dialog"
|
|
37
|
-
aria-modal="true"
|
|
38
|
-
@keydown="onBackdropKey($event)"
|
|
39
|
-
>
|
|
40
|
-
<slot />
|
|
41
|
-
</div>
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const className = $props.className || ''
|
|
3
|
-
export const as = $props.as || 'div'
|
|
4
|
-
|
|
5
|
-
const baseClasses = 'fixed inset-0 bg-black bg-opacity-25 dark:bg-opacity-50 transition-opacity'
|
|
6
|
-
const backdropClasses = `${baseClasses} ${className}`.trim()
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<component :is="{{ as }}" class="{{ backdropClasses }}" aria-hidden="true" />
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const className = $props.className || ''
|
|
3
|
-
export const as = $props.as || 'p'
|
|
4
|
-
|
|
5
|
-
const baseClasses = 'mt-2 text-sm text-neutral-500 dark:text-neutral-400'
|
|
6
|
-
const descriptionClasses = `${baseClasses} ${className}`.trim()
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<component :is="{{ as }}" class="{{ descriptionClasses }}">
|
|
10
|
-
<slot />
|
|
11
|
-
</component>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const className = $props.className || ''
|
|
3
|
-
export const as = $props.as || 'div'
|
|
4
|
-
|
|
5
|
-
const baseClasses = 'fixed inset-0 overflow-y-auto'
|
|
6
|
-
const panelWrapperClasses = 'flex min-h-full items-center justify-center p-4 text-center'
|
|
7
|
-
const panelClasses = `transform overflow-hidden rounded-lg bg-white dark:bg-neutral-800 p-6 text-left align-middle shadow-xl transition-all ${className}`.trim()
|
|
8
|
-
</script>
|
|
9
|
-
|
|
10
|
-
<component :is="{{ as }}" class="{{ baseClasses }}">
|
|
11
|
-
<div class="{{ panelWrapperClasses }}">
|
|
12
|
-
<div class="{{ panelClasses }}">
|
|
13
|
-
<slot />
|
|
14
|
-
</div>
|
|
15
|
-
</div>
|
|
16
|
-
</component>
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const className = $props.className || ''
|
|
3
|
-
export const as = $props.as || 'h3'
|
|
4
|
-
|
|
5
|
-
const baseClasses = 'text-lg font-medium leading-6 text-neutral-900 dark:text-white'
|
|
6
|
-
const titleClasses = `${baseClasses} ${className}`.trim()
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<component :is="{{ as }}" class="{{ titleClasses }}">
|
|
10
|
-
<slot />
|
|
11
|
-
</component>
|
package/src/ui/dialog/README.md
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
# Dialog Component
|
|
2
|
-
|
|
3
|
-
A modal dialog component for overlays, alerts, and confirmations. Built with STX and headwind.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
bun add @stacksjs/components
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```stx
|
|
14
|
-
<script server>
|
|
15
|
-
let isOpen = false
|
|
16
|
-
|
|
17
|
-
function closeModal() {
|
|
18
|
-
isOpen = false
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function openModal() {
|
|
22
|
-
isOpen = true
|
|
23
|
-
}
|
|
24
|
-
</script>
|
|
25
|
-
|
|
26
|
-
<Dialog :open="isOpen" :onClose="closeModal">
|
|
27
|
-
<DialogBackdrop />
|
|
28
|
-
|
|
29
|
-
<DialogPanel className="max-w-md">
|
|
30
|
-
<DialogTitle>Payment successful</DialogTitle>
|
|
31
|
-
|
|
32
|
-
<DialogDescription>
|
|
33
|
-
Your payment has been successfully submitted.
|
|
34
|
-
</DialogDescription>
|
|
35
|
-
|
|
36
|
-
<div class="mt-4">
|
|
37
|
-
<Button :onClick="closeModal">Got it, thanks!</Button>
|
|
38
|
-
</div>
|
|
39
|
-
</DialogPanel>
|
|
40
|
-
</Dialog>
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Props
|
|
44
|
-
|
|
45
|
-
### Dialog
|
|
46
|
-
| Prop | Type | Default | Description |
|
|
47
|
-
|------|------|---------|-------------|
|
|
48
|
-
| `open` | `boolean` | `false` | Whether dialog is open |
|
|
49
|
-
| `onClose` | `(value: boolean) => void` | - | Close handler |
|
|
50
|
-
| `className` | `string` | `''` | Additional CSS classes |
|
|
51
|
-
| `as` | `string` | `'div'` | HTML element to render |
|
|
52
|
-
|
|
53
|
-
### DialogBackdrop
|
|
54
|
-
| Prop | Type | Default | Description |
|
|
55
|
-
|------|------|---------|-------------|
|
|
56
|
-
| `className` | `string` | `''` | Additional CSS classes |
|
|
57
|
-
| `as` | `string` | `'div'` | HTML element to render |
|
|
58
|
-
|
|
59
|
-
### DialogPanel
|
|
60
|
-
| Prop | Type | Default | Description |
|
|
61
|
-
|------|------|---------|-------------|
|
|
62
|
-
| `className` | `string` | `''` | Additional CSS classes |
|
|
63
|
-
| `as` | `string` | `'div'` | HTML element to render |
|
|
64
|
-
|
|
65
|
-
### DialogTitle
|
|
66
|
-
| Prop | Type | Default | Description |
|
|
67
|
-
|------|------|---------|-------------|
|
|
68
|
-
| `className` | `string` | `''` | Additional CSS classes |
|
|
69
|
-
| `as` | `string` | `'h3'` | HTML element to render |
|
|
70
|
-
|
|
71
|
-
### DialogDescription
|
|
72
|
-
| Prop | Type | Default | Description |
|
|
73
|
-
|------|------|---------|-------------|
|
|
74
|
-
| `className` | `string` | `''` | Additional CSS classes |
|
|
75
|
-
| `as` | `string` | `'p'` | HTML element to render |
|
|
76
|
-
|
|
77
|
-
## Examples
|
|
78
|
-
|
|
79
|
-
### Confirmation Dialog
|
|
80
|
-
|
|
81
|
-
```stx
|
|
82
|
-
<Dialog :open="isOpen" :onClose="closeModal">
|
|
83
|
-
<DialogBackdrop />
|
|
84
|
-
|
|
85
|
-
<DialogPanel className="max-w-md">
|
|
86
|
-
<DialogTitle>Delete account</DialogTitle>
|
|
87
|
-
|
|
88
|
-
<DialogDescription>
|
|
89
|
-
Are you sure you want to delete your account? This action cannot be undone.
|
|
90
|
-
</DialogDescription>
|
|
91
|
-
|
|
92
|
-
<div class="mt-4 flex gap-2">
|
|
93
|
-
<Button variant="danger" :onClick="handleDelete">Delete</Button>
|
|
94
|
-
<Button variant="secondary" :onClick="closeModal">Cancel</Button>
|
|
95
|
-
</div>
|
|
96
|
-
</DialogPanel>
|
|
97
|
-
</Dialog>
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### Large Dialog
|
|
101
|
-
|
|
102
|
-
```stx
|
|
103
|
-
<DialogPanel className="max-w-4xl">
|
|
104
|
-
<DialogTitle>Terms and Conditions</DialogTitle>
|
|
105
|
-
|
|
106
|
-
<div class="mt-4 max-h-96 overflow-y-auto">
|
|
107
|
-
<!-- Long content -->
|
|
108
|
-
</div>
|
|
109
|
-
</DialogPanel>
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## Features
|
|
113
|
-
|
|
114
|
-
- Focus trap
|
|
115
|
-
- Backdrop overlay
|
|
116
|
-
- Keyboard support (ESC to close)
|
|
117
|
-
- Dark mode support
|
|
118
|
-
- Accessible (WAI-ARIA)
|
|
119
|
-
- Customizable with headwind classes
|
|
120
|
-
- Multiple sizes
|
|
121
|
-
- Scrollable content support
|
package/src/ui/dialog/index.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export { default as Dialog } from './Dialog.stx'
|
|
2
|
-
export { default as DialogBackdrop } from './DialogBackdrop.stx'
|
|
3
|
-
export { default as DialogDescription } from './DialogDescription.stx'
|
|
4
|
-
export { default as DialogPanel } from './DialogPanel.stx'
|
|
5
|
-
export { default as DialogTitle } from './DialogTitle.stx'
|
|
6
|
-
|
|
7
|
-
export interface DialogProps {
|
|
8
|
-
open?: boolean
|
|
9
|
-
onClose?: (value: boolean) => void
|
|
10
|
-
className?: string
|
|
11
|
-
as?: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface DialogBackdropProps {
|
|
15
|
-
className?: string
|
|
16
|
-
as?: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface DialogPanelProps {
|
|
20
|
-
className?: string
|
|
21
|
-
as?: string
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface DialogTitleProps {
|
|
25
|
-
className?: string
|
|
26
|
-
as?: string
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface DialogDescriptionProps {
|
|
30
|
-
className?: string
|
|
31
|
-
as?: string
|
|
32
|
-
}
|
package/src/ui/drawer/Drawer.stx
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const open = $props.open ?? false
|
|
3
|
-
export const position = $props.position || 'right'
|
|
4
|
-
export const title = $props.title || ''
|
|
5
|
-
export const className = $props.className || ''
|
|
6
|
-
|
|
7
|
-
const positionClasses = {
|
|
8
|
-
right: 'inset-y-0 right-0 pl-10 sm:pl-16',
|
|
9
|
-
left: 'inset-y-0 left-0 pr-10 sm:pr-16',
|
|
10
|
-
top: 'inset-x-0 top-0 pb-10',
|
|
11
|
-
bottom: 'inset-x-0 bottom-0 pt-10',
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const sizeClasses = {
|
|
15
|
-
right: 'max-w-md w-screen',
|
|
16
|
-
left: 'max-w-md w-screen',
|
|
17
|
-
top: 'max-h-[90vh] w-full',
|
|
18
|
-
bottom: 'max-h-[90vh] w-full',
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const closeButtonPosition = {
|
|
22
|
-
right: 'left-0 -ml-8 sm:-ml-10',
|
|
23
|
-
left: 'right-0 -mr-8 sm:-mr-10',
|
|
24
|
-
top: 'right-0 -mr-8',
|
|
25
|
-
bottom: 'right-0 -mr-8',
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const containerClasses = `pointer-events-none fixed ${positionClasses[position]} flex max-w-full`.trim()
|
|
29
|
-
export const panelClasses = `pointer-events-auto relative ${sizeClasses[position]} ${className}`.trim()
|
|
30
|
-
export const closeButtonClasses = `absolute top-0 ${closeButtonPosition[position]} flex pt-4 pr-2 sm:pr-4`.trim()
|
|
31
|
-
</script>
|
|
32
|
-
|
|
33
|
-
<script client>
|
|
34
|
-
const emit = defineEmits()
|
|
35
|
-
// useReactiveProp lets the parent drive `open` via signals
|
|
36
|
-
// (`:open="drawerOpen()"`) instead of the prop being captured once.
|
|
37
|
-
// See stacksjs/stx#1704.
|
|
38
|
-
const isOpen = useReactiveProp('open', {{ open }})
|
|
39
|
-
|
|
40
|
-
function close() {
|
|
41
|
-
isOpen.set(false)
|
|
42
|
-
emit('close')
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function onBackdropClick() {
|
|
46
|
-
close()
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function onPanelKey(event) {
|
|
50
|
-
if (event.key === 'Escape') close()
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
defineExpose({
|
|
54
|
-
open: () => isOpen.set(true),
|
|
55
|
-
close,
|
|
56
|
-
isOpen,
|
|
57
|
-
})
|
|
58
|
-
</script>
|
|
59
|
-
|
|
60
|
-
<div :show="isOpen()">
|
|
61
|
-
<div
|
|
62
|
-
class="fixed inset-0 z-50 bg-gray-500/75 dark:bg-gray-900/75 transition-opacity duration-500"
|
|
63
|
-
style="animation: fadeIn 0.5s ease-in-out"
|
|
64
|
-
@click="onBackdropClick()"
|
|
65
|
-
></div>
|
|
66
|
-
|
|
67
|
-
<div class="fixed inset-0 z-50 overflow-hidden" @keydown="onPanelKey($event)">
|
|
68
|
-
<div class="absolute inset-0 overflow-hidden">
|
|
69
|
-
<div class="{{ containerClasses }}">
|
|
70
|
-
<div
|
|
71
|
-
class="{{ panelClasses }}"
|
|
72
|
-
style="animation: slideIn 0.5s ease-in-out"
|
|
73
|
-
>
|
|
74
|
-
<div class="{{ closeButtonClasses }}">
|
|
75
|
-
<button
|
|
76
|
-
type="button"
|
|
77
|
-
class="relative rounded-md text-gray-300 dark:text-gray-400 hover:text-white dark:hover:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
|
78
|
-
@click="close()"
|
|
79
|
-
>
|
|
80
|
-
<span class="absolute -inset-2.5"></span>
|
|
81
|
-
<span class="sr-only">Close panel</span>
|
|
82
|
-
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
|
83
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
|
84
|
-
</svg>
|
|
85
|
-
</button>
|
|
86
|
-
</div>
|
|
87
|
-
|
|
88
|
-
<div class="relative flex h-full flex-col overflow-y-auto bg-white dark:bg-blue-gray-800 py-6 shadow-xl">
|
|
89
|
-
@if(title)
|
|
90
|
-
<div class="px-4 sm:px-6">
|
|
91
|
-
<h2 class="text-base font-semibold text-gray-900 dark:text-gray-100">
|
|
92
|
-
{{ title }}
|
|
93
|
-
</h2>
|
|
94
|
-
</div>
|
|
95
|
-
@endif
|
|
96
|
-
<div class="relative mt-6 flex-1 px-4 sm:px-6">
|
|
97
|
-
<slot />
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
</div>
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
</div>
|
|
104
|
-
</div>
|
|
105
|
-
|
|
106
|
-
<style>
|
|
107
|
-
@keyframes fadeIn {
|
|
108
|
-
from { opacity: 0; }
|
|
109
|
-
to { opacity: 1; }
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
@keyframes slideIn {
|
|
113
|
-
from {
|
|
114
|
-
transform: {{ position === 'right' ? 'translateX(100%)' : position === 'left' ? 'translateX(-100%)' : position === 'top' ? 'translateY(-100%)' : 'translateY(100%)' }};
|
|
115
|
-
}
|
|
116
|
-
to {
|
|
117
|
-
transform: translate(0, 0);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
</style>
|
package/src/ui/drawer/README.md
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# Drawer Component
|
|
2
|
-
|
|
3
|
-
A slide-out panel component that can appear from any side of the screen.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
bun add @stacksjs/components
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```stx
|
|
14
|
-
<script server>
|
|
15
|
-
let drawerOpen = false
|
|
16
|
-
</script>
|
|
17
|
-
|
|
18
|
-
<button
|
|
19
|
-
class="rounded-md bg-gray-950/5 px-2.5 py-1.5 text-sm font-semibold text-gray-900 hover:bg-gray-950/10"
|
|
20
|
-
onclick="drawerOpen = true"
|
|
21
|
-
>
|
|
22
|
-
Open drawer
|
|
23
|
-
</button>
|
|
24
|
-
|
|
25
|
-
<Drawer
|
|
26
|
-
:open="drawerOpen"
|
|
27
|
-
:onClose="() => drawerOpen = false"
|
|
28
|
-
position="right"
|
|
29
|
-
title="Panel title"
|
|
30
|
-
>
|
|
31
|
-
<p class="text-sm text-gray-500 dark:text-gray-400">
|
|
32
|
-
Your drawer content goes here.
|
|
33
|
-
</p>
|
|
34
|
-
</Drawer>
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Props
|
|
38
|
-
|
|
39
|
-
| Prop | Type | Default | Description |
|
|
40
|
-
|------|------|---------|-------------|
|
|
41
|
-
| `open` | `boolean` | `false` | Controls drawer visibility |
|
|
42
|
-
| `onClose` | `function` | - | Callback when drawer should close |
|
|
43
|
-
| `position` | `'right' \| 'left' \| 'top' \| 'bottom'` | `'right'` | Position of the drawer |
|
|
44
|
-
| `title` | `string` | `''` | Optional title for the drawer |
|
|
45
|
-
| `className` | `string` | `''` | Additional CSS classes |
|
|
46
|
-
|
|
47
|
-
## Positions
|
|
48
|
-
|
|
49
|
-
### Right (default)
|
|
50
|
-
```stx
|
|
51
|
-
<Drawer open position="right">Content</Drawer>
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### Left
|
|
55
|
-
```stx
|
|
56
|
-
<Drawer open position="left">Content</Drawer>
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Top
|
|
60
|
-
```stx
|
|
61
|
-
<Drawer open position="top">Content</Drawer>
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Bottom
|
|
65
|
-
```stx
|
|
66
|
-
<Drawer open position="bottom">Content</Drawer>
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Features
|
|
70
|
-
|
|
71
|
-
- **4 positions** - Slide from right, left, top, or bottom
|
|
72
|
-
- **Smooth animations** - CSS transitions for slide and fade effects
|
|
73
|
-
- **Backdrop click** - Closes drawer when clicking outside
|
|
74
|
-
- **Close button** - Positioned appropriately for each direction
|
|
75
|
-
- **Dark mode** - Full dark mode support
|
|
76
|
-
- **Accessible** - Screen reader support and focus management
|
|
77
|
-
- **Responsive** - Mobile-friendly with adjusted spacing
|
|
78
|
-
- **Modern ES modules** - Clean export syntax
|
|
79
|
-
- **Headwind styling** - Utility-first CSS classes
|
|
80
|
-
|
|
81
|
-
## Accessibility
|
|
82
|
-
|
|
83
|
-
- Close button includes `sr-only` text for screen readers
|
|
84
|
-
- Backdrop and close button have proper ARIA labels
|
|
85
|
-
- Keyboard accessible (ESC key closes drawer - handled by parent)
|
|
86
|
-
- Focus management for modal behavior
|
|
87
|
-
|
|
88
|
-
## Customization
|
|
89
|
-
|
|
90
|
-
The drawer accepts a `className` prop for additional styling and supports slot content for complete customization of the drawer body.
|
package/src/ui/drawer/index.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const className = $props.className || ''
|
|
3
|
-
export const as = $props.as || 'div'
|
|
4
|
-
|
|
5
|
-
const baseClasses = 'relative inline-block text-left'
|
|
6
|
-
export const dropdownClasses = `${baseClasses} ${className}`.trim()
|
|
7
|
-
export const dropdownInstanceId = `stx-dd-${Math.random().toString(36).slice(2, 11)}`
|
|
8
|
-
</script>
|
|
9
|
-
|
|
10
|
-
<script client>
|
|
11
|
-
const emit = defineEmits()
|
|
12
|
-
const dropdownInstanceId = {{ dropdownInstanceId }}
|
|
13
|
-
const isOpen = state(false)
|
|
14
|
-
let rootEl = null
|
|
15
|
-
let outsideHandler = null
|
|
16
|
-
|
|
17
|
-
function toggle() {
|
|
18
|
-
isOpen.set(!isOpen())
|
|
19
|
-
emit('change', isOpen())
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function open() {
|
|
23
|
-
if (isOpen()) return
|
|
24
|
-
isOpen.set(true)
|
|
25
|
-
emit('change', true)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function close() {
|
|
29
|
-
if (!isOpen()) return
|
|
30
|
-
isOpen.set(false)
|
|
31
|
-
emit('change', false)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function onItemSelect(event) {
|
|
35
|
-
event.stopPropagation()
|
|
36
|
-
emit('select', event.detail)
|
|
37
|
-
close()
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function onToggle(event) { event.stopPropagation(); toggle() }
|
|
41
|
-
function onOpen(event) { event.stopPropagation(); open() }
|
|
42
|
-
function onClose(event) { event.stopPropagation(); close() }
|
|
43
|
-
|
|
44
|
-
onMount(() => {
|
|
45
|
-
rootEl = document.querySelector(`[data-dropdown-id="${dropdownInstanceId}"]`)
|
|
46
|
-
outsideHandler = (event) => {
|
|
47
|
-
if (!isOpen()) return
|
|
48
|
-
if (rootEl && !rootEl.contains(event.target)) close()
|
|
49
|
-
}
|
|
50
|
-
document.addEventListener('click', outsideHandler, true)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
onDestroy(() => {
|
|
54
|
-
if (outsideHandler) document.removeEventListener('click', outsideHandler, true)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
const dataState = derived(() => isOpen() ? 'open' : 'closed')
|
|
58
|
-
const dataExpanded = derived(() => isOpen() ? 'true' : 'false')
|
|
59
|
-
|
|
60
|
-
defineExpose({ isOpen, toggle, open, close })
|
|
61
|
-
</script>
|
|
62
|
-
|
|
63
|
-
<component
|
|
64
|
-
:is="{{ as }}"
|
|
65
|
-
class="{{ dropdownClasses }}"
|
|
66
|
-
data-stx-dropdown
|
|
67
|
-
data-dropdown-id="{{ dropdownInstanceId }}"
|
|
68
|
-
:data-state="dataState()"
|
|
69
|
-
:data-expanded="dataExpanded()"
|
|
70
|
-
@stx:dropdown-toggle="onToggle($event)"
|
|
71
|
-
@stx:dropdown-open="onOpen($event)"
|
|
72
|
-
@stx:dropdown-close="onClose($event)"
|
|
73
|
-
@stx:dropdown-select="onItemSelect($event)"
|
|
74
|
-
>
|
|
75
|
-
<slot />
|
|
76
|
-
</component>
|
|
77
|
-
|
|
78
|
-
<style>
|
|
79
|
-
[data-stx-dropdown][data-state="closed"] [data-stx-dropdown-items] {
|
|
80
|
-
display: none;
|
|
81
|
-
}
|
|
82
|
-
</style>
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const className = $props.className || ''
|
|
3
|
-
export const as = $props.as || 'button'
|
|
4
|
-
export const disabled = $props.disabled || false
|
|
5
|
-
|
|
6
|
-
const baseClasses = 'inline-flex justify-center items-center rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75'
|
|
7
|
-
export const buttonClasses = `${baseClasses} ${className}`.trim()
|
|
8
|
-
</script>
|
|
9
|
-
|
|
10
|
-
<script client>
|
|
11
|
-
const emit = defineEmits()
|
|
12
|
-
const isDisabled = {{ disabled }}
|
|
13
|
-
|
|
14
|
-
function onClick(event) {
|
|
15
|
-
if (isDisabled) return
|
|
16
|
-
emit('click', event)
|
|
17
|
-
event.currentTarget.dispatchEvent(new CustomEvent('stx:dropdown-toggle', { bubbles: true }))
|
|
18
|
-
}
|
|
19
|
-
</script>
|
|
20
|
-
|
|
21
|
-
<component
|
|
22
|
-
:is="{{ as }}"
|
|
23
|
-
class="{{ buttonClasses }}"
|
|
24
|
-
data-stx-dropdown-button
|
|
25
|
-
@if(disabled)disabled aria-disabled="true"@endif
|
|
26
|
-
@click="onClick($event)"
|
|
27
|
-
>
|
|
28
|
-
<slot />
|
|
29
|
-
</component>
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const className = $props.className || ''
|
|
3
|
-
export const as = $props.as || 'div'
|
|
4
|
-
export const disabled = $props.disabled || false
|
|
5
|
-
export const value = $props.value
|
|
6
|
-
|
|
7
|
-
const baseClasses = 'group flex w-full items-center px-2 py-2 text-sm transition-colors text-neutral-900 dark:text-neutral-100 hover:bg-blue-500 hover:text-white dark:hover:bg-blue-600'
|
|
8
|
-
const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'
|
|
9
|
-
export const itemClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<script client>
|
|
13
|
-
const emit = defineEmits()
|
|
14
|
-
const isDisabled = {{ disabled }}
|
|
15
|
-
const itemValue = {{ value === undefined ? 'null' : value }}
|
|
16
|
-
|
|
17
|
-
function onClick(event) {
|
|
18
|
-
if (isDisabled) return
|
|
19
|
-
emit('click', event)
|
|
20
|
-
event.currentTarget.dispatchEvent(
|
|
21
|
-
new CustomEvent('stx:dropdown-select', { bubbles: true, detail: itemValue }),
|
|
22
|
-
)
|
|
23
|
-
}
|
|
24
|
-
</script>
|
|
25
|
-
|
|
26
|
-
<component
|
|
27
|
-
:is="{{ as }}"
|
|
28
|
-
class="{{ itemClasses }}"
|
|
29
|
-
data-stx-dropdown-item
|
|
30
|
-
role="menuitem"
|
|
31
|
-
@if(disabled)aria-disabled="true"@endif
|
|
32
|
-
@click="onClick($event)"
|
|
33
|
-
>
|
|
34
|
-
<slot :disabled="disabled" />
|
|
35
|
-
</component>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const className = $props.className || ''
|
|
3
|
-
export const as = $props.as || 'div'
|
|
4
|
-
|
|
5
|
-
const baseClasses = 'absolute z-10 mt-2 origin-top-right divide-y divide-neutral-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-neutral-800 dark:divide-neutral-700 dark:ring-neutral-600'
|
|
6
|
-
export const itemsClasses = `${baseClasses} ${className}`.trim()
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<component
|
|
10
|
-
:is="{{ as }}"
|
|
11
|
-
class="{{ itemsClasses }}"
|
|
12
|
-
data-stx-dropdown-items
|
|
13
|
-
role="menu"
|
|
14
|
-
aria-orientation="vertical"
|
|
15
|
-
tabindex="-1"
|
|
16
|
-
>
|
|
17
|
-
<slot />
|
|
18
|
-
</component>
|