yaxa-svelte 1.9.0 → 1.10.0
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/dist/admin/components/AdminDashboard.svelte +6 -0
- package/dist/admin/components/DevSandbox.svelte +6 -2
- package/dist/admin/components/RecordDrawer.svelte +4 -0
- package/dist/components/elements/Icon.svelte +32 -1
- package/dist/components/forms/Checkbox.svelte +3 -0
- package/dist/components/forms/Checkbox.svelte.d.ts +1 -0
- package/dist/components/forms/ColorPicker.svelte +22 -2
- package/dist/components/forms/ColorPicker.svelte.d.ts +5 -0
- package/dist/components/forms/Combobox.svelte +3 -0
- package/dist/components/forms/Dropzone.svelte +11 -0
- package/dist/components/forms/Dropzone.svelte.d.ts +4 -0
- package/dist/components/forms/FormField.svelte +6 -1
- package/dist/components/forms/FormField.svelte.d.ts +1 -0
- package/dist/components/forms/InputOTP.svelte +6 -0
- package/dist/components/forms/InputOTP.svelte.d.ts +2 -0
- package/dist/components/forms/MultiSelect.svelte +3 -0
- package/dist/components/forms/NumberInput.svelte +11 -1
- package/dist/components/forms/NumberInput.svelte.d.ts +4 -0
- package/dist/components/forms/RadioGroup.svelte +2 -0
- package/dist/components/forms/Select.svelte +14 -1
- package/dist/components/forms/Select.svelte.d.ts +5 -0
- package/dist/components/forms/Slider.svelte +14 -1
- package/dist/components/forms/Slider.svelte.d.ts +4 -0
- package/dist/components/forms/Switch.svelte +14 -1
- package/dist/components/forms/Switch.svelte.d.ts +3 -0
- package/dist/components/layout/Footer.svelte +10 -15
- package/dist/components/layout/Header.svelte +5 -4
- package/dist/components/layout/YaxaApp.svelte +9 -7
- package/dist/components/legal/LegalDocument.svelte +3 -2
- package/dist/components/navigation/CommandPalette.svelte +3 -0
- package/dist/components/navigation/DropdownMenu.svelte +14 -11
- package/dist/components/overlays/Popover.svelte +5 -1
- package/dist/components/overlays/Tooltip.svelte +9 -5
- package/dist/components/saas/Gate.svelte +3 -2
- package/dist/components/saas/UserMenu.svelte +3 -3
- package/dist/components/seo/Favicons.svelte +37 -12
- package/dist/components/seo/Favicons.svelte.d.ts +4 -0
- package/dist/components/seo/OgImage.svelte +3 -2
- package/dist/components/seo/Seo.svelte +6 -4
- package/dist/composables/useGate.svelte.js +3 -2
- package/dist/composables/useLocale.svelte.js +8 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/site/config.d.ts +2 -0
- package/dist/site/context.d.ts +1 -30
- package/dist/site/context.js +1 -43
- package/dist/site/context.svelte.d.ts +37 -0
- package/dist/site/context.svelte.js +52 -0
- package/dist/site/context.test.d.ts +1 -0
- package/dist/site/context.test.js +29 -0
- package/dist/styles/yaxa.css +21 -0
- package/dist/vite/index.js +12 -4
- package/dist/vite/index.test.js +6 -6
- package/package.json +6 -12
|
@@ -284,8 +284,11 @@
|
|
|
284
284
|
<div class="flex items-center gap-2">
|
|
285
285
|
<form onsubmit={handleSearch} class="relative">
|
|
286
286
|
<input
|
|
287
|
+
id="admin-search-input"
|
|
288
|
+
name="adminSearch"
|
|
287
289
|
type="search"
|
|
288
290
|
placeholder="Search records..."
|
|
291
|
+
aria-label="Search records"
|
|
289
292
|
bind:value={searchQuery}
|
|
290
293
|
class="w-48 rounded-lg border border-neutral-300 bg-white py-1.5 pr-3 pl-8 text-xs text-neutral-900 placeholder-neutral-400 transition-all focus:w-60 focus:border-primary-500 focus:ring-1 focus:ring-primary-500 focus:outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
|
|
291
294
|
/>
|
|
@@ -424,6 +427,7 @@
|
|
|
424
427
|
{#if col.dataType === 'boolean'}
|
|
425
428
|
<input
|
|
426
429
|
id={`create-${col.name}`}
|
|
430
|
+
name={col.name}
|
|
427
431
|
type="checkbox"
|
|
428
432
|
class="h-4 w-4 rounded border-neutral-300 text-primary-600 focus:ring-primary-500"
|
|
429
433
|
checked={Boolean(newRecordData[col.name])}
|
|
@@ -432,6 +436,7 @@
|
|
|
432
436
|
{:else if col.dataType === 'number' || col.dataType === 'integer'}
|
|
433
437
|
<input
|
|
434
438
|
id={`create-${col.name}`}
|
|
439
|
+
name={col.name}
|
|
435
440
|
type="number"
|
|
436
441
|
placeholder={col.primaryKey ? '(Auto-generated if empty)' : ''}
|
|
437
442
|
class="w-full rounded-md border border-neutral-300 bg-white px-3 py-1.5 text-xs dark:border-neutral-700 dark:bg-neutral-900"
|
|
@@ -443,6 +448,7 @@
|
|
|
443
448
|
{:else}
|
|
444
449
|
<input
|
|
445
450
|
id={`create-${col.name}`}
|
|
451
|
+
name={col.name}
|
|
446
452
|
type="text"
|
|
447
453
|
placeholder={col.primaryKey ? '(Auto-generated UUID if empty)' : ''}
|
|
448
454
|
class="w-full rounded-md border border-neutral-300 bg-white px-3 py-1.5 text-xs dark:border-neutral-700 dark:bg-neutral-900"
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import Icon from '../../components/elements/Icon.svelte';
|
|
6
6
|
import Progress from '../../components/elements/Progress.svelte';
|
|
7
7
|
import { useUpload } from '../../composables/useUpload.svelte';
|
|
8
|
-
import {
|
|
8
|
+
import { useYaxa } from '../../site/context';
|
|
9
9
|
|
|
10
10
|
interface Props {
|
|
11
11
|
apiPrefix?: string;
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
let { apiPrefix = '/admin/api', class: className = '' }: Props = $props();
|
|
16
16
|
|
|
17
17
|
// Auth & Context info
|
|
18
|
-
const
|
|
18
|
+
const yaxa = useYaxa();
|
|
19
|
+
const user = $derived(yaxa.user);
|
|
19
20
|
|
|
20
21
|
// Email Sandbox State
|
|
21
22
|
let emailTo = $state('developer@example.com');
|
|
@@ -96,6 +97,7 @@
|
|
|
96
97
|
>
|
|
97
98
|
<input
|
|
98
99
|
id="email-to"
|
|
100
|
+
name="emailTo"
|
|
99
101
|
type="email"
|
|
100
102
|
bind:value={emailTo}
|
|
101
103
|
placeholder="you@example.com"
|
|
@@ -109,6 +111,7 @@
|
|
|
109
111
|
>
|
|
110
112
|
<select
|
|
111
113
|
id="email-template"
|
|
114
|
+
name="emailTemplate"
|
|
112
115
|
bind:value={emailTemplate}
|
|
113
116
|
class="w-full rounded-md border border-neutral-300 bg-white px-3 py-1.5 text-xs text-neutral-900 focus:border-primary-500 focus:ring-1 focus:ring-primary-500 focus:outline-none dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
|
|
114
117
|
>
|
|
@@ -172,6 +175,7 @@
|
|
|
172
175
|
>
|
|
173
176
|
<input
|
|
174
177
|
id="storage-file"
|
|
178
|
+
name="storageFile"
|
|
175
179
|
type="file"
|
|
176
180
|
onchange={(e) => {
|
|
177
181
|
const files = e.currentTarget.files;
|
|
@@ -138,6 +138,7 @@
|
|
|
138
138
|
<div class="flex items-center gap-2 pt-1">
|
|
139
139
|
<input
|
|
140
140
|
id={`field-${col.name}`}
|
|
141
|
+
name={col.name}
|
|
141
142
|
type="checkbox"
|
|
142
143
|
class="h-4 w-4 rounded border-neutral-300 text-primary-600 focus:ring-primary-500 dark:border-neutral-700 dark:bg-neutral-800"
|
|
143
144
|
checked={Boolean(formData[col.name])}
|
|
@@ -150,6 +151,7 @@
|
|
|
150
151
|
{:else if col.dataType === 'number' || col.dataType === 'integer'}
|
|
151
152
|
<input
|
|
152
153
|
id={`field-${col.name}`}
|
|
154
|
+
name={col.name}
|
|
153
155
|
type="number"
|
|
154
156
|
class="w-full rounded-md border border-neutral-300 bg-white px-3 py-1.5 text-sm text-neutral-900 placeholder-neutral-400 focus:border-primary-500 focus:ring-1 focus:ring-primary-500 focus:outline-none disabled:opacity-50 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
|
|
155
157
|
disabled={col.primaryKey}
|
|
@@ -162,6 +164,7 @@
|
|
|
162
164
|
{:else if String(formData[col.name] ?? '').length > 60 || col.name.includes('description') || col.name.includes('body')}
|
|
163
165
|
<textarea
|
|
164
166
|
id={`field-${col.name}`}
|
|
167
|
+
name={col.name}
|
|
165
168
|
rows={3}
|
|
166
169
|
class="w-full rounded-md border border-neutral-300 bg-white px-3 py-1.5 font-mono text-sm text-xs text-neutral-900 placeholder-neutral-400 focus:border-primary-500 focus:ring-1 focus:ring-primary-500 focus:outline-none disabled:opacity-50 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
|
|
167
170
|
disabled={col.primaryKey}
|
|
@@ -172,6 +175,7 @@
|
|
|
172
175
|
{:else}
|
|
173
176
|
<input
|
|
174
177
|
id={`field-${col.name}`}
|
|
178
|
+
name={col.name}
|
|
175
179
|
type="text"
|
|
176
180
|
class="w-full rounded-md border border-neutral-300 bg-white px-3 py-1.5 text-sm text-neutral-900 placeholder-neutral-400 focus:border-primary-500 focus:ring-1 focus:ring-primary-500 focus:outline-none disabled:opacity-50 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
|
|
177
181
|
disabled={col.primaryKey}
|
|
@@ -126,7 +126,38 @@
|
|
|
126
126
|
'<circle cx="12" cy="12" r="1.5" fill="currentColor"/><circle cx="12" cy="5" r="1.5" fill="currentColor"/><circle cx="12" cy="19" r="1.5" fill="currentColor"/>',
|
|
127
127
|
user: '<path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none"/><circle cx="12" cy="7" r="4" stroke="currentColor" stroke-width="2" fill="none"/>',
|
|
128
128
|
users:
|
|
129
|
-
'<path d="M17 21v-2a4 4 0 00-3-3.87M9 21v-2a4 4 0 013-3.87M16 3.13a4 4 0 010 7.75M8 3.13a4 4 0 000 7.75" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none"/>'
|
|
129
|
+
'<path d="M17 21v-2a4 4 0 00-3-3.87M9 21v-2a4 4 0 013-3.87M16 3.13a4 4 0 010 7.75M8 3.13a4 4 0 000 7.75" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none"/>',
|
|
130
|
+
list: '<path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>',
|
|
131
|
+
'help-circle':
|
|
132
|
+
'<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"/><path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3m.08 4h.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
133
|
+
help: '<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"/><path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3m.08 4h.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
134
|
+
bolt: '<path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>',
|
|
135
|
+
cube: '<path d="M21 16V8a2 2 0 00-1-1.73l-7-4a2 2 0 00-2 0l-7 4A2 2 0 003 8v8a2 2 0 001 1.73l7 4a2 2 0 002 0l7-4A2 2 0 0021 16z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><polyline points="3.27 6.96 12 12.01 20.73 6.96" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><line x1="12" y1="22.08" x2="12" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
136
|
+
swatch:
|
|
137
|
+
'<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10c.88 0 1.6-.72 1.6-1.6 0-.41-.17-.79-.44-1.06-.27-.28-.44-.65-.44-1.06 0-.88.72-1.6 1.6-1.6h1.88c3.15 0 5.72-2.57 5.72-5.72C21.32 6.16 17.14 2 12 2z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><circle cx="6.5" cy="11.5" r="1.5" fill="currentColor"/><circle cx="9.5" cy="7.5" r="1.5" fill="currentColor"/><circle cx="14.5" cy="7.5" r="1.5" fill="currentColor"/><circle cx="17.5" cy="11.5" r="1.5" fill="currentColor"/>',
|
|
138
|
+
star: '<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>',
|
|
139
|
+
photo:
|
|
140
|
+
'<rect x="3" y="3" width="18" height="18" rx="2" stroke="currentColor" stroke-width="2" fill="none"/><circle cx="8.5" cy="8.5" r="1.5" fill="currentColor"/><polyline points="21 15 16 10 5 21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>',
|
|
141
|
+
'document-text':
|
|
142
|
+
'<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><polyline points="14 2 14 8 20 8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><line x1="8" y1="13" x2="16" y2="13" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="8" y1="17" x2="13" y2="17" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>',
|
|
143
|
+
'clipboard-document':
|
|
144
|
+
'<path d="M16 4h2a2 2 0 012 2v14a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2h2" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none"/><rect x="8" y="2" width="8" height="4" rx="1" stroke="currentColor" stroke-width="2" fill="none"/><line x1="9" y1="12" x2="15" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="9" y1="16" x2="13" y2="16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>',
|
|
145
|
+
'arrow-path':
|
|
146
|
+
'<path d="M21.5 2v6h-6M21.34 15.57a10 10 0 11-.57-8.38l5.67-5.19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>',
|
|
147
|
+
'code-bracket':
|
|
148
|
+
'<polyline points="16 18 22 12 16 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><polyline points="8 6 2 12 8 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>',
|
|
149
|
+
'squares-2x2':
|
|
150
|
+
'<rect x="3" y="3" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/><rect x="14" y="3" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/><rect x="14" y="14" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/><rect x="3" y="14" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/>',
|
|
151
|
+
'squares-plus':
|
|
152
|
+
'<rect x="3" y="3" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/><rect x="14" y="3" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/><rect x="3" y="14" width="7" height="7" rx="1" stroke="currentColor" stroke-width="2" fill="none"/><line x1="17.5" y1="14" x2="17.5" y2="21" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="14" y1="17.5" x2="21" y2="17.5" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>',
|
|
153
|
+
'arrow-top-right-on-square':
|
|
154
|
+
'<path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6M15 3h6v6M10 14L21 3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>',
|
|
155
|
+
sidebar:
|
|
156
|
+
'<rect x="3" y="3" width="18" height="18" rx="2" stroke="currentColor" stroke-width="2" fill="none"/><line x1="9" y1="3" x2="9" y2="21" stroke="currentColor" stroke-width="2"/>',
|
|
157
|
+
'layout-top':
|
|
158
|
+
'<rect x="3" y="3" width="18" height="18" rx="2" stroke="currentColor" stroke-width="2" fill="none"/><line x1="3" y1="9" x2="21" y2="9" stroke="currentColor" stroke-width="2"/>',
|
|
159
|
+
'panel-right':
|
|
160
|
+
'<rect x="3" y="3" width="18" height="18" rx="2" stroke="currentColor" stroke-width="2" fill="none"/><line x1="15" y1="3" x2="15" y2="21" stroke="currentColor" stroke-width="2"/>'
|
|
130
161
|
};
|
|
131
162
|
</script>
|
|
132
163
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import Icon from '../elements/Icon.svelte';
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
|
+
id?: string;
|
|
6
7
|
checked?: boolean;
|
|
7
8
|
label?: string;
|
|
8
9
|
description?: string;
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
let {
|
|
21
|
+
id,
|
|
20
22
|
checked = $bindable(false),
|
|
21
23
|
label,
|
|
22
24
|
description,
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
>
|
|
39
41
|
<div class="flex h-5 items-center">
|
|
40
42
|
<input
|
|
43
|
+
id={id || name}
|
|
41
44
|
type="checkbox"
|
|
42
45
|
bind:checked
|
|
43
46
|
aria-label={ariaLabelAttr || ariaLabel || label}
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
import Icon from '../elements/Icon.svelte';
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
|
+
id?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
label?: string;
|
|
9
|
+
'aria-label'?: string;
|
|
10
|
+
ariaLabel?: string;
|
|
6
11
|
value?: string;
|
|
7
12
|
presets?: string[];
|
|
8
13
|
disabled?: boolean;
|
|
@@ -23,6 +28,11 @@
|
|
|
23
28
|
];
|
|
24
29
|
|
|
25
30
|
let {
|
|
31
|
+
id,
|
|
32
|
+
name,
|
|
33
|
+
label,
|
|
34
|
+
'aria-label': ariaLabelAttr,
|
|
35
|
+
ariaLabel,
|
|
26
36
|
value = $bindable('#ff3e00'),
|
|
27
37
|
presets = defaultPresets,
|
|
28
38
|
disabled = false,
|
|
@@ -62,18 +72,23 @@
|
|
|
62
72
|
style="background-color: {value};"
|
|
63
73
|
>
|
|
64
74
|
<input
|
|
75
|
+
id={id ? `${id}-color` : name ? `${name}-color` : undefined}
|
|
76
|
+
name={name ? `${name}-color` : 'colorPickerValue'}
|
|
65
77
|
type="color"
|
|
66
78
|
bind:value
|
|
67
79
|
{disabled}
|
|
68
80
|
class="absolute inset-0 h-full w-full cursor-pointer opacity-0"
|
|
69
|
-
aria-label=
|
|
81
|
+
aria-label={ariaLabelAttr || ariaLabel || label || 'Pick color'}
|
|
70
82
|
/>
|
|
71
83
|
</label>
|
|
72
84
|
<input
|
|
85
|
+
id={id ? `${id}-hex` : name ? `${name}-hex` : undefined}
|
|
86
|
+
name={name || 'colorHex'}
|
|
73
87
|
type="text"
|
|
74
88
|
bind:value
|
|
75
89
|
{disabled}
|
|
76
90
|
placeholder="#ff3e00"
|
|
91
|
+
aria-label="Hex color code"
|
|
77
92
|
class="h-8 w-full rounded-md border border-neutral-200 bg-neutral-50 px-2.5 font-mono text-sm text-neutral-800 focus:border-primary-500 focus:outline-none dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-200"
|
|
78
93
|
/>
|
|
79
94
|
</div>
|
|
@@ -124,16 +139,21 @@
|
|
|
124
139
|
style="background-color: {value};"
|
|
125
140
|
>
|
|
126
141
|
<input
|
|
142
|
+
id={id ? `${id}-popover-color` : name ? `${name}-popover-color` : undefined}
|
|
143
|
+
name={name ? `${name}-popover-color` : 'colorPickerValue'}
|
|
127
144
|
type="color"
|
|
128
145
|
bind:value
|
|
129
146
|
class="absolute inset-0 h-full w-full cursor-pointer opacity-0"
|
|
130
|
-
aria-label=
|
|
147
|
+
aria-label={ariaLabelAttr || ariaLabel || label || 'Pick color'}
|
|
131
148
|
/>
|
|
132
149
|
</label>
|
|
133
150
|
<input
|
|
151
|
+
id={id ? `${id}-popover-hex` : name ? `${name}-popover-hex` : undefined}
|
|
152
|
+
name={name || 'colorHex'}
|
|
134
153
|
type="text"
|
|
135
154
|
bind:value
|
|
136
155
|
placeholder="#ff3e00"
|
|
156
|
+
aria-label="Hex color code"
|
|
137
157
|
class="h-8 w-full rounded-md border border-neutral-200 bg-neutral-50 px-2.5 font-mono text-sm text-neutral-800 focus:border-primary-500 focus:outline-none dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-200"
|
|
138
158
|
/>
|
|
139
159
|
</div>
|
|
@@ -180,9 +180,12 @@
|
|
|
180
180
|
>
|
|
181
181
|
<Icon name="search" size="xs" class="mr-2 shrink-0 text-neutral-400" />
|
|
182
182
|
<input
|
|
183
|
+
id={name ? `${name}-search` : undefined}
|
|
184
|
+
name={name ? `${name}-search` : 'comboboxSearch'}
|
|
183
185
|
type="text"
|
|
184
186
|
bind:value={query}
|
|
185
187
|
placeholder={searchPlaceholder}
|
|
188
|
+
aria-label={searchPlaceholder || 'Search options'}
|
|
186
189
|
onkeydown={handleKeydown}
|
|
187
190
|
class="h-8 w-full bg-transparent text-xs text-neutral-900 placeholder:text-neutral-400 focus:outline-none dark:text-white"
|
|
188
191
|
/>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
export interface DropzoneProps {
|
|
3
|
+
id?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
'aria-label'?: string;
|
|
6
|
+
ariaLabel?: string;
|
|
3
7
|
accept?: string;
|
|
4
8
|
multiple?: boolean;
|
|
5
9
|
maxSize?: number; // in bytes
|
|
@@ -23,6 +27,10 @@
|
|
|
23
27
|
import { useUpload } from '../../composables/useUpload.svelte';
|
|
24
28
|
|
|
25
29
|
let {
|
|
30
|
+
id,
|
|
31
|
+
name = 'dropzoneFiles',
|
|
32
|
+
'aria-label': ariaLabelAttr,
|
|
33
|
+
ariaLabel,
|
|
26
34
|
accept = '*/*',
|
|
27
35
|
multiple = false,
|
|
28
36
|
maxSize = 10 * 1024 * 1024, // 10MB default
|
|
@@ -166,11 +174,14 @@
|
|
|
166
174
|
aria-disabled={disabled}
|
|
167
175
|
>
|
|
168
176
|
<input
|
|
177
|
+
id={id || name || 'dropzone-file-input'}
|
|
178
|
+
name={name || 'dropzoneFiles'}
|
|
169
179
|
bind:this={fileInputEl}
|
|
170
180
|
type="file"
|
|
171
181
|
{accept}
|
|
172
182
|
{multiple}
|
|
173
183
|
{disabled}
|
|
184
|
+
aria-label={ariaLabelAttr || ariaLabel || label || 'Upload files'}
|
|
174
185
|
class="hidden"
|
|
175
186
|
onchange={handleInputChange}
|
|
176
187
|
/>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
5
|
+
id?: string;
|
|
5
6
|
label?: string;
|
|
6
7
|
description?: string;
|
|
7
8
|
error?: string;
|
|
@@ -13,6 +14,7 @@
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
let {
|
|
17
|
+
id,
|
|
16
18
|
label,
|
|
17
19
|
description,
|
|
18
20
|
error,
|
|
@@ -28,7 +30,10 @@
|
|
|
28
30
|
{#if label || hint}
|
|
29
31
|
<div class="flex items-center justify-between">
|
|
30
32
|
{#if label}
|
|
31
|
-
<label
|
|
33
|
+
<label
|
|
34
|
+
for={id || name}
|
|
35
|
+
class="block text-sm font-medium text-neutral-700 dark:text-neutral-300"
|
|
36
|
+
>
|
|
32
37
|
{label}
|
|
33
38
|
{#if required}
|
|
34
39
|
<span class="ml-0.5 text-rose-500">*</span>
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { cn } from '../../utils/cn';
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
5
|
+
id?: string;
|
|
6
|
+
name?: string;
|
|
5
7
|
length?: number;
|
|
6
8
|
value?: string;
|
|
7
9
|
type?: 'number' | 'text' | 'password';
|
|
@@ -17,6 +19,8 @@
|
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
let {
|
|
22
|
+
id,
|
|
23
|
+
name = 'otp',
|
|
20
24
|
length = 6,
|
|
21
25
|
value = $bindable(''),
|
|
22
26
|
type = 'number',
|
|
@@ -139,6 +143,8 @@
|
|
|
139
143
|
{/if}
|
|
140
144
|
|
|
141
145
|
<input
|
|
146
|
+
id={`${id || name}-${index + 1}`}
|
|
147
|
+
name={`${name}-${index + 1}`}
|
|
142
148
|
bind:this={inputRefs[index]}
|
|
143
149
|
type={type === 'password' ? 'password' : 'text'}
|
|
144
150
|
inputmode={type === 'number' ? 'numeric' : 'text'}
|
|
@@ -180,9 +180,12 @@
|
|
|
180
180
|
>
|
|
181
181
|
<Icon name="search" size="xs" class="mr-2 shrink-0 text-neutral-400" />
|
|
182
182
|
<input
|
|
183
|
+
id={name ? `${name}-search` : undefined}
|
|
184
|
+
name={name ? `${name}-search` : 'multiselectSearch'}
|
|
183
185
|
type="text"
|
|
184
186
|
bind:value={searchQuery}
|
|
185
187
|
placeholder={searchPlaceholder}
|
|
188
|
+
aria-label={searchPlaceholder || 'Search options'}
|
|
186
189
|
onkeydown={handleKeyDown}
|
|
187
190
|
class="h-8 w-full bg-transparent text-xs text-neutral-900 placeholder:text-neutral-400 focus:outline-none dark:text-white"
|
|
188
191
|
/>
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
export type NumberInputProps = VariantProps<typeof numberInputVariants> & {
|
|
26
|
+
id?: string;
|
|
26
27
|
value?: number;
|
|
27
28
|
min?: number;
|
|
28
29
|
max?: number;
|
|
@@ -32,6 +33,9 @@
|
|
|
32
33
|
placeholder?: string;
|
|
33
34
|
disabled?: boolean;
|
|
34
35
|
name?: string;
|
|
36
|
+
label?: string;
|
|
37
|
+
'aria-label'?: string;
|
|
38
|
+
ariaLabel?: string;
|
|
35
39
|
class?: string;
|
|
36
40
|
};
|
|
37
41
|
</script>
|
|
@@ -40,6 +44,7 @@
|
|
|
40
44
|
import Icon from '../elements/Icon.svelte';
|
|
41
45
|
|
|
42
46
|
let {
|
|
47
|
+
id,
|
|
43
48
|
value = $bindable(0),
|
|
44
49
|
min,
|
|
45
50
|
max,
|
|
@@ -49,6 +54,9 @@
|
|
|
49
54
|
placeholder,
|
|
50
55
|
disabled = false,
|
|
51
56
|
name,
|
|
57
|
+
label,
|
|
58
|
+
'aria-label': ariaLabelAttr,
|
|
59
|
+
ariaLabel,
|
|
52
60
|
size = 'md',
|
|
53
61
|
status = 'default',
|
|
54
62
|
class: className = ''
|
|
@@ -110,14 +118,16 @@
|
|
|
110
118
|
{/if}
|
|
111
119
|
|
|
112
120
|
<input
|
|
121
|
+
id={id || name}
|
|
113
122
|
type="number"
|
|
114
|
-
{name}
|
|
123
|
+
name={name || id || 'number-input'}
|
|
115
124
|
{min}
|
|
116
125
|
{max}
|
|
117
126
|
{step}
|
|
118
127
|
{disabled}
|
|
119
128
|
{placeholder}
|
|
120
129
|
{value}
|
|
130
|
+
aria-label={ariaLabelAttr || ariaLabel || label || placeholder || name || 'Number input'}
|
|
121
131
|
oninput={handleInput}
|
|
122
132
|
onkeydown={handleKeydown}
|
|
123
133
|
class="w-full [appearance:textfield] bg-transparent text-center font-mono focus:outline-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
|
|
@@ -31,6 +31,7 @@ export declare const numberInputVariants: import("tailwind-variants").TVReturnTy
|
|
|
31
31
|
};
|
|
32
32
|
}, undefined>>;
|
|
33
33
|
export type NumberInputProps = VariantProps<typeof numberInputVariants> & {
|
|
34
|
+
id?: string;
|
|
34
35
|
value?: number;
|
|
35
36
|
min?: number;
|
|
36
37
|
max?: number;
|
|
@@ -40,6 +41,9 @@ export type NumberInputProps = VariantProps<typeof numberInputVariants> & {
|
|
|
40
41
|
placeholder?: string;
|
|
41
42
|
disabled?: boolean;
|
|
42
43
|
name?: string;
|
|
44
|
+
label?: string;
|
|
45
|
+
'aria-label'?: string;
|
|
46
|
+
ariaLabel?: string;
|
|
43
47
|
class?: string;
|
|
44
48
|
};
|
|
45
49
|
declare const NumberInput: import("svelte").Component<NumberInputProps, {}, "value">;
|
|
@@ -45,11 +45,13 @@
|
|
|
45
45
|
: ''}"
|
|
46
46
|
>
|
|
47
47
|
<input
|
|
48
|
+
id={`${name}-${opt.value}`}
|
|
48
49
|
type="radio"
|
|
49
50
|
{name}
|
|
50
51
|
value={opt.value}
|
|
51
52
|
disabled={opt.disabled}
|
|
52
53
|
checked={isSelected}
|
|
54
|
+
aria-label={opt.label}
|
|
53
55
|
onchange={() => (value = opt.value)}
|
|
54
56
|
class="sr-only"
|
|
55
57
|
/>
|
|
@@ -31,13 +31,18 @@
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
export type SelectProps = VariantProps<typeof selectVariants> & {
|
|
34
|
+
id?: string;
|
|
34
35
|
value?: string;
|
|
35
36
|
options?: SelectOption[];
|
|
36
37
|
placeholder?: string;
|
|
37
38
|
icon?: IconSource;
|
|
38
39
|
disabled?: boolean;
|
|
39
40
|
name?: string;
|
|
41
|
+
label?: string;
|
|
42
|
+
'aria-label'?: string;
|
|
43
|
+
ariaLabel?: string;
|
|
40
44
|
class?: string;
|
|
45
|
+
[key: string]: any;
|
|
41
46
|
};
|
|
42
47
|
</script>
|
|
43
48
|
|
|
@@ -45,15 +50,20 @@
|
|
|
45
50
|
import Icon from '../elements/Icon.svelte';
|
|
46
51
|
|
|
47
52
|
let {
|
|
53
|
+
id,
|
|
48
54
|
value = $bindable(''),
|
|
49
55
|
options = [],
|
|
50
56
|
placeholder = 'Select an option...',
|
|
51
57
|
icon,
|
|
52
58
|
disabled = false,
|
|
53
59
|
name,
|
|
60
|
+
label,
|
|
61
|
+
'aria-label': ariaLabelAttr,
|
|
62
|
+
ariaLabel,
|
|
54
63
|
size = 'md',
|
|
55
64
|
status = 'default',
|
|
56
|
-
class: className = ''
|
|
65
|
+
class: className = '',
|
|
66
|
+
...restProps
|
|
57
67
|
}: SelectProps = $props();
|
|
58
68
|
</script>
|
|
59
69
|
|
|
@@ -65,14 +75,17 @@
|
|
|
65
75
|
{/if}
|
|
66
76
|
|
|
67
77
|
<select
|
|
78
|
+
id={id || name}
|
|
68
79
|
bind:value
|
|
69
80
|
{disabled}
|
|
70
81
|
{name}
|
|
82
|
+
aria-label={ariaLabelAttr || ariaLabel || label || placeholder || name || 'Select option'}
|
|
71
83
|
class="{selectVariants({ size, status, class: className })} {icon
|
|
72
84
|
? size === 'sm'
|
|
73
85
|
? 'pl-8'
|
|
74
86
|
: 'pl-10'
|
|
75
87
|
: ''}"
|
|
88
|
+
{...restProps}
|
|
76
89
|
>
|
|
77
90
|
{#if placeholder}
|
|
78
91
|
<option value="" disabled selected={!value}>
|
|
@@ -38,13 +38,18 @@ export declare const selectVariants: import("tailwind-variants").TVReturnType<{
|
|
|
38
38
|
};
|
|
39
39
|
}, undefined>>;
|
|
40
40
|
export type SelectProps = VariantProps<typeof selectVariants> & {
|
|
41
|
+
id?: string;
|
|
41
42
|
value?: string;
|
|
42
43
|
options?: SelectOption[];
|
|
43
44
|
placeholder?: string;
|
|
44
45
|
icon?: IconSource;
|
|
45
46
|
disabled?: boolean;
|
|
46
47
|
name?: string;
|
|
48
|
+
label?: string;
|
|
49
|
+
'aria-label'?: string;
|
|
50
|
+
ariaLabel?: string;
|
|
47
51
|
class?: string;
|
|
52
|
+
[key: string]: any;
|
|
48
53
|
};
|
|
49
54
|
declare const Select: import("svelte").Component<SelectProps, {}, "value">;
|
|
50
55
|
type Select = ReturnType<typeof Select>;
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
interface Props {
|
|
3
|
+
id?: string;
|
|
3
4
|
value?: number;
|
|
4
5
|
min?: number;
|
|
5
6
|
max?: number;
|
|
6
7
|
step?: number;
|
|
7
8
|
disabled?: boolean;
|
|
8
9
|
name?: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
'aria-label'?: string;
|
|
12
|
+
ariaLabel?: string;
|
|
9
13
|
class?: string;
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
let {
|
|
17
|
+
id,
|
|
13
18
|
value = $bindable(50),
|
|
14
19
|
min = 0,
|
|
15
20
|
max = 100,
|
|
16
21
|
step = 1,
|
|
17
22
|
disabled = false,
|
|
18
|
-
name,
|
|
23
|
+
name = 'slider',
|
|
24
|
+
label,
|
|
25
|
+
'aria-label': ariaLabelAttr,
|
|
26
|
+
ariaLabel,
|
|
19
27
|
class: className = ''
|
|
20
28
|
}: Props = $props();
|
|
21
29
|
|
|
@@ -24,6 +32,7 @@
|
|
|
24
32
|
|
|
25
33
|
<div class="relative flex w-full touch-none items-center select-none {className}">
|
|
26
34
|
<input
|
|
35
|
+
id={id || name}
|
|
27
36
|
type="range"
|
|
28
37
|
bind:value
|
|
29
38
|
{min}
|
|
@@ -31,6 +40,10 @@
|
|
|
31
40
|
{step}
|
|
32
41
|
{disabled}
|
|
33
42
|
{name}
|
|
43
|
+
aria-label={ariaLabelAttr || ariaLabel || label || 'Slider'}
|
|
44
|
+
aria-valuenow={value}
|
|
45
|
+
aria-valuemin={min}
|
|
46
|
+
aria-valuemax={max}
|
|
34
47
|
class="h-2 w-full cursor-pointer appearance-none rounded-lg bg-neutral-200 accent-primary-600 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-neutral-800"
|
|
35
48
|
style="background: linear-gradient(to right, rgb(37 99 235) {percentage}%, rgb(228 228 231) {percentage}%);"
|
|
36
49
|
/>
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
interface Props {
|
|
2
|
+
id?: string;
|
|
2
3
|
value?: number;
|
|
3
4
|
min?: number;
|
|
4
5
|
max?: number;
|
|
5
6
|
step?: number;
|
|
6
7
|
disabled?: boolean;
|
|
7
8
|
name?: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
'aria-label'?: string;
|
|
11
|
+
ariaLabel?: string;
|
|
8
12
|
class?: string;
|
|
9
13
|
}
|
|
10
14
|
declare const Slider: import("svelte").Component<Props, {}, "value">;
|