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,287 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
Tabs - A component for organizing content into tabbed sections.
|
|
4
|
+
Provides accessible tab navigation with keyboard support and various styling options.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
```svelte
|
|
8
|
+
<Tabs>
|
|
9
|
+
<TabList>
|
|
10
|
+
<Tab>First Tab</Tab>
|
|
11
|
+
<Tab>Second Tab</Tab>
|
|
12
|
+
<Tab>Third Tab</Tab>
|
|
13
|
+
</TabList>
|
|
14
|
+
|
|
15
|
+
<TabPanel>First tab content</TabPanel>
|
|
16
|
+
<TabPanel>Second tab content</TabPanel>
|
|
17
|
+
<TabPanel>Third tab content</TabPanel>
|
|
18
|
+
</Tabs>
|
|
19
|
+
```
|
|
20
|
+
-->
|
|
21
|
+
<script>
|
|
22
|
+
import { setContext } from "svelte"
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
/** @type {string} - Additional CSS classes */
|
|
26
|
+
class: className = "",
|
|
27
|
+
|
|
28
|
+
/** @type {string} - HTML id for accessibility */
|
|
29
|
+
id = crypto.randomUUID(),
|
|
30
|
+
|
|
31
|
+
/** @type {number} - Index of the initially selected tab */
|
|
32
|
+
defaultIndex = 0,
|
|
33
|
+
|
|
34
|
+
/** @type {string} - Tab variant (default, underline, pills, enclosed) */
|
|
35
|
+
variant = "default",
|
|
36
|
+
|
|
37
|
+
/** @type {string} - Tab size (sm, md, lg) */
|
|
38
|
+
size = "md",
|
|
39
|
+
|
|
40
|
+
/** @type {boolean} - Whether to make tabs take full width */
|
|
41
|
+
fullWidth = false,
|
|
42
|
+
|
|
43
|
+
/** @type {boolean} - Whether to center the tabs */
|
|
44
|
+
centered = false,
|
|
45
|
+
|
|
46
|
+
/** @type {boolean} - Whether tabs are disabled */
|
|
47
|
+
disabled = false,
|
|
48
|
+
|
|
49
|
+
/** @type {string} - ARIA label for the tablist */
|
|
50
|
+
ariaLabel = "Tabs",
|
|
51
|
+
|
|
52
|
+
/** @type {(event: CustomEvent) => void} - Change event handler */
|
|
53
|
+
onchange,
|
|
54
|
+
|
|
55
|
+
children,
|
|
56
|
+
} = $props()
|
|
57
|
+
|
|
58
|
+
// Tabs state
|
|
59
|
+
let selectedIndex = $state(defaultIndex)
|
|
60
|
+
let tabsCount = $state(0)
|
|
61
|
+
let tabsRefs = $state([])
|
|
62
|
+
let panelsRefs = $state([])
|
|
63
|
+
|
|
64
|
+
// Sync selectedIndex when defaultIndex changes
|
|
65
|
+
$effect(() => {
|
|
66
|
+
selectedIndex = defaultIndex
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Selects a tab by index
|
|
71
|
+
* @param {number} index - Tab index to select
|
|
72
|
+
*/
|
|
73
|
+
function selectTab(index) {
|
|
74
|
+
if (index < 0 || index >= tabsCount || disabled) return
|
|
75
|
+
|
|
76
|
+
selectedIndex = index
|
|
77
|
+
onchange?.(new CustomEvent("change", { detail: { index, tab: tabsRefs[index], panel: panelsRefs[index] } }))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Handles keyboard navigation
|
|
82
|
+
* @param {KeyboardEvent} event - Keydown event
|
|
83
|
+
* @param {number} index - Current tab index
|
|
84
|
+
*/
|
|
85
|
+
function handleKeydown(event, index) {
|
|
86
|
+
if (disabled) return
|
|
87
|
+
|
|
88
|
+
let newIndex
|
|
89
|
+
|
|
90
|
+
switch (event.key) {
|
|
91
|
+
case "ArrowLeft":
|
|
92
|
+
event.preventDefault()
|
|
93
|
+
newIndex = index - 1
|
|
94
|
+
if (newIndex < 0) newIndex = tabsCount - 1 // Wrap to last tab
|
|
95
|
+
selectTab(newIndex)
|
|
96
|
+
tabsRefs[newIndex]?.focus()
|
|
97
|
+
break
|
|
98
|
+
|
|
99
|
+
case "ArrowRight":
|
|
100
|
+
event.preventDefault()
|
|
101
|
+
newIndex = index + 1
|
|
102
|
+
if (newIndex >= tabsCount) newIndex = 0 // Wrap to first tab
|
|
103
|
+
selectTab(newIndex)
|
|
104
|
+
tabsRefs[newIndex]?.focus()
|
|
105
|
+
break
|
|
106
|
+
|
|
107
|
+
case "Home":
|
|
108
|
+
event.preventDefault()
|
|
109
|
+
selectTab(0)
|
|
110
|
+
tabsRefs[0]?.focus()
|
|
111
|
+
break
|
|
112
|
+
|
|
113
|
+
case "End":
|
|
114
|
+
event.preventDefault()
|
|
115
|
+
newIndex = tabsCount - 1
|
|
116
|
+
selectTab(newIndex)
|
|
117
|
+
tabsRefs[newIndex]?.focus()
|
|
118
|
+
break
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Registers a tab
|
|
124
|
+
* @param {HTMLElement} tabElement - Tab element reference
|
|
125
|
+
* @returns {number} - Tab index
|
|
126
|
+
*/
|
|
127
|
+
function registerTab(tabElement) {
|
|
128
|
+
const index = tabsRefs.length
|
|
129
|
+
tabsRefs = [...tabsRefs, tabElement]
|
|
130
|
+
tabsCount = tabsRefs.length
|
|
131
|
+
return index
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Registers a panel
|
|
136
|
+
* @param {HTMLElement} panelElement - Panel element reference
|
|
137
|
+
* @returns {number} - Panel index
|
|
138
|
+
*/
|
|
139
|
+
function registerPanel(panelElement) {
|
|
140
|
+
const index = panelsRefs.length
|
|
141
|
+
panelsRefs = [...panelsRefs, panelElement]
|
|
142
|
+
return index
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Provide context for child components
|
|
146
|
+
$effect(() => {
|
|
147
|
+
setContext("tabs", {
|
|
148
|
+
selectedIndex: () => selectedIndex,
|
|
149
|
+
registerTab,
|
|
150
|
+
registerPanel,
|
|
151
|
+
selectTab,
|
|
152
|
+
handleKeydown,
|
|
153
|
+
disabled: () => disabled,
|
|
154
|
+
variant,
|
|
155
|
+
size,
|
|
156
|
+
fullWidth,
|
|
157
|
+
centered,
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
// Determine variant classes
|
|
162
|
+
const variantClasses = $derived(
|
|
163
|
+
{
|
|
164
|
+
default: "tabs-default",
|
|
165
|
+
underline: "tabs-underline",
|
|
166
|
+
pills: "tabs-pills",
|
|
167
|
+
enclosed: "tabs-enclosed",
|
|
168
|
+
}[variant] || "tabs-default"
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
// Determine size classes
|
|
172
|
+
const sizeClasses = $derived(
|
|
173
|
+
{
|
|
174
|
+
sm: "tabs-sm",
|
|
175
|
+
md: "tabs-md",
|
|
176
|
+
lg: "tabs-lg",
|
|
177
|
+
}[size] || "tabs-md"
|
|
178
|
+
)
|
|
179
|
+
</script>
|
|
180
|
+
|
|
181
|
+
<div
|
|
182
|
+
{id}
|
|
183
|
+
class="
|
|
184
|
+
tabs
|
|
185
|
+
{variantClasses}
|
|
186
|
+
{sizeClasses}
|
|
187
|
+
{fullWidth ? 'tabs-full-width' : ''}
|
|
188
|
+
{centered ? 'tabs-centered' : ''}
|
|
189
|
+
{disabled ? 'tabs-disabled' : ''}
|
|
190
|
+
{className}
|
|
191
|
+
"
|
|
192
|
+
>
|
|
193
|
+
{@render children?.()}
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<style>
|
|
197
|
+
@reference "../../twintrinsic.css";
|
|
198
|
+
|
|
199
|
+
.tabs {
|
|
200
|
+
@apply w-full;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.tabs-disabled {
|
|
204
|
+
@apply opacity-60 pointer-events-none;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Size variants */
|
|
208
|
+
.tabs-sm :global(.tab) {
|
|
209
|
+
@apply text-sm py-1 px-2;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.tabs-md :global(.tab) {
|
|
213
|
+
@apply text-base py-2 px-3;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.tabs-lg :global(.tab) {
|
|
217
|
+
@apply text-lg py-3 px-4;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Layout variants */
|
|
221
|
+
.tabs-full-width :global(.tab-list) {
|
|
222
|
+
@apply w-full;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.tabs-full-width :global(.tab) {
|
|
226
|
+
@apply flex-1;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.tabs-centered :global(.tab-list) {
|
|
230
|
+
@apply justify-center;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* Style variants */
|
|
234
|
+
.tabs-default :global(.tab) {
|
|
235
|
+
@apply border-b-2 border-transparent;
|
|
236
|
+
@apply hover:border-border dark:hover:border-border;
|
|
237
|
+
@apply hover:text-text dark:hover:text-text;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.tabs-default :global(.tab[aria-selected="true"]) {
|
|
241
|
+
@apply border-b-2 border-primary-500 dark:border-primary-400;
|
|
242
|
+
@apply text-primary-700 dark:text-primary-300;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.tabs-underline :global(.tab-list) {
|
|
246
|
+
@apply border-b border-border dark:border-border;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.tabs-underline :global(.tab) {
|
|
250
|
+
@apply border-b-2 border-transparent -mb-px;
|
|
251
|
+
@apply hover:border-border dark:hover:border-border;
|
|
252
|
+
@apply hover:text-text dark:hover:text-text;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.tabs-underline :global(.tab[aria-selected="true"]) {
|
|
256
|
+
@apply border-b-2 border-primary-500 dark:border-primary-400;
|
|
257
|
+
@apply text-primary-700 dark:text-primary-300;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.tabs-pills :global(.tab) {
|
|
261
|
+
@apply rounded-md;
|
|
262
|
+
@apply hover:bg-hover dark:hover:bg-hover;
|
|
263
|
+
@apply hover:text-text dark:hover:text-text;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.tabs-pills :global(.tab[aria-selected="true"]) {
|
|
267
|
+
@apply bg-primary-500 dark:bg-primary-500;
|
|
268
|
+
@apply text-white dark:text-white;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.tabs-enclosed :global(.tab-list) {
|
|
272
|
+
@apply p-1 bg-surface dark:bg-surface rounded-md;
|
|
273
|
+
@apply border border-border dark:border-border;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.tabs-enclosed :global(.tab) {
|
|
277
|
+
@apply rounded-md;
|
|
278
|
+
@apply hover:bg-hover dark:hover:bg-hover;
|
|
279
|
+
@apply hover:text-text dark:hover:text-text;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.tabs-enclosed :global(.tab[aria-selected="true"]) {
|
|
283
|
+
@apply bg-background dark:bg-background;
|
|
284
|
+
@apply text-text dark:text-text;
|
|
285
|
+
@apply shadow-sm;
|
|
286
|
+
}
|
|
287
|
+
</style>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export default Tabs;
|
|
2
|
+
type Tabs = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Tabs - A component for organizing content into tabbed sections.
|
|
8
|
+
* Provides accessible tab navigation with keyboard support and various styling options.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```svelte
|
|
12
|
+
* <Tabs>
|
|
13
|
+
* <TabList>
|
|
14
|
+
* <Tab>First Tab</Tab>
|
|
15
|
+
* <Tab>Second Tab</Tab>
|
|
16
|
+
* <Tab>Third Tab</Tab>
|
|
17
|
+
* </TabList>
|
|
18
|
+
*
|
|
19
|
+
* <TabPanel>First tab content</TabPanel>
|
|
20
|
+
* <TabPanel>Second tab content</TabPanel>
|
|
21
|
+
* <TabPanel>Third tab content</TabPanel>
|
|
22
|
+
* </Tabs>
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare const Tabs: import("svelte").Component<{
|
|
26
|
+
class?: string;
|
|
27
|
+
id?: any;
|
|
28
|
+
defaultIndex?: number;
|
|
29
|
+
variant?: string;
|
|
30
|
+
size?: string;
|
|
31
|
+
fullWidth?: boolean;
|
|
32
|
+
centered?: boolean;
|
|
33
|
+
disabled?: boolean;
|
|
34
|
+
ariaLabel?: string;
|
|
35
|
+
onchange: any;
|
|
36
|
+
children: any;
|
|
37
|
+
}, {}, "">;
|
|
38
|
+
type $$ComponentProps = {
|
|
39
|
+
class?: string;
|
|
40
|
+
id?: any;
|
|
41
|
+
defaultIndex?: number;
|
|
42
|
+
variant?: string;
|
|
43
|
+
size?: string;
|
|
44
|
+
fullWidth?: boolean;
|
|
45
|
+
centered?: boolean;
|
|
46
|
+
disabled?: boolean;
|
|
47
|
+
ariaLabel?: string;
|
|
48
|
+
onchange: any;
|
|
49
|
+
children: any;
|
|
50
|
+
};
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
Tag - A component for displaying tags, labels, or status indicators.
|
|
4
|
+
Provides consistent styling, accessibility features, and various display options.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
```svelte
|
|
8
|
+
<Tag>Default Tag</Tag>
|
|
9
|
+
|
|
10
|
+
<Tag variant="primary" size="lg">Primary Tag</Tag>
|
|
11
|
+
|
|
12
|
+
<Tag variant="success" icon="<svg>...</svg>">Success</Tag>
|
|
13
|
+
|
|
14
|
+
<Tag variant="warning" dismissible ondismiss={() => handleDismiss()}>Warning</Tag>
|
|
15
|
+
```
|
|
16
|
+
-->
|
|
17
|
+
<script>
|
|
18
|
+
const {
|
|
19
|
+
/** @type {string} - Additional CSS classes */
|
|
20
|
+
class: className = "",
|
|
21
|
+
|
|
22
|
+
/** @type {string} - HTML id for accessibility */
|
|
23
|
+
id = crypto.randomUUID(),
|
|
24
|
+
|
|
25
|
+
/** @type {string} - Visual style variant */
|
|
26
|
+
variant = "default",
|
|
27
|
+
|
|
28
|
+
/** @type {string} - Size of the tag (sm, md, lg) */
|
|
29
|
+
size = "md",
|
|
30
|
+
|
|
31
|
+
/** @type {string} - Icon to display (HTML or SVG string) */
|
|
32
|
+
icon,
|
|
33
|
+
|
|
34
|
+
/** @type {boolean} - Whether the tag is dismissible */
|
|
35
|
+
dismissible = false,
|
|
36
|
+
|
|
37
|
+
/** @type {boolean} - Whether to show the tag as an outline */
|
|
38
|
+
outline = false,
|
|
39
|
+
|
|
40
|
+
/** @type {boolean} - Whether to show the tag as a pill */
|
|
41
|
+
pill = false,
|
|
42
|
+
|
|
43
|
+
/** @type {boolean} - Whether the tag is clickable */
|
|
44
|
+
clickable = false,
|
|
45
|
+
|
|
46
|
+
/** @type {string} - URL for the tag (makes it a link) */
|
|
47
|
+
href,
|
|
48
|
+
|
|
49
|
+
/** @type {string} - Link target (_blank, _self, etc.) */
|
|
50
|
+
target,
|
|
51
|
+
|
|
52
|
+
/** @type {string} - ARIA label for the dismiss button */
|
|
53
|
+
dismissAriaLabel = "Dismiss",
|
|
54
|
+
|
|
55
|
+
/** @type {string} - Custom dismiss icon (HTML or SVG string) */
|
|
56
|
+
dismissIcon,
|
|
57
|
+
|
|
58
|
+
/** @type {(event: CustomEvent) => void} - Dismiss event handler */
|
|
59
|
+
ondismiss,
|
|
60
|
+
|
|
61
|
+
children,
|
|
62
|
+
} = $props()
|
|
63
|
+
|
|
64
|
+
// Determine variant classes
|
|
65
|
+
const variantClasses = $derived(
|
|
66
|
+
outline
|
|
67
|
+
? {
|
|
68
|
+
default: "bg-transparent border border-muted text-text dark:border-muted dark:text-text",
|
|
69
|
+
primary:
|
|
70
|
+
"bg-transparent border border-primary-500 text-primary-500 dark:border-primary-500 dark:text-primary-500",
|
|
71
|
+
secondary:
|
|
72
|
+
"bg-transparent border border-secondary-500 text-secondary-500 dark:border-secondary-500 dark:text-secondary-500",
|
|
73
|
+
success:
|
|
74
|
+
"bg-transparent border border-success-500 text-success-500 dark:border-success-500 dark:text-success-500",
|
|
75
|
+
warning:
|
|
76
|
+
"bg-transparent border border-warning-500 text-warning-500 dark:border-warning-500 dark:text-warning-500",
|
|
77
|
+
error:
|
|
78
|
+
"bg-transparent border border-error-500 text-error-500 dark:border-error-500 dark:text-error-500",
|
|
79
|
+
info: "bg-transparent border border-info-500 text-info-500 dark:border-info-500 dark:text-info-500",
|
|
80
|
+
}[variant]
|
|
81
|
+
: {
|
|
82
|
+
default: "bg-muted/10 text-text dark:bg-muted/20 dark:text-text",
|
|
83
|
+
primary: "bg-primary-100 text-primary-800 dark:bg-primary-900 dark:text-primary-200",
|
|
84
|
+
secondary:
|
|
85
|
+
"bg-secondary-100 text-secondary-800 dark:bg-secondary-900 dark:text-secondary-200",
|
|
86
|
+
success: "bg-success-100 text-success-800 dark:bg-success-900 dark:text-success-200",
|
|
87
|
+
warning: "bg-warning-100 text-warning-800 dark:bg-warning-900 dark:text-warning-200",
|
|
88
|
+
error: "bg-error-100 text-error-800 dark:bg-error-900 dark:text-error-200",
|
|
89
|
+
info: "bg-info-100 text-info-800 dark:bg-info-900 dark:text-info-200",
|
|
90
|
+
}[variant]
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
// Determine size classes
|
|
94
|
+
const sizeClasses = $derived(
|
|
95
|
+
{
|
|
96
|
+
sm: "text-xs px-2 py-0.5 h-5",
|
|
97
|
+
md: "text-sm px-2.5 py-0.5 h-6",
|
|
98
|
+
lg: "text-base px-3 py-1 h-8",
|
|
99
|
+
}[size] || "text-sm px-2.5 py-0.5 h-6"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
// Determine icon size classes
|
|
103
|
+
const iconSizeClasses = $derived(
|
|
104
|
+
{
|
|
105
|
+
sm: "w-3 h-3",
|
|
106
|
+
md: "w-4 h-4",
|
|
107
|
+
lg: "w-5 h-5",
|
|
108
|
+
}[size] || "w-4 h-4"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Handles dismiss button click
|
|
113
|
+
* @param {MouseEvent} event - Click event
|
|
114
|
+
*/
|
|
115
|
+
function handleDismiss(event) {
|
|
116
|
+
event.stopPropagation()
|
|
117
|
+
ondismiss?.(new CustomEvent("dismiss"))
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Handles click on the tag
|
|
122
|
+
* @param {MouseEvent} event - Click event
|
|
123
|
+
*/
|
|
124
|
+
function handleClick(event) {
|
|
125
|
+
if (clickable && !href) {
|
|
126
|
+
// Click events are handled by native browser behavior for links
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
</script>
|
|
130
|
+
|
|
131
|
+
{#if href}
|
|
132
|
+
<a
|
|
133
|
+
{id}
|
|
134
|
+
href={href}
|
|
135
|
+
target={target}
|
|
136
|
+
class="
|
|
137
|
+
tag
|
|
138
|
+
{variantClasses}
|
|
139
|
+
{sizeClasses}
|
|
140
|
+
{pill ? 'tag-pill' : ''}
|
|
141
|
+
{clickable || href ? 'tag-clickable' : ''}
|
|
142
|
+
{className}
|
|
143
|
+
"
|
|
144
|
+
onclick={handleClick}
|
|
145
|
+
>
|
|
146
|
+
{#if icon}
|
|
147
|
+
<span class="tag-icon {iconSizeClasses}">
|
|
148
|
+
{@html icon}
|
|
149
|
+
</span>
|
|
150
|
+
{/if}
|
|
151
|
+
|
|
152
|
+
<span class="tag-content">
|
|
153
|
+
{@render children?.()}
|
|
154
|
+
</span>
|
|
155
|
+
|
|
156
|
+
{#if dismissible}
|
|
157
|
+
<button
|
|
158
|
+
type="button"
|
|
159
|
+
class="tag-dismiss"
|
|
160
|
+
aria-label={dismissAriaLabel}
|
|
161
|
+
onclick={handleDismiss}
|
|
162
|
+
>
|
|
163
|
+
{#if dismissIcon}
|
|
164
|
+
<span class="tag-dismiss-icon">
|
|
165
|
+
{@html dismissIcon}
|
|
166
|
+
</span>
|
|
167
|
+
{:else}
|
|
168
|
+
<svg class="{iconSizeClasses}" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
169
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
170
|
+
</svg>
|
|
171
|
+
{/if}
|
|
172
|
+
</button>
|
|
173
|
+
{/if}
|
|
174
|
+
</a>
|
|
175
|
+
{:else}
|
|
176
|
+
<span
|
|
177
|
+
{id}
|
|
178
|
+
class="
|
|
179
|
+
tag
|
|
180
|
+
{variantClasses}
|
|
181
|
+
{sizeClasses}
|
|
182
|
+
{pill ? 'tag-pill' : ''}
|
|
183
|
+
{clickable ? 'tag-clickable' : ''}
|
|
184
|
+
{className}
|
|
185
|
+
"
|
|
186
|
+
role={clickable ? 'button' : undefined}
|
|
187
|
+
tabindex={clickable ? 0 : undefined}
|
|
188
|
+
onclick={handleClick}
|
|
189
|
+
onkeydown={(e) => e.key === 'Enter' && clickable && handleClick(e)}
|
|
190
|
+
>
|
|
191
|
+
{#if icon}
|
|
192
|
+
<span class="tag-icon {iconSizeClasses}">
|
|
193
|
+
{@html icon}
|
|
194
|
+
</span>
|
|
195
|
+
{/if}
|
|
196
|
+
|
|
197
|
+
<span class="tag-content">
|
|
198
|
+
{@render children?.()}
|
|
199
|
+
</span>
|
|
200
|
+
|
|
201
|
+
{#if dismissible}
|
|
202
|
+
<button
|
|
203
|
+
type="button"
|
|
204
|
+
class="tag-dismiss"
|
|
205
|
+
aria-label={dismissAriaLabel}
|
|
206
|
+
onclick={handleDismiss}
|
|
207
|
+
>
|
|
208
|
+
{#if dismissIcon}
|
|
209
|
+
<span class="tag-dismiss-icon">
|
|
210
|
+
{@html dismissIcon}
|
|
211
|
+
</span>
|
|
212
|
+
{:else}
|
|
213
|
+
<svg class="{iconSizeClasses}" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
214
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
215
|
+
</svg>
|
|
216
|
+
{/if}
|
|
217
|
+
</button>
|
|
218
|
+
{/if}
|
|
219
|
+
</span>
|
|
220
|
+
{/if}
|
|
221
|
+
|
|
222
|
+
<style>
|
|
223
|
+
@reference "../../twintrinsic.css";
|
|
224
|
+
|
|
225
|
+
.tag {
|
|
226
|
+
@apply inline-flex items-center;
|
|
227
|
+
@apply rounded;
|
|
228
|
+
@apply font-medium;
|
|
229
|
+
@apply transition-colors duration-150;
|
|
230
|
+
@apply max-w-full;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.tag-pill {
|
|
234
|
+
@apply rounded-full;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.tag-clickable {
|
|
238
|
+
@apply cursor-pointer;
|
|
239
|
+
@apply hover:bg-inherit/80 dark:hover:bg-inherit/80;
|
|
240
|
+
@apply focus:outline-none focus:ring-2 focus:ring-primary-500 dark:focus:ring-primary-400 focus:ring-offset-2;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.tag-icon {
|
|
244
|
+
@apply mr-1 flex-shrink-0;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.tag-content {
|
|
248
|
+
@apply truncate;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.tag-dismiss {
|
|
252
|
+
@apply ml-1 -mr-1 p-0.5;
|
|
253
|
+
@apply rounded-full;
|
|
254
|
+
@apply flex items-center justify-center;
|
|
255
|
+
@apply text-current opacity-70;
|
|
256
|
+
@apply hover:opacity-100;
|
|
257
|
+
@apply focus:outline-none focus:ring-2 focus:ring-primary-500 dark:focus:ring-primary-400;
|
|
258
|
+
@apply transition-opacity duration-150;
|
|
259
|
+
}
|
|
260
|
+
</style>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export default Tag;
|
|
2
|
+
type Tag = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Tag - A component for displaying tags, labels, or status indicators.
|
|
8
|
+
* Provides consistent styling, accessibility features, and various display options.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```svelte
|
|
12
|
+
* <Tag>Default Tag</Tag>
|
|
13
|
+
*
|
|
14
|
+
* <Tag variant="primary" size="lg">Primary Tag</Tag>
|
|
15
|
+
*
|
|
16
|
+
* <Tag variant="success" icon="<svg>...</svg>">Success</Tag>
|
|
17
|
+
*
|
|
18
|
+
* <Tag variant="warning" dismissible ondismiss={() => handleDismiss()}>Warning</Tag>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare const Tag: import("svelte").Component<{
|
|
22
|
+
class?: string;
|
|
23
|
+
id?: any;
|
|
24
|
+
variant?: string;
|
|
25
|
+
size?: string;
|
|
26
|
+
icon: any;
|
|
27
|
+
dismissible?: boolean;
|
|
28
|
+
outline?: boolean;
|
|
29
|
+
pill?: boolean;
|
|
30
|
+
clickable?: boolean;
|
|
31
|
+
href: any;
|
|
32
|
+
target: any;
|
|
33
|
+
dismissAriaLabel?: string;
|
|
34
|
+
dismissIcon: any;
|
|
35
|
+
ondismiss: any;
|
|
36
|
+
children: any;
|
|
37
|
+
}, {}, "">;
|
|
38
|
+
type $$ComponentProps = {
|
|
39
|
+
class?: string;
|
|
40
|
+
id?: any;
|
|
41
|
+
variant?: string;
|
|
42
|
+
size?: string;
|
|
43
|
+
icon: any;
|
|
44
|
+
dismissible?: boolean;
|
|
45
|
+
outline?: boolean;
|
|
46
|
+
pill?: boolean;
|
|
47
|
+
clickable?: boolean;
|
|
48
|
+
href: any;
|
|
49
|
+
target: any;
|
|
50
|
+
dismissAriaLabel?: string;
|
|
51
|
+
dismissIcon: any;
|
|
52
|
+
ondismiss: any;
|
|
53
|
+
children: any;
|
|
54
|
+
};
|