@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.
Files changed (187) hide show
  1. package/dist/index.js +4 -4
  2. package/package.json +5 -6
  3. package/src/components/CodeBlock.stx +0 -54
  4. package/src/components/Footer.stx +0 -66
  5. package/src/components/Hero.stx +0 -25
  6. package/src/components/Installation.stx +0 -37
  7. package/src/components/index.ts +0 -4
  8. package/src/composables/index.ts +0 -4
  9. package/src/composables/useCopyCode.ts +0 -73
  10. package/src/composables/useDarkMode.ts +0 -100
  11. package/src/composables/useSEO.ts +0 -230
  12. package/src/composables/utilities/index.ts +0 -7
  13. package/src/composables/utilities/useClickOutside.ts +0 -72
  14. package/src/composables/utilities/useFocusTrap.ts +0 -159
  15. package/src/composables/utilities/useKeyboard.ts +0 -124
  16. package/src/composables/utilities/useLocalStorage.ts +0 -132
  17. package/src/composables/utilities/useMediaQuery.ts +0 -118
  18. package/src/index.ts +0 -99
  19. package/src/stx.d.ts +0 -4
  20. package/src/ui/accordion/Accordion.stx +0 -146
  21. package/src/ui/accordion/AccordionItem.stx +0 -37
  22. package/src/ui/accordion/index.ts +0 -47
  23. package/src/ui/audio/Audio.stx +0 -50
  24. package/src/ui/audio/README.md +0 -41
  25. package/src/ui/audio/index.ts +0 -13
  26. package/src/ui/auth/Login.stx +0 -161
  27. package/src/ui/auth/README.md +0 -142
  28. package/src/ui/auth/Signup.stx +0 -159
  29. package/src/ui/auth/TwoFactorChallenge.stx +0 -111
  30. package/src/ui/auth/index.ts +0 -32
  31. package/src/ui/avatar/Avatar.stx +0 -77
  32. package/src/ui/avatar/index.ts +0 -12
  33. package/src/ui/badge/Badge.stx +0 -62
  34. package/src/ui/badge/index.ts +0 -10
  35. package/src/ui/breadcrumb/Breadcrumb.stx +0 -79
  36. package/src/ui/breadcrumb/index.ts +0 -15
  37. package/src/ui/button/Button.stx +0 -74
  38. package/src/ui/button/README.md +0 -80
  39. package/src/ui/button/index.ts +0 -85
  40. package/src/ui/calendar/Calendar.stx +0 -189
  41. package/src/ui/calendar/README.md +0 -254
  42. package/src/ui/calendar/index.ts +0 -14
  43. package/src/ui/card/Card.stx +0 -68
  44. package/src/ui/card/index.ts +0 -13
  45. package/src/ui/checkbox/Checkbox.stx +0 -86
  46. package/src/ui/checkbox/index.ts +0 -16
  47. package/src/ui/combobox/Combobox.stx +0 -96
  48. package/src/ui/combobox/ComboboxButton.stx +0 -25
  49. package/src/ui/combobox/ComboboxInput.stx +0 -32
  50. package/src/ui/combobox/ComboboxOption.stx +0 -49
  51. package/src/ui/combobox/ComboboxOptions.stx +0 -16
  52. package/src/ui/combobox/README.md +0 -150
  53. package/src/ui/combobox/index.ts +0 -40
  54. package/src/ui/command-palette/CommandPalette.stx +0 -81
  55. package/src/ui/command-palette/CommandPaletteItem.stx +0 -27
  56. package/src/ui/command-palette/README.md +0 -42
  57. package/src/ui/command-palette/index.ts +0 -15
  58. package/src/ui/dialog/Dialog.stx +0 -41
  59. package/src/ui/dialog/DialogBackdrop.stx +0 -9
  60. package/src/ui/dialog/DialogDescription.stx +0 -11
  61. package/src/ui/dialog/DialogPanel.stx +0 -16
  62. package/src/ui/dialog/DialogTitle.stx +0 -11
  63. package/src/ui/dialog/README.md +0 -121
  64. package/src/ui/dialog/index.ts +0 -32
  65. package/src/ui/drawer/Drawer.stx +0 -120
  66. package/src/ui/drawer/README.md +0 -90
  67. package/src/ui/drawer/index.ts +0 -9
  68. package/src/ui/dropdown/Dropdown.stx +0 -82
  69. package/src/ui/dropdown/DropdownButton.stx +0 -29
  70. package/src/ui/dropdown/DropdownItem.stx +0 -35
  71. package/src/ui/dropdown/DropdownItems.stx +0 -18
  72. package/src/ui/dropdown/README.md +0 -114
  73. package/src/ui/dropdown/index.ts +0 -29
  74. package/src/ui/form/Form.stx +0 -95
  75. package/src/ui/form/index.ts +0 -67
  76. package/src/ui/heatmap/Heatmap.stx +0 -294
  77. package/src/ui/image/Image.stx +0 -165
  78. package/src/ui/image/README.md +0 -164
  79. package/src/ui/image/index.ts +0 -22
  80. package/src/ui/input/EmailInput.stx +0 -30
  81. package/src/ui/input/NumberInput.stx +0 -126
  82. package/src/ui/input/PasswordInput.stx +0 -143
  83. package/src/ui/input/SearchInput.stx +0 -44
  84. package/src/ui/input/TextInput.stx +0 -132
  85. package/src/ui/input/index.ts +0 -180
  86. package/src/ui/listbox/Listbox.stx +0 -101
  87. package/src/ui/listbox/ListboxButton.stx +0 -28
  88. package/src/ui/listbox/ListboxLabel.stx +0 -11
  89. package/src/ui/listbox/ListboxOption.stx +0 -49
  90. package/src/ui/listbox/ListboxOptions.stx +0 -16
  91. package/src/ui/listbox/README.md +0 -135
  92. package/src/ui/listbox/index.ts +0 -39
  93. package/src/ui/navigator/Navigator.stx +0 -113
  94. package/src/ui/navigator/README.md +0 -352
  95. package/src/ui/navigator/index.ts +0 -20
  96. package/src/ui/notification/Notification.stx +0 -117
  97. package/src/ui/notification/README.md +0 -114
  98. package/src/ui/notification/index.ts +0 -12
  99. package/src/ui/pagination/Pagination.stx +0 -150
  100. package/src/ui/pagination/index.ts +0 -11
  101. package/src/ui/payment/Checkout.stx +0 -31
  102. package/src/ui/payment/DefaultPaymentMethod.stx +0 -62
  103. package/src/ui/payment/PaymentMethods.stx +0 -104
  104. package/src/ui/payment/README.md +0 -345
  105. package/src/ui/payment/SubscriptionCheckout.stx +0 -323
  106. package/src/ui/payment/index.ts +0 -59
  107. package/src/ui/popover/Popover.stx +0 -60
  108. package/src/ui/popover/PopoverButton.stx +0 -29
  109. package/src/ui/popover/PopoverPanel.stx +0 -23
  110. package/src/ui/popover/README.md +0 -91
  111. package/src/ui/popover/index.ts +0 -22
  112. package/src/ui/portal/Portal.stx +0 -57
  113. package/src/ui/portal/index.ts +0 -6
  114. package/src/ui/progress/Progress.stx +0 -131
  115. package/src/ui/progress/index.ts +0 -12
  116. package/src/ui/radio/Radio.stx +0 -77
  117. package/src/ui/radio/index.ts +0 -15
  118. package/src/ui/radio-group/README.md +0 -139
  119. package/src/ui/radio-group/RadioGroup.stx +0 -60
  120. package/src/ui/radio-group/RadioGroupDescription.stx +0 -11
  121. package/src/ui/radio-group/RadioGroupLabel.stx +0 -11
  122. package/src/ui/radio-group/RadioGroupOption.stx +0 -58
  123. package/src/ui/radio-group/index.ts +0 -30
  124. package/src/ui/select/README.md +0 -180
  125. package/src/ui/select/Select.stx +0 -82
  126. package/src/ui/select/index.ts +0 -21
  127. package/src/ui/sidebar/Sidebar.stx +0 -476
  128. package/src/ui/sidebar/SidebarFooter.stx +0 -71
  129. package/src/ui/sidebar/SidebarHeader.stx +0 -103
  130. package/src/ui/sidebar/SidebarItem.stx +0 -86
  131. package/src/ui/sidebar/SidebarSection.stx +0 -83
  132. package/src/ui/sidebar/index.ts +0 -153
  133. package/src/ui/sidebar/themes.ts +0 -240
  134. package/src/ui/skeleton/Skeleton.stx +0 -48
  135. package/src/ui/skeleton/index.ts +0 -11
  136. package/src/ui/spinner/Spinner.stx +0 -109
  137. package/src/ui/spinner/index.ts +0 -9
  138. package/src/ui/stepper/README.md +0 -36
  139. package/src/ui/stepper/Stepper.stx +0 -17
  140. package/src/ui/stepper/StepperStep.stx +0 -57
  141. package/src/ui/stepper/index.ts +0 -19
  142. package/src/ui/storage/README.md +0 -193
  143. package/src/ui/storage/index.ts +0 -347
  144. package/src/ui/switch/README.md +0 -114
  145. package/src/ui/switch/Switch.stx +0 -72
  146. package/src/ui/switch/index.ts +0 -10
  147. package/src/ui/table/README.md +0 -39
  148. package/src/ui/table/Table.stx +0 -14
  149. package/src/ui/table/TableBody.stx +0 -10
  150. package/src/ui/table/TableCell.stx +0 -10
  151. package/src/ui/table/TableHead.stx +0 -10
  152. package/src/ui/table/TableHeader.stx +0 -20
  153. package/src/ui/table/TableRow.stx +0 -11
  154. package/src/ui/table/index.ts +0 -35
  155. package/src/ui/tabs/TabPanel.stx +0 -25
  156. package/src/ui/tabs/Tabs.stx +0 -202
  157. package/src/ui/tabs/index.ts +0 -50
  158. package/src/ui/teleport/Teleport.stx +0 -65
  159. package/src/ui/teleport/index.ts +0 -7
  160. package/src/ui/textarea/Textarea.stx +0 -108
  161. package/src/ui/textarea/index.ts +0 -20
  162. package/src/ui/tooltip/Tooltip.stx +0 -71
  163. package/src/ui/tooltip/index.ts +0 -10
  164. package/src/ui/transition/README.md +0 -30
  165. package/src/ui/transition/Transition.stx +0 -102
  166. package/src/ui/transition/index.ts +0 -25
  167. package/src/ui/video/README.md +0 -47
  168. package/src/ui/video/Video.stx +0 -45
  169. package/src/ui/video/index.ts +0 -16
  170. package/src/ui/virtual-list/VirtualList.stx +0 -67
  171. package/src/ui/virtual-list/index.ts +0 -10
  172. package/src/ui/virtual-table/VirtualTable.stx +0 -103
  173. package/src/ui/virtual-table/index.ts +0 -21
  174. package/src/utils/PROP_VALIDATION.md +0 -458
  175. package/src/utils/THEME_SYSTEM.md +0 -702
  176. package/src/utils/accessibility.ts +0 -841
  177. package/src/utils/animation/easing.ts +0 -368
  178. package/src/utils/animation/helpers.ts +0 -223
  179. package/src/utils/animation/index.ts +0 -5
  180. package/src/utils/animation/keyframes.ts +0 -230
  181. package/src/utils/error-handling.ts +0 -475
  182. package/src/utils/highlighter.ts +0 -93
  183. package/src/utils/i18n.ts +0 -634
  184. package/src/utils/keep-alive.ts +0 -819
  185. package/src/utils/lazy-loading.ts +0 -530
  186. package/src/utils/prop-validation.ts +0 -478
  187. package/src/utils/theme.ts +0 -626
@@ -1,59 +0,0 @@
1
- export { default as Checkout } from './Checkout.stx'
2
- export { default as DefaultPaymentMethod } from './DefaultPaymentMethod.stx'
3
- export { default as PaymentMethods } from './PaymentMethods.stx'
4
- export { default as SubscriptionCheckout } from './SubscriptionCheckout.stx'
5
-
6
- export interface PaymentMethod {
7
- id: string | number
8
- brand: string
9
- last_four: string
10
- exp_month: number
11
- exp_year: number
12
- is_default?: boolean
13
- }
14
-
15
- export interface PaymentMethodsProps {
16
- paymentMethods: PaymentMethod[]
17
- onDeletePaymentMethod?: (id: string | number) => void
18
- onMakeDefault?: (id: string | number) => void
19
- isLoading?: boolean
20
- className?: string
21
- }
22
-
23
- export interface DefaultPaymentMethodProps {
24
- paymentMethod: PaymentMethod | null
25
- isLoading?: boolean
26
- className?: string
27
- }
28
-
29
- export interface Product {
30
- id: string | number
31
- name: string
32
- price: number // in cents
33
- images?: string
34
- quantity?: number
35
- }
36
-
37
- export interface SubscriptionCheckoutProps {
38
- products: Product[]
39
- stripePublicKey: string
40
- apiUrl: string
41
- onSubmit?: (result: { success: boolean }) => void
42
- onRemoveProduct?: (id: string | number) => void
43
- shipping?: number
44
- taxes?: number
45
- className?: string
46
- }
47
-
48
- export interface CheckoutProps {
49
- products: Product[]
50
- redirectUrl: string
51
- mode: 'one-time' | 'subscription'
52
- stripePublicKey: string
53
- apiUrl: string
54
- onSubmit?: (result: { success: boolean }) => void
55
- onRemoveProduct?: (id: string | number) => void
56
- shipping?: number
57
- taxes?: number
58
- className?: string
59
- }
@@ -1,60 +0,0 @@
1
- <script server>
2
- export const className = $props.className || ''
3
- export const as = $props.as || 'div'
4
-
5
- const baseClasses = 'relative'
6
- export const popoverClasses = `${baseClasses} ${className}`.trim()
7
- export const popoverInstanceId = `stx-pop-${Math.random().toString(36).slice(2, 11)}`
8
- </script>
9
-
10
- <script client>
11
- const emit = defineEmits()
12
- const popoverInstanceId = {{ popoverInstanceId }}
13
- const isOpen = state(false)
14
- let rootEl = null
15
- let outsideHandler = null
16
-
17
- function open() { if (!isOpen()) { isOpen.set(true); emit('change', true) } }
18
- function close() { if (isOpen()) { isOpen.set(false); emit('change', false) } }
19
- function toggle() { isOpen() ? close() : open() }
20
-
21
- function onToggle(event) { event.stopPropagation(); toggle() }
22
- function onClose(event) { event.stopPropagation(); close() }
23
- function onOpen(event) { event.stopPropagation(); open() }
24
-
25
- onMount(() => {
26
- rootEl = document.querySelector(`[data-popover-id="${popoverInstanceId}"]`)
27
- outsideHandler = (event) => {
28
- if (!isOpen()) return
29
- if (rootEl && !rootEl.contains(event.target)) close()
30
- }
31
- document.addEventListener('click', outsideHandler, true)
32
- })
33
-
34
- onDestroy(() => {
35
- if (outsideHandler) document.removeEventListener('click', outsideHandler, true)
36
- })
37
-
38
- const dataState = derived(() => isOpen() ? 'open' : 'closed')
39
-
40
- defineExpose({ isOpen, toggle, open, close })
41
- </script>
42
-
43
- <component
44
- :is="{{ as }}"
45
- class="{{ popoverClasses }}"
46
- data-stx-popover
47
- data-popover-id="{{ popoverInstanceId }}"
48
- :data-state="dataState()"
49
- @stx:popover-toggle="onToggle($event)"
50
- @stx:popover-open="onOpen($event)"
51
- @stx:popover-close="onClose($event)"
52
- >
53
- <slot />
54
- </component>
55
-
56
- <style>
57
- [data-stx-popover][data-state="closed"] [data-stx-popover-panel] {
58
- display: none;
59
- }
60
- </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 items-center gap-2 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:popover-toggle', { bubbles: true }))
18
- }
19
- </script>
20
-
21
- <component
22
- :is="{{ as }}"
23
- class="{{ buttonClasses }}"
24
- data-stx-popover-button
25
- @if(disabled)disabled aria-disabled="true"@endif
26
- @click="onClick($event)"
27
- >
28
- <slot />
29
- </component>
@@ -1,23 +0,0 @@
1
- <script server>
2
- export const className = $props.className || ''
3
- export const as = $props.as || 'div'
4
- export const position = $props.position || 'bottom'
5
-
6
- const positionClasses = {
7
- top: 'bottom-full mb-2',
8
- bottom: 'top-full mt-2',
9
- left: 'right-full mr-2',
10
- right: 'left-full ml-2',
11
- }
12
-
13
- const baseClasses = 'absolute z-10 rounded-lg bg-white dark:bg-neutral-800 p-4 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none'
14
- export const panelClasses = `${baseClasses} ${positionClasses[position]} ${className}`.trim()
15
- </script>
16
-
17
- <component
18
- :is="{{ as }}"
19
- class="{{ panelClasses }}"
20
- data-stx-popover-panel
21
- >
22
- <slot />
23
- </component>
@@ -1,91 +0,0 @@
1
- # Popover Component
2
-
3
- A floating panel that displays rich content anchored to a button or element.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- bun add @stacksjs/components
9
- ```
10
-
11
- ## Usage
12
-
13
- ```stx
14
- <Popover>
15
- <PopoverButton className="px-4 py-2 bg-blue-500 text-white rounded">
16
- Solutions
17
- </PopoverButton>
18
-
19
- <PopoverPanel className="w-64">
20
- <div class="grid gap-4">
21
- <a href="/analytics">Analytics</a>
22
- <a href="/engagement">Engagement</a>
23
- <a href="/security">Security</a>
24
- </div>
25
- </PopoverPanel>
26
- </Popover>
27
- ```
28
-
29
- ## Props
30
-
31
- ### Popover
32
- | Prop | Type | Default | Description |
33
- |------|------|---------|-------------|
34
- | `className` | `string` | `''` | Additional CSS classes |
35
- | `as` | `string` | `'div'` | HTML element to render |
36
-
37
- ### PopoverButton
38
- | Prop | Type | Default | Description |
39
- |------|------|---------|-------------|
40
- | `className` | `string` | `''` | Additional CSS classes |
41
- | `as` | `string` | `'button'` | HTML element to render |
42
- | `disabled` | `boolean` | `false` | Disable the button |
43
- | `onClick` | `(e: Event) => void` | - | Click handler |
44
-
45
- ### PopoverPanel
46
- | Prop | Type | Default | Description |
47
- |------|------|---------|-------------|
48
- | `className` | `string` | `''` | Additional CSS classes |
49
- | `as` | `string` | `'div'` | HTML element to render |
50
- | `static` | `boolean` | `false` | Keep visible regardless of state |
51
- | `position` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'bottom'` | Panel position |
52
-
53
- ## Examples
54
-
55
- ### Solutions Menu
56
-
57
- ```stx
58
- <PopoverPanel className="w-80">
59
- <div class="grid gap-8">
60
- <a href="/analytics" class="flex items-start gap-4 group">
61
- <div class="shrink-0 text-blue-500">
62
- <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
63
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
64
- </svg>
65
- </div>
66
- <div>
67
- <p class="font-semibold text-neutral-900 dark:text-white group-hover:text-blue-500">Analytics</p>
68
- <p class="text-sm text-neutral-500 dark:text-neutral-400">Get a better understanding of your traffic</p>
69
- </div>
70
- </a>
71
- </div>
72
- </PopoverPanel>
73
- ```
74
-
75
- ### Different Positions
76
-
77
- ```stx
78
- <PopoverPanel position="top">Content appears above</PopoverPanel>
79
-
80
- <PopoverPanel position="left">Content appears to the left</PopoverPanel>
81
- ```
82
-
83
- ## Features
84
-
85
- - Multiple positioning options
86
- - Auto-positioning
87
- - Dark mode support
88
- - Accessible (WAI-ARIA)
89
- - Keyboard support
90
- - Focus management
91
- - Customizable styling
@@ -1,22 +0,0 @@
1
- export { default as Popover } from './Popover.stx'
2
- export { default as PopoverButton } from './PopoverButton.stx'
3
- export { default as PopoverPanel } from './PopoverPanel.stx'
4
-
5
- export interface PopoverProps {
6
- className?: string
7
- as?: string
8
- }
9
-
10
- export interface PopoverButtonProps {
11
- className?: string
12
- as?: string
13
- disabled?: boolean
14
- onClick?: (e: Event) => void
15
- }
16
-
17
- export interface PopoverPanelProps {
18
- className?: string
19
- as?: string
20
- static?: boolean
21
- position?: 'top' | 'bottom' | 'left' | 'right'
22
- }
@@ -1,57 +0,0 @@
1
- <script server>
2
- export const target = $props.target || 'body'
3
- export const disabled = $props.disabled || false
4
-
5
- export const portalId = `portal-content-${Math.random().toString(36).slice(2, 11)}`
6
- </script>
7
-
8
- <script client>
9
- const target = {{ target }}
10
- const isDisabled = {{ disabled }}
11
- const portalId = {{ portalId }}
12
-
13
- let portalContainer = null
14
-
15
- function createPortal() {
16
- if (isDisabled) return
17
- const targetElement = typeof target === 'string' ? document.querySelector(target) : target
18
- if (!targetElement) {
19
- console.warn(`Portal target "${target}" not found`)
20
- return
21
- }
22
- portalContainer = document.createElement('div')
23
- portalContainer.setAttribute('data-portal', 'true')
24
- const portalContent = document.getElementById(portalId)
25
- if (portalContent) {
26
- while (portalContent.firstChild) {
27
- portalContainer.appendChild(portalContent.firstChild)
28
- }
29
- }
30
- targetElement.appendChild(portalContainer)
31
- }
32
-
33
- function cleanupPortal() {
34
- if (portalContainer && portalContainer.parentNode) {
35
- portalContainer.parentNode.removeChild(portalContainer)
36
- portalContainer = null
37
- }
38
- }
39
-
40
- onMount(() => {
41
- setTimeout(createPortal, 0)
42
- window.addEventListener('beforeunload', cleanupPortal)
43
- })
44
-
45
- onDestroy(() => {
46
- cleanupPortal()
47
- window.removeEventListener('beforeunload', cleanupPortal)
48
- })
49
- </script>
50
-
51
- @if(disabled)
52
- <slot />
53
- @else
54
- <div id="{{ portalId }}" style="display: none;">
55
- <slot />
56
- </div>
57
- @endif
@@ -1,6 +0,0 @@
1
- export { default as Portal } from './Portal.stx'
2
-
3
- export interface PortalProps {
4
- target?: string | HTMLElement
5
- disabled?: boolean
6
- }
@@ -1,131 +0,0 @@
1
- <script server>
2
- export const value = $props.value || 0
3
- export const max = $props.max || 100
4
- export const variant = $props.variant || 'linear'
5
- export const size = $props.size || 'md'
6
- export const color = $props.color || 'primary'
7
- export const showLabel = $props.showLabel ?? false
8
- export const indeterminate = $props.indeterminate || false
9
- export const className = $props.className || ''
10
-
11
- const linearSizeClasses = { sm: 'h-1', md: 'h-2', lg: 'h-3' }
12
- const circularSizeClasses = { sm: 'w-12 h-12', md: 'w-16 h-16', lg: 'w-24 h-24' }
13
- const colorClasses = {
14
- primary: 'bg-blue-600 dark:bg-blue-500',
15
- secondary: 'bg-purple-600 dark:bg-purple-500',
16
- success: 'bg-green-600 dark:bg-green-500',
17
- warning: 'bg-yellow-600 dark:bg-yellow-500',
18
- danger: 'bg-red-600 dark:bg-red-500',
19
- info: 'bg-cyan-600 dark:bg-cyan-500',
20
- }
21
-
22
- export const circularSize = size === 'sm' ? 48 : size === 'md' ? 64 : 96
23
- export const strokeWidth = size === 'sm' ? 4 : size === 'md' ? 6 : 8
24
- export const radius = (circularSize - strokeWidth) / 2
25
- export const circumference = 2 * Math.PI * radius
26
-
27
- export const containerClasses = variant === 'linear'
28
- ? `w-full ${className}`.trim()
29
- : `inline-flex items-center justify-center ${className}`.trim()
30
-
31
- export const linearTrackClasses = `w-full ${linearSizeClasses[size]} bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden`.trim()
32
- export const linearBarClasses = `h-full ${colorClasses[color]} transition-all duration-300 ease-in-out ${indeterminate ? 'animate-progress-indeterminate' : ''}`.trim()
33
- export const circularSizeClass = circularSizeClasses[size]
34
- export const labelClasses = `text-sm font-medium text-gray-700 dark:text-gray-300 mb-2`.trim()
35
- export const circularTrackColor = 'stroke-gray-200 dark:stroke-gray-700'
36
- export const circularBarColor = color === 'primary' ? 'stroke-blue-600 dark:stroke-blue-500'
37
- : color === 'secondary' ? 'stroke-purple-600 dark:stroke-purple-500'
38
- : color === 'success' ? 'stroke-green-600 dark:stroke-green-500'
39
- : color === 'warning' ? 'stroke-yellow-600 dark:stroke-yellow-500'
40
- : color === 'danger' ? 'stroke-red-600 dark:stroke-red-500'
41
- : 'stroke-cyan-600 dark:stroke-cyan-500'
42
- </script>
43
-
44
- <script client>
45
- const max = {{ max }}
46
- const indeterminate = {{ indeterminate }}
47
- const circumference = {{ circumference }}
48
- // Reactive prop binding — parent can drive `value` via signals. See #1704.
49
- const value = useReactiveProp('value', {{ value }})
50
-
51
- const percentage = derived(() => Math.min(Math.max((value() / max) * 100, 0), 100))
52
- const percentLabel = derived(() => `${Math.round(percentage())}%`)
53
- const linearWidth = derived(() => indeterminate ? '30%' : `${percentage()}%`)
54
- const dashOffset = derived(() => indeterminate ? 0 : circumference - (percentage() / 100) * circumference)
55
-
56
- defineExpose({ value, setValue: (v) => value.set(v) })
57
- </script>
58
-
59
- @if(variant === 'linear')
60
- <div class="{{ containerClasses }}">
61
- @if(showLabel)
62
- <div class="flex items-center justify-between mb-2">
63
- <span class="{{ labelClasses }}" x-text="percentLabel()"></span>
64
- </div>
65
- @endif
66
-
67
- <div
68
- class="{{ linearTrackClasses }}"
69
- role="progressbar"
70
- :aria-valuenow="value()"
71
- aria-valuemin="0"
72
- aria-valuemax="{{ max }}"
73
- >
74
- <div
75
- class="{{ linearBarClasses }}"
76
- :style="`width: ${linearWidth()}`"
77
- ></div>
78
- </div>
79
- </div>
80
- @else
81
- <div class="{{ containerClasses }}">
82
- <div class="{{ circularSizeClass }} relative">
83
- <svg
84
- class="transform -rotate-90"
85
- width="{{ circularSize }}"
86
- height="{{ circularSize }}"
87
- role="progressbar"
88
- :aria-valuenow="value()"
89
- aria-valuemin="0"
90
- aria-valuemax="{{ max }}"
91
- >
92
- <circle
93
- class="{{ circularTrackColor }}"
94
- cx="{{ circularSize / 2 }}"
95
- cy="{{ circularSize / 2 }}"
96
- r="{{ radius }}"
97
- stroke-width="{{ strokeWidth }}"
98
- fill="none"
99
- />
100
- <circle
101
- class="{{ circularBarColor }} transition-all duration-300 ease-in-out {{ indeterminate ? 'animate-spin' : '' }}"
102
- cx="{{ circularSize / 2 }}"
103
- cy="{{ circularSize / 2 }}"
104
- r="{{ radius }}"
105
- stroke-width="{{ strokeWidth }}"
106
- fill="none"
107
- stroke-dasharray="{{ circumference }}"
108
- :stroke-dashoffset="dashOffset()"
109
- stroke-linecap="round"
110
- />
111
- </svg>
112
-
113
- @if(showLabel)
114
- <div class="absolute inset-0 flex items-center justify-center">
115
- <span class="text-sm font-semibold text-gray-700 dark:text-gray-300" x-text="percentLabel()"></span>
116
- </div>
117
- @endif
118
- </div>
119
- </div>
120
- @endif
121
-
122
- <style>
123
- @keyframes progress-indeterminate {
124
- 0% { transform: translateX(-100%); }
125
- 100% { transform: translateX(400%); }
126
- }
127
-
128
- .animate-progress-indeterminate {
129
- animation: progress-indeterminate 1.5s ease-in-out infinite;
130
- }
131
- </style>
@@ -1,12 +0,0 @@
1
- export { default as Progress } from './Progress.stx'
2
-
3
- export interface ProgressProps {
4
- value?: number
5
- max?: number
6
- variant?: 'linear' | 'circular'
7
- size?: 'sm' | 'md' | 'lg'
8
- color?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info'
9
- showLabel?: boolean
10
- indeterminate?: boolean
11
- className?: string
12
- }
@@ -1,77 +0,0 @@
1
- <script server>
2
- export const checked = $props.checked || false
3
- export const disabled = $props.disabled || false
4
- export const size = $props.size || 'md'
5
- export const label = $props.label || ''
6
- export const description = $props.description || ''
7
- export const error = $props.error || false
8
- export const required = $props.required || false
9
- export const value = $props.value || ''
10
- export const name = $props.name || ''
11
- export const className = $props.className || ''
12
-
13
- const sizeClasses = { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6' }
14
- const baseClasses = 'border-gray-300 dark:border-gray-600 text-indigo-600 dark:text-indigo-500 focus:ring-indigo-600 dark:focus:ring-indigo-500 focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 transition-colors'
15
- const stateClasses = error ? 'border-red-300 dark:border-red-600 text-red-600 dark:text-red-500 focus:ring-red-500 dark:focus:ring-red-400' : ''
16
- const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'
17
-
18
- export const radioClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses}`.trim()
19
- export const labelClasses = `text-sm font-medium ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-900 dark:text-gray-100'} ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`.trim()
20
- export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
21
- export const inputId = `radio-${value || label}`
22
- </script>
23
-
24
- <script client>
25
- const emit = defineEmits()
26
- const isDisabled = {{ disabled }}
27
- const radioValue = {{ value }}
28
- // Reactive prop binding — parent can drive `checked` via signals. See #1704.
29
- const isChecked = useReactiveProp('checked', {{ checked }})
30
-
31
- function onInputChange(event) {
32
- if (isDisabled) {
33
- event.target.checked = isChecked()
34
- return
35
- }
36
- isChecked.set(event.target.checked)
37
- emit('change', { value: radioValue, checked: isChecked() })
38
- }
39
-
40
- defineExpose({ isChecked })
41
- </script>
42
-
43
- <div class="relative flex items-start {{ className }}">
44
- <div class="flex h-6 items-center">
45
- <input
46
- id="{{ inputId }}"
47
- type="radio"
48
- name="{{ name }}"
49
- value="{{ value }}"
50
- :checked="isChecked()"
51
- @if(disabled)disabled@endif
52
- @if(required)required@endif
53
- class="{{ radioClasses }}"
54
- @change="onInputChange($event)"
55
- :aria-invalid="{{ error ? 'true' : 'false' }}"
56
- @if(description)aria-describedby="radio-description"@endif
57
- />
58
- </div>
59
-
60
- @if(label || description)
61
- <div class="ml-3 text-sm leading-6">
62
- @if(label)
63
- <label for="{{ inputId }}" class="{{ labelClasses }}">
64
- {{ label }}
65
- @if(required)
66
- <span class="text-red-500 ml-1">*</span>
67
- @endif
68
- </label>
69
- @endif
70
- @if(description)
71
- <p id="radio-description" class="{{ descriptionClasses }}">
72
- {{ description }}
73
- </p>
74
- @endif
75
- </div>
76
- @endif
77
- </div>
@@ -1,15 +0,0 @@
1
- export { default as Radio } from './Radio.stx'
2
-
3
- export interface RadioProps {
4
- checked?: boolean
5
- onChange?: (value: string, checked: boolean) => void
6
- disabled?: boolean
7
- size?: 'sm' | 'md' | 'lg'
8
- label?: string
9
- description?: string
10
- error?: boolean
11
- required?: boolean
12
- value?: string
13
- name?: string
14
- className?: string
15
- }