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.
- package/LICENSE +674 -0
- package/README.md +150 -0
- package/dist/App/App.svelte +54 -0
- package/dist/App/App.svelte.d.ts +65 -0
- package/dist/Section.svelte +25 -0
- package/dist/Section.svelte.d.ts +34 -0
- package/dist/actions/clickOutside.d.ts +9 -0
- package/dist/actions/clickOutside.js +19 -0
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.js +1 -0
- package/dist/components/Accordion/Accordion.svelte +75 -0
- package/dist/components/Accordion/Accordion.svelte.d.ts +39 -0
- package/dist/components/Accordion/AccordionItem.svelte +150 -0
- package/dist/components/Accordion/AccordionItem.svelte.d.ts +30 -0
- package/dist/components/App/App.story.md +8 -0
- package/dist/components/App/App.story.svelte +170 -0
- package/dist/components/App/App.story.svelte.d.ts +22 -0
- package/dist/components/App/App.svelte +77 -0
- package/dist/components/App/App.svelte.d.ts +66 -0
- package/dist/components/App/Split.svelte +346 -0
- package/dist/components/App/Split.svelte.d.ts +54 -0
- package/dist/components/App/index.d.ts +2 -0
- package/dist/components/App/index.js +3 -0
- package/dist/components/AppHeader/AppHeader.svelte +439 -0
- package/dist/components/AppHeader/AppHeader.svelte.d.ts +24 -0
- package/dist/components/Avatar/Avatar.svelte +300 -0
- package/dist/components/Avatar/Avatar.svelte.d.ts +48 -0
- package/dist/components/Avatar/AvatarGroup.svelte +185 -0
- package/dist/components/Avatar/AvatarGroup.svelte.d.ts +46 -0
- package/dist/components/Badge/Badge.svelte +186 -0
- package/dist/components/Badge/Badge.svelte.d.ts +51 -0
- package/dist/components/BottomBar/BottomBar.svelte +146 -0
- package/dist/components/BottomBar/BottomBar.svelte.d.ts +38 -0
- package/dist/components/Breadcrumb/Breadcrumb.svelte +77 -0
- package/dist/components/Breadcrumb/Breadcrumb.svelte.d.ts +42 -0
- package/dist/components/Breadcrumb/BreadcrumbItem.svelte +171 -0
- package/dist/components/Breadcrumb/BreadcrumbItem.svelte.d.ts +38 -0
- package/dist/components/Button/Button.svelte +252 -0
- package/dist/components/Button/Button.svelte.d.ts +80 -0
- package/dist/components/Button/ButtonGroup.svelte +127 -0
- package/dist/components/Button/ButtonGroup.svelte.d.ts +44 -0
- package/dist/components/Card/Card.svelte +152 -0
- package/dist/components/Card/Card.svelte.d.ts +55 -0
- package/dist/components/Carousel/Carousel.svelte +461 -0
- package/dist/components/Carousel/Carousel.svelte.d.ts +79 -0
- package/dist/components/Carousel/CarouselItem.svelte +149 -0
- package/dist/components/Carousel/CarouselItem.svelte.d.ts +35 -0
- package/dist/components/Chip/Chip.svelte +288 -0
- package/dist/components/Chip/Chip.svelte.d.ts +71 -0
- package/dist/components/Chip/ChipGroup.svelte +190 -0
- package/dist/components/Chip/ChipGroup.svelte.d.ts +71 -0
- package/dist/components/CodeBlock/CodeBlock.svelte +356 -0
- package/dist/components/CodeBlock/CodeBlock.svelte.d.ts +44 -0
- package/dist/components/CodeBlock/index.d.ts +1 -0
- package/dist/components/CodeBlock/index.js +1 -0
- package/dist/components/CodeBlockSpeed/CodeBlockSpeed.svelte +145 -0
- package/dist/components/CodeBlockSpeed/CodeBlockSpeed.svelte.d.ts +44 -0
- package/dist/components/CodeEditor/CodeEditor.svelte +229 -0
- package/dist/components/CodeEditor/CodeEditor.svelte.d.ts +23 -0
- package/dist/components/Combobox/Combobox.svelte +279 -0
- package/dist/components/Combobox/Combobox.svelte.d.ts +34 -0
- package/dist/components/Container/Container.svelte +45 -0
- package/dist/components/Container/Container.svelte.d.ts +36 -0
- package/dist/components/DataTable/DataTable.svelte +879 -0
- package/dist/components/DataTable/DataTable.svelte.d.ts +102 -0
- package/dist/components/Form/AutoComplete.svelte +357 -0
- package/dist/components/Form/AutoComplete.svelte.d.ts +73 -0
- package/dist/components/Form/Calendar.svelte +429 -0
- package/dist/components/Form/Calendar.svelte.d.ts +53 -0
- package/dist/components/Form/Checkbox.svelte +196 -0
- package/dist/components/Form/Checkbox.svelte.d.ts +50 -0
- package/dist/components/Form/ColorPicker.svelte +396 -0
- package/dist/components/Form/ColorPicker.svelte.d.ts +43 -0
- package/dist/components/Form/Combobox.svelte +645 -0
- package/dist/components/Form/Combobox.svelte.d.ts +93 -0
- package/dist/components/Form/Dropdown.svelte +773 -0
- package/dist/components/Form/Dropdown.svelte.d.ts +81 -0
- package/dist/components/Form/FileUpload.svelte +796 -0
- package/dist/components/Form/FileUpload.svelte.d.ts +78 -0
- package/dist/components/Form/FloatLabel.svelte +245 -0
- package/dist/components/Form/FloatLabel.svelte.d.ts +44 -0
- package/dist/components/Form/Form.svelte +281 -0
- package/dist/components/Form/Form.svelte.d.ts +54 -0
- package/dist/components/Form/FormField.svelte +218 -0
- package/dist/components/Form/FormField.svelte.d.ts +47 -0
- package/dist/components/Form/Input.svelte +340 -0
- package/dist/components/Form/Input.svelte.d.ts +79 -0
- package/dist/components/Form/InputSwitch.svelte +189 -0
- package/dist/components/Form/InputSwitch.svelte.d.ts +46 -0
- package/dist/components/Form/InvalidState.svelte +97 -0
- package/dist/components/Form/InvalidState.svelte.d.ts +37 -0
- package/dist/components/Form/Knob.svelte +537 -0
- package/dist/components/Form/Knob.svelte.d.ts +78 -0
- package/dist/components/Form/ListInput.svelte +469 -0
- package/dist/components/Form/ListInput.svelte.d.ts +70 -0
- package/dist/components/Form/Listbox.svelte +513 -0
- package/dist/components/Form/Listbox.svelte.d.ts +74 -0
- package/dist/components/Form/NumberInput.svelte +452 -0
- package/dist/components/Form/NumberInput.svelte.d.ts +82 -0
- package/dist/components/Form/Radio.svelte +192 -0
- package/dist/components/Form/Radio.svelte.d.ts +53 -0
- package/dist/components/Form/RadioGroup.svelte +155 -0
- package/dist/components/Form/RadioGroup.svelte.d.ts +48 -0
- package/dist/components/Form/Rating.svelte +380 -0
- package/dist/components/Form/Rating.svelte.d.ts +64 -0
- package/dist/components/Form/Select.svelte +436 -0
- package/dist/components/Form/Select.svelte.d.ts +49 -0
- package/dist/components/Form/SelectGroup.svelte +34 -0
- package/dist/components/Form/SelectGroup.svelte.d.ts +33 -0
- package/dist/components/Form/Slider.svelte +622 -0
- package/dist/components/Form/Slider.svelte.d.ts +73 -0
- package/dist/components/Form/Switch.svelte +192 -0
- package/dist/components/Form/Switch.svelte.d.ts +46 -0
- package/dist/components/Form/TextInput.svelte +274 -0
- package/dist/components/Form/TextInput.svelte.d.ts +74 -0
- package/dist/components/Form/Textarea.svelte +207 -0
- package/dist/components/Form/Textarea.svelte.d.ts +62 -0
- package/dist/components/Icon/Icon.svelte +140 -0
- package/dist/components/Icon/Icon.svelte.d.ts +25 -0
- package/dist/components/Icon/index.d.ts +1 -0
- package/dist/components/Icon/index.js +1 -0
- package/dist/components/Lazy/Lazy.svelte +158 -0
- package/dist/components/Lazy/Lazy.svelte.d.ts +42 -0
- package/dist/components/Masonry/Masonry.svelte +299 -0
- package/dist/components/Masonry/Masonry.svelte.d.ts +55 -0
- package/dist/components/Menu/Menu/Menu.svelte +65 -0
- package/dist/components/Menu/Menu/Menu.svelte.d.ts +17 -0
- package/dist/components/Menu/Menu/MenuItem.svelte +90 -0
- package/dist/components/Menu/Menu/MenuItem.svelte.d.ts +27 -0
- package/dist/components/Modal/Modal.svelte +334 -0
- package/dist/components/Modal/Modal.svelte.d.ts +55 -0
- package/dist/components/Panel/Card.svelte +141 -0
- package/dist/components/Panel/Card.svelte.d.ts +52 -0
- package/dist/components/Panel/Hero/Hero.story.md +9 -0
- package/dist/components/Panel/Hero/Hero.story.svelte +49 -0
- package/dist/components/Panel/Hero/Hero.story.svelte.d.ts +21 -0
- package/dist/components/Panel/Hero/Hero.svelte +24 -0
- package/dist/components/Panel/Hero/Hero.svelte.d.ts +32 -0
- package/dist/components/Panel/LazyPanel.svelte +110 -0
- package/dist/components/Panel/LazyPanel.svelte.d.ts +46 -0
- package/dist/components/Panel/Panel.svelte +205 -0
- package/dist/components/Panel/Panel.svelte.d.ts +23 -0
- package/dist/components/Progress/Progress.svelte +220 -0
- package/dist/components/Progress/Progress.svelte.d.ts +61 -0
- package/dist/components/Separator/Separator.svelte +109 -0
- package/dist/components/Separator/Separator.svelte.d.ts +35 -0
- package/dist/components/Sidebar/Sidebar.svelte +213 -0
- package/dist/components/Sidebar/Sidebar.svelte.d.ts +60 -0
- package/dist/components/Skeleton/Skeleton.svelte +170 -0
- package/dist/components/Skeleton/Skeleton.svelte.d.ts +48 -0
- package/dist/components/Stepper/Stepper.svelte +111 -0
- package/dist/components/Stepper/Stepper.svelte.d.ts +54 -0
- package/dist/components/Stepper/StepperStep.svelte +369 -0
- package/dist/components/Stepper/StepperStep.svelte.d.ts +63 -0
- package/dist/components/Table/Table.svelte +167 -0
- package/dist/components/Table/Table.svelte.d.ts +56 -0
- package/dist/components/Table/TableBody.svelte +41 -0
- package/dist/components/Table/TableBody.svelte.d.ts +33 -0
- package/dist/components/Table/TableCell.svelte +76 -0
- package/dist/components/Table/TableCell.svelte.d.ts +36 -0
- package/dist/components/Table/TableHead.svelte +41 -0
- package/dist/components/Table/TableHead.svelte.d.ts +32 -0
- package/dist/components/Table/TableHeader.svelte +148 -0
- package/dist/components/Table/TableHeader.svelte.d.ts +42 -0
- package/dist/components/Table/TableRow.svelte +99 -0
- package/dist/components/Table/TableRow.svelte.d.ts +40 -0
- package/dist/components/Tabs/Tab.svelte +145 -0
- package/dist/components/Tabs/Tab.svelte.d.ts +36 -0
- package/dist/components/Tabs/TabList.svelte +60 -0
- package/dist/components/Tabs/TabList.svelte.d.ts +32 -0
- package/dist/components/Tabs/TabPanel.svelte +118 -0
- package/dist/components/Tabs/TabPanel.svelte.d.ts +38 -0
- package/dist/components/Tabs/Tabs.svelte +287 -0
- package/dist/components/Tabs/Tabs.svelte.d.ts +50 -0
- package/dist/components/Tag/Tag.svelte +260 -0
- package/dist/components/Tag/Tag.svelte.d.ts +54 -0
- package/dist/components/Tag/TagGroup.svelte +147 -0
- package/dist/components/Tag/TagGroup.svelte.d.ts +62 -0
- package/dist/components/ThemeToggle/ThemeToggle.svelte +93 -0
- package/dist/components/ThemeToggle/ThemeToggle.svelte.d.ts +12 -0
- package/dist/components/Timeline/Timeline.svelte +144 -0
- package/dist/components/Timeline/Timeline.svelte.d.ts +48 -0
- package/dist/components/Timeline/TimelineItem.svelte +391 -0
- package/dist/components/Timeline/TimelineItem.svelte.d.ts +63 -0
- package/dist/components/Toast/Toast.svelte +313 -0
- package/dist/components/Toast/Toast.svelte.d.ts +44 -0
- package/dist/components/Toast/toastStore.d.ts +40 -0
- package/dist/components/Toast/toastStore.js +293 -0
- package/dist/components/Tooltip/Tooltip.svelte +282 -0
- package/dist/components/Tooltip/Tooltip.svelte.d.ts +55 -0
- package/dist/components/Tree/Tree.svelte +129 -0
- package/dist/components/Tree/Tree.svelte.d.ts +61 -0
- package/dist/components/Tree/TreeNode.svelte +332 -0
- package/dist/components/Tree/TreeNode.svelte.d.ts +55 -0
- package/dist/components/icons/TwintrinsicLogo.svelte +73 -0
- package/dist/components/icons/TwintrinsicLogo.svelte.d.ts +17 -0
- package/dist/components/icons/twintrinsic-source.svg +73 -0
- package/dist/components/icons/twintrinsic.svg +38 -0
- package/dist/docs/EventsTable.svelte +86 -0
- package/dist/docs/EventsTable.svelte.d.ts +27 -0
- package/dist/docs/PropsTable.svelte +103 -0
- package/dist/docs/PropsTable.svelte.d.ts +28 -0
- package/dist/docs/index.d.ts +2 -0
- package/dist/docs/index.js +2 -0
- package/dist/helpers/detectLanguage.d.ts +6 -0
- package/dist/helpers/detectLanguage.js +60 -0
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +1 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +94 -0
- package/dist/twintrinsic.css +347 -0
- 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>;
|