@happyvertical/smrt-ui 0.55.15 → 0.55.17
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/AGENTS.md +14 -0
- package/README.md +68 -0
- package/dist/components/calendar/Calendar.svelte +59 -56
- package/dist/components/calendar/CalendarView.svelte +79 -76
- package/dist/components/calendar/DayView.svelte +39 -36
- package/dist/components/chat/MessageBubble.svelte +26 -23
- package/dist/components/chat/ReactionPicker.svelte +10 -7
- package/dist/components/chat/TypingIndicator.svelte +12 -9
- package/dist/components/data/CollectionList.svelte +10 -7
- package/dist/components/data/CollectionToolbar.svelte +5 -2
- package/dist/components/data/DataTable.svelte +51 -48
- package/dist/components/data/ListSortSelect.svelte +8 -5
- package/dist/components/data/SortableHeader.svelte +9 -6
- package/dist/components/display/ConfidenceBadge.svelte +11 -8
- package/dist/components/display/CurrencyDisplay.svelte +7 -4
- package/dist/components/display/DateDisplay.svelte +6 -3
- package/dist/components/display/Icon.svelte +4 -1
- package/dist/components/display/StatusBadge.svelte +9 -6
- package/dist/components/feedback/Alert.svelte +9 -6
- package/dist/components/feedback/ConfirmDialog.svelte +13 -10
- package/dist/components/feedback/LoadingOverlay.svelte +35 -32
- package/dist/components/feedback/Meter.svelte +4 -1
- package/dist/components/feedback/Modal.svelte +20 -17
- package/dist/components/feedback/PhoneSheet.svelte +4 -1
- package/dist/components/feedback/Progress.svelte +8 -5
- package/dist/components/feedback/ProgressBar.svelte +13 -10
- package/dist/components/feedback/Spinner.svelte +4 -1
- package/dist/components/feedback/ToastViewport.svelte +17 -14
- package/dist/components/feedback/WorkingStrip.svelte +6 -3
- package/dist/components/forms/CameraCapture.svelte +6 -3
- package/dist/components/forms/Checkbox.svelte +10 -7
- package/dist/components/forms/Combobox.svelte +4 -1
- package/dist/components/forms/DatePicker.svelte +7 -2
- package/dist/components/forms/DictationButton.svelte +17 -14
- package/dist/components/forms/DictationStatus.svelte +12 -9
- package/dist/components/forms/ErrorSummary.svelte +4 -1
- package/dist/components/forms/FieldLabel.svelte +9 -6
- package/dist/components/forms/Fieldset.svelte +4 -1
- package/dist/components/forms/FilePicker.svelte +4 -1
- package/dist/components/forms/Form.svelte +1 -1
- package/dist/components/forms/FormActionBar.svelte +4 -1
- package/dist/components/forms/FormGroup.svelte +6 -3
- package/dist/components/forms/Input.svelte +14 -11
- package/dist/components/forms/InputGroup.svelte +5 -2
- package/dist/components/forms/Listbox.svelte +4 -1
- package/dist/components/forms/MultiSelect.svelte +4 -1
- package/dist/components/forms/Radio.svelte +8 -5
- package/dist/components/forms/RadioGroup.svelte +5 -2
- package/dist/components/forms/RangeSlider.svelte +4 -1
- package/dist/components/forms/RelationInput.svelte +7 -4
- package/dist/components/forms/SearchInput.svelte +5 -2
- package/dist/components/forms/SegmentedControl.svelte +5 -2
- package/dist/components/forms/Select.svelte +12 -9
- package/dist/components/forms/SignaturePad.svelte +6 -3
- package/dist/components/forms/Slider.svelte +4 -1
- package/dist/components/forms/StagedControlReview.svelte +15 -12
- package/dist/components/forms/Switch.svelte +7 -4
- package/dist/components/forms/TagsInput.svelte +4 -1
- package/dist/components/forms/Textarea.svelte +13 -10
- package/dist/components/forms/TimePicker.svelte +7 -2
- package/dist/components/forms/Toggle.svelte +13 -10
- package/dist/components/forms/ToggleButton.svelte +4 -1
- package/dist/components/layout/ActionGroup.svelte +4 -1
- package/dist/components/layout/Container.svelte +4 -1
- package/dist/components/layout/EmptyState.svelte +11 -8
- package/dist/components/layout/Footer.svelte +4 -1
- package/dist/components/layout/Grid.svelte +13 -10
- package/dist/components/layout/Header.svelte +4 -1
- package/dist/components/layout/Masthead.svelte +4 -1
- package/dist/components/layout/PageHeader.svelte +10 -7
- package/dist/components/layout/PageLayout.svelte +3 -0
- package/dist/components/layout/SummaryCard.svelte +9 -6
- package/dist/components/memberships/MembershipCard.svelte +5 -2
- package/dist/components/memberships/MembershipList.svelte +5 -2
- package/dist/components/nav/FilterChips.svelte +13 -10
- package/dist/components/nav/Tabs.svelte +28 -24
- package/dist/components/permissions/PermissionPicker.svelte +4 -1
- package/dist/components/roles/RoleBadge.svelte +8 -5
- package/dist/components/roles/RoleSelector.svelte +21 -18
- package/dist/components/theme/ThemeProvider.svelte +7 -4
- package/dist/components/ui/Accordion.svelte +4 -1
- package/dist/components/ui/AccordionItem.svelte +4 -1
- package/dist/components/ui/Avatar.svelte +10 -7
- package/dist/components/ui/Badge.svelte +4 -1
- package/dist/components/ui/Button.svelte +11 -8
- package/dist/components/ui/Card.svelte +7 -4
- package/dist/components/ui/Chip.svelte +12 -9
- package/dist/components/ui/Disclosure.svelte +4 -1
- package/dist/components/ui/Dropdown.svelte +17 -14
- package/dist/components/ui/IconToggle.svelte +10 -7
- package/dist/components/ui/IconToggle.svelte.d.ts +1 -1
- package/dist/components/ui/IconToggle.svelte.d.ts.map +1 -1
- package/dist/components/ui/IconToggleGroup.svelte +8 -5
- package/dist/components/ui/Pagination.svelte +11 -8
- package/dist/components/ui/Popover.svelte +5 -2
- package/dist/components/ui/Skeleton.svelte +10 -7
- package/dist/components/ui/Tooltip.svelte +12 -9
- package/dist/components/ui/Tree.svelte +10 -7
- package/dist/styles/layers.css +8 -0
- package/dist/styles/layers.d.ts +9 -0
- package/dist/styles/layers.d.ts.map +1 -0
- package/dist/styles/layers.js +8 -0
- package/dist/styles/tokens.css +27 -69
- package/dist/styles/unstyled.css +65 -0
- package/dist/svelte/playground/BaseControlsPreview.svelte +3 -0
- package/dist/svelte/playground/CalendarPreview.svelte +5 -2
- package/dist/svelte/playground/CapturePreview.svelte +3 -0
- package/dist/svelte/playground/CodeSelectorsPreview.svelte +3 -0
- package/dist/svelte/playground/CollectionsPreview.svelte +3 -0
- package/dist/svelte/playground/DataTablePreview.svelte +3 -0
- package/dist/svelte/playground/FeedbackPreview.svelte +3 -0
- package/dist/svelte/playground/InteractiveControlsPreview.svelte +3 -0
- package/dist/svelte/playground/StylelessPreview.svelte +110 -0
- package/dist/svelte/playground/StylelessPreview.svelte.d.ts +4 -0
- package/dist/svelte/playground/StylelessPreview.svelte.d.ts.map +1 -0
- package/dist/svelte/playground.d.ts.map +1 -1
- package/dist/svelte/playground.js +10 -0
- package/dist/test-support/setup.js +9 -0
- package/dist/theme/ThemeProvider.svelte +3 -0
- package/dist/themes/CUSTOM_THEME_GUIDE.md +25 -0
- package/dist/themes/README.md +25 -0
- package/dist/themes/ThemeProvider.svelte +11 -2
- package/dist/themes/ThemeProvider.svelte.d.ts.map +1 -1
- package/dist/themes/components/ColorSchemeToggle.svelte +17 -14
- package/dist/themes/components/ThemeSwitcher.svelte +14 -11
- package/dist/themes/create-theme.d.ts.map +1 -1
- package/dist/themes/create-theme.js +8 -5
- package/dist/themes/css-generator.d.ts.map +1 -1
- package/dist/themes/css-generator.js +5 -4
- package/dist/themes/required-tokens.generated.json +172 -0
- package/dist/themes/styles/base.css +4 -1
- package/dist/themes/styles/glass.css +4 -1
- package/dist/themes/styles/happyvertical.css +7 -3
- package/dist/themes/styles/smrt.css +4 -1
- package/dist/themes/styles/studio.css +4 -1
- package/dist/utils/theme/typography.d.ts +21 -21
- package/dist/utils/theme/typography.js +21 -21
- package/package.json +8 -2
|
@@ -33,12 +33,14 @@ const { t } = useI18n();
|
|
|
33
33
|
role="group"
|
|
34
34
|
aria-label={label ?? t(M['ui.form_action_bar.label'])}
|
|
35
35
|
data-form-action-bar
|
|
36
|
-
data-testid="form-action-bar"
|
|
36
|
+
data-testid="form-action-bar" data-smrt-component="FormActionBar"
|
|
37
37
|
>
|
|
38
38
|
{@render children()}
|
|
39
39
|
</div>
|
|
40
40
|
|
|
41
41
|
<style>
|
|
42
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
43
|
+
@layer smrt.theme {
|
|
42
44
|
.form-action-bar {
|
|
43
45
|
display: flex;
|
|
44
46
|
flex-wrap: wrap;
|
|
@@ -81,4 +83,5 @@ const { t } = useI18n();
|
|
|
81
83
|
display: none;
|
|
82
84
|
}
|
|
83
85
|
}
|
|
86
|
+
}
|
|
84
87
|
</style>
|
|
@@ -62,7 +62,7 @@ setFormGroupContext(
|
|
|
62
62
|
);
|
|
63
63
|
</script>
|
|
64
64
|
|
|
65
|
-
<div class="form-group">
|
|
65
|
+
<div class="form-group" data-smrt-component="FormGroup">
|
|
66
66
|
<FieldLabel for={fieldId} {label} {required} />
|
|
67
67
|
{@render children()}
|
|
68
68
|
{#if hintId}
|
|
@@ -74,6 +74,8 @@ setFormGroupContext(
|
|
|
74
74
|
</div>
|
|
75
75
|
|
|
76
76
|
<style>
|
|
77
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
78
|
+
@layer smrt.theme {
|
|
77
79
|
.form-group {
|
|
78
80
|
margin-bottom: 1rem;
|
|
79
81
|
}
|
|
@@ -83,12 +85,13 @@ setFormGroupContext(
|
|
|
83
85
|
.form-hint {
|
|
84
86
|
margin: 0.25rem 0 0;
|
|
85
87
|
font-size: var(--smrt-typography-body-small-size, 0.75rem);
|
|
86
|
-
color: var(--smrt-color-on-surface-variant
|
|
88
|
+
color: var(--smrt-color-on-surface-variant);
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
.form-error {
|
|
90
92
|
margin: 0.25rem 0 0;
|
|
91
93
|
font-size: var(--smrt-typography-body-small-size, 0.75rem);
|
|
92
|
-
color: var(--smrt-color-error
|
|
94
|
+
color: var(--smrt-color-error);
|
|
93
95
|
}
|
|
96
|
+
}
|
|
94
97
|
</style>
|
|
@@ -218,10 +218,12 @@ export function getElement(): HTMLInputElement | null {
|
|
|
218
218
|
data-smrt-form={controlInteraction?.formId}
|
|
219
219
|
data-smrt-subject-type={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.type}
|
|
220
220
|
data-smrt-subject-id={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.id}
|
|
221
|
-
{...rest}
|
|
221
|
+
{...rest} data-smrt-component="Input"
|
|
222
222
|
/>
|
|
223
223
|
|
|
224
224
|
<style>
|
|
225
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
226
|
+
@layer smrt.theme {
|
|
225
227
|
.input {
|
|
226
228
|
box-sizing: border-box;
|
|
227
229
|
display: block;
|
|
@@ -229,9 +231,9 @@ export function getElement(): HTMLInputElement | null {
|
|
|
229
231
|
padding: 0.5rem 0.75rem;
|
|
230
232
|
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
231
233
|
line-height: var(--smrt-typography-body-medium-line-height, 1.5);
|
|
232
|
-
color: var(--smrt-color-on-surface
|
|
233
|
-
background-color: var(--smrt-color-surface
|
|
234
|
-
border: 1px solid var(--smrt-color-outline
|
|
234
|
+
color: var(--smrt-color-on-surface);
|
|
235
|
+
background-color: var(--smrt-color-surface);
|
|
236
|
+
border: 1px solid var(--smrt-color-outline);
|
|
235
237
|
border-radius: var(--smrt-radius-small, 0.375rem);
|
|
236
238
|
transition:
|
|
237
239
|
border-color var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease-in-out),
|
|
@@ -240,24 +242,24 @@ export function getElement(): HTMLInputElement | null {
|
|
|
240
242
|
|
|
241
243
|
.input:focus {
|
|
242
244
|
outline: none;
|
|
243
|
-
border-color: var(--smrt-color-primary
|
|
244
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--smrt-color-primary
|
|
245
|
+
border-color: var(--smrt-color-primary);
|
|
246
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--smrt-color-primary) 10%, transparent);
|
|
245
247
|
}
|
|
246
248
|
|
|
247
249
|
.input[data-smrt-highlighted='true'] {
|
|
248
|
-
outline: 3px solid var(--smrt-color-tertiary
|
|
250
|
+
outline: 3px solid var(--smrt-color-tertiary);
|
|
249
251
|
outline-offset: 3px;
|
|
250
|
-
box-shadow: 0 0 0 6px color-mix(in srgb, var(--smrt-color-tertiary
|
|
252
|
+
box-shadow: 0 0 0 6px color-mix(in srgb, var(--smrt-color-tertiary) 20%, transparent);
|
|
251
253
|
}
|
|
252
254
|
|
|
253
255
|
.input:disabled {
|
|
254
|
-
background-color: var(--smrt-color-surface-container-high
|
|
256
|
+
background-color: var(--smrt-color-surface-container-high);
|
|
255
257
|
cursor: not-allowed;
|
|
256
258
|
opacity: 0.7;
|
|
257
259
|
}
|
|
258
260
|
|
|
259
261
|
.input::placeholder {
|
|
260
|
-
color: var(--smrt-color-on-surface-variant
|
|
262
|
+
color: var(--smrt-color-on-surface-variant);
|
|
261
263
|
}
|
|
262
264
|
|
|
263
265
|
/* Phones: 16px text so iOS Safari doesn't zoom the page when the field
|
|
@@ -275,7 +277,8 @@ export function getElement(): HTMLInputElement | null {
|
|
|
275
277
|
}
|
|
276
278
|
}
|
|
277
279
|
|
|
278
|
-
.input[data-density='touch'] { --smrt-control-target-min: var(--smrt-touch-target-min
|
|
280
|
+
.input[data-density='touch'] { --smrt-control-target-min: var(--smrt-touch-target-min); }
|
|
279
281
|
.input[data-density='comfortable'] { --smrt-control-target-min: 0px; }
|
|
280
282
|
.input { min-height: var(--smrt-control-target-min, 0px); }
|
|
283
|
+
}
|
|
281
284
|
</style>
|
|
@@ -12,10 +12,13 @@ export interface Props {
|
|
|
12
12
|
}
|
|
13
13
|
let { prefix, suffix, children, class: className = '' }: Props = $props();
|
|
14
14
|
</script>
|
|
15
|
-
<div class="input-group {className}">{#if prefix}<span class="adornment">{@render prefix()}</span>{/if}<div class="control">{@render children()}</div>{#if suffix}<span class="adornment">{@render suffix()}</span>{/if}</div>
|
|
15
|
+
<div class="input-group {className}" data-smrt-component="InputGroup">{#if prefix}<span class="adornment">{@render prefix()}</span>{/if}<div class="control">{@render children()}</div>{#if suffix}<span class="adornment">{@render suffix()}</span>{/if}</div>
|
|
16
16
|
<style>
|
|
17
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
18
|
+
@layer smrt.theme {
|
|
17
19
|
.input-group { display: flex; align-items: stretch; width: 100%; border: 1px solid var(--smrt-color-outline); border-radius: var(--smrt-radius-small); background: var(--smrt-color-surface); overflow: hidden; }
|
|
18
20
|
.adornment { display: inline-flex; align-items: center; padding: 0 var(--smrt-spacing-3); background: var(--smrt-color-surface-container-low); color: var(--smrt-color-on-surface-variant); }
|
|
19
|
-
.control { flex: 1; min-width: 0; } .control :global(input), .control :global(select), .control :global(textarea) { border: 0
|
|
21
|
+
.control { flex: 1; min-width: 0; } .input-group .control :global(input), .input-group .control :global(select), .input-group .control :global(textarea) { border: 0; border-radius: 0; box-shadow: none; }
|
|
20
22
|
.input-group:focus-within { outline: 2px solid var(--smrt-color-primary); outline-offset: 1px; }
|
|
23
|
+
}
|
|
21
24
|
</style>
|
|
@@ -156,15 +156,18 @@ useControlRegistration(() => {
|
|
|
156
156
|
</script>
|
|
157
157
|
<div bind:this={rootEl} class="listbox {className}" role="listbox" aria-label={label} aria-disabled={disabled} data-smrt-control={controlId} data-smrt-form={interactionContext?.formId}
|
|
158
158
|
data-smrt-subject-type={interaction === false ? undefined : interaction?.subject?.type}
|
|
159
|
-
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id}>
|
|
159
|
+
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id} data-smrt-component="Listbox">
|
|
160
160
|
{#if name}<input type="hidden" {name} value={value ?? ''} disabled={disabled || matchingOption(options, value)?.disabled} />{/if}
|
|
161
161
|
{#each options as option, index (option.value)}<button bind:this={optionEls[index]} type="button" role="option" aria-selected={value === option.value}
|
|
162
162
|
disabled={disabled || option.disabled} tabindex={value === option.value || (value === undefined && index === 0) ? 0 : -1}
|
|
163
163
|
onkeydown={(event) => move(event, index)} onclick={() => select(option.value, true)}>{option.label}</button>{/each}
|
|
164
164
|
</div>
|
|
165
165
|
<style>
|
|
166
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
167
|
+
@layer smrt.theme {
|
|
166
168
|
.listbox { display: grid; padding: var(--smrt-spacing-1); border: 1px solid var(--smrt-color-outline); border-radius: var(--smrt-radius-small); background: var(--smrt-color-surface); }
|
|
167
169
|
button { padding: var(--smrt-spacing-2) var(--smrt-spacing-3); border: 0; border-radius: var(--smrt-radius-extra-small); background: transparent; color: var(--smrt-color-on-surface); text-align: left; cursor: pointer; }
|
|
168
170
|
button[aria-selected='true'] { background: var(--smrt-color-secondary-container); color: var(--smrt-color-on-secondary-container); } button:focus-visible { outline: 2px solid var(--smrt-color-primary); }
|
|
169
171
|
button:disabled { opacity: .5; cursor: not-allowed; } :global(.listbox[data-smrt-highlighted='true']) { outline: 3px solid var(--smrt-color-tertiary); outline-offset: 4px; }
|
|
172
|
+
}
|
|
170
173
|
</style>
|
|
@@ -216,15 +216,18 @@ useControlRegistration(() => {
|
|
|
216
216
|
</script>
|
|
217
217
|
<div bind:this={rootEl} class="multi-select {className}" data-smrt-control={controlId} data-smrt-form={interactionContext?.formId}
|
|
218
218
|
data-smrt-subject-type={interaction === false ? undefined : interaction?.subject?.type}
|
|
219
|
-
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id}>
|
|
219
|
+
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id} data-smrt-component="MultiSelect">
|
|
220
220
|
{#if name}{#each canonicalValues as value}<input type="hidden" {name} value={String(value)} disabled={disabled || options.some((option) => Object.is(option.value, value) && option.disabled)} />{/each}{/if}
|
|
221
221
|
<span class="label" id={`${listId}-label`}>{label}</span><button bind:this={triggerEl} id={triggerId} type="button" class="trigger" {disabled} aria-haspopup="listbox" aria-expanded={open} aria-controls={listId} aria-labelledby={`${listId}-label ${triggerId}`} onclick={() => open ? closeOptions() : openOptions()} onkeydown={handleTriggerKeydown}>{selectedLabels.length ? selectedLabels.join(', ') : placeholder}</button>
|
|
222
222
|
{#if open}<div id={listId} class="options" role="listbox" tabindex="-1" aria-multiselectable="true" aria-labelledby={`${listId}-label`} onkeydown={handleOptionsKeydown}>{#each options as option, index (option.value)}<button bind:this={optionEls[index]} type="button" role="option" tabindex="-1" aria-selected={canonicalValues.some((value) => Object.is(value, option.value))} disabled={option.disabled} onclick={() => toggle(option)}><span aria-hidden="true">{canonicalValues.some((value) => Object.is(value, option.value)) ? '✓' : ''}</span>{option.label}</button>{/each}</div>{/if}
|
|
223
223
|
</div>
|
|
224
224
|
<style>
|
|
225
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
226
|
+
@layer smrt.theme {
|
|
225
227
|
.multi-select { position: relative; display: grid; gap: var(--smrt-spacing-1); color: var(--smrt-color-on-surface); } .label { font: var(--smrt-typography-label-large-font); }
|
|
226
228
|
.trigger { width: 100%; min-height: 2.5rem; padding: var(--smrt-spacing-2) var(--smrt-spacing-3); border: 1px solid var(--smrt-color-outline); border-radius: var(--smrt-radius-small); background: var(--smrt-color-surface); color: inherit; text-align: left; }
|
|
227
229
|
.options { position: absolute; z-index: var(--smrt-z-index-dropdown); top: 100%; left: 0; right: 0; display: grid; padding: var(--smrt-spacing-1); border: 1px solid var(--smrt-color-outline-variant); background: var(--smrt-color-surface-container); box-shadow: var(--smrt-elevation-2); }
|
|
228
230
|
.options button { display: grid; grid-template-columns: 1.25rem 1fr; gap: var(--smrt-spacing-2); padding: var(--smrt-spacing-2); border: 0; background: transparent; color: inherit; text-align: left; } .options button[aria-selected='true'] { background: var(--smrt-color-secondary-container); }
|
|
229
231
|
:global(.multi-select[data-smrt-highlighted='true']) { outline: 3px solid var(--smrt-color-tertiary); outline-offset: 4px; }
|
|
232
|
+
}
|
|
230
233
|
</style>
|
|
@@ -20,20 +20,22 @@ function handleChange(event: Event & { currentTarget: HTMLInputElement }) {
|
|
|
20
20
|
onchange?.(event);
|
|
21
21
|
}
|
|
22
22
|
</script>
|
|
23
|
-
<label class="radio" class:disabled={disabled || group.disabled} data-smrt-hit-target>
|
|
23
|
+
<label class="radio" class:disabled={disabled || group.disabled} data-smrt-hit-target data-smrt-component="Radio">
|
|
24
24
|
<input id={resolvedId} type="radio" name={group.name} {value} disabled={disabled || group.disabled} required={group.required}
|
|
25
25
|
checked={group.value === value} onchange={handleChange} {...rest} />
|
|
26
26
|
<span class="radio__mark" aria-hidden="true"></span><span class="radio__label">{label}</span>
|
|
27
27
|
</label>
|
|
28
28
|
<style>
|
|
29
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
30
|
+
@layer smrt.theme {
|
|
29
31
|
/* The visible mark stays 18px; a transparent 44x44 ::before hit area (see Checkbox) makes the
|
|
30
32
|
touch target. Mark and label text sit above every hit area, so neighbours' hit areas never
|
|
31
33
|
steal their clicks. Beside other content (a group's other options, text, a link) it keeps to
|
|
32
34
|
the mark's column and grows vertically only. --smrt-control-hit-size resizes it (0px turns it
|
|
33
35
|
off). */
|
|
34
|
-
.radio { --
|
|
35
|
-
.radio::before { content: ''; position: absolute; z-index: 0; inset-block-start: 50%; inset-inline-start: calc(var(--
|
|
36
|
-
.radio:not(:only-child)::before { inline-size: var(--
|
|
36
|
+
.radio { --smrt-radio-box: 1.15rem; --smrt-radio-hit: max(var(--smrt-control-hit-size, 2.75rem), var(--smrt-radio-box)); position: relative; display: inline-flex; align-items: center; gap: var(--smrt-spacing-2); cursor: pointer; }
|
|
37
|
+
.radio::before { content: ''; position: absolute; z-index: 0; inset-block-start: 50%; inset-inline-start: calc(var(--smrt-radio-box) / 2); inline-size: var(--smrt-radio-hit); block-size: var(--smrt-radio-hit); margin-block-start: calc(var(--smrt-radio-hit) / -2); margin-inline-start: calc(var(--smrt-radio-hit) / -2); }
|
|
38
|
+
.radio:not(:only-child)::before { inline-size: var(--smrt-radio-box); margin-inline-start: calc(var(--smrt-radio-box) / -2); }
|
|
37
39
|
.radio.disabled { opacity: .5; cursor: not-allowed; }
|
|
38
40
|
input { position: absolute; opacity: 0; width: 1px; height: 1px; }
|
|
39
41
|
.radio__mark { position: relative; z-index: 1; width: 1.15rem; height: 1.15rem; border: 2px solid var(--smrt-color-outline); border-radius: 50%; display: grid; place-items: center; }
|
|
@@ -45,5 +47,6 @@ function handleChange(event: Event & { currentTarget: HTMLInputElement }) {
|
|
|
45
47
|
.radio { min-height: var(--smrt-control-target-min, 0px); min-width: var(--smrt-control-target-min, 0px); }
|
|
46
48
|
|
|
47
49
|
/* Table cells: grow vertically only, never into a neighbouring cell. */
|
|
48
|
-
:global(:is(td, th)) .radio::before { inline-size: var(--
|
|
50
|
+
:global(:is(td, th)) .radio::before { inline-size: var(--smrt-radio-box); margin-inline-start: calc(var(--smrt-radio-box) / -2); }
|
|
51
|
+
}
|
|
49
52
|
</style>
|
|
@@ -139,13 +139,15 @@ useControlRegistration(() => {
|
|
|
139
139
|
<fieldset bind:this={fieldsetEl} data-density={density} class="radio-group {className}" {disabled}
|
|
140
140
|
aria-describedby={description ? `${name}-description` : undefined} data-smrt-control={controlId} data-smrt-form={interactionContext?.formId}
|
|
141
141
|
data-smrt-subject-type={interaction === false ? undefined : interaction?.subject?.type}
|
|
142
|
-
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id}>
|
|
142
|
+
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id} data-smrt-component="RadioGroup">
|
|
143
143
|
{#if label}<legend>{label}{#if required}<span aria-hidden="true"> *</span>{/if}</legend>{/if}
|
|
144
144
|
{#if description}<p id={`${name}-description`} class="description">{description}</p>{/if}
|
|
145
145
|
<div class="options">{@render children()}</div>
|
|
146
146
|
{#if error}<p class="error" role="alert">{error}</p>{/if}
|
|
147
147
|
</fieldset>
|
|
148
148
|
<style>
|
|
149
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
150
|
+
@layer smrt.theme {
|
|
149
151
|
.radio-group { margin: 0; padding: 0; border: 0; color: var(--smrt-color-on-surface); }
|
|
150
152
|
legend { margin-bottom: var(--smrt-spacing-2); font: var(--smrt-typography-label-large-font); }
|
|
151
153
|
.description, .error { margin: var(--smrt-spacing-1) 0 var(--smrt-spacing-2); font: var(--smrt-typography-body-small-font); color: var(--smrt-color-on-surface-variant); }
|
|
@@ -153,6 +155,7 @@ useControlRegistration(() => {
|
|
|
153
155
|
.options { display: flex; flex-wrap: wrap; gap: var(--smrt-spacing-3); }
|
|
154
156
|
:global(.radio-group[data-smrt-highlighted='true']) { outline: 3px solid var(--smrt-color-tertiary); outline-offset: 4px; border-radius: var(--smrt-radius-small); }
|
|
155
157
|
|
|
156
|
-
.radio-group[data-density='touch'] { --smrt-control-target-min: var(--smrt-touch-target-min
|
|
158
|
+
.radio-group[data-density='touch'] { --smrt-control-target-min: var(--smrt-touch-target-min); }
|
|
157
159
|
.radio-group[data-density='comfortable'] { --smrt-control-target-min: 0px; }
|
|
160
|
+
}
|
|
158
161
|
</style>
|
|
@@ -175,7 +175,7 @@ useControlRegistration(() => {
|
|
|
175
175
|
</script>
|
|
176
176
|
<div bind:this={rootEl} class="range-slider {className}" class:disabled data-smrt-control={controlId} data-smrt-form={interactionContext?.formId}
|
|
177
177
|
data-smrt-subject-type={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.type}
|
|
178
|
-
data-smrt-subject-id={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.id} role="group" aria-label={label ?? formGroup?.().label ?? 'Range'}>
|
|
178
|
+
data-smrt-subject-id={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.id} role="group" aria-label={label ?? formGroup?.().label ?? 'Range'} data-smrt-component="RangeSlider">
|
|
179
179
|
{#if label}<div class="range-slider__header"><span>{label}</span><output>{value.min}{unit ?? ''} – {value.max}{unit ?? ''}</output></div>{/if}
|
|
180
180
|
<div class="range-slider__track">
|
|
181
181
|
<input bind:this={minEl} id={minId} type="range" name={name ? `${name}[min]` : undefined} {min} max={value.max} {step} {disabled} value={value.min}
|
|
@@ -189,6 +189,8 @@ useControlRegistration(() => {
|
|
|
189
189
|
</div>
|
|
190
190
|
</div>
|
|
191
191
|
<style>
|
|
192
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
193
|
+
@layer smrt.theme {
|
|
192
194
|
.range-slider { display: grid; gap: var(--smrt-spacing-3); color: var(--smrt-color-on-surface); }
|
|
193
195
|
.range-slider.disabled { opacity: .5; }
|
|
194
196
|
.range-slider__header { display: flex; justify-content: space-between; font: var(--smrt-typography-label-large-font); }
|
|
@@ -202,4 +204,5 @@ useControlRegistration(() => {
|
|
|
202
204
|
.range-slider__inputs input { width: 100%; padding: var(--smrt-spacing-2); border: 1px solid var(--smrt-color-outline); border-radius: var(--smrt-radius-small); background: var(--smrt-color-surface); color: var(--smrt-color-on-surface); }
|
|
203
205
|
input:focus-visible { outline: 2px solid var(--smrt-color-primary); outline-offset: 3px; }
|
|
204
206
|
:global(.range-slider[data-smrt-highlighted='true']) { outline: 3px solid var(--smrt-color-tertiary); outline-offset: 4px; border-radius: var(--smrt-radius-small); }
|
|
207
|
+
}
|
|
205
208
|
</style>
|
|
@@ -288,7 +288,7 @@ $effect(() => {
|
|
|
288
288
|
$effect(() => () => clearTimeout(timer));
|
|
289
289
|
</script>
|
|
290
290
|
|
|
291
|
-
<div class="relation-input" bind:this={rootEl}>
|
|
291
|
+
<div class="relation-input" bind:this={rootEl} data-smrt-component="RelationInput">
|
|
292
292
|
<div class="field">
|
|
293
293
|
<Combobox
|
|
294
294
|
{name}
|
|
@@ -343,9 +343,11 @@ $effect(() => () => clearTimeout(timer));
|
|
|
343
343
|
</div>
|
|
344
344
|
|
|
345
345
|
<style>
|
|
346
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
347
|
+
@layer smrt.theme {
|
|
346
348
|
.relation-input {
|
|
347
349
|
display: grid;
|
|
348
|
-
gap: var(--smrt-spacing-1
|
|
350
|
+
gap: var(--smrt-spacing-1);
|
|
349
351
|
min-width: 0;
|
|
350
352
|
}
|
|
351
353
|
.field {
|
|
@@ -353,8 +355,8 @@ $effect(() => () => clearTimeout(timer));
|
|
|
353
355
|
}
|
|
354
356
|
.field :global(.clear) {
|
|
355
357
|
position: absolute;
|
|
356
|
-
right: var(--smrt-spacing-1
|
|
357
|
-
bottom: var(--smrt-spacing-1
|
|
358
|
+
right: var(--smrt-spacing-1);
|
|
359
|
+
bottom: var(--smrt-spacing-1);
|
|
358
360
|
}
|
|
359
361
|
.option-label,
|
|
360
362
|
.option-detail {
|
|
@@ -375,4 +377,5 @@ $effect(() => () => clearTimeout(timer));
|
|
|
375
377
|
.error {
|
|
376
378
|
color: var(--smrt-color-error);
|
|
377
379
|
}
|
|
380
|
+
}
|
|
378
381
|
</style>
|
|
@@ -112,7 +112,7 @@ function clear() {
|
|
|
112
112
|
onDestroy(cancel);
|
|
113
113
|
</script>
|
|
114
114
|
|
|
115
|
-
<div class="search-input {className}" role="search">
|
|
115
|
+
<div class="search-input {className}" role="search" data-smrt-component="SearchInput">
|
|
116
116
|
<label class="search-input__label" for={inputId}>{label}</label>
|
|
117
117
|
<span class="search-input__icon" aria-hidden="true">
|
|
118
118
|
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" /></svg>
|
|
@@ -137,6 +137,8 @@ onDestroy(cancel);
|
|
|
137
137
|
</div>
|
|
138
138
|
|
|
139
139
|
<style>
|
|
140
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
141
|
+
@layer smrt.theme {
|
|
140
142
|
.search-input {
|
|
141
143
|
position: relative;
|
|
142
144
|
display: flex;
|
|
@@ -185,7 +187,7 @@ onDestroy(cancel);
|
|
|
185
187
|
block-size: 2.75rem;
|
|
186
188
|
padding: 0;
|
|
187
189
|
border: none;
|
|
188
|
-
border-radius: var(--smrt-radius-full
|
|
190
|
+
border-radius: var(--smrt-radius-full);
|
|
189
191
|
background: transparent;
|
|
190
192
|
color: var(--smrt-color-on-surface-variant);
|
|
191
193
|
cursor: pointer;
|
|
@@ -204,4 +206,5 @@ onDestroy(cancel);
|
|
|
204
206
|
max-inline-size: none;
|
|
205
207
|
}
|
|
206
208
|
}
|
|
209
|
+
}
|
|
207
210
|
</style>
|
|
@@ -236,7 +236,7 @@ useControlRegistration(() => {
|
|
|
236
236
|
</script>
|
|
237
237
|
<div bind:this={rootEl} data-density={density} class="segmented {className}" class:full-width={fullWidth} role="radiogroup" tabindex="-1" aria-label={label} aria-required={required} onkeydown={handleKeydown} data-smrt-control={controlId} data-smrt-form={interactionContext?.formId}
|
|
238
238
|
data-smrt-subject-type={interaction === false ? undefined : interaction?.subject?.type}
|
|
239
|
-
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id}>
|
|
239
|
+
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id} data-smrt-component="SegmentedControl">
|
|
240
240
|
{#each options as option, index (option.value)}
|
|
241
241
|
<label class:selected={selectedOption === option} class:disabled={disabled || option.disabled}>
|
|
242
242
|
<input type="radio" {name} value={option.value} disabled={disabled || option.disabled}
|
|
@@ -250,6 +250,8 @@ useControlRegistration(() => {
|
|
|
250
250
|
{/each}
|
|
251
251
|
</div>
|
|
252
252
|
<style>
|
|
253
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
254
|
+
@layer smrt.theme {
|
|
253
255
|
.segmented { display: inline-flex; border: 1px solid var(--smrt-color-outline); border-radius: var(--smrt-radius-full); overflow: hidden; }
|
|
254
256
|
.segmented.full-width { display: flex; width: 100%; }
|
|
255
257
|
label { position: relative; display: inline-flex; align-items: center; justify-content: center; flex: 1; min-height: 2.5rem; padding: 0 var(--smrt-spacing-4); border: 0; border-right: 1px solid var(--smrt-color-outline); background: var(--smrt-color-surface); color: var(--smrt-color-on-surface); cursor: pointer; }
|
|
@@ -257,8 +259,9 @@ useControlRegistration(() => {
|
|
|
257
259
|
label:has(input:focus-visible) { outline: 2px solid var(--smrt-color-primary); outline-offset: -3px; } label.disabled, label:has(input:disabled) { opacity: .5; cursor: not-allowed; }
|
|
258
260
|
:global(.segmented[data-smrt-highlighted='true']) { outline: 3px solid var(--smrt-color-tertiary); outline-offset: 4px; }
|
|
259
261
|
|
|
260
|
-
.segmented[data-density='touch'] { --smrt-control-target-min: var(--smrt-touch-target-min
|
|
262
|
+
.segmented[data-density='touch'] { --smrt-control-target-min: var(--smrt-touch-target-min); }
|
|
261
263
|
.segmented[data-density='comfortable'] { --smrt-control-target-min: 0px; }
|
|
262
264
|
label { min-height: max(2.5rem, var(--smrt-control-target-min, 0px)); min-width: var(--smrt-control-target-min, 0px); }
|
|
263
265
|
input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: inherit; }
|
|
266
|
+
}
|
|
264
267
|
</style>
|
|
@@ -148,12 +148,14 @@ export function getElement(): HTMLSelectElement | null {
|
|
|
148
148
|
data-smrt-form={controlInteraction?.formId}
|
|
149
149
|
data-smrt-subject-type={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.type}
|
|
150
150
|
data-smrt-subject-id={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.id}
|
|
151
|
-
{...rest}
|
|
151
|
+
{...rest} data-smrt-component="Select"
|
|
152
152
|
>
|
|
153
153
|
{@render children()}
|
|
154
154
|
</select>
|
|
155
155
|
|
|
156
156
|
<style>
|
|
157
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
158
|
+
@layer smrt.theme {
|
|
157
159
|
.select {
|
|
158
160
|
box-sizing: border-box;
|
|
159
161
|
display: block;
|
|
@@ -161,13 +163,13 @@ export function getElement(): HTMLSelectElement | null {
|
|
|
161
163
|
padding: 0.5rem 2rem 0.5rem 0.75rem;
|
|
162
164
|
font-size: var(--smrt-typography-body-medium-size, 0.875rem);
|
|
163
165
|
line-height: var(--smrt-typography-body-medium-line-height, 1.5);
|
|
164
|
-
color: var(--smrt-color-on-surface
|
|
165
|
-
background-color: var(--smrt-color-surface
|
|
166
|
+
color: var(--smrt-color-on-surface);
|
|
167
|
+
background-color: var(--smrt-color-surface);
|
|
166
168
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%2379747e' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
|
|
167
169
|
background-position: right 0.5rem center;
|
|
168
170
|
background-repeat: no-repeat;
|
|
169
171
|
background-size: 1.5em 1.5em;
|
|
170
|
-
border: 1px solid var(--smrt-color-outline
|
|
172
|
+
border: 1px solid var(--smrt-color-outline);
|
|
171
173
|
border-radius: 0.375rem;
|
|
172
174
|
appearance: none;
|
|
173
175
|
cursor: pointer;
|
|
@@ -178,17 +180,17 @@ export function getElement(): HTMLSelectElement | null {
|
|
|
178
180
|
|
|
179
181
|
.select:focus {
|
|
180
182
|
outline: none;
|
|
181
|
-
border-color: var(--smrt-color-primary
|
|
182
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--smrt-color-primary
|
|
183
|
+
border-color: var(--smrt-color-primary);
|
|
184
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--smrt-color-primary) 10%, transparent);
|
|
183
185
|
}
|
|
184
186
|
|
|
185
187
|
.select[data-smrt-highlighted='true'] {
|
|
186
|
-
outline: 3px solid var(--smrt-color-tertiary
|
|
188
|
+
outline: 3px solid var(--smrt-color-tertiary);
|
|
187
189
|
outline-offset: 3px;
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
.select:disabled {
|
|
191
|
-
background-color: var(--smrt-color-surface-container-high
|
|
193
|
+
background-color: var(--smrt-color-surface-container-high);
|
|
192
194
|
cursor: not-allowed;
|
|
193
195
|
opacity: 0.7;
|
|
194
196
|
}
|
|
@@ -208,7 +210,8 @@ export function getElement(): HTMLSelectElement | null {
|
|
|
208
210
|
}
|
|
209
211
|
}
|
|
210
212
|
|
|
211
|
-
.select[data-density='touch'] { --smrt-control-target-min: var(--smrt-touch-target-min
|
|
213
|
+
.select[data-density='touch'] { --smrt-control-target-min: var(--smrt-touch-target-min); }
|
|
212
214
|
.select[data-density='comfortable'] { --smrt-control-target-min: 0px; }
|
|
213
215
|
.select { min-height: var(--smrt-control-target-min, 0px); }
|
|
216
|
+
}
|
|
214
217
|
</style>
|
|
@@ -313,7 +313,7 @@ useControlRegistration(() => {
|
|
|
313
313
|
data-smrt-control={controlId}
|
|
314
314
|
data-smrt-form={interactionContext?.formId}
|
|
315
315
|
data-smrt-subject-type={interaction === false ? undefined : interaction?.subject?.type}
|
|
316
|
-
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id}
|
|
316
|
+
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id} data-smrt-component="SignaturePad"
|
|
317
317
|
>
|
|
318
318
|
<canvas
|
|
319
319
|
bind:this={canvasEl}
|
|
@@ -358,6 +358,8 @@ useControlRegistration(() => {
|
|
|
358
358
|
</div>
|
|
359
359
|
|
|
360
360
|
<style>
|
|
361
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
362
|
+
@layer smrt.theme {
|
|
361
363
|
.signature-pad {
|
|
362
364
|
display: grid;
|
|
363
365
|
gap: var(--smrt-spacing-3);
|
|
@@ -405,8 +407,8 @@ useControlRegistration(() => {
|
|
|
405
407
|
flex: 1 1 auto;
|
|
406
408
|
/* Capture is a touch flow: its actions are touch targets at every
|
|
407
409
|
density, on the shared scale (smrt#3252). */
|
|
408
|
-
min-width: var(--smrt-touch-target-min
|
|
409
|
-
min-height: var(--smrt-touch-target-min
|
|
410
|
+
min-width: var(--smrt-touch-target-min);
|
|
411
|
+
min-height: var(--smrt-touch-target-min);
|
|
410
412
|
padding: 0 var(--smrt-spacing-4);
|
|
411
413
|
border: 1px solid var(--smrt-color-outline);
|
|
412
414
|
border-radius: var(--smrt-radius-small);
|
|
@@ -433,4 +435,5 @@ useControlRegistration(() => {
|
|
|
433
435
|
outline: 3px solid var(--smrt-color-tertiary);
|
|
434
436
|
outline-offset: 4px;
|
|
435
437
|
}
|
|
438
|
+
}
|
|
436
439
|
</style>
|
|
@@ -139,7 +139,7 @@ useControlRegistration(() => {
|
|
|
139
139
|
</script>
|
|
140
140
|
<div class="slider {className}" data-smrt-control={controlId} data-smrt-form={interactionContext?.formId}
|
|
141
141
|
data-smrt-subject-type={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.type}
|
|
142
|
-
data-smrt-subject-id={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.id}>
|
|
142
|
+
data-smrt-subject-id={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.id} data-smrt-component="Slider">
|
|
143
143
|
{#if label}<div class="slider__header"><label for={resolvedId}>{label}</label><output for={resolvedId}>{formatValue(value)}</output></div>{/if}
|
|
144
144
|
<div class="slider__controls">
|
|
145
145
|
<input bind:this={rangeEl} id={resolvedId} type="range" {name} {min} {max} {step} {disabled} value={value}
|
|
@@ -150,6 +150,8 @@ useControlRegistration(() => {
|
|
|
150
150
|
</div>
|
|
151
151
|
</div>
|
|
152
152
|
<style>
|
|
153
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
154
|
+
@layer smrt.theme {
|
|
153
155
|
.slider { display: grid; gap: var(--smrt-spacing-2); color: var(--smrt-color-on-surface); }
|
|
154
156
|
.slider__header, .slider__controls { display: flex; align-items: center; gap: var(--smrt-spacing-3); }
|
|
155
157
|
.slider__header { justify-content: space-between; font: var(--smrt-typography-label-large-font); }
|
|
@@ -158,4 +160,5 @@ useControlRegistration(() => {
|
|
|
158
160
|
.slider__number { width: 5.5rem; padding: var(--smrt-spacing-2); border: 1px solid var(--smrt-color-outline); border-radius: var(--smrt-radius-small); background: var(--smrt-color-surface); color: var(--smrt-color-on-surface); }
|
|
159
161
|
input:focus-visible { outline: 2px solid var(--smrt-color-primary); outline-offset: 3px; }
|
|
160
162
|
.slider[data-smrt-highlighted='true'] { outline: 3px solid var(--smrt-color-tertiary); outline-offset: 4px; border-radius: var(--smrt-radius-small); }
|
|
163
|
+
}
|
|
161
164
|
</style>
|
|
@@ -536,7 +536,7 @@ async function discardAll(event: MouseEvent): Promise<void> {
|
|
|
536
536
|
bind:this={reviewElement}
|
|
537
537
|
class="staged-review"
|
|
538
538
|
data-staged-control-review
|
|
539
|
-
aria-label={text.region}
|
|
539
|
+
aria-label={text.region} data-smrt-component="StagedControlReview"
|
|
540
540
|
>
|
|
541
541
|
<header>
|
|
542
542
|
<div>
|
|
@@ -623,31 +623,34 @@ async function discardAll(event: MouseEvent): Promise<void> {
|
|
|
623
623
|
{/if}
|
|
624
624
|
|
|
625
625
|
{#if summary && reviewActivated}
|
|
626
|
-
<p class="status visually-hidden" role="status" aria-live="polite" aria-atomic="true">{status}</p>
|
|
626
|
+
<p class="status visually-hidden" role="status" aria-live="polite" aria-atomic="true" data-smrt-component="StagedControlReview">{status}</p>
|
|
627
627
|
{/if}
|
|
628
628
|
|
|
629
629
|
<style>
|
|
630
|
-
|
|
630
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
631
|
+
@layer smrt.theme {
|
|
632
|
+
.staged-review { margin-block-start: var(--smrt-spacing-5, 1.25rem); padding: var(--smrt-spacing-4, 1rem); color: var(--smrt-color-on-surface); background: var(--smrt-color-surface-container-low); border: 1px solid var(--smrt-color-outline-variant); border-inline-start: 4px solid var(--smrt-color-tertiary); border-radius: var(--smrt-radius-medium, .5rem); }
|
|
631
633
|
header, .proposal-heading, .batch-actions, .item-actions { display: flex; align-items: center; gap: var(--smrt-spacing-2, .5rem); }
|
|
632
634
|
header { justify-content: space-between; align-items: flex-start; gap: var(--smrt-spacing-4, 1rem); }
|
|
633
635
|
h2, p { margin: 0; } h2 { font: var(--smrt-typography-title-medium-font, 600 1rem/1.4 system-ui); }
|
|
634
|
-
header p, .proposal-heading span, dt { color: var(--smrt-color-on-surface-variant
|
|
636
|
+
header p, .proposal-heading span, dt { color: var(--smrt-color-on-surface-variant); font-size: .875rem; }
|
|
635
637
|
.proposal-heading strong, .proposal-heading .subject { display: block; }
|
|
636
638
|
ul { display: grid; gap: var(--smrt-spacing-3, .75rem); padding: 0; list-style: none; }
|
|
637
|
-
li { padding: var(--smrt-spacing-3, .75rem); background: var(--smrt-color-surface
|
|
638
|
-
li.stale, li.invalid { border-color: var(--smrt-color-error
|
|
639
|
+
li { padding: var(--smrt-spacing-3, .75rem); background: var(--smrt-color-surface); border: 1px solid var(--smrt-color-outline-variant); border-radius: var(--smrt-radius-small, .375rem); }
|
|
640
|
+
li.stale, li.invalid { border-color: var(--smrt-color-error); }
|
|
639
641
|
.proposal-heading { justify-content: space-between; }
|
|
640
642
|
dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--smrt-spacing-3, .75rem); }
|
|
641
643
|
dt { font-weight: 600; } dd { margin: .25rem 0 0; overflow-wrap: anywhere; }
|
|
642
|
-
input, textarea { width: 100%; box-sizing: border-box; padding: .4rem .5rem; color: inherit; background: var(--smrt-color-surface
|
|
644
|
+
input, textarea { width: 100%; box-sizing: border-box; padding: .4rem .5rem; color: inherit; background: var(--smrt-color-surface); border: 1px solid var(--smrt-color-outline); border-radius: var(--smrt-radius-small, .375rem); }
|
|
643
645
|
input[type="checkbox"] { width: auto; }
|
|
644
|
-
button { min-height: 2.25rem; padding: .4rem .75rem; color: var(--smrt-color-on-primary
|
|
645
|
-
button.secondary { color: var(--smrt-color-primary
|
|
646
|
-
button:focus-visible, input:focus-visible, textarea:focus-visible { outline: 2px solid var(--smrt-color-primary
|
|
646
|
+
button { min-height: 2.25rem; padding: .4rem .75rem; color: var(--smrt-color-on-primary); background: var(--smrt-color-primary); border: 1px solid transparent; border-radius: var(--smrt-radius-small, .375rem); cursor: pointer; }
|
|
647
|
+
button.secondary { color: var(--smrt-color-primary); background: transparent; border-color: var(--smrt-color-outline); }
|
|
648
|
+
button:focus-visible, input:focus-visible, textarea:focus-visible { outline: 2px solid var(--smrt-color-primary); outline-offset: 2px; }
|
|
647
649
|
button:disabled { cursor: not-allowed; opacity: .55; }
|
|
648
650
|
.item-actions { margin-block-start: var(--smrt-spacing-3, .75rem); }
|
|
649
|
-
.problem { margin-block-start: var(--smrt-spacing-2, .5rem); color: var(--smrt-color-error
|
|
651
|
+
.problem { margin-block-start: var(--smrt-spacing-2, .5rem); color: var(--smrt-color-error); }
|
|
650
652
|
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
|
|
651
|
-
:global([data-smrt-staged='true']) { outline: 3px solid var(--smrt-color-tertiary
|
|
653
|
+
:global([data-smrt-staged='true']) { outline: 3px solid var(--smrt-color-tertiary); outline-offset: 3px; }
|
|
652
654
|
@media (max-width: 40rem) { header, .proposal-heading { align-items: stretch; flex-direction: column; } dl { grid-template-columns: 1fr; } }
|
|
655
|
+
}
|
|
653
656
|
</style>
|
|
@@ -118,7 +118,7 @@ useControlRegistration(() => {
|
|
|
118
118
|
|
|
119
119
|
<label data-density={density} class="switch switch--{size} {className}" class:switch--disabled={disabled} data-smrt-hit-target data-smrt-control={controlId} data-smrt-form={interactionContext?.formId}
|
|
120
120
|
data-smrt-subject-type={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.type}
|
|
121
|
-
data-smrt-subject-id={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.id}>
|
|
121
|
+
data-smrt-subject-id={resolvedInteraction === false ? undefined : resolvedInteraction.subject?.id} data-smrt-component="Switch">
|
|
122
122
|
{#if label && labelPosition === 'left'}<span class="switch__label">{label}</span>{/if}
|
|
123
123
|
<span class="switch__control">
|
|
124
124
|
<input bind:this={inputEl} id={resolvedId} type="checkbox" role="switch" {name} {value} {disabled} {required} checked={checked}
|
|
@@ -130,14 +130,16 @@ useControlRegistration(() => {
|
|
|
130
130
|
</label>
|
|
131
131
|
|
|
132
132
|
<style>
|
|
133
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
134
|
+
@layer smrt.theme {
|
|
133
135
|
.switch { display: inline-flex; align-items: center; gap: var(--smrt-spacing-2, .5rem); cursor: pointer; color: var(--smrt-color-on-surface); }
|
|
134
136
|
.switch--disabled { opacity: .5; cursor: not-allowed; }
|
|
135
137
|
/* Phones: the whole row (track and label) is at least a 44px touch target. */
|
|
136
138
|
@media (max-width: 48rem) { .switch { min-block-size: 2.75rem; } }
|
|
137
139
|
/* The 2.75rem-wide track gets a transparent 44px-tall ::before hit area (see Checkbox); the
|
|
138
140
|
track and label sit above every hit area. --smrt-control-hit-size resizes it (0px = off). */
|
|
139
|
-
.switch__control { --
|
|
140
|
-
.switch__control::before { content: ''; position: absolute; z-index: 0; inset-block-start: 50%; inset-inline: calc((100% - var(--
|
|
141
|
+
.switch__control { --smrt-switch-hit: max(var(--smrt-control-hit-size, 2.75rem), 1.5rem); position: relative; display: inline-flex; }
|
|
142
|
+
.switch__control::before { content: ''; position: absolute; z-index: 0; inset-block-start: 50%; inset-inline: calc((100% - var(--smrt-switch-hit)) / 2); block-size: var(--smrt-switch-hit); margin-block-start: calc(var(--smrt-switch-hit) / -2); }
|
|
141
143
|
.switch__label { position: relative; z-index: 1; }
|
|
142
144
|
input { position: absolute; width: 1px; height: 1px; opacity: 0; }
|
|
143
145
|
.switch__track { position: relative; z-index: 1; width: 2.75rem; height: 1.5rem; padding: 2px; border-radius: var(--smrt-radius-full); background: var(--smrt-color-surface-container-highest); border: 1px solid var(--smrt-color-outline); transition: background var(--smrt-duration-short2); }
|
|
@@ -150,7 +152,8 @@ useControlRegistration(() => {
|
|
|
150
152
|
.switch[data-smrt-highlighted='true'] { outline: 3px solid var(--smrt-color-tertiary); outline-offset: 4px; border-radius: var(--smrt-radius-full); }
|
|
151
153
|
@media (prefers-reduced-motion: reduce) { .switch__track, .switch__thumb { transition: none; } }
|
|
152
154
|
|
|
153
|
-
.switch[data-density='touch'] { --smrt-control-target-min: var(--smrt-touch-target-min
|
|
155
|
+
.switch[data-density='touch'] { --smrt-control-target-min: var(--smrt-touch-target-min); }
|
|
154
156
|
.switch[data-density='comfortable'] { --smrt-control-target-min: 0px; }
|
|
155
157
|
.switch { min-height: var(--smrt-control-target-min, 0px); min-width: var(--smrt-control-target-min, 0px); }
|
|
158
|
+
}
|
|
156
159
|
</style>
|
|
@@ -129,13 +129,15 @@ useControlRegistration(() => {
|
|
|
129
129
|
};
|
|
130
130
|
});
|
|
131
131
|
</script>
|
|
132
|
-
<div class="tags-field {className}"><label for={inputId}>{label}</label><div bind:this={rootEl} class="tags" data-smrt-control={controlId} data-smrt-form={interactionContext?.formId}
|
|
132
|
+
<div class="tags-field {className}" data-smrt-component="TagsInput"><label for={inputId}>{label}</label><div bind:this={rootEl} class="tags" data-smrt-control={controlId} data-smrt-form={interactionContext?.formId}
|
|
133
133
|
data-smrt-subject-type={interaction === false ? undefined : interaction?.subject?.type}
|
|
134
134
|
data-smrt-subject-id={interaction === false ? undefined : interaction?.subject?.id}>
|
|
135
135
|
{#each values as tag, index}<span class="tag">{tag}<button type="button" disabled={disabled} aria-label={`Remove ${tag}`} onclick={() => remove(index)}>×</button><input type="hidden" name={name ? `${name}[]` : undefined} value={tag} /></span>{/each}
|
|
136
136
|
<input bind:this={inputEl} id={inputId} {placeholder} {disabled} bind:value={draft} onkeydown={handleKeydown} onblur={() => commit(draft)} />
|
|
137
137
|
</div></div>
|
|
138
138
|
<style>
|
|
139
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
140
|
+
@layer smrt.theme {
|
|
139
141
|
.tags-field { display: grid; gap: var(--smrt-spacing-1); color: var(--smrt-color-on-surface); } label { font: var(--smrt-typography-label-large-font); }
|
|
140
142
|
.tags { display: flex; flex-wrap: wrap; gap: var(--smrt-spacing-1); min-height: 2.5rem; padding: var(--smrt-spacing-1); border: 1px solid var(--smrt-color-outline); border-radius: var(--smrt-radius-small); background: var(--smrt-color-surface); }
|
|
141
143
|
.tag { display: inline-flex; align-items: center; gap: var(--smrt-spacing-1); padding: var(--smrt-spacing-1) var(--smrt-spacing-2); border-radius: var(--smrt-radius-full); background: var(--smrt-color-secondary-container); color: var(--smrt-color-on-secondary-container); }
|
|
@@ -148,4 +150,5 @@ useControlRegistration(() => {
|
|
|
148
150
|
.tag button:focus-visible { outline: 2px solid var(--smrt-color-primary); outline-offset: -2px; border-radius: var(--smrt-radius-full); }
|
|
149
151
|
.tags > input { flex: 1; min-width: 8rem; border: 0; outline: 0; background: transparent; color: inherit; }
|
|
150
152
|
:global(.tags[data-smrt-highlighted='true']) { outline: 3px solid var(--smrt-color-tertiary); outline-offset: 4px; }
|
|
153
|
+
}
|
|
151
154
|
</style>
|