@tabelhadev/tabelhawebui 0.28.4

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 (175) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +222 -0
  3. package/README.pt-BR.md +217 -0
  4. package/dist/actions/click-outside.d.ts +3 -0
  5. package/dist/actions/click-outside.js +12 -0
  6. package/dist/actions/combobox-keyboard-nav.d.ts +9 -0
  7. package/dist/actions/combobox-keyboard-nav.js +28 -0
  8. package/dist/actions/focus-trap.d.ts +1 -0
  9. package/dist/actions/focus-trap.js +34 -0
  10. package/dist/actions/scroll-lock.d.ts +1 -0
  11. package/dist/actions/scroll-lock.js +17 -0
  12. package/dist/components/actions/Button.svelte +169 -0
  13. package/dist/components/actions/Button.svelte.d.ts +19 -0
  14. package/dist/components/appshell/AppShell.svelte +50 -0
  15. package/dist/components/appshell/AppShell.svelte.d.ts +19 -0
  16. package/dist/components/appshell/AppShellBottomNav.svelte +67 -0
  17. package/dist/components/appshell/AppShellBottomNav.svelte.d.ts +9 -0
  18. package/dist/components/appshell/AppShellContent.svelte +38 -0
  19. package/dist/components/appshell/AppShellContent.svelte.d.ts +10 -0
  20. package/dist/components/appshell/AppShellSidebar.svelte +196 -0
  21. package/dist/components/appshell/AppShellSidebar.svelte.d.ts +15 -0
  22. package/dist/components/appshell/types.d.ts +6 -0
  23. package/dist/components/appshell/types.js +1 -0
  24. package/dist/components/appshell/utils.d.ts +1 -0
  25. package/dist/components/appshell/utils.js +3 -0
  26. package/dist/components/card/Card.svelte +31 -0
  27. package/dist/components/card/Card.svelte.d.ts +9 -0
  28. package/dist/components/card/CardAction.svelte +57 -0
  29. package/dist/components/card/CardAction.svelte.d.ts +10 -0
  30. package/dist/components/card/CardContent.svelte +25 -0
  31. package/dist/components/card/CardContent.svelte.d.ts +8 -0
  32. package/dist/components/card/CardDescription.svelte +24 -0
  33. package/dist/components/card/CardDescription.svelte.d.ts +8 -0
  34. package/dist/components/card/CardFooter.svelte +25 -0
  35. package/dist/components/card/CardFooter.svelte.d.ts +8 -0
  36. package/dist/components/card/CardHeader.svelte +54 -0
  37. package/dist/components/card/CardHeader.svelte.d.ts +10 -0
  38. package/dist/components/card/CardTitle.svelte +25 -0
  39. package/dist/components/card/CardTitle.svelte.d.ts +8 -0
  40. package/dist/components/chat/ChatMessage.svelte +104 -0
  41. package/dist/components/chat/ChatMessage.svelte.d.ts +10 -0
  42. package/dist/components/choice/Listbox.svelte +183 -0
  43. package/dist/components/choice/Listbox.svelte.d.ts +15 -0
  44. package/dist/components/choice/MultiSelect.svelte +278 -0
  45. package/dist/components/choice/MultiSelect.svelte.d.ts +18 -0
  46. package/dist/components/choice/Rating.svelte +91 -0
  47. package/dist/components/choice/Rating.svelte.d.ts +12 -0
  48. package/dist/components/choice/Toggle.svelte +112 -0
  49. package/dist/components/choice/Toggle.svelte.d.ts +12 -0
  50. package/dist/components/feedback/Badge.svelte +66 -0
  51. package/dist/components/feedback/Badge.svelte.d.ts +9 -0
  52. package/dist/components/feedback/ErrorPage.svelte +99 -0
  53. package/dist/components/feedback/ErrorPage.svelte.d.ts +13 -0
  54. package/dist/components/feedback/Message.svelte +130 -0
  55. package/dist/components/feedback/Message.svelte.d.ts +14 -0
  56. package/dist/components/feedback/ProgressBar.svelte +69 -0
  57. package/dist/components/feedback/ProgressBar.svelte.d.ts +8 -0
  58. package/dist/components/feedback/Skeleton.svelte +47 -0
  59. package/dist/components/feedback/Skeleton.svelte.d.ts +9 -0
  60. package/dist/components/feedback/Status.svelte +75 -0
  61. package/dist/components/feedback/Status.svelte.d.ts +10 -0
  62. package/dist/components/feedback/StatusPill.svelte +94 -0
  63. package/dist/components/feedback/StatusPill.svelte.d.ts +13 -0
  64. package/dist/components/feedback/Toaster.svelte +122 -0
  65. package/dist/components/feedback/Toaster.svelte.d.ts +7 -0
  66. package/dist/components/feedback/Tooltip.svelte +126 -0
  67. package/dist/components/feedback/Tooltip.svelte.d.ts +10 -0
  68. package/dist/components/feedback/toast.svelte.d.ts +27 -0
  69. package/dist/components/feedback/toast.svelte.js +23 -0
  70. package/dist/components/forms/Checkbox.svelte +96 -0
  71. package/dist/components/forms/Checkbox.svelte.d.ts +11 -0
  72. package/dist/components/forms/DatePicker.svelte +372 -0
  73. package/dist/components/forms/DatePicker.svelte.d.ts +21 -0
  74. package/dist/components/forms/Field.svelte +47 -0
  75. package/dist/components/forms/Field.svelte.d.ts +11 -0
  76. package/dist/components/forms/FileUpload.svelte +504 -0
  77. package/dist/components/forms/FileUpload.svelte.d.ts +43 -0
  78. package/dist/components/forms/Input.svelte +93 -0
  79. package/dist/components/forms/Input.svelte.d.ts +9 -0
  80. package/dist/components/forms/Label.svelte +30 -0
  81. package/dist/components/forms/Label.svelte.d.ts +10 -0
  82. package/dist/components/forms/Radio.svelte +80 -0
  83. package/dist/components/forms/Radio.svelte.d.ts +11 -0
  84. package/dist/components/forms/Select.svelte +322 -0
  85. package/dist/components/forms/Select.svelte.d.ts +22 -0
  86. package/dist/components/forms/TagInput.svelte +336 -0
  87. package/dist/components/forms/TagInput.svelte.d.ts +16 -0
  88. package/dist/components/forms/Textarea.svelte +64 -0
  89. package/dist/components/forms/Textarea.svelte.d.ts +9 -0
  90. package/dist/components/landing/Landing.svelte +47 -0
  91. package/dist/components/landing/Landing.svelte.d.ts +8 -0
  92. package/dist/components/landing/LandingFeatures.svelte +92 -0
  93. package/dist/components/landing/LandingFeatures.svelte.d.ts +15 -0
  94. package/dist/components/landing/LandingHero.svelte +92 -0
  95. package/dist/components/landing/LandingHero.svelte.d.ts +13 -0
  96. package/dist/components/landing/LandingRoadmap.svelte +42 -0
  97. package/dist/components/landing/LandingRoadmap.svelte.d.ts +11 -0
  98. package/dist/components/landing/LandingSection.svelte +25 -0
  99. package/dist/components/landing/LandingSection.svelte.d.ts +9 -0
  100. package/dist/components/landing/LandingSectionHeading.svelte +19 -0
  101. package/dist/components/landing/LandingSectionHeading.svelte.d.ts +10 -0
  102. package/dist/components/landing/LandingSteps.svelte +100 -0
  103. package/dist/components/landing/LandingSteps.svelte.d.ts +13 -0
  104. package/dist/components/layout/BracketLink.svelte +41 -0
  105. package/dist/components/layout/BracketLink.svelte.d.ts +9 -0
  106. package/dist/components/layout/Divider.svelte +70 -0
  107. package/dist/components/layout/Divider.svelte.d.ts +9 -0
  108. package/dist/components/layout/Eyebrow.svelte +24 -0
  109. package/dist/components/layout/Eyebrow.svelte.d.ts +8 -0
  110. package/dist/components/layout/PageHeader.svelte +106 -0
  111. package/dist/components/layout/PageHeader.svelte.d.ts +15 -0
  112. package/dist/components/layout/PageSeo.svelte +34 -0
  113. package/dist/components/layout/PageSeo.svelte.d.ts +10 -0
  114. package/dist/components/layout/PageShell.svelte +25 -0
  115. package/dist/components/layout/PageShell.svelte.d.ts +8 -0
  116. package/dist/components/layout/Panel.svelte +105 -0
  117. package/dist/components/layout/Panel.svelte.d.ts +12 -0
  118. package/dist/components/layout/Prose.svelte +101 -0
  119. package/dist/components/layout/Prose.svelte.d.ts +7 -0
  120. package/dist/components/layout/RuleCard.svelte +63 -0
  121. package/dist/components/layout/RuleCard.svelte.d.ts +13 -0
  122. package/dist/components/layout/SectionHeading.svelte +57 -0
  123. package/dist/components/layout/SectionHeading.svelte.d.ts +10 -0
  124. package/dist/components/layout/StatTile.svelte +76 -0
  125. package/dist/components/layout/StatTile.svelte.d.ts +12 -0
  126. package/dist/components/layout/TerminalWindow.svelte +81 -0
  127. package/dist/components/layout/TerminalWindow.svelte.d.ts +9 -0
  128. package/dist/components/layout/Wordmark.svelte +26 -0
  129. package/dist/components/layout/Wordmark.svelte.d.ts +8 -0
  130. package/dist/components/list/List.svelte +40 -0
  131. package/dist/components/list/List.svelte.d.ts +13 -0
  132. package/dist/components/list/ListItem.svelte +81 -0
  133. package/dist/components/list/ListItem.svelte.d.ts +13 -0
  134. package/dist/components/marketing/MarketingShell.svelte +170 -0
  135. package/dist/components/marketing/MarketingShell.svelte.d.ts +23 -0
  136. package/dist/components/marketing/MarketingShellFooter.svelte +92 -0
  137. package/dist/components/marketing/MarketingShellFooter.svelte.d.ts +14 -0
  138. package/dist/components/navigation/Accordion.svelte +110 -0
  139. package/dist/components/navigation/Accordion.svelte.d.ts +15 -0
  140. package/dist/components/navigation/Carousel.svelte +115 -0
  141. package/dist/components/navigation/Carousel.svelte.d.ts +12 -0
  142. package/dist/components/navigation/InstructionStep.svelte +115 -0
  143. package/dist/components/navigation/InstructionStep.svelte.d.ts +10 -0
  144. package/dist/components/navigation/InstructionSteps.svelte +39 -0
  145. package/dist/components/navigation/InstructionSteps.svelte.d.ts +8 -0
  146. package/dist/components/navigation/Nav.svelte +102 -0
  147. package/dist/components/navigation/Nav.svelte.d.ts +14 -0
  148. package/dist/components/navigation/Stepper.svelte +112 -0
  149. package/dist/components/navigation/Stepper.svelte.d.ts +12 -0
  150. package/dist/components/navigation/TabCard.svelte +62 -0
  151. package/dist/components/navigation/TabCard.svelte.d.ts +10 -0
  152. package/dist/components/navigation/Tabs.svelte +83 -0
  153. package/dist/components/navigation/Tabs.svelte.d.ts +12 -0
  154. package/dist/components/navigation/ThemeToggle.svelte +118 -0
  155. package/dist/components/navigation/ThemeToggle.svelte.d.ts +20 -0
  156. package/dist/components/overlay/Dialog.svelte +200 -0
  157. package/dist/components/overlay/Dialog.svelte.d.ts +19 -0
  158. package/dist/components/overlay/DialogActions.svelte +50 -0
  159. package/dist/components/overlay/DialogActions.svelte.d.ts +9 -0
  160. package/dist/components/overlay/Dropdown.svelte +110 -0
  161. package/dist/components/overlay/Dropdown.svelte.d.ts +10 -0
  162. package/dist/components/overlay/FloatingActionPill.svelte +96 -0
  163. package/dist/components/overlay/FloatingActionPill.svelte.d.ts +14 -0
  164. package/dist/components/overlay/Sidebar.svelte +258 -0
  165. package/dist/components/overlay/Sidebar.svelte.d.ts +18 -0
  166. package/dist/components/table/Table.svelte +550 -0
  167. package/dist/components/table/Table.svelte.d.ts +42 -0
  168. package/dist/components/timeline/Timeline.svelte +25 -0
  169. package/dist/components/timeline/Timeline.svelte.d.ts +8 -0
  170. package/dist/components/timeline/TimelineItem.svelte +220 -0
  171. package/dist/components/timeline/TimelineItem.svelte.d.ts +18 -0
  172. package/dist/index.d.ts +156 -0
  173. package/dist/index.js +149 -0
  174. package/dist/theme/theme.css +348 -0
  175. package/package.json +52 -0
@@ -0,0 +1,278 @@
1
+ <script lang="ts">
2
+ import { fade } from 'svelte/transition';
3
+ import type { SelectOption } from '../forms/Select.svelte';
4
+ import { clickOutside } from '../../actions/click-outside';
5
+
6
+ let {
7
+ options = [],
8
+ value = $bindable([]),
9
+ label,
10
+ name,
11
+ disabled = false,
12
+ placeholder = 'Selecione...',
13
+ filter = false,
14
+ filterPlaceholder = 'Buscar...',
15
+ 'aria-label': ariaLabel,
16
+ class: className = '',
17
+ ...rest
18
+ }: {
19
+ options?: SelectOption[];
20
+ value?: string[];
21
+ label?: string;
22
+ name?: string;
23
+ disabled?: boolean;
24
+ placeholder?: string;
25
+ filter?: boolean;
26
+ filterPlaceholder?: string;
27
+ class?: string;
28
+ } & { 'aria-label'?: string; id?: string } = $props();
29
+
30
+ let open = $state(false);
31
+ let rootEl = $state<HTMLDivElement | undefined>();
32
+ let query = $state('');
33
+
34
+ const selected = $derived(options.filter((o) => value.includes(o.value)));
35
+ const visibleOptions = $derived(
36
+ filter && query.trim()
37
+ ? options.filter((o) => o.label.toLowerCase().includes(query.trim().toLowerCase()))
38
+ : options
39
+ );
40
+
41
+ function toggle() {
42
+ if (disabled) return;
43
+ open = !open;
44
+ if (open) query = '';
45
+ }
46
+
47
+ function toggleOption(option: SelectOption) {
48
+ if (option.disabled) return;
49
+ value = value.includes(option.value)
50
+ ? value.filter((v) => v !== option.value)
51
+ : [...value, option.value];
52
+ }
53
+ </script>
54
+
55
+ <div
56
+ class="twui-multiselect {className}"
57
+ bind:this={rootEl}
58
+ use:clickOutside={() => (open = false)}
59
+ >
60
+ <button
61
+ type="button"
62
+ class="twui-multiselect-trigger"
63
+ {...rest}
64
+ aria-label={ariaLabel ?? label}
65
+ disabled={disabled}
66
+ aria-haspopup="listbox"
67
+ aria-expanded={open}
68
+ onclick={toggle}
69
+ >
70
+ <span class="twui-multiselect-value {selected.length ? '' : 'twui-multiselect-placeholder'}">
71
+ {selected.length ? selected.map((o) => o.label).join(', ') : placeholder}
72
+ </span>
73
+ <svg
74
+ class="twui-multiselect-chevron {open ? 'twui-multiselect-chevron-open' : ''}"
75
+ width="16"
76
+ height="16"
77
+ viewBox="0 0 24 24"
78
+ fill="none"
79
+ stroke="currentColor"
80
+ stroke-width="2"
81
+ stroke-linecap="round"
82
+ stroke-linejoin="round"
83
+ aria-hidden="true"
84
+ ><path d="m6 9 6 6 6-6" /></svg>
85
+ </button>
86
+
87
+ {#if name}
88
+ <input type="hidden" {name} value={value.join(',')} />
89
+ {/if}
90
+
91
+ {#if open}
92
+ <div
93
+ class="twui-multiselect-popover"
94
+ role="listbox"
95
+ aria-multiselectable="true"
96
+ transition:fade={{ duration: 100 }}
97
+ >
98
+ {#if filter}
99
+ <div class="twui-multiselect-filter">
100
+ <input
101
+ type="text"
102
+ class="twui-multiselect-filter-input"
103
+ placeholder={filterPlaceholder}
104
+ bind:value={query}
105
+ aria-label={filterPlaceholder}
106
+ />
107
+ </div>
108
+ {/if}
109
+ {#if visibleOptions.length > 0}
110
+ {#each visibleOptions as option (option.value)}
111
+ <button
112
+ type="button"
113
+ role="option"
114
+ aria-selected={value.includes(option.value)}
115
+ class="twui-multiselect-option {value.includes(option.value) ? 'twui-multiselect-option-selected' : ''}"
116
+ disabled={option.disabled}
117
+ onclick={() => toggleOption(option)}
118
+ >
119
+ <span class="twui-multiselect-check" aria-hidden="true">{value.includes(option.value) ? '✓' : ''}</span>
120
+ {option.label}
121
+ </button>
122
+ {/each}
123
+ {:else}
124
+ <div class="twui-multiselect-empty">Nenhum resultado</div>
125
+ {/if}
126
+ </div>
127
+ {/if}
128
+ </div>
129
+
130
+ <style>
131
+ .twui-multiselect {
132
+ position: relative;
133
+ width: 100%;
134
+ }
135
+
136
+ .twui-multiselect-trigger {
137
+ display: flex;
138
+ align-items: center;
139
+ justify-content: space-between;
140
+ gap: 8px;
141
+ width: 100%;
142
+ padding: 8px 12px;
143
+ border: 1px solid var(--twui-rule);
144
+ background: var(--twui-paper);
145
+ font-family: var(--twui-font-mono);
146
+ font-size: 14px;
147
+ text-align: left;
148
+ color: var(--twui-ink);
149
+ cursor: pointer;
150
+ transition:
151
+ border-color 0.15s ease,
152
+ box-shadow 0.15s ease;
153
+ }
154
+
155
+ .twui-multiselect-trigger:focus-visible {
156
+ border-color: var(--twui-accent);
157
+ }
158
+
159
+ .twui-multiselect-trigger:disabled {
160
+ opacity: 0.5;
161
+ cursor: not-allowed;
162
+ }
163
+
164
+ .twui-multiselect-value {
165
+ overflow: hidden;
166
+ text-overflow: ellipsis;
167
+ white-space: nowrap;
168
+ }
169
+
170
+ .twui-multiselect-placeholder {
171
+ color: var(--twui-ink-faint);
172
+ }
173
+
174
+ .twui-multiselect-chevron {
175
+ flex-shrink: 0;
176
+ color: var(--twui-ink-soft);
177
+ transition: transform 0.15s ease;
178
+ }
179
+
180
+ .twui-multiselect-chevron-open {
181
+ transform: rotate(180deg);
182
+ }
183
+
184
+ .twui-multiselect-popover {
185
+ position: absolute;
186
+ top: calc(100% + 4px);
187
+ right: 0;
188
+ left: 0;
189
+ z-index: 50;
190
+ max-height: 240px;
191
+ overflow-y: auto;
192
+ border: 1px solid var(--twui-rule);
193
+ background: var(--twui-paper-raised);
194
+ box-shadow: var(--twui-shadow-offset, 3px 3px 0 0 var(--twui-rule));
195
+ padding: 4px;
196
+ }
197
+
198
+ .twui-multiselect-filter {
199
+ padding: 4px 4px 8px;
200
+ border-bottom: 1px solid var(--twui-rule);
201
+ margin-bottom: 4px;
202
+ }
203
+
204
+ .twui-multiselect-filter-input {
205
+ width: 100%;
206
+ padding: 6px 8px;
207
+ border: 1px solid var(--twui-rule);
208
+ background: var(--twui-paper);
209
+ font-family: var(--twui-font-mono);
210
+ font-size: 13px;
211
+ color: var(--twui-ink);
212
+ outline: none;
213
+ }
214
+
215
+ .twui-multiselect-filter-input::placeholder {
216
+ color: var(--twui-ink-faint);
217
+ }
218
+
219
+ .twui-multiselect-filter-input:focus-visible {
220
+ border-color: var(--twui-accent);
221
+ }
222
+
223
+ .twui-multiselect-option {
224
+ display: flex;
225
+ align-items: center;
226
+ gap: 8px;
227
+ width: 100%;
228
+ padding: 6px 10px;
229
+ border: none;
230
+ background: transparent;
231
+ font-family: var(--twui-font-mono);
232
+ font-size: 13px;
233
+ text-align: left;
234
+ color: var(--twui-ink);
235
+ cursor: pointer;
236
+ }
237
+
238
+ .twui-multiselect-option:hover {
239
+ background: var(--twui-accent-soft);
240
+ color: var(--twui-accent);
241
+ }
242
+
243
+ .twui-multiselect-option-selected {
244
+ color: var(--twui-accent);
245
+ font-weight: 500;
246
+ }
247
+
248
+ .twui-multiselect-option:disabled {
249
+ opacity: 0.4;
250
+ cursor: not-allowed;
251
+ }
252
+
253
+ .twui-multiselect-check {
254
+ display: inline-flex;
255
+ align-items: center;
256
+ justify-content: center;
257
+ width: 14px;
258
+ height: 14px;
259
+ flex-shrink: 0;
260
+ border: 1px solid var(--twui-rule);
261
+ border-radius: 2px;
262
+ font-size: 10px;
263
+ line-height: 1;
264
+ }
265
+
266
+ .twui-multiselect-option-selected .twui-multiselect-check {
267
+ border-color: var(--twui-accent);
268
+ background: var(--twui-accent);
269
+ color: var(--twui-paper);
270
+ }
271
+
272
+ .twui-multiselect-empty {
273
+ padding: 8px 10px;
274
+ font-family: var(--twui-font-mono);
275
+ font-size: 13px;
276
+ color: var(--twui-ink-faint);
277
+ }
278
+ </style>
@@ -0,0 +1,18 @@
1
+ import type { SelectOption } from '../forms/Select.svelte';
2
+ type $$ComponentProps = {
3
+ options?: SelectOption[];
4
+ value?: string[];
5
+ label?: string;
6
+ name?: string;
7
+ disabled?: boolean;
8
+ placeholder?: string;
9
+ filter?: boolean;
10
+ filterPlaceholder?: string;
11
+ class?: string;
12
+ } & {
13
+ 'aria-label'?: string;
14
+ id?: string;
15
+ };
16
+ declare const MultiSelect: import("svelte").Component<$$ComponentProps, {}, "value">;
17
+ type MultiSelect = ReturnType<typeof MultiSelect>;
18
+ export default MultiSelect;
@@ -0,0 +1,91 @@
1
+ <script lang="ts">
2
+ let {
3
+ value = $bindable(0),
4
+ max = 5,
5
+ readonly = false,
6
+ cancel = false,
7
+ cancelLabel = 'Cancelar avaliação',
8
+ label = 'Avaliação',
9
+ class: className = ''
10
+ }: {
11
+ value?: number;
12
+ max?: number;
13
+ readonly?: boolean;
14
+ cancel?: boolean;
15
+ cancelLabel?: string;
16
+ label?: string;
17
+ class?: string;
18
+ } = $props();
19
+ </script>
20
+
21
+ <div class="twui-rating {className}" role="radiogroup" aria-label={label}>
22
+ {#if cancel}
23
+ <button
24
+ type="button"
25
+ class="twui-rating-cancel"
26
+ aria-label={cancelLabel}
27
+ onclick={() => (value = 0)}
28
+ >×</button>
29
+ {/if}
30
+ {#each Array(max) as _, i (i)}
31
+ <button
32
+ type="button"
33
+ class="twui-rating-star {i < value ? 'twui-rating-star-on' : ''}"
34
+ role="radio"
35
+ aria-checked={i < value}
36
+ aria-label={`${i + 1} de ${max}`}
37
+ disabled={readonly}
38
+ onclick={() => (value = i + 1)}
39
+ >★</button>
40
+ {/each}
41
+ </div>
42
+
43
+ <style>
44
+ .twui-rating {
45
+ display: inline-flex;
46
+ align-items: center;
47
+ gap: 2px;
48
+ }
49
+
50
+ .twui-rating-star,
51
+ .twui-rating-cancel {
52
+ display: inline-flex;
53
+ align-items: center;
54
+ justify-content: center;
55
+ width: 24px;
56
+ height: 24px;
57
+ padding: 0;
58
+ border: none;
59
+ background: transparent;
60
+ font-size: 16px;
61
+ line-height: 1;
62
+ color: var(--twui-ink-faint);
63
+ cursor: pointer;
64
+ transition: color 0.15s ease;
65
+ }
66
+
67
+ .twui-rating-star:hover:not(:disabled) {
68
+ color: var(--twui-accent);
69
+ }
70
+
71
+ .twui-rating-star-on {
72
+ color: var(--twui-accent);
73
+ }
74
+
75
+ .twui-rating-cancel {
76
+ color: var(--twui-ink-faint);
77
+ font-size: 15px;
78
+ margin-right: 4px;
79
+ }
80
+
81
+ .twui-rating:has(.twui-rating-star:focus-visible),
82
+ .twui-rating:has(.twui-rating-cancel:focus-visible) {
83
+ outline: 2px solid var(--twui-accent);
84
+ outline-offset: 2px;
85
+ }
86
+
87
+ .twui-rating-star:disabled {
88
+ opacity: 0.6;
89
+ cursor: default;
90
+ }
91
+ </style>
@@ -0,0 +1,12 @@
1
+ type $$ComponentProps = {
2
+ value?: number;
3
+ max?: number;
4
+ readonly?: boolean;
5
+ cancel?: boolean;
6
+ cancelLabel?: string;
7
+ label?: string;
8
+ class?: string;
9
+ };
10
+ declare const Rating: import("svelte").Component<$$ComponentProps, {}, "value">;
11
+ type Rating = ReturnType<typeof Rating>;
12
+ export default Rating;
@@ -0,0 +1,112 @@
1
+ <script lang="ts">
2
+ import type { HTMLInputAttributes } from 'svelte/elements';
3
+
4
+ let {
5
+ class: className = '',
6
+ checked = $bindable(false),
7
+ name,
8
+ value,
9
+ disabled = false,
10
+ invalid = false,
11
+ label,
12
+ 'aria-label': ariaLabel,
13
+ ...rest
14
+ }: HTMLInputAttributes & {
15
+ checked?: boolean;
16
+ name?: string;
17
+ value?: string;
18
+ disabled?: boolean;
19
+ invalid?: boolean;
20
+ label?: string;
21
+ } = $props();
22
+ </script>
23
+
24
+ <label class="twui-toggle {disabled ? 'twui-toggle-disabled' : ''} {className}">
25
+ <input
26
+ {...rest}
27
+ type="checkbox"
28
+ {name}
29
+ {value}
30
+ {disabled}
31
+ checked={checked}
32
+ onchange={(e) => (checked = e.currentTarget.checked)}
33
+ class="twui-toggle-input"
34
+ role="switch"
35
+ aria-checked={checked}
36
+ aria-invalid={invalid}
37
+ aria-label={ariaLabel ?? label}
38
+ />
39
+ <span class="twui-toggle-track {invalid ? 'twui-toggle-invalid' : ''}" aria-hidden="true">
40
+ <span class="twui-toggle-knob"></span>
41
+ </span>
42
+ {#if label}
43
+ <span class="twui-toggle-label">{label}</span>
44
+ {/if}
45
+ </label>
46
+
47
+ <style>
48
+ .twui-toggle {
49
+ display: inline-flex;
50
+ align-items: center;
51
+ gap: 8px;
52
+ cursor: pointer;
53
+ font-family: var(--twui-font-mono);
54
+ font-size: 14px;
55
+ color: var(--twui-ink);
56
+ }
57
+
58
+ .twui-toggle-input {
59
+ position: absolute;
60
+ opacity: 0;
61
+ pointer-events: none;
62
+ }
63
+
64
+ .twui-toggle-track {
65
+ position: relative;
66
+ width: 34px;
67
+ height: 18px;
68
+ flex-shrink: 0;
69
+ border: 1px solid var(--twui-rule);
70
+ background: var(--twui-paper);
71
+ border-radius: 9999px;
72
+ transition:
73
+ border-color 0.15s ease,
74
+ background 0.15s ease;
75
+ }
76
+
77
+ .twui-toggle-knob {
78
+ position: absolute;
79
+ top: 2px;
80
+ left: 2px;
81
+ width: 12px;
82
+ height: 12px;
83
+ border-radius: 9999px;
84
+ background: var(--twui-ink-soft);
85
+ transition:
86
+ transform 0.15s ease,
87
+ background 0.15s ease;
88
+ }
89
+
90
+ .twui-toggle-input:checked + .twui-toggle-track {
91
+ border-color: var(--twui-accent);
92
+ background: var(--twui-accent);
93
+ }
94
+
95
+ .twui-toggle-input:checked + .twui-toggle-track .twui-toggle-knob {
96
+ transform: translateX(16px);
97
+ background: var(--twui-paper);
98
+ }
99
+
100
+ .twui-toggle:has(.twui-toggle-input:focus-visible) .twui-toggle-track {
101
+ box-shadow: 0 0 0 2px var(--twui-accent-soft);
102
+ }
103
+
104
+ .twui-toggle-invalid {
105
+ border-color: var(--twui-danger);
106
+ }
107
+
108
+ .twui-toggle-disabled {
109
+ opacity: 0.5;
110
+ cursor: not-allowed;
111
+ }
112
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { HTMLInputAttributes } from 'svelte/elements';
2
+ type $$ComponentProps = HTMLInputAttributes & {
3
+ checked?: boolean;
4
+ name?: string;
5
+ value?: string;
6
+ disabled?: boolean;
7
+ invalid?: boolean;
8
+ label?: string;
9
+ };
10
+ declare const Toggle: import("svelte").Component<$$ComponentProps, {}, "checked">;
11
+ type Toggle = ReturnType<typeof Toggle>;
12
+ export default Toggle;
@@ -0,0 +1,66 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ let {
5
+ variant = 'primary',
6
+ children,
7
+ class: className = ''
8
+ }: {
9
+ variant?: 'primary' | 'secondary' | 'outline' | 'success' | 'danger' | 'info' | 'warn';
10
+ children: Snippet;
11
+ class?: string;
12
+ } = $props();
13
+ </script>
14
+
15
+ <span class="twui-badge twui-badge-{variant} {className}">
16
+ [&nbsp;{@render children()}&nbsp;]
17
+ </span>
18
+
19
+ <style>
20
+ .twui-badge {
21
+ display: inline-flex;
22
+ align-items: center;
23
+ padding: 2px 6px;
24
+ border: 1px solid var(--twui-rule);
25
+ font-family: var(--twui-font-mono);
26
+ font-size: 12px;
27
+ color: var(--twui-ink-soft);
28
+ line-height: 1.4;
29
+ }
30
+
31
+ .twui-badge-primary {
32
+ background: color-mix(in oklab, var(--twui-accent) 12%, transparent);
33
+ color: var(--twui-accent);
34
+ }
35
+
36
+ .twui-badge-secondary {
37
+ background: var(--twui-rule);
38
+ color: var(--twui-ink);
39
+ }
40
+
41
+ .twui-badge-outline {
42
+ border-color: var(--twui-ink-soft);
43
+ background: transparent;
44
+ color: var(--twui-ink);
45
+ }
46
+
47
+ .twui-badge-success {
48
+ background: color-mix(in oklab, var(--twui-signal, #22c55e) 10%, transparent);
49
+ color: var(--twui-signal, #22c55e);
50
+ }
51
+
52
+ .twui-badge-danger {
53
+ background: color-mix(in oklab, var(--twui-danger) 10%, transparent);
54
+ color: var(--twui-danger);
55
+ }
56
+
57
+ .twui-badge-info {
58
+ background: color-mix(in oklab, var(--twui-accent) 10%, transparent);
59
+ color: var(--twui-accent);
60
+ }
61
+
62
+ .twui-badge-warn {
63
+ background: color-mix(in oklab, var(--twui-warning, #f59e0b) 10%, transparent);
64
+ color: var(--twui-warning, #f59e0b);
65
+ }
66
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ variant?: 'primary' | 'secondary' | 'outline' | 'success' | 'danger' | 'info' | 'warn';
4
+ children: Snippet;
5
+ class?: string;
6
+ };
7
+ declare const Badge: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type Badge = ReturnType<typeof Badge>;
9
+ export default Badge;
@@ -0,0 +1,99 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ let {
5
+ status,
6
+ title,
7
+ description = '',
8
+ homeHref = '/',
9
+ homeLabel = 'Voltar ao início',
10
+ actions,
11
+ class: className = ''
12
+ }: {
13
+ status: number;
14
+ title: string;
15
+ description?: string;
16
+ homeHref?: string;
17
+ homeLabel?: string;
18
+ actions?: Snippet;
19
+ class?: string;
20
+ } = $props();
21
+ </script>
22
+
23
+ <div class="twui-error-page {className}">
24
+ <div class="twui-error-code" aria-hidden="true">{status}</div>
25
+ <h1 class="twui-error-title">{title}</h1>
26
+ {#if description}
27
+ <p class="twui-error-description">{description}</p>
28
+ {/if}
29
+ <div class="twui-error-actions">
30
+ <a class="twui-error-home" href={homeHref}>{homeLabel}</a>
31
+ {#if actions}
32
+ {@render actions()}
33
+ {/if}
34
+ </div>
35
+ </div>
36
+
37
+ <style>
38
+ .twui-error-page {
39
+ display: flex;
40
+ min-height: 100svh;
41
+ flex-direction: column;
42
+ align-items: center;
43
+ justify-content: center;
44
+ gap: 8px;
45
+ padding: 24px;
46
+ text-align: center;
47
+ background: var(--twui-paper);
48
+ }
49
+
50
+ .twui-error-code {
51
+ font-family: var(--twui-font-mono);
52
+ font-size: 88px;
53
+ font-weight: 700;
54
+ line-height: 1;
55
+ color: var(--twui-accent);
56
+ }
57
+
58
+ .twui-error-title {
59
+ margin: 0;
60
+ font-family: var(--twui-font-mono);
61
+ font-size: 16px;
62
+ font-weight: 600;
63
+ color: var(--twui-ink);
64
+ }
65
+
66
+ .twui-error-description {
67
+ margin: 0;
68
+ max-width: 420px;
69
+ font-family: var(--twui-font-mono);
70
+ font-size: 13px;
71
+ color: var(--twui-ink-soft);
72
+ }
73
+
74
+ .twui-error-actions {
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ gap: 8px;
79
+ margin-top: 12px;
80
+ }
81
+
82
+ .twui-error-home {
83
+ display: inline-flex;
84
+ align-items: center;
85
+ border: 1px solid var(--twui-accent);
86
+ background: var(--twui-accent);
87
+ padding: 8px 16px;
88
+ font-family: var(--twui-font-mono);
89
+ font-size: 13px;
90
+ font-weight: 500;
91
+ color: var(--twui-paper);
92
+ text-decoration: none;
93
+ cursor: pointer;
94
+ }
95
+
96
+ .twui-error-home:hover {
97
+ opacity: 0.85;
98
+ }
99
+ </style>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ status: number;
4
+ title: string;
5
+ description?: string;
6
+ homeHref?: string;
7
+ homeLabel?: string;
8
+ actions?: Snippet;
9
+ class?: string;
10
+ };
11
+ declare const ErrorPage: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type ErrorPage = ReturnType<typeof ErrorPage>;
13
+ export default ErrorPage;