twintrinsic 0.0.1

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 (212) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +150 -0
  3. package/dist/App/App.svelte +54 -0
  4. package/dist/App/App.svelte.d.ts +65 -0
  5. package/dist/Section.svelte +25 -0
  6. package/dist/Section.svelte.d.ts +34 -0
  7. package/dist/actions/clickOutside.d.ts +9 -0
  8. package/dist/actions/clickOutside.js +19 -0
  9. package/dist/actions/index.d.ts +1 -0
  10. package/dist/actions/index.js +1 -0
  11. package/dist/components/Accordion/Accordion.svelte +75 -0
  12. package/dist/components/Accordion/Accordion.svelte.d.ts +39 -0
  13. package/dist/components/Accordion/AccordionItem.svelte +150 -0
  14. package/dist/components/Accordion/AccordionItem.svelte.d.ts +30 -0
  15. package/dist/components/App/App.story.md +8 -0
  16. package/dist/components/App/App.story.svelte +170 -0
  17. package/dist/components/App/App.story.svelte.d.ts +22 -0
  18. package/dist/components/App/App.svelte +77 -0
  19. package/dist/components/App/App.svelte.d.ts +66 -0
  20. package/dist/components/App/Split.svelte +346 -0
  21. package/dist/components/App/Split.svelte.d.ts +54 -0
  22. package/dist/components/App/index.d.ts +2 -0
  23. package/dist/components/App/index.js +3 -0
  24. package/dist/components/AppHeader/AppHeader.svelte +439 -0
  25. package/dist/components/AppHeader/AppHeader.svelte.d.ts +24 -0
  26. package/dist/components/Avatar/Avatar.svelte +300 -0
  27. package/dist/components/Avatar/Avatar.svelte.d.ts +48 -0
  28. package/dist/components/Avatar/AvatarGroup.svelte +185 -0
  29. package/dist/components/Avatar/AvatarGroup.svelte.d.ts +46 -0
  30. package/dist/components/Badge/Badge.svelte +186 -0
  31. package/dist/components/Badge/Badge.svelte.d.ts +51 -0
  32. package/dist/components/BottomBar/BottomBar.svelte +146 -0
  33. package/dist/components/BottomBar/BottomBar.svelte.d.ts +38 -0
  34. package/dist/components/Breadcrumb/Breadcrumb.svelte +77 -0
  35. package/dist/components/Breadcrumb/Breadcrumb.svelte.d.ts +42 -0
  36. package/dist/components/Breadcrumb/BreadcrumbItem.svelte +171 -0
  37. package/dist/components/Breadcrumb/BreadcrumbItem.svelte.d.ts +38 -0
  38. package/dist/components/Button/Button.svelte +252 -0
  39. package/dist/components/Button/Button.svelte.d.ts +80 -0
  40. package/dist/components/Button/ButtonGroup.svelte +127 -0
  41. package/dist/components/Button/ButtonGroup.svelte.d.ts +44 -0
  42. package/dist/components/Card/Card.svelte +152 -0
  43. package/dist/components/Card/Card.svelte.d.ts +55 -0
  44. package/dist/components/Carousel/Carousel.svelte +461 -0
  45. package/dist/components/Carousel/Carousel.svelte.d.ts +79 -0
  46. package/dist/components/Carousel/CarouselItem.svelte +149 -0
  47. package/dist/components/Carousel/CarouselItem.svelte.d.ts +35 -0
  48. package/dist/components/Chip/Chip.svelte +288 -0
  49. package/dist/components/Chip/Chip.svelte.d.ts +71 -0
  50. package/dist/components/Chip/ChipGroup.svelte +190 -0
  51. package/dist/components/Chip/ChipGroup.svelte.d.ts +71 -0
  52. package/dist/components/CodeBlock/CodeBlock.svelte +356 -0
  53. package/dist/components/CodeBlock/CodeBlock.svelte.d.ts +44 -0
  54. package/dist/components/CodeBlock/index.d.ts +1 -0
  55. package/dist/components/CodeBlock/index.js +1 -0
  56. package/dist/components/CodeBlockSpeed/CodeBlockSpeed.svelte +145 -0
  57. package/dist/components/CodeBlockSpeed/CodeBlockSpeed.svelte.d.ts +44 -0
  58. package/dist/components/CodeEditor/CodeEditor.svelte +229 -0
  59. package/dist/components/CodeEditor/CodeEditor.svelte.d.ts +23 -0
  60. package/dist/components/Combobox/Combobox.svelte +279 -0
  61. package/dist/components/Combobox/Combobox.svelte.d.ts +34 -0
  62. package/dist/components/Container/Container.svelte +45 -0
  63. package/dist/components/Container/Container.svelte.d.ts +36 -0
  64. package/dist/components/DataTable/DataTable.svelte +879 -0
  65. package/dist/components/DataTable/DataTable.svelte.d.ts +102 -0
  66. package/dist/components/Form/AutoComplete.svelte +357 -0
  67. package/dist/components/Form/AutoComplete.svelte.d.ts +73 -0
  68. package/dist/components/Form/Calendar.svelte +429 -0
  69. package/dist/components/Form/Calendar.svelte.d.ts +53 -0
  70. package/dist/components/Form/Checkbox.svelte +196 -0
  71. package/dist/components/Form/Checkbox.svelte.d.ts +50 -0
  72. package/dist/components/Form/ColorPicker.svelte +396 -0
  73. package/dist/components/Form/ColorPicker.svelte.d.ts +43 -0
  74. package/dist/components/Form/Combobox.svelte +645 -0
  75. package/dist/components/Form/Combobox.svelte.d.ts +93 -0
  76. package/dist/components/Form/Dropdown.svelte +773 -0
  77. package/dist/components/Form/Dropdown.svelte.d.ts +81 -0
  78. package/dist/components/Form/FileUpload.svelte +796 -0
  79. package/dist/components/Form/FileUpload.svelte.d.ts +78 -0
  80. package/dist/components/Form/FloatLabel.svelte +245 -0
  81. package/dist/components/Form/FloatLabel.svelte.d.ts +44 -0
  82. package/dist/components/Form/Form.svelte +281 -0
  83. package/dist/components/Form/Form.svelte.d.ts +54 -0
  84. package/dist/components/Form/FormField.svelte +218 -0
  85. package/dist/components/Form/FormField.svelte.d.ts +47 -0
  86. package/dist/components/Form/Input.svelte +340 -0
  87. package/dist/components/Form/Input.svelte.d.ts +79 -0
  88. package/dist/components/Form/InputSwitch.svelte +189 -0
  89. package/dist/components/Form/InputSwitch.svelte.d.ts +46 -0
  90. package/dist/components/Form/InvalidState.svelte +97 -0
  91. package/dist/components/Form/InvalidState.svelte.d.ts +37 -0
  92. package/dist/components/Form/Knob.svelte +537 -0
  93. package/dist/components/Form/Knob.svelte.d.ts +78 -0
  94. package/dist/components/Form/ListInput.svelte +469 -0
  95. package/dist/components/Form/ListInput.svelte.d.ts +70 -0
  96. package/dist/components/Form/Listbox.svelte +513 -0
  97. package/dist/components/Form/Listbox.svelte.d.ts +74 -0
  98. package/dist/components/Form/NumberInput.svelte +452 -0
  99. package/dist/components/Form/NumberInput.svelte.d.ts +82 -0
  100. package/dist/components/Form/Radio.svelte +192 -0
  101. package/dist/components/Form/Radio.svelte.d.ts +53 -0
  102. package/dist/components/Form/RadioGroup.svelte +155 -0
  103. package/dist/components/Form/RadioGroup.svelte.d.ts +48 -0
  104. package/dist/components/Form/Rating.svelte +380 -0
  105. package/dist/components/Form/Rating.svelte.d.ts +64 -0
  106. package/dist/components/Form/Select.svelte +436 -0
  107. package/dist/components/Form/Select.svelte.d.ts +49 -0
  108. package/dist/components/Form/SelectGroup.svelte +34 -0
  109. package/dist/components/Form/SelectGroup.svelte.d.ts +33 -0
  110. package/dist/components/Form/Slider.svelte +622 -0
  111. package/dist/components/Form/Slider.svelte.d.ts +73 -0
  112. package/dist/components/Form/Switch.svelte +192 -0
  113. package/dist/components/Form/Switch.svelte.d.ts +46 -0
  114. package/dist/components/Form/TextInput.svelte +274 -0
  115. package/dist/components/Form/TextInput.svelte.d.ts +74 -0
  116. package/dist/components/Form/Textarea.svelte +207 -0
  117. package/dist/components/Form/Textarea.svelte.d.ts +62 -0
  118. package/dist/components/Icon/Icon.svelte +140 -0
  119. package/dist/components/Icon/Icon.svelte.d.ts +25 -0
  120. package/dist/components/Icon/index.d.ts +1 -0
  121. package/dist/components/Icon/index.js +1 -0
  122. package/dist/components/Lazy/Lazy.svelte +158 -0
  123. package/dist/components/Lazy/Lazy.svelte.d.ts +42 -0
  124. package/dist/components/Masonry/Masonry.svelte +299 -0
  125. package/dist/components/Masonry/Masonry.svelte.d.ts +55 -0
  126. package/dist/components/Menu/Menu/Menu.svelte +65 -0
  127. package/dist/components/Menu/Menu/Menu.svelte.d.ts +17 -0
  128. package/dist/components/Menu/Menu/MenuItem.svelte +90 -0
  129. package/dist/components/Menu/Menu/MenuItem.svelte.d.ts +27 -0
  130. package/dist/components/Modal/Modal.svelte +334 -0
  131. package/dist/components/Modal/Modal.svelte.d.ts +55 -0
  132. package/dist/components/Panel/Card.svelte +141 -0
  133. package/dist/components/Panel/Card.svelte.d.ts +52 -0
  134. package/dist/components/Panel/Hero/Hero.story.md +9 -0
  135. package/dist/components/Panel/Hero/Hero.story.svelte +49 -0
  136. package/dist/components/Panel/Hero/Hero.story.svelte.d.ts +21 -0
  137. package/dist/components/Panel/Hero/Hero.svelte +24 -0
  138. package/dist/components/Panel/Hero/Hero.svelte.d.ts +32 -0
  139. package/dist/components/Panel/LazyPanel.svelte +110 -0
  140. package/dist/components/Panel/LazyPanel.svelte.d.ts +46 -0
  141. package/dist/components/Panel/Panel.svelte +205 -0
  142. package/dist/components/Panel/Panel.svelte.d.ts +23 -0
  143. package/dist/components/Progress/Progress.svelte +220 -0
  144. package/dist/components/Progress/Progress.svelte.d.ts +61 -0
  145. package/dist/components/Separator/Separator.svelte +109 -0
  146. package/dist/components/Separator/Separator.svelte.d.ts +35 -0
  147. package/dist/components/Sidebar/Sidebar.svelte +213 -0
  148. package/dist/components/Sidebar/Sidebar.svelte.d.ts +60 -0
  149. package/dist/components/Skeleton/Skeleton.svelte +170 -0
  150. package/dist/components/Skeleton/Skeleton.svelte.d.ts +48 -0
  151. package/dist/components/Stepper/Stepper.svelte +111 -0
  152. package/dist/components/Stepper/Stepper.svelte.d.ts +54 -0
  153. package/dist/components/Stepper/StepperStep.svelte +369 -0
  154. package/dist/components/Stepper/StepperStep.svelte.d.ts +63 -0
  155. package/dist/components/Table/Table.svelte +167 -0
  156. package/dist/components/Table/Table.svelte.d.ts +56 -0
  157. package/dist/components/Table/TableBody.svelte +41 -0
  158. package/dist/components/Table/TableBody.svelte.d.ts +33 -0
  159. package/dist/components/Table/TableCell.svelte +76 -0
  160. package/dist/components/Table/TableCell.svelte.d.ts +36 -0
  161. package/dist/components/Table/TableHead.svelte +41 -0
  162. package/dist/components/Table/TableHead.svelte.d.ts +32 -0
  163. package/dist/components/Table/TableHeader.svelte +148 -0
  164. package/dist/components/Table/TableHeader.svelte.d.ts +42 -0
  165. package/dist/components/Table/TableRow.svelte +99 -0
  166. package/dist/components/Table/TableRow.svelte.d.ts +40 -0
  167. package/dist/components/Tabs/Tab.svelte +145 -0
  168. package/dist/components/Tabs/Tab.svelte.d.ts +36 -0
  169. package/dist/components/Tabs/TabList.svelte +60 -0
  170. package/dist/components/Tabs/TabList.svelte.d.ts +32 -0
  171. package/dist/components/Tabs/TabPanel.svelte +118 -0
  172. package/dist/components/Tabs/TabPanel.svelte.d.ts +38 -0
  173. package/dist/components/Tabs/Tabs.svelte +287 -0
  174. package/dist/components/Tabs/Tabs.svelte.d.ts +50 -0
  175. package/dist/components/Tag/Tag.svelte +260 -0
  176. package/dist/components/Tag/Tag.svelte.d.ts +54 -0
  177. package/dist/components/Tag/TagGroup.svelte +147 -0
  178. package/dist/components/Tag/TagGroup.svelte.d.ts +62 -0
  179. package/dist/components/ThemeToggle/ThemeToggle.svelte +93 -0
  180. package/dist/components/ThemeToggle/ThemeToggle.svelte.d.ts +12 -0
  181. package/dist/components/Timeline/Timeline.svelte +144 -0
  182. package/dist/components/Timeline/Timeline.svelte.d.ts +48 -0
  183. package/dist/components/Timeline/TimelineItem.svelte +391 -0
  184. package/dist/components/Timeline/TimelineItem.svelte.d.ts +63 -0
  185. package/dist/components/Toast/Toast.svelte +313 -0
  186. package/dist/components/Toast/Toast.svelte.d.ts +44 -0
  187. package/dist/components/Toast/toastStore.d.ts +40 -0
  188. package/dist/components/Toast/toastStore.js +293 -0
  189. package/dist/components/Tooltip/Tooltip.svelte +282 -0
  190. package/dist/components/Tooltip/Tooltip.svelte.d.ts +55 -0
  191. package/dist/components/Tree/Tree.svelte +129 -0
  192. package/dist/components/Tree/Tree.svelte.d.ts +61 -0
  193. package/dist/components/Tree/TreeNode.svelte +332 -0
  194. package/dist/components/Tree/TreeNode.svelte.d.ts +55 -0
  195. package/dist/components/icons/TwintrinsicLogo.svelte +73 -0
  196. package/dist/components/icons/TwintrinsicLogo.svelte.d.ts +17 -0
  197. package/dist/components/icons/twintrinsic-source.svg +73 -0
  198. package/dist/components/icons/twintrinsic.svg +38 -0
  199. package/dist/docs/EventsTable.svelte +86 -0
  200. package/dist/docs/EventsTable.svelte.d.ts +27 -0
  201. package/dist/docs/PropsTable.svelte +103 -0
  202. package/dist/docs/PropsTable.svelte.d.ts +28 -0
  203. package/dist/docs/index.d.ts +2 -0
  204. package/dist/docs/index.js +2 -0
  205. package/dist/helpers/detectLanguage.d.ts +6 -0
  206. package/dist/helpers/detectLanguage.js +60 -0
  207. package/dist/helpers/index.d.ts +1 -0
  208. package/dist/helpers/index.js +1 -0
  209. package/dist/index.d.ts +86 -0
  210. package/dist/index.js +94 -0
  211. package/dist/twintrinsic.css +347 -0
  212. package/package.json +98 -0
@@ -0,0 +1,192 @@
1
+ <!--
2
+ @component
3
+ Switch - A toggle switch component that provides an alternative to checkboxes.
4
+ Supports labels, disabled states, and integrates with the Form component.
5
+
6
+ Usage:
7
+ ```svelte
8
+ <Switch
9
+ name="darkMode"
10
+ label="Enable dark mode"
11
+ checked={true}
12
+ />
13
+
14
+ <FormField label="Notifications">
15
+ <Switch name="notifications" />
16
+ </FormField>
17
+ ```
18
+ -->
19
+ <script>
20
+ import { getContext } from "svelte"
21
+
22
+ const {
23
+ /** @type {string} - Additional CSS classes */
24
+ class: className = "",
25
+
26
+ /** @type {string} - HTML id for accessibility */
27
+ id = crypto.randomUUID(),
28
+
29
+ /** @type {string} - Input name */
30
+ name,
31
+
32
+ /** @type {string} - Label text */
33
+ label,
34
+
35
+ /** @type {boolean} - Whether the switch is checked */
36
+ checked = false,
37
+
38
+ /** @type {boolean} - Whether the switch is required */
39
+ required = false,
40
+
41
+ /** @type {boolean} - Whether the switch is disabled */
42
+ disabled = false,
43
+
44
+ /** @type {string} - Size of the switch (sm, md, lg) */
45
+ size = "md",
46
+
47
+ /** @type {string} - ARIA label for accessibility */
48
+ ariaLabel,
49
+
50
+ /** @type {(event: CustomEvent) => void} - Change event handler */
51
+ onchange,
52
+
53
+ /** @type {object} - Additional props to pass to the input element */
54
+ ...restProps
55
+ } = $props()
56
+
57
+ // Get form context if available
58
+ const formContext = getContext("form")
59
+
60
+ // Switch state
61
+ let isChecked = $state(checked)
62
+ let fieldApi = $state()
63
+
64
+ // Register with form if available
65
+ $effect(() => {
66
+ if (formContext && name) {
67
+ fieldApi = formContext.registerField(name, checked)
68
+ }
69
+ })
70
+
71
+ // Update value when form field changes
72
+ $effect(() => {
73
+ if (fieldApi) {
74
+ const formValue = fieldApi.getValue()
75
+ if (formValue !== undefined && formValue !== isChecked) {
76
+ isChecked = !!formValue
77
+ }
78
+ }
79
+ })
80
+
81
+ // Update checked state when prop changes
82
+ $effect(() => {
83
+ isChecked = checked
84
+ })
85
+
86
+ /**
87
+ * Handles switch toggle
88
+ * @param {Event} event - Change event
89
+ */
90
+ function handleChange(event) {
91
+ isChecked = event.target.checked
92
+
93
+ // Update form field if available
94
+ if (fieldApi) {
95
+ fieldApi.setValue(isChecked)
96
+ }
97
+
98
+ onchange?.(new CustomEvent("change", { detail: { checked: isChecked } }))
99
+ }
100
+
101
+ // Determine switch size classes
102
+ const switchSizeClasses = $derived(
103
+ {
104
+ sm: "w-8 h-4",
105
+ md: "w-10 h-5",
106
+ lg: "w-12 h-6",
107
+ }[size] || "w-10 h-5"
108
+ )
109
+
110
+ const thumbSizeClasses = $derived(
111
+ {
112
+ sm: "w-3 h-3",
113
+ md: "w-4 h-4",
114
+ lg: "w-5 h-5",
115
+ }[size] || "w-4 h-4"
116
+ )
117
+
118
+ const labelSizeClasses = $derived(
119
+ {
120
+ sm: "text-xs",
121
+ md: "text-sm",
122
+ lg: "text-base",
123
+ }[size] || "text-sm"
124
+ )
125
+ </script>
126
+
127
+ <label
128
+ class="switch-wrapper {className} {labelSizeClasses} {disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}"
129
+ >
130
+ <div class="switch-container">
131
+ <input
132
+ type="checkbox"
133
+ {id}
134
+ {name}
135
+ checked={isChecked}
136
+ {required}
137
+ disabled={disabled || (fieldApi && fieldApi.isDisabled())}
138
+ aria-label={ariaLabel || label}
139
+ class="switch-input"
140
+ onchange={handleChange}
141
+ {...restProps}
142
+ />
143
+
144
+ <span class="switch-track {switchSizeClasses}" aria-hidden="true">
145
+ <span
146
+ class="switch-thumb {thumbSizeClasses}"
147
+ class:translate-x-full={isChecked}
148
+ ></span>
149
+ </span>
150
+ </div>
151
+
152
+ {#if label}
153
+ <span class="switch-label">{label}</span>
154
+ {/if}
155
+ </label>
156
+
157
+ <style>
158
+ @reference "../../twintrinsic.css";
159
+
160
+ .switch-wrapper {
161
+ @apply inline-flex items-center gap-2;
162
+ }
163
+
164
+ .switch-container {
165
+ @apply relative;
166
+ }
167
+
168
+ .switch-input {
169
+ @apply sr-only;
170
+ }
171
+
172
+ .switch-track {
173
+ @apply block rounded-full bg-muted dark:bg-muted transition-colors duration-200 ease-in-out;
174
+ @apply flex items-center px-0.5;
175
+ }
176
+
177
+ .switch-input:checked + .switch-track {
178
+ @apply bg-primary-500 dark:bg-primary-400;
179
+ }
180
+
181
+ .switch-input:focus + .switch-track {
182
+ @apply ring-2 ring-offset-2 ring-primary-500 dark:ring-primary-400;
183
+ }
184
+
185
+ .switch-thumb {
186
+ @apply rounded-full bg-white dark:bg-white transform transition-transform duration-200 ease-in-out;
187
+ }
188
+
189
+ .switch-label {
190
+ @apply text-text dark:text-text;
191
+ }
192
+ </style>
@@ -0,0 +1,46 @@
1
+ export default Switch;
2
+ type Switch = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ /**
7
+ * Switch - A toggle switch component that provides an alternative to checkboxes.
8
+ * Supports labels, disabled states, and integrates with the Form component.
9
+ *
10
+ * Usage:
11
+ * ```svelte
12
+ * <Switch
13
+ * name="darkMode"
14
+ * label="Enable dark mode"
15
+ * checked={true}
16
+ * />
17
+ *
18
+ * <FormField label="Notifications">
19
+ * <Switch name="notifications" />
20
+ * </FormField>
21
+ * ```
22
+ */
23
+ declare const Switch: import("svelte").Component<{
24
+ class?: string;
25
+ id?: any;
26
+ name: any;
27
+ label: any;
28
+ checked?: boolean;
29
+ required?: boolean;
30
+ disabled?: boolean;
31
+ size?: string;
32
+ ariaLabel: any;
33
+ onchange: any;
34
+ } & Record<string, any>, {}, "">;
35
+ type $$ComponentProps = {
36
+ class?: string;
37
+ id?: any;
38
+ name: any;
39
+ label: any;
40
+ checked?: boolean;
41
+ required?: boolean;
42
+ disabled?: boolean;
43
+ size?: string;
44
+ ariaLabel: any;
45
+ onchange: any;
46
+ } & Record<string, any>;
@@ -0,0 +1,274 @@
1
+ <!--
2
+ @component
3
+ TextInput - A styled text input component with support for various input types.
4
+ Provides consistent styling, accessibility features, and integration with the Form component.
5
+
6
+ Usage:
7
+ ```svelte
8
+ <TextInput
9
+ name="username"
10
+ placeholder="Enter username"
11
+ value="initialValue"
12
+ />
13
+
14
+ <TextInput
15
+ type="email"
16
+ name="email"
17
+ required
18
+ />
19
+ ```
20
+ -->
21
+ <script>
22
+ import { getContext } from "svelte"
23
+
24
+ const {
25
+ /** @type {string} - Input type (text, email, password, etc.) */
26
+ type = "text",
27
+
28
+ /** @type {string} - Additional CSS classes */
29
+ class: className = "",
30
+
31
+ /** @type {string} - HTML id for accessibility */
32
+ id,
33
+
34
+ /** @type {string} - Input name */
35
+ name,
36
+
37
+ /** @type {string} - Input placeholder */
38
+ placeholder = "",
39
+
40
+ /** @type {string} - Input value */
41
+ value = "",
42
+
43
+ /** @type {boolean} - Whether the input is required */
44
+ required = false,
45
+
46
+ /** @type {boolean} - Whether the input is disabled */
47
+ disabled = false,
48
+
49
+ /** @type {boolean} - Whether the input is readonly */
50
+ readonly = false,
51
+
52
+ /** @type {string} - Minimum length */
53
+ minlength,
54
+
55
+ /** @type {string} - Maximum length */
56
+ maxlength,
57
+
58
+ /** @type {string} - Pattern for validation */
59
+ pattern,
60
+
61
+ /** @type {string} - Autocomplete attribute */
62
+ autocomplete,
63
+
64
+ /** @type {string} - Input size (sm, md, lg) */
65
+ size = "md",
66
+
67
+ /** @type {boolean} - Whether to show a clear button */
68
+ clearable = false,
69
+
70
+ /** @type {string} - Icon to show at the start of the input */
71
+ startIcon,
72
+
73
+ /** @type {string} - Icon to show at the end of the input */
74
+ endIcon,
75
+
76
+ /** @type {string} - ARIA label for accessibility */
77
+ ariaLabel,
78
+
79
+ /** @type {(event: CustomEvent) => void} - Input event handler */
80
+ oninput,
81
+ /** @type {(event: CustomEvent) => void} - Change event handler */
82
+ onchange,
83
+ /** @type {(event: Event) => void} - Focus event handler */
84
+ onfocus,
85
+ /** @type {(event: Event) => void} - Blur event handler */
86
+ onblur,
87
+ /** @type {() => void} - Clear event handler */
88
+ onclear,
89
+
90
+ /** @type {object} - Additional props to pass to the input element */
91
+ ...restProps
92
+ } = $props()
93
+
94
+ // Get form context if available
95
+ const formContext = getContext("form")
96
+
97
+ // Generate unique ID if not provided
98
+ const inputId = id || `input-${crypto.randomUUID()}`
99
+
100
+ // Input state
101
+ let inputValue = $state(value)
102
+ let isFocused = $state(false)
103
+ let fieldApi = $state()
104
+
105
+ // Register with form if available
106
+ $effect(() => {
107
+ if (formContext && name) {
108
+ fieldApi = formContext.registerField(name, value)
109
+ }
110
+ })
111
+
112
+ // Update value when form field changes
113
+ $effect(() => {
114
+ if (fieldApi) {
115
+ const formValue = fieldApi.getValue()
116
+ if (formValue !== undefined && formValue !== inputValue) {
117
+ inputValue = formValue
118
+ }
119
+ }
120
+ })
121
+
122
+ // Update input value when prop changes
123
+ $effect(() => {
124
+ inputValue = value
125
+ })
126
+
127
+ /**
128
+ * Handles input changes
129
+ * @param {Event} event - Input event
130
+ */
131
+ function handleInput(event) {
132
+ const newValue = event.target.value
133
+ inputValue = newValue
134
+
135
+ // Update form field if available
136
+ if (fieldApi) {
137
+ fieldApi.setValue(newValue)
138
+ }
139
+
140
+ oninput?.(new CustomEvent("input", { detail: { value: newValue } }))
141
+ onchange?.(new CustomEvent("change", { detail: { value: newValue } }))
142
+ }
143
+
144
+ /**
145
+ * Handles focus events
146
+ */
147
+ function handleFocus(event) {
148
+ isFocused = true
149
+ onfocus?.(event)
150
+ }
151
+
152
+ /**
153
+ * Handles blur events
154
+ */
155
+ function handleBlur(event) {
156
+ isFocused = false
157
+ onblur?.(event)
158
+ }
159
+
160
+ /**
161
+ * Clears the input value
162
+ */
163
+ function clearInput() {
164
+ inputValue = ""
165
+
166
+ // Update form field if available
167
+ if (fieldApi) {
168
+ fieldApi.setValue("")
169
+ }
170
+
171
+ dispatch("input", { value: "" })
172
+ dispatch("change", { value: "" })
173
+ dispatch("clear")
174
+ }
175
+
176
+ // Determine input size classes
177
+ const sizeClasses = $derived(
178
+ {
179
+ sm: "h-8 text-sm px-2",
180
+ md: "h-10 text-base px-3",
181
+ lg: "h-12 text-lg px-4",
182
+ }[size] || "h-10 text-base px-3"
183
+ )
184
+ </script>
185
+
186
+ <div class="input-wrapper {className}">
187
+ <div class="input-container {isFocused ? 'is-focused' : ''}">
188
+ {#if startIcon}
189
+ <div class="input-icon input-icon-start">
190
+ {@html startIcon}
191
+ </div>
192
+ {/if}
193
+
194
+ <input
195
+ {type}
196
+ id={inputId}
197
+ {name}
198
+ {placeholder}
199
+ value={inputValue}
200
+ {required}
201
+ disabled={disabled || (fieldApi && fieldApi.isDisabled())}
202
+ {readonly}
203
+ {minlength}
204
+ {maxlength}
205
+ {pattern}
206
+ {autocomplete}
207
+ aria-label={ariaLabel}
208
+ class="input {sizeClasses} {startIcon ? 'pl-9' : ''} {(endIcon || clearable) ? 'pr-9' : ''}"
209
+ oninput={handleInput}
210
+ onfocus={handleFocus}
211
+ onblur={handleBlur}
212
+ {...restProps}
213
+ />
214
+
215
+ {#if clearable && inputValue}
216
+ <button
217
+ type="button"
218
+ class="input-clear-button"
219
+ aria-label="Clear input"
220
+ onclick={clearInput}
221
+ tabindex="-1"
222
+ >
223
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
224
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
225
+ </svg>
226
+ </button>
227
+ {:else if endIcon}
228
+ <div class="input-icon input-icon-end">
229
+ {@html endIcon}
230
+ </div>
231
+ {/if}
232
+ </div>
233
+ </div>
234
+
235
+ <style>
236
+ @reference "../../twintrinsic.css";
237
+
238
+ .input-wrapper {
239
+ @apply w-full;
240
+ }
241
+
242
+ .input-container {
243
+ @apply relative flex items-center;
244
+ }
245
+
246
+ .input {
247
+ @apply w-full rounded-md border-border dark:border-border bg-background dark:bg-background text-text dark:text-text;
248
+ @apply border focus:outline-none focus:ring-2 focus:ring-primary-500 dark:focus:ring-primary-400 focus:border-primary-500 dark:focus:border-primary-400;
249
+ @apply disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-surface dark:disabled:bg-surface;
250
+ @apply placeholder:text-muted dark:placeholder:text-muted;
251
+ }
252
+
253
+ .input-icon {
254
+ @apply absolute flex items-center justify-center w-9 h-full text-muted dark:text-muted pointer-events-none;
255
+ }
256
+
257
+ .input-icon-start {
258
+ @apply left-0;
259
+ }
260
+
261
+ .input-icon-end {
262
+ @apply right-0;
263
+ }
264
+
265
+ .input-clear-button {
266
+ @apply absolute right-0 flex items-center justify-center w-9 h-full text-muted dark:text-muted;
267
+ @apply hover:text-text dark:hover:text-text focus:outline-none;
268
+ }
269
+
270
+ .is-focused .input-icon,
271
+ .is-focused .input-clear-button {
272
+ @apply text-primary-500 dark:text-primary-400;
273
+ }
274
+ </style>
@@ -0,0 +1,74 @@
1
+ export default TextInput;
2
+ type TextInput = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ /**
7
+ * TextInput - A styled text input component with support for various input types.
8
+ * Provides consistent styling, accessibility features, and integration with the Form component.
9
+ *
10
+ * Usage:
11
+ * ```svelte
12
+ * <TextInput
13
+ * name="username"
14
+ * placeholder="Enter username"
15
+ * value="initialValue"
16
+ * />
17
+ *
18
+ * <TextInput
19
+ * type="email"
20
+ * name="email"
21
+ * required
22
+ * />
23
+ * ```
24
+ */
25
+ declare const TextInput: import("svelte").Component<{
26
+ type?: string;
27
+ class?: string;
28
+ id: any;
29
+ name: any;
30
+ placeholder?: string;
31
+ value?: string;
32
+ required?: boolean;
33
+ disabled?: boolean;
34
+ readonly?: boolean;
35
+ minlength: any;
36
+ maxlength: any;
37
+ pattern: any;
38
+ autocomplete: any;
39
+ size?: string;
40
+ clearable?: boolean;
41
+ startIcon: any;
42
+ endIcon: any;
43
+ ariaLabel: any;
44
+ oninput: any;
45
+ onchange: any;
46
+ onfocus: any;
47
+ onblur: any;
48
+ onclear: any;
49
+ } & Record<string, any>, {}, "">;
50
+ type $$ComponentProps = {
51
+ type?: string;
52
+ class?: string;
53
+ id: any;
54
+ name: any;
55
+ placeholder?: string;
56
+ value?: string;
57
+ required?: boolean;
58
+ disabled?: boolean;
59
+ readonly?: boolean;
60
+ minlength: any;
61
+ maxlength: any;
62
+ pattern: any;
63
+ autocomplete: any;
64
+ size?: string;
65
+ clearable?: boolean;
66
+ startIcon: any;
67
+ endIcon: any;
68
+ ariaLabel: any;
69
+ oninput: any;
70
+ onchange: any;
71
+ onfocus: any;
72
+ onblur: any;
73
+ onclear: any;
74
+ } & Record<string, any>;