@stacksjs/components 0.2.92 → 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/{Sidebar-yb115a2w.stx → Sidebar-4hn7vw4n.stx} +18 -0
- package/dist/index.js +5 -5
- 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 -458
- 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/avatar/Avatar.stx
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const src = $props.src || ''
|
|
3
|
-
export const alt = $props.alt || ''
|
|
4
|
-
export const initials = $props.initials || ''
|
|
5
|
-
export const size = $props.size || 'md'
|
|
6
|
-
export const shape = $props.shape || 'circle'
|
|
7
|
-
export const status = $props.status || ''
|
|
8
|
-
export const className = $props.className || ''
|
|
9
|
-
|
|
10
|
-
const sizeClasses = {
|
|
11
|
-
xs: 'w-6 h-6 text-xs',
|
|
12
|
-
sm: 'w-8 h-8 text-sm',
|
|
13
|
-
md: 'w-10 h-10 text-base',
|
|
14
|
-
lg: 'w-12 h-12 text-lg',
|
|
15
|
-
xl: 'w-16 h-16 text-xl',
|
|
16
|
-
'2xl': 'w-20 h-20 text-2xl',
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const shapeClasses = { circle: 'rounded-full', square: 'rounded-md' }
|
|
20
|
-
|
|
21
|
-
const statusSizeClasses = {
|
|
22
|
-
xs: 'w-1.5 h-1.5 border',
|
|
23
|
-
sm: 'w-2 h-2 border',
|
|
24
|
-
md: 'w-2.5 h-2.5 border-2',
|
|
25
|
-
lg: 'w-3 h-3 border-2',
|
|
26
|
-
xl: 'w-3.5 h-3.5 border-2',
|
|
27
|
-
'2xl': 'w-4 h-4 border-2',
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const statusColorClasses = {
|
|
31
|
-
online: 'bg-green-500 dark:bg-green-400',
|
|
32
|
-
offline: 'bg-gray-400 dark:bg-gray-600',
|
|
33
|
-
away: 'bg-yellow-500 dark:bg-yellow-400',
|
|
34
|
-
busy: 'bg-red-500 dark:bg-red-400',
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export const containerClasses = `relative inline-block ${className}`.trim()
|
|
38
|
-
export const avatarClasses = `flex items-center justify-center overflow-hidden bg-gray-200 dark:bg-gray-700 ${sizeClasses[size]} ${shapeClasses[shape]}`.trim()
|
|
39
|
-
export const imageClasses = `w-full h-full object-cover`.trim()
|
|
40
|
-
export const initialsClasses = `font-medium text-gray-600 dark:text-gray-300 uppercase select-none`.trim()
|
|
41
|
-
export const statusClasses = status ? `absolute bottom-0 right-0 ${statusSizeClasses[size]} ${statusColorClasses[status]} ${shapeClasses[shape]} border-white dark:border-gray-900`.trim() : ''
|
|
42
|
-
export const displayInitials = initials || (alt ? alt.split(' ').map(n => n[0]).join('').substring(0, 2) : '?')
|
|
43
|
-
</script>
|
|
44
|
-
|
|
45
|
-
<script client>
|
|
46
|
-
const emit = defineEmits()
|
|
47
|
-
const imageError = state(false)
|
|
48
|
-
const hasSrc = {{ !!src }}
|
|
49
|
-
|
|
50
|
-
function onImageError(event) {
|
|
51
|
-
imageError.set(true)
|
|
52
|
-
emit('error', event)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const showImage = derived(() => hasSrc && !imageError())
|
|
56
|
-
</script>
|
|
57
|
-
|
|
58
|
-
<div class="{{ containerClasses }}">
|
|
59
|
-
<div class="{{ avatarClasses }}">
|
|
60
|
-
<img
|
|
61
|
-
:show="showImage()"
|
|
62
|
-
src="{{ src }}"
|
|
63
|
-
alt="{{ alt }}"
|
|
64
|
-
class="{{ imageClasses }}"
|
|
65
|
-
@error="onImageError($event)"
|
|
66
|
-
/>
|
|
67
|
-
<span :show="!showImage()" class="{{ initialsClasses }}">{{ displayInitials }}</span>
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
@if(status)
|
|
71
|
-
<span
|
|
72
|
-
class="{{ statusClasses }}"
|
|
73
|
-
role="status"
|
|
74
|
-
aria-label="{{ status }}"
|
|
75
|
-
></span>
|
|
76
|
-
@endif
|
|
77
|
-
</div>
|
package/src/ui/avatar/index.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export { default as Avatar } from './Avatar.stx'
|
|
2
|
-
|
|
3
|
-
export interface AvatarProps {
|
|
4
|
-
src?: string
|
|
5
|
-
alt?: string
|
|
6
|
-
initials?: string
|
|
7
|
-
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
|
8
|
-
shape?: 'circle' | 'square'
|
|
9
|
-
status?: 'online' | 'offline' | 'away' | 'busy' | ''
|
|
10
|
-
onError?: (event: Event) => void
|
|
11
|
-
className?: string
|
|
12
|
-
}
|
package/src/ui/badge/Badge.stx
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const variant = $props.variant || 'default'
|
|
3
|
-
export const size = $props.size || 'md'
|
|
4
|
-
export const dot = $props.dot || false
|
|
5
|
-
export const removable = $props.removable || false
|
|
6
|
-
export const className = $props.className || ''
|
|
7
|
-
|
|
8
|
-
const variantClasses = {
|
|
9
|
-
default: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300',
|
|
10
|
-
primary: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200',
|
|
11
|
-
secondary: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200',
|
|
12
|
-
success: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
|
13
|
-
warning: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',
|
|
14
|
-
danger: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
|
|
15
|
-
info: 'bg-cyan-100 text-cyan-800 dark:bg-cyan-900 dark:text-cyan-200',
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const sizeClasses = { sm: 'px-2 py-0.5 text-xs', md: 'px-2.5 py-0.5 text-sm', lg: 'px-3 py-1 text-base' }
|
|
19
|
-
|
|
20
|
-
const dotColorClasses = {
|
|
21
|
-
default: 'bg-gray-500 dark:bg-gray-400',
|
|
22
|
-
primary: 'bg-blue-500 dark:bg-blue-400',
|
|
23
|
-
secondary: 'bg-purple-500 dark:bg-purple-400',
|
|
24
|
-
success: 'bg-green-500 dark:bg-green-400',
|
|
25
|
-
warning: 'bg-yellow-500 dark:bg-yellow-400',
|
|
26
|
-
danger: 'bg-red-500 dark:bg-red-400',
|
|
27
|
-
info: 'bg-cyan-500 dark:bg-cyan-400',
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export const badgeClasses = `inline-flex items-center gap-1.5 font-medium rounded-full ${variantClasses[variant]} ${sizeClasses[size]} ${className}`.trim()
|
|
31
|
-
export const dotClasses = `w-2 h-2 rounded-full ${dotColorClasses[variant]}`.trim()
|
|
32
|
-
export const removeButtonClasses = `ml-0.5 -mr-1 text-current hover:bg-black hover:bg-opacity-10 dark:hover:bg-white dark:hover:bg-opacity-10 rounded-full p-0.5 transition-colors duration-150`.trim()
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<script client>
|
|
36
|
-
const emit = defineEmits()
|
|
37
|
-
|
|
38
|
-
function onRemove() {
|
|
39
|
-
emit('remove')
|
|
40
|
-
}
|
|
41
|
-
</script>
|
|
42
|
-
|
|
43
|
-
<span class="{{ badgeClasses }}" role="status">
|
|
44
|
-
@if(dot)
|
|
45
|
-
<span class="{{ dotClasses }}" aria-hidden="true"></span>
|
|
46
|
-
@endif
|
|
47
|
-
|
|
48
|
-
<slot />
|
|
49
|
-
|
|
50
|
-
@if(removable)
|
|
51
|
-
<button
|
|
52
|
-
type="button"
|
|
53
|
-
@click="onRemove()"
|
|
54
|
-
class="{{ removeButtonClasses }}"
|
|
55
|
-
aria-label="Remove"
|
|
56
|
-
>
|
|
57
|
-
<svg class="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
58
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
59
|
-
</svg>
|
|
60
|
-
</button>
|
|
61
|
-
@endif
|
|
62
|
-
</span>
|
package/src/ui/badge/index.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export { default as Badge } from './Badge.stx'
|
|
2
|
-
|
|
3
|
-
export interface BadgeProps {
|
|
4
|
-
variant?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info'
|
|
5
|
-
size?: 'sm' | 'md' | 'lg'
|
|
6
|
-
dot?: boolean
|
|
7
|
-
removable?: boolean
|
|
8
|
-
onRemove?: () => void
|
|
9
|
-
className?: string
|
|
10
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const items = $props.items || []
|
|
3
|
-
export const separator = $props.separator || '/'
|
|
4
|
-
export const maxItems = $props.maxItems || 0
|
|
5
|
-
export const className = $props.className || ''
|
|
6
|
-
|
|
7
|
-
// Handle collapse if maxItems is set
|
|
8
|
-
let displayItems = items
|
|
9
|
-
if (maxItems > 0 && items.length > maxItems) {
|
|
10
|
-
const firstItems = items.slice(0, 1)
|
|
11
|
-
const lastItems = items.slice(-(maxItems - 1))
|
|
12
|
-
displayItems = [...firstItems, { label: '...', href: '#', collapsed: true }, ...lastItems]
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Separator element
|
|
16
|
-
const separatorElement = separator === '/' ? '/' :
|
|
17
|
-
separator === '>' ? '›' :
|
|
18
|
-
separator === 'arrow' ? `<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /></svg>` :
|
|
19
|
-
separator
|
|
20
|
-
|
|
21
|
-
export const breadcrumbClasses = `flex items-center flex-wrap gap-2 text-sm ${className}`.trim()
|
|
22
|
-
export const itemClasses = `text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 transition-colors duration-150`.trim()
|
|
23
|
-
export const activeItemClasses = `text-gray-900 dark:text-gray-100 font-medium`.trim()
|
|
24
|
-
export const separatorClasses = `text-gray-400 dark:text-gray-600 select-none`.trim()
|
|
25
|
-
export const collapsedClasses = `text-gray-400 dark:text-gray-600 cursor-default`.trim()
|
|
26
|
-
</script>
|
|
27
|
-
|
|
28
|
-
<nav class="{{ breadcrumbClasses }}" aria-label="Breadcrumb">
|
|
29
|
-
<ol class="flex items-center gap-2">
|
|
30
|
-
@foreach(item in displayItems)
|
|
31
|
-
<li class="flex items-center gap-2">
|
|
32
|
-
@if(item.collapsed)
|
|
33
|
-
<!-- Collapsed indicator -->
|
|
34
|
-
<span class="{{ collapsedClasses }}">{{ item.label }}</span>
|
|
35
|
-
@else
|
|
36
|
-
@if($loop.last)
|
|
37
|
-
<!-- Last item (current page) -->
|
|
38
|
-
<span class="{{ activeItemClasses }}" aria-current="page">
|
|
39
|
-
@if(item.icon)
|
|
40
|
-
<span class="inline-flex items-center gap-1.5">
|
|
41
|
-
<span innerHTML="{!! item.icon !!}"></span>
|
|
42
|
-
<span>{{ item.label }}</span>
|
|
43
|
-
</span>
|
|
44
|
-
@else
|
|
45
|
-
{{ item.label }}
|
|
46
|
-
@endif
|
|
47
|
-
</span>
|
|
48
|
-
@else
|
|
49
|
-
<!-- Link item -->
|
|
50
|
-
<a
|
|
51
|
-
href="{{ item.href }}"
|
|
52
|
-
class="{{ itemClasses }}"
|
|
53
|
-
>
|
|
54
|
-
@if(item.icon)
|
|
55
|
-
<span class="inline-flex items-center gap-1.5">
|
|
56
|
-
<span innerHTML="{!! item.icon !!}"></span>
|
|
57
|
-
<span>{{ item.label }}</span>
|
|
58
|
-
</span>
|
|
59
|
-
@else
|
|
60
|
-
{{ item.label }}
|
|
61
|
-
@endif
|
|
62
|
-
</a>
|
|
63
|
-
@endif
|
|
64
|
-
@endif
|
|
65
|
-
|
|
66
|
-
<!-- Separator (not after last item) -->
|
|
67
|
-
@if(!$loop.last)
|
|
68
|
-
<span class="{{ separatorClasses }}" aria-hidden="true">
|
|
69
|
-
@if(separator === 'arrow')
|
|
70
|
-
{!! separatorElement !!}
|
|
71
|
-
@else
|
|
72
|
-
{{ separatorElement }}
|
|
73
|
-
@endif
|
|
74
|
-
</span>
|
|
75
|
-
@endif
|
|
76
|
-
</li>
|
|
77
|
-
@endforeach
|
|
78
|
-
</ol>
|
|
79
|
-
</nav>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export { default as Breadcrumb } from './Breadcrumb.stx'
|
|
2
|
-
|
|
3
|
-
export interface BreadcrumbItem {
|
|
4
|
-
label: string
|
|
5
|
-
href: string
|
|
6
|
-
icon?: string
|
|
7
|
-
collapsed?: boolean
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface BreadcrumbProps {
|
|
11
|
-
items: BreadcrumbItem[]
|
|
12
|
-
separator?: '/' | '>' | 'arrow' | string
|
|
13
|
-
maxItems?: number
|
|
14
|
-
className?: string
|
|
15
|
-
}
|
package/src/ui/button/Button.stx
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
<script server>
|
|
2
|
-
export const variant = $props.variant || 'primary'
|
|
3
|
-
export const size = $props.size || 'md'
|
|
4
|
-
export const disabled = $props.disabled || false
|
|
5
|
-
export const loading = $props.loading || false
|
|
6
|
-
export const type = $props.type || 'button'
|
|
7
|
-
export const fullWidth = $props.fullWidth || false
|
|
8
|
-
export const leftIcon = $props.leftIcon || ''
|
|
9
|
-
export const rightIcon = $props.rightIcon || ''
|
|
10
|
-
export const className = $props.className || ''
|
|
11
|
-
|
|
12
|
-
const variantClasses = {
|
|
13
|
-
primary: 'bg-blue-500 hover:bg-blue-600 text-white shadow-md hover:shadow-lg dark:bg-blue-600 dark:hover:bg-blue-700',
|
|
14
|
-
secondary: 'bg-neutral-200 hover:bg-neutral-300 text-neutral-900 dark:bg-neutral-700 dark:hover:bg-neutral-600 dark:text-white',
|
|
15
|
-
outline: 'border-2 border-blue-500 text-blue-500 hover:bg-blue-50 dark:border-blue-400 dark:text-blue-400 dark:hover:bg-blue-950',
|
|
16
|
-
ghost: 'hover:bg-neutral-100 text-neutral-700 dark:hover:bg-neutral-800 dark:text-neutral-300',
|
|
17
|
-
danger: 'bg-red-500 hover:bg-red-600 text-white shadow-md hover:shadow-lg dark:bg-red-600 dark:hover:bg-red-700',
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const sizeClasses = {
|
|
21
|
-
xs: 'px-2.5 py-1 text-xs h-7 gap-1',
|
|
22
|
-
sm: 'px-3 py-1.5 text-sm h-8 gap-1.5',
|
|
23
|
-
md: 'px-4 py-2 text-base h-10 gap-2',
|
|
24
|
-
lg: 'px-6 py-3 text-lg h-12 gap-2.5',
|
|
25
|
-
xl: 'px-8 py-4 text-xl h-14 gap-3',
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const iconSizeClasses = { xs: 'h-3 w-3', sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6', xl: 'h-7 w-7' }
|
|
29
|
-
const baseClasses = 'inline-flex items-center justify-center font-semibold rounded-md transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none'
|
|
30
|
-
const widthClasses = fullWidth ? 'w-full' : ''
|
|
31
|
-
export const isDisabled = disabled || loading
|
|
32
|
-
|
|
33
|
-
export const buttonClasses = `${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${widthClasses} ${className}`.trim()
|
|
34
|
-
export const iconClasses = iconSizeClasses[size]
|
|
35
|
-
export const spinnerClasses = `animate-spin ${iconClasses}`.trim()
|
|
36
|
-
</script>
|
|
37
|
-
|
|
38
|
-
<script client>
|
|
39
|
-
const emit = defineEmits()
|
|
40
|
-
const disabledNow = {{ isDisabled }}
|
|
41
|
-
|
|
42
|
-
function onClick(event) {
|
|
43
|
-
if (disabledNow) {
|
|
44
|
-
event.preventDefault()
|
|
45
|
-
return
|
|
46
|
-
}
|
|
47
|
-
emit('click', event)
|
|
48
|
-
}
|
|
49
|
-
</script>
|
|
50
|
-
|
|
51
|
-
<button
|
|
52
|
-
type="{{ type }}"
|
|
53
|
-
class="{{ buttonClasses }}"
|
|
54
|
-
@if(isDisabled)disabled@endif
|
|
55
|
-
@click="onClick($event)"
|
|
56
|
-
aria-busy="{{ loading ? 'true' : 'false' }}"
|
|
57
|
-
>
|
|
58
|
-
@if(loading)
|
|
59
|
-
<svg class="{{ spinnerClasses }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
60
|
-
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
61
|
-
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
62
|
-
</svg>
|
|
63
|
-
@else
|
|
64
|
-
@if(leftIcon)
|
|
65
|
-
<span class="{{ iconClasses }}">{!! leftIcon !!}</span>
|
|
66
|
-
@endif
|
|
67
|
-
@endif
|
|
68
|
-
|
|
69
|
-
<slot />
|
|
70
|
-
|
|
71
|
-
@if(!loading && rightIcon)
|
|
72
|
-
<span class="{{ iconClasses }}">{!! rightIcon !!}</span>
|
|
73
|
-
@endif
|
|
74
|
-
</button>
|
package/src/ui/button/README.md
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# Button Component
|
|
2
|
-
|
|
3
|
-
A versatile button component built with STX and headwind utility classes.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
bun add @stacksjs/components
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
```stx
|
|
14
|
-
<Button variant="primary" size="md">Click me</Button>
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Props
|
|
18
|
-
|
|
19
|
-
| Prop | Type | Default | Description |
|
|
20
|
-
|------|------|---------|-------------|
|
|
21
|
-
| `variant` | `'primary' \| 'secondary' \| 'outline' \| 'ghost' \| 'danger'` | `'primary'` | Button visual style |
|
|
22
|
-
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Button size |
|
|
23
|
-
| `disabled` | `boolean` | `false` | Disable the button |
|
|
24
|
-
| `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | Button HTML type |
|
|
25
|
-
| `className` | `string` | `''` | Additional CSS classes |
|
|
26
|
-
| `onClick` | `() => void` | - | Click handler |
|
|
27
|
-
|
|
28
|
-
## Examples
|
|
29
|
-
|
|
30
|
-
### Variants
|
|
31
|
-
|
|
32
|
-
```stx
|
|
33
|
-
<Button variant="primary">Primary Button</Button>
|
|
34
|
-
|
|
35
|
-
<Button variant="secondary">Secondary Button</Button>
|
|
36
|
-
|
|
37
|
-
<Button variant="outline">Outline Button</Button>
|
|
38
|
-
|
|
39
|
-
<Button variant="ghost">Ghost Button</Button>
|
|
40
|
-
|
|
41
|
-
<Button variant="danger">Danger Button</Button>
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### Sizes
|
|
45
|
-
|
|
46
|
-
```stx
|
|
47
|
-
<Button size="sm">Small Button</Button>
|
|
48
|
-
|
|
49
|
-
<Button size="md">Medium Button</Button>
|
|
50
|
-
|
|
51
|
-
<Button size="lg">Large Button</Button>
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### Disabled State
|
|
55
|
-
|
|
56
|
-
```stx
|
|
57
|
-
<Button disabled>Disabled Button</Button>
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### With Icon
|
|
61
|
-
|
|
62
|
-
```stx
|
|
63
|
-
<Button variant="primary">
|
|
64
|
-
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
65
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
|
|
66
|
-
</svg>
|
|
67
|
-
Add Item
|
|
68
|
-
</Button>
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Features
|
|
72
|
-
|
|
73
|
-
- 5 visual variants (primary, secondary, outline, ghost, danger)
|
|
74
|
-
- 3 size options (sm, md, lg)
|
|
75
|
-
- Disabled state support
|
|
76
|
-
- Focus ring with keyboard navigation
|
|
77
|
-
- Dark mode support
|
|
78
|
-
- Accessible by default
|
|
79
|
-
- Smooth transitions
|
|
80
|
-
- Headwind utility classes for easy customization
|
package/src/ui/button/index.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import type { PropSchema, ValidationResult } from '../../utils/prop-validation'
|
|
2
|
-
import { ErrorTypes, wrapErrorHandler } from '../../utils/error-handling'
|
|
3
|
-
import { createPropValidator, PropTypes } from '../../utils/prop-validation'
|
|
4
|
-
|
|
5
|
-
export { default as Button } from './Button.stx'
|
|
6
|
-
|
|
7
|
-
export interface ButtonProps {
|
|
8
|
-
variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger'
|
|
9
|
-
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
|
10
|
-
disabled?: boolean
|
|
11
|
-
loading?: boolean
|
|
12
|
-
type?: 'button' | 'submit' | 'reset'
|
|
13
|
-
fullWidth?: boolean
|
|
14
|
-
leftIcon?: string
|
|
15
|
-
rightIcon?: string
|
|
16
|
-
className?: string
|
|
17
|
-
onClick?: (event: Event) => void
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Button prop validation schema
|
|
22
|
-
*/
|
|
23
|
-
export const buttonPropSchema: PropSchema = {
|
|
24
|
-
variant: PropTypes.oneOf(['primary', 'secondary', 'outline', 'ghost', 'danger']),
|
|
25
|
-
size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
|
|
26
|
-
disabled: PropTypes.boolean,
|
|
27
|
-
loading: PropTypes.boolean,
|
|
28
|
-
type: PropTypes.oneOf(['button', 'submit', 'reset']),
|
|
29
|
-
fullWidth: PropTypes.boolean,
|
|
30
|
-
leftIcon: PropTypes.string,
|
|
31
|
-
rightIcon: PropTypes.string,
|
|
32
|
-
className: PropTypes.string,
|
|
33
|
-
onClick: PropTypes.func,
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Validate Button component props
|
|
38
|
-
* Only runs in development mode
|
|
39
|
-
*/
|
|
40
|
-
export const validateButtonProps: (props: Record<string, any>) => ValidationResult = createPropValidator('Button', buttonPropSchema)
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Create a safe onClick handler that catches and reports errors
|
|
44
|
-
*
|
|
45
|
-
* @param handler - Click handler function
|
|
46
|
-
* @returns Wrapped handler with error handling
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```ts
|
|
50
|
-
* const safeHandler = createSafeClickHandler(() => {
|
|
51
|
-
* // Your click logic
|
|
52
|
-
* })
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export function createSafeClickHandler(handler: (event: Event) => void): (event: Event) => void {
|
|
56
|
-
return wrapErrorHandler(handler, 'Button', 'onClick')
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Helper to validate button variant
|
|
61
|
-
*/
|
|
62
|
-
export function validateVariant(variant?: string): void {
|
|
63
|
-
if (variant && !['primary', 'secondary', 'outline', 'ghost', 'danger'].includes(variant)) {
|
|
64
|
-
throw ErrorTypes.invalidProp(
|
|
65
|
-
'Button',
|
|
66
|
-
'variant',
|
|
67
|
-
variant,
|
|
68
|
-
['primary', 'secondary', 'outline', 'ghost', 'danger'],
|
|
69
|
-
)
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Helper to validate button size
|
|
75
|
-
*/
|
|
76
|
-
export function validateSize(size?: string): void {
|
|
77
|
-
if (size && !['xs', 'sm', 'md', 'lg', 'xl'].includes(size)) {
|
|
78
|
-
throw ErrorTypes.invalidProp(
|
|
79
|
-
'Button',
|
|
80
|
-
'size',
|
|
81
|
-
size,
|
|
82
|
-
['xs', 'sm', 'md', 'lg', 'xl'],
|
|
83
|
-
)
|
|
84
|
-
}
|
|
85
|
-
}
|