@stacksjs/components 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +477 -0
- package/dist/Accordion-x2gjedap.stx +108 -0
- package/dist/Audio-0fk6p9tn.stx +50 -0
- package/dist/Avatar-5m0v0s4x.stx +88 -0
- package/dist/Badge-ynes82vv.stx +70 -0
- package/dist/Breadcrumb-h9n427sk.stx +79 -0
- package/dist/Button-7xtrzn14.stx +89 -0
- package/dist/Calendar-egvx1pma.stx +232 -0
- package/dist/Card-r9w7vy1a.stx +74 -0
- package/dist/Checkbox-m8v46pmx.stx +92 -0
- package/dist/Checkout-vcnnr176.stx +39 -0
- package/dist/CodeBlock-mwex82cm.stx +57 -0
- package/dist/Combobox-npb08vkp.stx +13 -0
- package/dist/ComboboxButton-vcdyq4zw.stx +13 -0
- package/dist/ComboboxInput-c9d2p02m.stx +25 -0
- package/dist/ComboboxOption-7d0h9ash.stx +52 -0
- package/dist/ComboboxOptions-4dtqc0qa.stx +12 -0
- package/dist/CommandPalette-ah00bf8v.stx +39 -0
- package/dist/CommandPaletteItem-2yx0gvtj.stx +32 -0
- package/dist/DefaultPaymentMethod-emw5fg8s.stx +62 -0
- package/dist/Dialog-1w4rz7x0.stx +19 -0
- package/dist/DialogBackdrop-qbm3y5ab.stx +9 -0
- package/dist/DialogDescription-01w5j74b.stx +11 -0
- package/dist/DialogPanel-brsszrrs.stx +16 -0
- package/dist/DialogTitle-3rxhwg21.stx +11 -0
- package/dist/Drawer-yfaz8q7f.stx +137 -0
- package/dist/Dropdown-ng7nx556.stx +24 -0
- package/dist/DropdownButton-vc4zpyrb.stx +23 -0
- package/dist/DropdownItem-z491y23c.stx +43 -0
- package/dist/DropdownItems-7ykf29sj.stx +18 -0
- package/dist/EmailInput-bfshpj92.stx +41 -0
- package/dist/Footer-xdaf02nr.stx +66 -0
- package/dist/Form-z4f7w6r1.stx +209 -0
- package/dist/Hero-9vvp7pxf.stx +25 -0
- package/dist/Image-ktk0451c.stx +197 -0
- package/dist/Installation-33bj4rm7.stx +39 -0
- package/dist/Listbox-xcejcmyc.stx +14 -0
- package/dist/ListboxButton-nx5kmw19.stx +17 -0
- package/dist/ListboxLabel-aky8a73n.stx +11 -0
- package/dist/ListboxOption-6h4hsdz5.stx +57 -0
- package/dist/ListboxOptions-2sacdtm5.stx +16 -0
- package/dist/Login-s2jkvd9y.stx +163 -0
- package/dist/Navigator-tqqdgdkw.stx +138 -0
- package/dist/Notification-sry8egea.stx +71 -0
- package/dist/NumberInput-zm93ddfw.stx +138 -0
- package/dist/Pagination-yza9v4qw.stx +183 -0
- package/dist/PasswordInput-4xnndp5y.stx +155 -0
- package/dist/PaymentMethods-jxba6kek.stx +113 -0
- package/dist/Popover-scbqatjq.stx +24 -0
- package/dist/PopoverButton-rbxhzj4k.stx +23 -0
- package/dist/PopoverPanel-9ng1rm6e.stx +23 -0
- package/dist/Portal-j111yvqp.stx +74 -0
- package/dist/Progress-gbmw3akr.stx +142 -0
- package/dist/Radio-1n9qamv1.stx +81 -0
- package/dist/RadioGroup-12dw2vhk.stx +13 -0
- package/dist/RadioGroupDescription-bjm3mdht.stx +11 -0
- package/dist/RadioGroupLabel-aky8a73n.stx +11 -0
- package/dist/RadioGroupOption-9pcxgwmd.stx +51 -0
- package/dist/SearchInput-g240e2nq.stx +63 -0
- package/dist/Select-p9f94b20.stx +89 -0
- package/dist/Sidebar-gwxw8q38.stx +288 -0
- package/dist/SidebarFooter-887kxret.stx +95 -0
- package/dist/SidebarHeader-qjeyx0hv.stx +100 -0
- package/dist/SidebarItem-4dpwtmb4.stx +118 -0
- package/dist/SidebarSection-kh92fk4m.stx +108 -0
- package/dist/Signup-3nxq5zag.stx +161 -0
- package/dist/Skeleton-g0nx1njm.stx +48 -0
- package/dist/Spinner-w4zj58xp.stx +109 -0
- package/dist/Stepper-rwc5actp.stx +17 -0
- package/dist/StepperStep-h0k657nm.stx +53 -0
- package/dist/SubscriptionCheckout-4cbxdg7w.stx +353 -0
- package/dist/Switch-kjq8qd2p.stx +74 -0
- package/dist/Table-59j9qwp0.stx +14 -0
- package/dist/TableBody-reka2gwv.stx +10 -0
- package/dist/TableCell-j7nh4sgr.stx +10 -0
- package/dist/TableHead-ecbrwpqm.stx +10 -0
- package/dist/TableHeader-jn2shwsv.stx +13 -0
- package/dist/TableRow-xz8rrxhc.stx +11 -0
- package/dist/Tabs-kb6ex6m7.stx +145 -0
- package/dist/Teleport-819cg9zm.stx +101 -0
- package/dist/TextInput-zx9kgr79.stx +146 -0
- package/dist/Textarea-5xvmrb0z.stx +119 -0
- package/dist/Tooltip-5ehqsy49.stx +76 -0
- package/dist/Transition-2j39s044.stx +174 -0
- package/dist/TwoFactorChallenge-2q4gg89m.stx +125 -0
- package/dist/Video-6aq4shh4.stx +45 -0
- package/dist/VirtualList-weh5qtm1.stx +83 -0
- package/dist/VirtualTable-59a1eskc.stx +113 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/composables/index.d.ts +4 -0
- package/dist/composables/index.js +3 -0
- package/dist/composables/useCopyCode.d.ts +19 -0
- package/dist/composables/useDarkMode.d.ts +25 -0
- package/dist/composables/useSEO.d.ts +36 -0
- package/dist/composables/utilities/index.d.ts +5 -0
- package/dist/composables/utilities/useClickOutside.d.ts +28 -0
- package/dist/composables/utilities/useFocusTrap.d.ts +34 -0
- package/dist/composables/utilities/useKeyboard.d.ts +55 -0
- package/dist/composables/utilities/useLocalStorage.d.ts +33 -0
- package/dist/composables/utilities/useMediaQuery.d.ts +64 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +19 -0
- package/dist/ui/accordion/index.d.ts +12 -0
- package/dist/ui/audio/index.d.ts +12 -0
- package/dist/ui/auth/index.d.ts +29 -0
- package/dist/ui/avatar/index.d.ts +11 -0
- package/dist/ui/badge/index.d.ts +9 -0
- package/dist/ui/breadcrumb/index.d.ts +13 -0
- package/dist/ui/button/index.d.ts +45 -0
- package/dist/ui/calendar/index.d.ts +13 -0
- package/dist/ui/card/index.d.ts +12 -0
- package/dist/ui/checkbox/index.d.ts +15 -0
- package/dist/ui/combobox/index.d.ts +35 -0
- package/dist/ui/command-palette/index.d.ts +13 -0
- package/dist/ui/dialog/index.d.ts +27 -0
- package/dist/ui/drawer/index.d.ts +8 -0
- package/dist/ui/dropdown/index.d.ts +25 -0
- package/dist/ui/form/index.d.ts +48 -0
- package/dist/ui/image/index.d.ts +21 -0
- package/dist/ui/input/index.d.ts +73 -0
- package/dist/ui/listbox/index.d.ts +34 -0
- package/dist/ui/navigator/index.d.ts +18 -0
- package/dist/ui/notification/index.d.ts +11 -0
- package/dist/ui/pagination/index.d.ts +10 -0
- package/dist/ui/payment/index.d.ts +53 -0
- package/dist/ui/popover/index.d.ts +19 -0
- package/dist/ui/portal/index.d.ts +5 -0
- package/dist/ui/progress/index.d.ts +11 -0
- package/dist/ui/radio/index.d.ts +14 -0
- package/dist/ui/radio-group/index.d.ts +26 -0
- package/dist/ui/select/index.d.ts +19 -0
- package/dist/ui/sidebar/index.d.ts +129 -0
- package/dist/ui/skeleton/index.d.ts +10 -0
- package/dist/ui/spinner/index.d.ts +8 -0
- package/dist/ui/stepper/index.d.ts +17 -0
- package/dist/ui/storage/index.d.ts +40 -0
- package/dist/ui/switch/index.d.ts +9 -0
- package/dist/ui/table/index.d.ts +29 -0
- package/dist/ui/tabs/index.d.ts +14 -0
- package/dist/ui/teleport/index.d.ts +6 -0
- package/dist/ui/textarea/index.d.ts +19 -0
- package/dist/ui/tooltip/index.d.ts +9 -0
- package/dist/ui/transition/index.d.ts +24 -0
- package/dist/ui/video/index.d.ts +15 -0
- package/dist/ui/virtual-list/index.d.ts +9 -0
- package/dist/ui/virtual-table/index.d.ts +19 -0
- package/dist/utils/accessibility.d.ts +285 -0
- package/dist/utils/animation/easing.d.ts +112 -0
- package/dist/utils/animation/helpers.d.ts +119 -0
- package/dist/utils/animation/index.d.ts +3 -0
- package/dist/utils/animation/keyframes.d.ts +334 -0
- package/dist/utils/error-handling.d.ts +182 -0
- package/dist/utils/highlighter.d.ts +27 -0
- package/dist/utils/highlighter.js +2 -0
- package/dist/utils/i18n.d.ts +245 -0
- package/dist/utils/keep-alive.d.ts +171 -0
- package/dist/utils/lazy-loading.d.ts +174 -0
- package/dist/utils/prop-validation.d.ts +106 -0
- package/dist/utils/theme.d.ts +234 -0
- package/package.json +69 -0
- package/src/components/CodeBlock.stx +57 -0
- package/src/components/Footer.stx +66 -0
- package/src/components/Hero.stx +25 -0
- package/src/components/Installation.stx +39 -0
- package/src/components/index.ts +4 -0
- package/src/composables/index.ts +4 -0
- package/src/composables/useCopyCode.ts +73 -0
- package/src/composables/useDarkMode.ts +100 -0
- package/src/composables/useSEO.ts +229 -0
- package/src/composables/utilities/index.ts +7 -0
- package/src/composables/utilities/useClickOutside.ts +72 -0
- package/src/composables/utilities/useFocusTrap.ts +159 -0
- package/src/composables/utilities/useKeyboard.ts +124 -0
- package/src/composables/utilities/useLocalStorage.ts +132 -0
- package/src/composables/utilities/useMediaQuery.ts +118 -0
- package/src/index.ts +99 -0
- package/src/stx.d.ts +4 -0
- package/src/ui/accordion/Accordion.stx +108 -0
- package/src/ui/accordion/index.ts +14 -0
- package/src/ui/audio/Audio.stx +50 -0
- package/src/ui/audio/README.md +42 -0
- package/src/ui/audio/index.ts +13 -0
- package/src/ui/auth/Login.stx +163 -0
- package/src/ui/auth/README.md +145 -0
- package/src/ui/auth/Signup.stx +161 -0
- package/src/ui/auth/TwoFactorChallenge.stx +125 -0
- package/src/ui/auth/index.ts +32 -0
- package/src/ui/avatar/Avatar.stx +88 -0
- package/src/ui/avatar/index.ts +12 -0
- package/src/ui/badge/Badge.stx +70 -0
- package/src/ui/badge/index.ts +10 -0
- package/src/ui/breadcrumb/Breadcrumb.stx +79 -0
- package/src/ui/breadcrumb/index.ts +15 -0
- package/src/ui/button/Button.stx +89 -0
- package/src/ui/button/README.md +100 -0
- package/src/ui/button/index.ts +85 -0
- package/src/ui/calendar/Calendar.stx +232 -0
- package/src/ui/calendar/README.md +254 -0
- package/src/ui/calendar/index.ts +14 -0
- package/src/ui/card/Card.stx +74 -0
- package/src/ui/card/index.ts +13 -0
- package/src/ui/checkbox/Checkbox.stx +92 -0
- package/src/ui/checkbox/index.ts +16 -0
- package/src/ui/combobox/Combobox.stx +13 -0
- package/src/ui/combobox/ComboboxButton.stx +13 -0
- package/src/ui/combobox/ComboboxInput.stx +25 -0
- package/src/ui/combobox/ComboboxOption.stx +52 -0
- package/src/ui/combobox/ComboboxOptions.stx +12 -0
- package/src/ui/combobox/README.md +154 -0
- package/src/ui/combobox/index.ts +40 -0
- package/src/ui/command-palette/CommandPalette.stx +39 -0
- package/src/ui/command-palette/CommandPaletteItem.stx +32 -0
- package/src/ui/command-palette/README.md +42 -0
- package/src/ui/command-palette/index.ts +15 -0
- package/src/ui/dialog/Dialog.stx +19 -0
- package/src/ui/dialog/DialogBackdrop.stx +9 -0
- package/src/ui/dialog/DialogDescription.stx +11 -0
- package/src/ui/dialog/DialogPanel.stx +16 -0
- package/src/ui/dialog/DialogTitle.stx +11 -0
- package/src/ui/dialog/README.md +133 -0
- package/src/ui/dialog/index.ts +32 -0
- package/src/ui/drawer/Drawer.stx +137 -0
- package/src/ui/drawer/README.md +110 -0
- package/src/ui/drawer/index.ts +9 -0
- package/src/ui/dropdown/Dropdown.stx +24 -0
- package/src/ui/dropdown/DropdownButton.stx +23 -0
- package/src/ui/dropdown/DropdownItem.stx +43 -0
- package/src/ui/dropdown/DropdownItems.stx +18 -0
- package/src/ui/dropdown/README.md +142 -0
- package/src/ui/dropdown/index.ts +29 -0
- package/src/ui/form/Form.stx +209 -0
- package/src/ui/form/index.ts +67 -0
- package/src/ui/heatmap/Heatmap.stx +315 -0
- package/src/ui/image/Image.stx +197 -0
- package/src/ui/image/README.md +171 -0
- package/src/ui/image/index.ts +22 -0
- package/src/ui/input/EmailInput.stx +41 -0
- package/src/ui/input/NumberInput.stx +138 -0
- package/src/ui/input/PasswordInput.stx +155 -0
- package/src/ui/input/SearchInput.stx +63 -0
- package/src/ui/input/TextInput.stx +146 -0
- package/src/ui/input/index.ts +180 -0
- package/src/ui/listbox/Listbox.stx +14 -0
- package/src/ui/listbox/ListboxButton.stx +17 -0
- package/src/ui/listbox/ListboxLabel.stx +11 -0
- package/src/ui/listbox/ListboxOption.stx +57 -0
- package/src/ui/listbox/ListboxOptions.stx +16 -0
- package/src/ui/listbox/README.md +143 -0
- package/src/ui/listbox/index.ts +39 -0
- package/src/ui/navigator/Navigator.stx +138 -0
- package/src/ui/navigator/README.md +352 -0
- package/src/ui/navigator/index.ts +20 -0
- package/src/ui/notification/Notification.stx +71 -0
- package/src/ui/notification/README.md +118 -0
- package/src/ui/notification/index.ts +12 -0
- package/src/ui/pagination/Pagination.stx +183 -0
- package/src/ui/pagination/index.ts +11 -0
- package/src/ui/payment/Checkout.stx +39 -0
- package/src/ui/payment/DefaultPaymentMethod.stx +62 -0
- package/src/ui/payment/PaymentMethods.stx +113 -0
- package/src/ui/payment/README.md +427 -0
- package/src/ui/payment/SubscriptionCheckout.stx +353 -0
- package/src/ui/payment/index.ts +59 -0
- package/src/ui/popover/Popover.stx +24 -0
- package/src/ui/popover/PopoverButton.stx +23 -0
- package/src/ui/popover/PopoverPanel.stx +23 -0
- package/src/ui/popover/README.md +95 -0
- package/src/ui/popover/index.ts +22 -0
- package/src/ui/portal/Portal.stx +74 -0
- package/src/ui/portal/index.ts +6 -0
- package/src/ui/progress/Progress.stx +142 -0
- package/src/ui/progress/index.ts +12 -0
- package/src/ui/radio/Radio.stx +81 -0
- package/src/ui/radio/index.ts +15 -0
- package/src/ui/radio-group/README.md +145 -0
- package/src/ui/radio-group/RadioGroup.stx +13 -0
- package/src/ui/radio-group/RadioGroupDescription.stx +11 -0
- package/src/ui/radio-group/RadioGroupLabel.stx +11 -0
- package/src/ui/radio-group/RadioGroupOption.stx +51 -0
- package/src/ui/radio-group/index.ts +30 -0
- package/src/ui/select/README.md +204 -0
- package/src/ui/select/Select.stx +89 -0
- package/src/ui/select/index.ts +21 -0
- package/src/ui/sidebar/Sidebar.stx +288 -0
- package/src/ui/sidebar/SidebarFooter.stx +95 -0
- package/src/ui/sidebar/SidebarHeader.stx +100 -0
- package/src/ui/sidebar/SidebarItem.stx +118 -0
- package/src/ui/sidebar/SidebarSection.stx +108 -0
- package/src/ui/sidebar/index.ts +175 -0
- package/src/ui/skeleton/Skeleton.stx +48 -0
- package/src/ui/skeleton/index.ts +11 -0
- package/src/ui/spinner/Spinner.stx +109 -0
- package/src/ui/spinner/index.ts +9 -0
- package/src/ui/stepper/README.md +36 -0
- package/src/ui/stepper/Stepper.stx +17 -0
- package/src/ui/stepper/StepperStep.stx +53 -0
- package/src/ui/stepper/index.ts +19 -0
- package/src/ui/storage/README.md +193 -0
- package/src/ui/storage/index.ts +347 -0
- package/src/ui/switch/README.md +133 -0
- package/src/ui/switch/Switch.stx +74 -0
- package/src/ui/switch/index.ts +10 -0
- package/src/ui/table/README.md +39 -0
- package/src/ui/table/Table.stx +14 -0
- package/src/ui/table/TableBody.stx +10 -0
- package/src/ui/table/TableCell.stx +10 -0
- package/src/ui/table/TableHead.stx +10 -0
- package/src/ui/table/TableHeader.stx +13 -0
- package/src/ui/table/TableRow.stx +11 -0
- package/src/ui/table/index.ts +35 -0
- package/src/ui/tabs/Tabs.stx +145 -0
- package/src/ui/tabs/index.ts +16 -0
- package/src/ui/teleport/Teleport.stx +101 -0
- package/src/ui/teleport/index.ts +7 -0
- package/src/ui/textarea/Textarea.stx +119 -0
- package/src/ui/textarea/index.ts +20 -0
- package/src/ui/tooltip/Tooltip.stx +76 -0
- package/src/ui/tooltip/index.ts +10 -0
- package/src/ui/transition/README.md +30 -0
- package/src/ui/transition/Transition.stx +174 -0
- package/src/ui/transition/index.ts +25 -0
- package/src/ui/video/README.md +48 -0
- package/src/ui/video/Video.stx +45 -0
- package/src/ui/video/index.ts +16 -0
- package/src/ui/virtual-list/VirtualList.stx +83 -0
- package/src/ui/virtual-list/index.ts +10 -0
- package/src/ui/virtual-table/VirtualTable.stx +113 -0
- package/src/ui/virtual-table/index.ts +21 -0
- package/src/utils/PROP_VALIDATION.md +458 -0
- package/src/utils/THEME_SYSTEM.md +702 -0
- package/src/utils/accessibility.ts +841 -0
- package/src/utils/animation/easing.ts +368 -0
- package/src/utils/animation/helpers.ts +223 -0
- package/src/utils/animation/index.ts +5 -0
- package/src/utils/animation/keyframes.ts +230 -0
- package/src/utils/error-handling.ts +473 -0
- package/src/utils/highlighter.ts +93 -0
- package/src/utils/i18n.ts +634 -0
- package/src/utils/keep-alive.ts +818 -0
- package/src/utils/lazy-loading.ts +530 -0
- package/src/utils/prop-validation.ts +478 -0
- package/src/utils/theme.ts +626 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<script>
|
|
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
|
+
// Calculate percentage
|
|
12
|
+
const percentage = Math.min(Math.max((value / max) * 100, 0), 100)
|
|
13
|
+
|
|
14
|
+
// Size classes for linear
|
|
15
|
+
const linearSizeClasses = {
|
|
16
|
+
sm: 'h-1',
|
|
17
|
+
md: 'h-2',
|
|
18
|
+
lg: 'h-3',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Size classes for circular
|
|
22
|
+
const circularSizeClasses = {
|
|
23
|
+
sm: 'w-12 h-12',
|
|
24
|
+
md: 'w-16 h-16',
|
|
25
|
+
lg: 'w-24 h-24',
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Color classes
|
|
29
|
+
const colorClasses = {
|
|
30
|
+
primary: 'bg-blue-600 dark:bg-blue-500',
|
|
31
|
+
secondary: 'bg-purple-600 dark:bg-purple-500',
|
|
32
|
+
success: 'bg-green-600 dark:bg-green-500',
|
|
33
|
+
warning: 'bg-yellow-600 dark:bg-yellow-500',
|
|
34
|
+
danger: 'bg-red-600 dark:bg-red-500',
|
|
35
|
+
info: 'bg-cyan-600 dark:bg-cyan-500',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Circular SVG values
|
|
39
|
+
const circularSize = size === 'sm' ? 48 : size === 'md' ? 64 : 96
|
|
40
|
+
const strokeWidth = size === 'sm' ? 4 : size === 'md' ? 6 : 8
|
|
41
|
+
const radius = (circularSize - strokeWidth) / 2
|
|
42
|
+
const circumference = 2 * Math.PI * radius
|
|
43
|
+
const strokeDashoffset = indeterminate ? 0 : circumference - (percentage / 100) * circumference
|
|
44
|
+
|
|
45
|
+
export const containerClasses = variant === 'linear'
|
|
46
|
+
? `w-full ${className}`.trim()
|
|
47
|
+
: `inline-flex items-center justify-center ${className}`.trim()
|
|
48
|
+
|
|
49
|
+
export const linearTrackClasses = `w-full ${linearSizeClasses[size]} bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden`.trim()
|
|
50
|
+
export const linearBarClasses = `h-full ${colorClasses[color]} transition-all duration-300 ease-in-out ${indeterminate ? 'animate-progress-indeterminate' : ''}`.trim()
|
|
51
|
+
export const labelClasses = `text-sm font-medium text-gray-700 dark:text-gray-300 mb-2`.trim()
|
|
52
|
+
export const circularTrackColor = 'stroke-gray-200 dark:stroke-gray-700'
|
|
53
|
+
export const circularBarColor = color === 'primary' ? 'stroke-blue-600 dark:stroke-blue-500' :
|
|
54
|
+
color === 'secondary' ? 'stroke-purple-600 dark:stroke-purple-500' :
|
|
55
|
+
color === 'success' ? 'stroke-green-600 dark:stroke-green-500' :
|
|
56
|
+
color === 'warning' ? 'stroke-yellow-600 dark:stroke-yellow-500' :
|
|
57
|
+
color === 'danger' ? 'stroke-red-600 dark:stroke-red-500' :
|
|
58
|
+
'stroke-cyan-600 dark:stroke-cyan-500'
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
@if(variant === 'linear')
|
|
62
|
+
<div class="{{ containerClasses }}">
|
|
63
|
+
@if(showLabel)
|
|
64
|
+
<div class="flex items-center justify-between mb-2">
|
|
65
|
+
<span class="{{ labelClasses }}">{{ Math.round(percentage) }}%</span>
|
|
66
|
+
</div>
|
|
67
|
+
@endif
|
|
68
|
+
|
|
69
|
+
<div
|
|
70
|
+
class="{{ linearTrackClasses }}"
|
|
71
|
+
role="progressbar"
|
|
72
|
+
aria-valuenow="{{ value }}"
|
|
73
|
+
aria-valuemin="0"
|
|
74
|
+
aria-valuemax="{{ max }}"
|
|
75
|
+
>
|
|
76
|
+
<div
|
|
77
|
+
class="{{ linearBarClasses }}"
|
|
78
|
+
style="width: {{ indeterminate ? '30%' : percentage + '%' }}"
|
|
79
|
+
></div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
@else
|
|
83
|
+
<!-- Circular Progress -->
|
|
84
|
+
<div class="{{ containerClasses }}">
|
|
85
|
+
<div class="{{ circularSizeClasses[size] }} relative">
|
|
86
|
+
<svg
|
|
87
|
+
class="transform -rotate-90"
|
|
88
|
+
width="{{ circularSize }}"
|
|
89
|
+
height="{{ circularSize }}"
|
|
90
|
+
role="progressbar"
|
|
91
|
+
aria-valuenow="{{ value }}"
|
|
92
|
+
aria-valuemin="0"
|
|
93
|
+
aria-valuemax="{{ max }}"
|
|
94
|
+
>
|
|
95
|
+
<!-- Background circle -->
|
|
96
|
+
<circle
|
|
97
|
+
class="{{ circularTrackColor }}"
|
|
98
|
+
cx="{{ circularSize / 2 }}"
|
|
99
|
+
cy="{{ circularSize / 2 }}"
|
|
100
|
+
r="{{ radius }}"
|
|
101
|
+
stroke-width="{{ strokeWidth }}"
|
|
102
|
+
fill="none"
|
|
103
|
+
/>
|
|
104
|
+
<!-- Progress circle -->
|
|
105
|
+
<circle
|
|
106
|
+
class="{{ circularBarColor }} transition-all duration-300 ease-in-out {{ indeterminate ? 'animate-spin' : '' }}"
|
|
107
|
+
cx="{{ circularSize / 2 }}"
|
|
108
|
+
cy="{{ circularSize / 2 }}"
|
|
109
|
+
r="{{ radius }}"
|
|
110
|
+
stroke-width="{{ strokeWidth }}"
|
|
111
|
+
fill="none"
|
|
112
|
+
stroke-dasharray="{{ circumference }}"
|
|
113
|
+
stroke-dashoffset="{{ strokeDashoffset }}"
|
|
114
|
+
stroke-linecap="round"
|
|
115
|
+
/>
|
|
116
|
+
</svg>
|
|
117
|
+
|
|
118
|
+
@if(showLabel)
|
|
119
|
+
<div class="absolute inset-0 flex items-center justify-center">
|
|
120
|
+
<span class="text-sm font-semibold text-gray-700 dark:text-gray-300">
|
|
121
|
+
{{ Math.round(percentage) }}%
|
|
122
|
+
</span>
|
|
123
|
+
</div>
|
|
124
|
+
@endif
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
@endif
|
|
128
|
+
|
|
129
|
+
<style>
|
|
130
|
+
@keyframes progress-indeterminate {
|
|
131
|
+
0% {
|
|
132
|
+
transform: translateX(-100%);
|
|
133
|
+
}
|
|
134
|
+
100% {
|
|
135
|
+
transform: translateX(400%);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.animate-progress-indeterminate {
|
|
140
|
+
animation: progress-indeterminate 1.5s ease-in-out infinite;
|
|
141
|
+
}
|
|
142
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const checked = $props.checked || false
|
|
3
|
+
export const onChange = $props.onChange || (() => {})
|
|
4
|
+
export const disabled = $props.disabled || false
|
|
5
|
+
export const size = $props.size || 'md'
|
|
6
|
+
export const label = $props.label || ''
|
|
7
|
+
export const description = $props.description || ''
|
|
8
|
+
export const error = $props.error || false
|
|
9
|
+
export const required = $props.required || false
|
|
10
|
+
export const value = $props.value || ''
|
|
11
|
+
export const name = $props.name || ''
|
|
12
|
+
export const className = $props.className || ''
|
|
13
|
+
|
|
14
|
+
// Size classes
|
|
15
|
+
const sizeClasses = {
|
|
16
|
+
sm: 'h-4 w-4',
|
|
17
|
+
md: 'h-5 w-5',
|
|
18
|
+
lg: 'h-6 w-6',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Base classes for radio
|
|
22
|
+
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'
|
|
23
|
+
|
|
24
|
+
const stateClasses = error
|
|
25
|
+
? 'border-red-300 dark:border-red-600 text-red-600 dark:text-red-500 focus:ring-red-500 dark:focus:ring-red-400'
|
|
26
|
+
: ''
|
|
27
|
+
|
|
28
|
+
const disabledClasses = disabled
|
|
29
|
+
? 'opacity-50 cursor-not-allowed'
|
|
30
|
+
: 'cursor-pointer'
|
|
31
|
+
|
|
32
|
+
export const radioClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses}`.trim()
|
|
33
|
+
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()
|
|
34
|
+
export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<div class="relative flex items-start {{ className }}">
|
|
38
|
+
<div class="flex h-6 items-center">
|
|
39
|
+
<input
|
|
40
|
+
id="radio-{{ value || label }}"
|
|
41
|
+
type="radio"
|
|
42
|
+
name="{{ name }}"
|
|
43
|
+
value="{{ value }}"
|
|
44
|
+
checked="{{ checked }}"
|
|
45
|
+
disabled="{{ disabled }}"
|
|
46
|
+
required="{{ required }}"
|
|
47
|
+
class="{{ radioClasses }}"
|
|
48
|
+
onchange="handleChange(event)"
|
|
49
|
+
aria-invalid="{{ error ? 'true' : 'false' }}"
|
|
50
|
+
@if(description)aria-describedby="radio-description"@endif
|
|
51
|
+
/>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
@if(label || description)
|
|
55
|
+
<div class="ml-3 text-sm leading-6">
|
|
56
|
+
@if(label)
|
|
57
|
+
<label for="radio-{{ value || label }}" class="{{ labelClasses }}">
|
|
58
|
+
{{ label }}
|
|
59
|
+
@if(required)
|
|
60
|
+
<span class="text-red-500 ml-1">*</span>
|
|
61
|
+
@endif
|
|
62
|
+
</label>
|
|
63
|
+
@endif
|
|
64
|
+
@if(description)
|
|
65
|
+
<p id="radio-description" class="{{ descriptionClasses }}">
|
|
66
|
+
{{ description }}
|
|
67
|
+
</p>
|
|
68
|
+
@endif
|
|
69
|
+
</div>
|
|
70
|
+
@endif
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<script>
|
|
74
|
+
function handleChange(event) {
|
|
75
|
+
const isChecked = event.target.checked
|
|
76
|
+
|
|
77
|
+
if (!disabled && onChange) {
|
|
78
|
+
onChange(value, isChecked)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
</script>
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Radio Group Component
|
|
2
|
+
|
|
3
|
+
A set of checkable buttons (radio buttons) where only one can be checked at a time.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @stacksjs/components
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```stx
|
|
14
|
+
<script>
|
|
15
|
+
export let selected = 'option1'
|
|
16
|
+
|
|
17
|
+
export function handleChange(value) {
|
|
18
|
+
selected = value
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
@component('RadioGroup', { value: selected, onChange: handleChange })
|
|
23
|
+
@component('RadioGroupLabel')
|
|
24
|
+
Choose an option
|
|
25
|
+
@endcomponent
|
|
26
|
+
|
|
27
|
+
@component('RadioGroupOption', { value: 'option1', currentValue: selected, onChange: handleChange })
|
|
28
|
+
Option 1
|
|
29
|
+
@endcomponent
|
|
30
|
+
|
|
31
|
+
@component('RadioGroupOption', { value: 'option2', currentValue: selected, onChange: handleChange })
|
|
32
|
+
Option 2
|
|
33
|
+
@endcomponent
|
|
34
|
+
@endcomponent
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Props
|
|
38
|
+
|
|
39
|
+
### RadioGroup
|
|
40
|
+
| Prop | Type | Default | Description |
|
|
41
|
+
|------|------|---------|-------------|
|
|
42
|
+
| `value` | `any` | - | Currently selected value |
|
|
43
|
+
| `onChange` | `(value: any) => void` | - | Change handler |
|
|
44
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
45
|
+
| `as` | `string` | `'div'` | HTML element to render |
|
|
46
|
+
|
|
47
|
+
### RadioGroupLabel
|
|
48
|
+
| Prop | Type | Default | Description |
|
|
49
|
+
|------|------|---------|-------------|
|
|
50
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
51
|
+
| `as` | `string` | `'label'` | HTML element to render |
|
|
52
|
+
|
|
53
|
+
### RadioGroupOption
|
|
54
|
+
| Prop | Type | Default | Description |
|
|
55
|
+
|------|------|---------|-------------|
|
|
56
|
+
| `value` | `any` | - | Option value |
|
|
57
|
+
| `disabled` | `boolean` | `false` | Disable the option |
|
|
58
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
59
|
+
| `as` | `string` | `'div'` | HTML element to render |
|
|
60
|
+
| `currentValue` | `any` | - | Current selected value |
|
|
61
|
+
| `onChange` | `(value: any) => void` | - | Change handler |
|
|
62
|
+
|
|
63
|
+
### RadioGroupDescription
|
|
64
|
+
| Prop | Type | Default | Description |
|
|
65
|
+
|------|------|---------|-------------|
|
|
66
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
67
|
+
| `as` | `string` | `'span'` | HTML element to render |
|
|
68
|
+
|
|
69
|
+
## Examples
|
|
70
|
+
|
|
71
|
+
### Server Plans
|
|
72
|
+
|
|
73
|
+
```stx
|
|
74
|
+
<script>
|
|
75
|
+
export const plans = [
|
|
76
|
+
{ name: 'Startup', ram: '12GB', cpus: '6 CPUs', disk: '160 GB SSD' },
|
|
77
|
+
{ name: 'Business', ram: '16GB', cpus: '8 CPUs', disk: '512 GB SSD' },
|
|
78
|
+
{ name: 'Enterprise', ram: '32GB', cpus: '12 CPUs', disk: '1024 GB SSD' }
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
export let selected = plans[0]
|
|
82
|
+
|
|
83
|
+
export function handleChange(plan) {
|
|
84
|
+
selected = plan
|
|
85
|
+
}
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
@component('RadioGroup', { value: selected, onChange: handleChange })
|
|
89
|
+
@component('RadioGroupLabel', { className: 'sr-only' })
|
|
90
|
+
Server size
|
|
91
|
+
@endcomponent
|
|
92
|
+
|
|
93
|
+
<div class="space-y-2">
|
|
94
|
+
@foreach(plan in plans)
|
|
95
|
+
@component('RadioGroupOption', {
|
|
96
|
+
value: plan,
|
|
97
|
+
currentValue: selected,
|
|
98
|
+
onChange: handleChange
|
|
99
|
+
})
|
|
100
|
+
<div class="w-full flex items-center justify-between">
|
|
101
|
+
<div class="flex items-center">
|
|
102
|
+
<div class="text-sm">
|
|
103
|
+
@component('RadioGroupLabel', {
|
|
104
|
+
className: 'font-medium'
|
|
105
|
+
})
|
|
106
|
+
{{ plan.name }}
|
|
107
|
+
@endcomponent
|
|
108
|
+
|
|
109
|
+
@component('RadioGroupDescription')
|
|
110
|
+
{{ plan.ram }}/{{ plan.cpus }} · {{ plan.disk }}
|
|
111
|
+
@endcomponent
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
@if(selected === plan)
|
|
116
|
+
<svg class="h-6 w-6 shrink-0 text-white" viewBox="0 0 24 24" fill="none">
|
|
117
|
+
<circle cx="12" cy="12" r="12" fill="#fff" fill-opacity="0.2" />
|
|
118
|
+
<path d="M7 13l3 3 7-7" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
119
|
+
</svg>
|
|
120
|
+
@endif
|
|
121
|
+
</div>
|
|
122
|
+
@endcomponent
|
|
123
|
+
@endforeach
|
|
124
|
+
</div>
|
|
125
|
+
@endcomponent
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### With Disabled Option
|
|
129
|
+
|
|
130
|
+
```stx
|
|
131
|
+
@component('RadioGroupOption', { value: 'disabled', disabled: true })
|
|
132
|
+
This option is disabled
|
|
133
|
+
@endcomponent
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Features
|
|
137
|
+
|
|
138
|
+
- Single selection from multiple options
|
|
139
|
+
- Keyboard navigation
|
|
140
|
+
- Focus management
|
|
141
|
+
- Dark mode support
|
|
142
|
+
- Accessible (WAI-ARIA)
|
|
143
|
+
- Disabled state support
|
|
144
|
+
- Active state on focus
|
|
145
|
+
- Customizable styling
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const value = $props.value
|
|
3
|
+
export const onChange = $props.onChange
|
|
4
|
+
export const className = $props.className || ''
|
|
5
|
+
export const as = $props.as || 'div'
|
|
6
|
+
|
|
7
|
+
const baseClasses = 'w-full'
|
|
8
|
+
const groupClasses = `${baseClasses} ${className}`.trim()
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<component :is="{{ as }}" class="{{ groupClasses }}" role="radiogroup">
|
|
12
|
+
<slot :value="value" :onChange="onChange" />
|
|
13
|
+
</component>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const className = $props.className || ''
|
|
3
|
+
export const as = $props.as || 'span'
|
|
4
|
+
|
|
5
|
+
const baseClasses = 'inline 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>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const className = $props.className || ''
|
|
3
|
+
export const as = $props.as || 'label'
|
|
4
|
+
|
|
5
|
+
const baseClasses = 'block text-sm font-medium text-neutral-900 dark:text-white'
|
|
6
|
+
const labelClasses = `${baseClasses} ${className}`.trim()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<component :is="{{ as }}" class="{{ labelClasses }}">
|
|
10
|
+
<slot />
|
|
11
|
+
</component>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const value = $props.value
|
|
3
|
+
export const disabled = $props.disabled || false
|
|
4
|
+
export const className = $props.className || ''
|
|
5
|
+
export const as = $props.as || 'div'
|
|
6
|
+
export const currentValue = $props.currentValue
|
|
7
|
+
export const onChange = $props.onChange
|
|
8
|
+
|
|
9
|
+
export let active = false
|
|
10
|
+
export const checked = currentValue === value
|
|
11
|
+
|
|
12
|
+
const baseClasses = 'relative flex cursor-pointer rounded-lg px-5 py-4 shadow-md focus:outline-none transition-all'
|
|
13
|
+
const stateClasses = checked
|
|
14
|
+
? 'bg-blue-900 bg-opacity-75 text-white dark:bg-blue-800'
|
|
15
|
+
: 'bg-white dark:bg-neutral-800'
|
|
16
|
+
const activeClasses = active
|
|
17
|
+
? 'ring-2 ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-300 dark:ring-offset-blue-700'
|
|
18
|
+
: ''
|
|
19
|
+
const disabledClasses = disabled
|
|
20
|
+
? 'opacity-50 cursor-not-allowed'
|
|
21
|
+
: ''
|
|
22
|
+
|
|
23
|
+
const optionClasses = `${baseClasses} ${stateClasses} ${activeClasses} ${disabledClasses} ${className}`.trim()
|
|
24
|
+
|
|
25
|
+
export function handleClick() {
|
|
26
|
+
if (disabled) return
|
|
27
|
+
onChange?.(value)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function handleFocus() {
|
|
31
|
+
if (!disabled) active = true
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function handleBlur() {
|
|
35
|
+
active = false
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<component
|
|
40
|
+
:is="{{ as }}"
|
|
41
|
+
class="{{ optionClasses }}"
|
|
42
|
+
role="radio"
|
|
43
|
+
aria-checked="{{ checked ? 'true' : 'false' }}"
|
|
44
|
+
@if(disabled)aria-disabled="true"@endif
|
|
45
|
+
tabindex="{{ disabled ? '-1' : '0' }}"
|
|
46
|
+
@click="handleClick"
|
|
47
|
+
@focus="handleFocus"
|
|
48
|
+
@blur="handleBlur"
|
|
49
|
+
>
|
|
50
|
+
<slot :active="active" :checked="checked" :disabled="disabled" />
|
|
51
|
+
</component>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export { default as RadioGroup } from './RadioGroup.stx'
|
|
2
|
+
export { default as RadioGroupDescription } from './RadioGroupDescription.stx'
|
|
3
|
+
export { default as RadioGroupLabel } from './RadioGroupLabel.stx'
|
|
4
|
+
export { default as RadioGroupOption } from './RadioGroupOption.stx'
|
|
5
|
+
|
|
6
|
+
export interface RadioGroupProps {
|
|
7
|
+
value?: any
|
|
8
|
+
onChange?: (value: any) => void
|
|
9
|
+
className?: string
|
|
10
|
+
as?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface RadioGroupLabelProps {
|
|
14
|
+
className?: string
|
|
15
|
+
as?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface RadioGroupOptionProps {
|
|
19
|
+
value: any
|
|
20
|
+
disabled?: boolean
|
|
21
|
+
className?: string
|
|
22
|
+
as?: string
|
|
23
|
+
currentValue?: any
|
|
24
|
+
onChange?: (value: any) => void
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface RadioGroupDescriptionProps {
|
|
28
|
+
className?: string
|
|
29
|
+
as?: string
|
|
30
|
+
}
|