@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,159 +0,0 @@
1
- <script server>
2
- export const headingText = $props.headingText || 'Sign up for Stacks'
3
- export const showSocialSignup = $props.showSocialSignup ?? true
4
- export const className = $props.className || ''
5
-
6
- export const containerClasses = `min-h-full flex flex-col justify-center py-12 lg:px-8 sm:px-6 dark:bg-blue-gray-900 ${className}`.trim()
7
- </script>
8
-
9
- <script client>
10
- const emit = defineEmits()
11
-
12
- function onSubmit(event) {
13
- event.preventDefault()
14
- const formData = new FormData(event.target)
15
- const name = formData.get('name')
16
- const email = formData.get('email')
17
- const confirmEmail = formData.get('confirm_email')
18
- const password = formData.get('password')
19
-
20
- if (email !== confirmEmail) {
21
- emit('error', { message: 'Emails do not match' })
22
- return
23
- }
24
-
25
- emit('submit', { name, email, password })
26
-
27
- setTimeout(() => {
28
- event.target.querySelector('#password')?.setAttribute('value', '')
29
- event.target.querySelector('#confirm_email')?.setAttribute('value', '')
30
- }, 1000)
31
- }
32
- </script>
33
-
34
- <div class="{{ containerClasses }}">
35
- <div class="sm:mx-auto sm:max-w-md sm:w-full">
36
- <h2 class="mt-6 text-center text-2xl text-gray-900 dark:text-gray-100 font-bold leading-9 tracking-tight">
37
- {{ headingText }}
38
- </h2>
39
- </div>
40
-
41
- <div class="mt-10 sm:mx-auto sm:max-w-[480px] sm:w-full">
42
- <div class="bg-white dark:bg-blue-gray-800 px-6 py-12 shadow sm:rounded-lg sm:px-12">
43
- <form class="space-y-6" @submit="onSubmit($event)">
44
- <div>
45
- <label for="name" class="block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
46
- Full Name
47
- </label>
48
- <div class="mt-2">
49
- <input
50
- id="name"
51
- name="name"
52
- type="text"
53
- autocomplete="name"
54
- required
55
- class="block w-full border-0 rounded-md p-2 py-1.5 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset sm:text-sm placeholder:text-gray-400 dark:placeholder:text-gray-500 sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
56
- />
57
- </div>
58
- </div>
59
-
60
- <div>
61
- <label for="email" class="block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
62
- Email address
63
- </label>
64
- <div class="mt-2">
65
- <input
66
- id="email"
67
- name="email"
68
- type="email"
69
- autocomplete="email"
70
- required
71
- class="block w-full border-0 rounded-md p-2 py-1.5 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset sm:text-sm placeholder:text-gray-400 dark:placeholder:text-gray-500 sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
72
- />
73
- </div>
74
- </div>
75
-
76
- <div>
77
- <label for="confirm_email" class="block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
78
- Confirm Email
79
- </label>
80
- <div class="mt-2">
81
- <input
82
- id="confirm_email"
83
- name="confirm_email"
84
- type="email"
85
- autocomplete="email"
86
- required
87
- class="block w-full border-0 rounded-md p-2 py-1.5 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset sm:text-sm placeholder:text-gray-400 dark:placeholder:text-gray-500 sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
88
- />
89
- </div>
90
- </div>
91
-
92
- <div>
93
- <label for="password" class="block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
94
- Password
95
- </label>
96
- <div class="mt-2">
97
- <input
98
- id="password"
99
- name="password"
100
- type="password"
101
- autocomplete="new-password"
102
- required
103
- class="block w-full border-0 rounded-md p-2 py-1.5 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset sm:text-sm placeholder:text-gray-400 dark:placeholder:text-gray-500 sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
104
- />
105
- </div>
106
- </div>
107
-
108
- <div>
109
- <button
110
- type="submit"
111
- class="w-full flex justify-center rounded-md bg-teal-600 px-3 py-1.5 text-sm text-white font-semibold leading-6 shadow-sm hover:bg-teal-500 focus-visible:outline-2 focus-visible:outline-teal-600 focus-visible:outline-offset-2 focus-visible:outline"
112
- >
113
- Sign up
114
- </button>
115
- </div>
116
- </form>
117
-
118
- @if(showSocialSignup)
119
- <div>
120
- <div class="relative mt-10">
121
- <div class="absolute inset-0 flex items-center" aria-hidden="true">
122
- <div class="w-full border-t border-gray-200 dark:border-gray-600"></div>
123
- </div>
124
- <div class="relative flex justify-center text-sm font-medium leading-6">
125
- <span class="bg-white dark:bg-blue-gray-800 px-6 text-gray-900 dark:text-gray-100">
126
- Or signup with
127
- </span>
128
- </div>
129
- </div>
130
-
131
- <div class="grid grid-cols-2 mt-6 gap-4">
132
- <a
133
- href="#"
134
- class="w-full flex items-center justify-center gap-3 rounded-md bg-white dark:bg-blue-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-gray-100 font-semibold shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:ring-transparent"
135
- >
136
- <svg class="h-5 w-5" viewBox="0 0 24 24" aria-hidden="true">
137
- <path d="M12.0003 4.75C13.7703 4.75 15.3553 5.36002 16.6053 6.54998L20.0303 3.125C17.9502 1.19 15.2353 0 12.0003 0C7.31028 0 3.25527 2.69 1.28027 6.60998L5.27028 9.70498C6.21525 6.86002 8.87028 4.75 12.0003 4.75Z" fill="#EA4335" />
138
- <path d="M23.49 12.275C23.49 11.49 23.415 10.73 23.3 10H12V14.51H18.47C18.18 15.99 17.34 17.25 16.08 18.1L19.945 21.1C22.2 19.01 23.49 15.92 23.49 12.275Z" fill="#4285F4" />
139
- <path d="M5.26498 14.2949C5.02498 13.5699 4.88501 12.7999 4.88501 11.9999C4.88501 11.1999 5.01998 10.4299 5.26498 9.7049L1.275 6.60986C0.46 8.22986 0 10.0599 0 11.9999C0 13.9399 0.46 15.7699 1.28 17.3899L5.26498 14.2949Z" fill="#FBBC05" />
140
- <path d="M12.0004 24.0001C15.2404 24.0001 17.9654 22.935 19.9454 21.095L16.0804 18.095C15.0054 18.82 13.6204 19.245 12.0004 19.245C8.8704 19.245 6.21537 17.135 5.2654 14.29L1.27539 17.385C3.25539 21.31 7.3104 24.0001 12.0004 24.0001Z" fill="#34A853" />
141
- </svg>
142
- <span class="text-sm font-semibold leading-6">Google</span>
143
- </a>
144
-
145
- <a
146
- href="#"
147
- class="w-full flex items-center justify-center gap-3 rounded-md bg-white dark:bg-blue-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-gray-100 font-semibold shadow-sm ring-1 ring-gray-300 dark:ring-gray-600 ring-inset hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:ring-transparent"
148
- >
149
- <svg class="h-5 w-5 fill-[#24292F] dark:fill-white" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
150
- <path fill-rule="evenodd" d="M10 0C4.477 0 0 4.484 0 10.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0110 4.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.203 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.942.359.31.678.921.678 1.856 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0020 10.017C20 4.484 15.522 0 10 0z" clip-rule="evenodd" />
151
- </svg>
152
- <span class="text-sm font-semibold leading-6">GitHub</span>
153
- </a>
154
- </div>
155
- </div>
156
- @endif
157
- </div>
158
- </div>
159
- </div>
@@ -1,111 +0,0 @@
1
- <script server>
2
- export const headingText = $props.headingText || 'Two Factor Authentication'
3
- export const labelText = $props.labelText || 'Authentication code'
4
- export const instructionText = $props.instructionText || 'Open your Symantec 2FA app to view your authentication code.'
5
- export const codeLength = $props.codeLength || 6
6
- export const showRecoveryCode = $props.showRecoveryCode ?? true
7
- export const className = $props.className || ''
8
-
9
- export const containerClasses = `py-32 dark:bg-blue-gray-900 ${className}`.trim()
10
- </script>
11
-
12
- <script client>
13
- const emit = defineEmits()
14
- const codeLength = {{ codeLength }}
15
-
16
- function onCodeInput(event, index) {
17
- const input = event.target
18
- const value = input.value
19
- if (!/^\d*$/.test(value)) {
20
- input.value = ''
21
- return
22
- }
23
- if (value.length === 1 && index < codeLength - 1) {
24
- document.getElementById(`code-${index + 1}`)?.focus()
25
- }
26
- }
27
-
28
- function onKeyDown(event, index) {
29
- if (event.key === 'Backspace' && !event.target.value && index > 0) {
30
- document.getElementById(`code-${index - 1}`)?.focus()
31
- }
32
- }
33
-
34
- function onSubmit(event) {
35
- event.preventDefault()
36
- const code = []
37
- for (let i = 0; i < codeLength; i++) {
38
- const input = document.getElementById(`code-${i}`)
39
- if (input?.value) code.push(input.value)
40
- }
41
- if (code.length === codeLength) {
42
- emit('submit', code.join(''))
43
- }
44
- else {
45
- emit('error', { message: 'Please enter all digits' })
46
- }
47
- }
48
-
49
- function onRecoveryCode(event) {
50
- event.preventDefault()
51
- emit('useRecoveryCode')
52
- }
53
- </script>
54
-
55
- <div class="{{ containerClasses }}">
56
- <div class="mx-auto max-w-sm rounded-md px-8 py-4 shadow-md bg-white dark:bg-blue-gray-800">
57
- <div class="card-body">
58
- <div>
59
- <h3 class="text-center text-sm text-gray-900 dark:text-gray-100 font-semibold">
60
- {{ headingText }}
61
- </h3>
62
- <label for="code-0" class="mt-4 block text-sm text-gray-900 dark:text-gray-100 font-medium leading-6">
63
- {{ labelText }}
64
- </label>
65
- <form @submit="onSubmit($event)">
66
- <div class="mt-2 flex rounded-md shadow-sm space-x-2">
67
- @for(i in Array(codeLength).keys())
68
- <input
69
- id="code-{{ i }}"
70
- type="text"
71
- maxlength="1"
72
- name="code-{{ i }}"
73
- placeholder="-"
74
- class="block w-full border-0 rounded-md px-2 py-2 text-center text-gray-900 dark:text-gray-100 ring-1 ring-gray-300 dark:ring-gray-600 ring-inset sm:text-sm placeholder:text-gray-400 dark:placeholder:text-gray-500 sm:leading-6 focus:ring-2 focus:ring-indigo-600 focus:ring-inset dark:bg-blue-gray-700"
75
- @input="onCodeInput($event, {{ i }})"
76
- @keydown="onKeyDown($event, {{ i }})"
77
- />
78
- @endfor
79
- </div>
80
- <div class="py-4">
81
- <button
82
- type="submit"
83
- class="relative h-8 w-full flex items-center justify-center rounded-full bg-teal-600 px-4 text-white font-semibold hover:bg-teal-500 focus:outline-none focus:ring-2 focus:ring-teal-600 focus:ring-offset-2"
84
- >
85
- Verify
86
- </button>
87
- </div>
88
- </form>
89
- <div>
90
- <p class="text-xs text-gray-700 dark:text-gray-300 font-semibold">
91
- {{ instructionText }}
92
- </p>
93
- </div>
94
- @if(showRecoveryCode)
95
- <div class="mt-4">
96
- <p class="text-xs text-gray-700 dark:text-gray-300 font-semibold">
97
- Having Problems?
98
- </p>
99
- <a
100
- href="#"
101
- @click="onRecoveryCode($event)"
102
- class="text-xs text-blue-500 hover:underline"
103
- >
104
- Use recovery code instead
105
- </a>
106
- </div>
107
- @endif
108
- </div>
109
- </div>
110
- </div>
111
- </div>
@@ -1,32 +0,0 @@
1
- export { default as Login } from './Login.stx'
2
- export { default as Signup } from './Signup.stx'
3
- export { default as TwoFactorChallenge } from './TwoFactorChallenge.stx'
4
-
5
- export interface LoginProps {
6
- showLogo?: boolean
7
- headingText?: string
8
- showSocialLogin?: boolean
9
- showRememberMe?: boolean
10
- showForgotPassword?: boolean
11
- showSignup?: boolean
12
- signupText?: string
13
- onSubmit?: (data: { email: string, password: string }) => void
14
- className?: string
15
- }
16
-
17
- export interface SignupProps {
18
- headingText?: string
19
- showSocialSignup?: boolean
20
- onSubmit?: (data: { name: string, email: string, password: string }) => void
21
- className?: string
22
- }
23
-
24
- export interface TwoFactorChallengeProps {
25
- headingText?: string
26
- labelText?: string
27
- instructionText?: string
28
- codeLength?: number
29
- onSubmit?: (code: string) => void
30
- onUseRecoveryCode?: () => void
31
- className?: string
32
- }
@@ -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>
@@ -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
- }
@@ -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>
@@ -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
- }
@@ -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>