@sveltia/ui 0.20.2 → 0.22.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/{package → dist}/components/button/button.svelte +1 -1
- package/{package → dist}/components/button/select-button-group.svelte +3 -0
- package/{package → dist}/components/calendar/calendar.svelte +1 -1
- package/{package → dist}/components/checkbox/checkbox.svelte +9 -2
- package/{package → dist}/components/grid/grid.svelte +1 -1
- package/{package → dist}/components/listbox/listbox.svelte +3 -0
- package/{package → dist}/components/menu/menu-button.svelte +1 -1
- package/{package → dist}/components/progressbar/progressbar.svelte +4 -1
- package/{package → dist}/components/radio/radio-group.svelte +9 -0
- package/{package → dist}/components/radio/radio.svelte +3 -3
- package/{package → dist}/components/select/combobox.svelte +6 -2
- package/{package → dist}/components/select/select-tags.svelte +1 -1
- package/{package → dist}/components/slider/slider.svelte +14 -7
- package/{package → dist}/components/switch/switch.svelte +4 -1
- package/{package → dist}/components/tabs/tab-list.svelte +1 -1
- package/{package → dist}/components/text-editor/core.d.ts +3 -1
- package/{package → dist}/components/text-editor/core.js +113 -19
- package/{package → dist}/components/text-editor/index.js +6 -0
- package/dist/components/text-editor/lexical-root.svelte +288 -0
- package/{package → dist}/components/text-editor/text-editor.svelte +18 -9
- package/{package → dist}/components/text-editor/text-editor.svelte.d.ts +8 -0
- package/{package → dist}/components/text-editor/toolbar/editor-toolbar.svelte +15 -0
- package/dist/components/text-editor/toolbar/insert-image-button.svelte +43 -0
- package/dist/components/text-editor/toolbar/insert-image-button.svelte.d.ts +17 -0
- package/dist/components/text-editor/toolbar/insert-menu-button.svelte +53 -0
- package/dist/components/text-editor/toolbar/insert-menu-button.svelte.d.ts +17 -0
- package/{package → dist}/components/text-editor/toolbar/toggle-block-menu-item.svelte +7 -0
- package/{package → dist}/components/text-field/number-input.svelte +31 -16
- package/{package → dist}/components/text-field/number-input.svelte.d.ts +8 -0
- package/{package → dist}/components/text-field/password-input.svelte +1 -0
- package/{package → dist}/components/text-field/password-input.svelte.d.ts +8 -0
- package/{package → dist}/components/text-field/search-bar.svelte +1 -0
- package/{package → dist}/components/text-field/search-bar.svelte.d.ts +8 -0
- package/{package → dist}/components/text-field/text-area.svelte +4 -4
- package/{package → dist}/components/text-field/text-input.svelte +7 -2
- package/{package → dist}/components/text-field/text-input.svelte.d.ts +13 -2
- package/{package → dist}/components/toast/toast.svelte +1 -1
- package/{package → dist}/components/toolbar/toolbar.svelte +2 -2
- package/{package → dist}/components/util/app-shell.svelte +6 -6
- package/{package → dist}/components/util/app-shell.svelte.d.ts +2 -2
- package/{package → dist}/components/util/popup.svelte +2 -2
- package/{package → dist}/locales/en.d.ts +1 -0
- package/{package → dist}/locales/en.js +1 -0
- package/{package → dist}/locales/ja.d.ts +1 -0
- package/{package → dist}/locales/ja.js +1 -0
- package/{package → dist}/styles/variables.scss +2 -2
- package/{package → dist}/typedefs.d.ts +32 -5
- package/{package → dist}/typedefs.js +26 -14
- package/package.json +20 -19
- package/package/components/text-editor/lexical-root.svelte +0 -156
- /package/{package → dist}/components/alert/alert.svelte +0 -0
- /package/{package → dist}/components/alert/alert.svelte.d.ts +0 -0
- /package/{package → dist}/components/button/button-group.svelte +0 -0
- /package/{package → dist}/components/button/button-group.svelte.d.ts +0 -0
- /package/{package → dist}/components/button/button.svelte.d.ts +0 -0
- /package/{package → dist}/components/button/select-button-group.svelte.d.ts +0 -0
- /package/{package → dist}/components/button/select-button.svelte +0 -0
- /package/{package → dist}/components/button/select-button.svelte.d.ts +0 -0
- /package/{package → dist}/components/button/split-button.svelte +0 -0
- /package/{package → dist}/components/button/split-button.svelte.d.ts +0 -0
- /package/{package → dist}/components/calendar/calendar.svelte.d.ts +0 -0
- /package/{package → dist}/components/checkbox/checkbox-group.svelte +0 -0
- /package/{package → dist}/components/checkbox/checkbox-group.svelte.d.ts +0 -0
- /package/{package → dist}/components/checkbox/checkbox.svelte.d.ts +0 -0
- /package/{package → dist}/components/dialog/alert-dialog.svelte +0 -0
- /package/{package → dist}/components/dialog/alert-dialog.svelte.d.ts +0 -0
- /package/{package → dist}/components/dialog/confirmation-dialog.svelte +0 -0
- /package/{package → dist}/components/dialog/confirmation-dialog.svelte.d.ts +0 -0
- /package/{package → dist}/components/dialog/dialog.svelte +0 -0
- /package/{package → dist}/components/dialog/dialog.svelte.d.ts +0 -0
- /package/{package → dist}/components/dialog/prompt-dialog.svelte +0 -0
- /package/{package → dist}/components/dialog/prompt-dialog.svelte.d.ts +0 -0
- /package/{package → dist}/components/disclosure/disclosure.svelte +0 -0
- /package/{package → dist}/components/disclosure/disclosure.svelte.d.ts +0 -0
- /package/{package → dist}/components/divider/divider.svelte +0 -0
- /package/{package → dist}/components/divider/divider.svelte.d.ts +0 -0
- /package/{package → dist}/components/divider/spacer.svelte +0 -0
- /package/{package → dist}/components/divider/spacer.svelte.d.ts +0 -0
- /package/{package → dist}/components/drawer/drawer.svelte +0 -0
- /package/{package → dist}/components/drawer/drawer.svelte.d.ts +0 -0
- /package/{package → dist}/components/grid/grid-body.svelte +0 -0
- /package/{package → dist}/components/grid/grid-body.svelte.d.ts +0 -0
- /package/{package → dist}/components/grid/grid-cell.svelte +0 -0
- /package/{package → dist}/components/grid/grid-cell.svelte.d.ts +0 -0
- /package/{package → dist}/components/grid/grid-col-header.svelte +0 -0
- /package/{package → dist}/components/grid/grid-col-header.svelte.d.ts +0 -0
- /package/{package → dist}/components/grid/grid-foot.svelte +0 -0
- /package/{package → dist}/components/grid/grid-foot.svelte.d.ts +0 -0
- /package/{package → dist}/components/grid/grid-head.svelte +0 -0
- /package/{package → dist}/components/grid/grid-head.svelte.d.ts +0 -0
- /package/{package → dist}/components/grid/grid-row-header.svelte +0 -0
- /package/{package → dist}/components/grid/grid-row-header.svelte.d.ts +0 -0
- /package/{package → dist}/components/grid/grid-row.svelte +0 -0
- /package/{package → dist}/components/grid/grid-row.svelte.d.ts +0 -0
- /package/{package → dist}/components/grid/grid.svelte.d.ts +0 -0
- /package/{package → dist}/components/icon/icon.svelte +0 -0
- /package/{package → dist}/components/icon/icon.svelte.d.ts +0 -0
- /package/{package → dist}/components/listbox/listbox.svelte.d.ts +0 -0
- /package/{package → dist}/components/listbox/option-group.svelte +0 -0
- /package/{package → dist}/components/listbox/option-group.svelte.d.ts +0 -0
- /package/{package → dist}/components/listbox/option.svelte +0 -0
- /package/{package → dist}/components/listbox/option.svelte.d.ts +0 -0
- /package/{package → dist}/components/menu/menu-button.svelte.d.ts +0 -0
- /package/{package → dist}/components/menu/menu-item-checkbox.svelte +0 -0
- /package/{package → dist}/components/menu/menu-item-checkbox.svelte.d.ts +0 -0
- /package/{package → dist}/components/menu/menu-item-group.svelte +0 -0
- /package/{package → dist}/components/menu/menu-item-group.svelte.d.ts +0 -0
- /package/{package → dist}/components/menu/menu-item-radio.svelte +0 -0
- /package/{package → dist}/components/menu/menu-item-radio.svelte.d.ts +0 -0
- /package/{package → dist}/components/menu/menu-item.svelte +0 -0
- /package/{package → dist}/components/menu/menu-item.svelte.d.ts +0 -0
- /package/{package → dist}/components/menu/menu.svelte +0 -0
- /package/{package → dist}/components/menu/menu.svelte.d.ts +0 -0
- /package/{package → dist}/components/progressbar/progressbar.svelte.d.ts +0 -0
- /package/{package → dist}/components/radio/radio-group.svelte.d.ts +0 -0
- /package/{package → dist}/components/radio/radio.svelte.d.ts +0 -0
- /package/{package → dist}/components/select/combobox.svelte.d.ts +0 -0
- /package/{package → dist}/components/select/select-tags.svelte.d.ts +0 -0
- /package/{package → dist}/components/select/select.svelte +0 -0
- /package/{package → dist}/components/select/select.svelte.d.ts +0 -0
- /package/{package → dist}/components/slider/slider.svelte.d.ts +0 -0
- /package/{package → dist}/components/switch/switch.svelte.d.ts +0 -0
- /package/{package → dist}/components/table/table-body.svelte +0 -0
- /package/{package → dist}/components/table/table-body.svelte.d.ts +0 -0
- /package/{package → dist}/components/table/table-cell.svelte +0 -0
- /package/{package → dist}/components/table/table-cell.svelte.d.ts +0 -0
- /package/{package → dist}/components/table/table-col-header.svelte +0 -0
- /package/{package → dist}/components/table/table-col-header.svelte.d.ts +0 -0
- /package/{package → dist}/components/table/table-foot.svelte +0 -0
- /package/{package → dist}/components/table/table-foot.svelte.d.ts +0 -0
- /package/{package → dist}/components/table/table-head.svelte +0 -0
- /package/{package → dist}/components/table/table-head.svelte.d.ts +0 -0
- /package/{package → dist}/components/table/table-row-header.svelte +0 -0
- /package/{package → dist}/components/table/table-row-header.svelte.d.ts +0 -0
- /package/{package → dist}/components/table/table-row.svelte +0 -0
- /package/{package → dist}/components/table/table-row.svelte.d.ts +0 -0
- /package/{package → dist}/components/table/table.svelte +0 -0
- /package/{package → dist}/components/table/table.svelte.d.ts +0 -0
- /package/{package → dist}/components/tabs/tab-box.svelte +0 -0
- /package/{package → dist}/components/tabs/tab-box.svelte.d.ts +0 -0
- /package/{package → dist}/components/tabs/tab-list.svelte.d.ts +0 -0
- /package/{package → dist}/components/tabs/tab-panel.svelte +0 -0
- /package/{package → dist}/components/tabs/tab-panel.svelte.d.ts +0 -0
- /package/{package → dist}/components/tabs/tab-panels.svelte +0 -0
- /package/{package → dist}/components/tabs/tab-panels.svelte.d.ts +0 -0
- /package/{package → dist}/components/tabs/tab.svelte +0 -0
- /package/{package → dist}/components/tabs/tab.svelte.d.ts +0 -0
- /package/{package → dist}/components/text-editor/index.d.ts +0 -0
- /package/{package → dist}/components/text-editor/lexical-root.svelte.d.ts +0 -0
- /package/{package → dist}/components/text-editor/toolbar/editor-toolbar.svelte.d.ts +0 -0
- /package/{package → dist}/components/text-editor/toolbar/format-text-button.svelte +0 -0
- /package/{package → dist}/components/text-editor/toolbar/format-text-button.svelte.d.ts +0 -0
- /package/{package → dist}/components/text-editor/toolbar/insert-link-button.svelte +0 -0
- /package/{package → dist}/components/text-editor/toolbar/insert-link-button.svelte.d.ts +0 -0
- /package/{package → dist}/components/text-editor/toolbar/toggle-block-menu-item.svelte.d.ts +0 -0
- /package/{package → dist}/components/text-field/text-area.svelte.d.ts +0 -0
- /package/{package → dist}/components/toast/toast.svelte.d.ts +0 -0
- /package/{package → dist}/components/toolbar/toolbar.svelte.d.ts +0 -0
- /package/{package → dist}/components/util/group.svelte +0 -0
- /package/{package → dist}/components/util/group.svelte.d.ts +0 -0
- /package/{package → dist}/components/util/modal.svelte +0 -0
- /package/{package → dist}/components/util/modal.svelte.d.ts +0 -0
- /package/{package → dist}/components/util/placeholder.svelte +0 -0
- /package/{package → dist}/components/util/placeholder.svelte.d.ts +0 -0
- /package/{package → dist}/components/util/popup.svelte.d.ts +0 -0
- /package/{package → dist}/index.d.ts +0 -0
- /package/{package → dist}/index.js +0 -0
- /package/{package → dist}/services/events.svelte.d.ts +0 -0
- /package/{package → dist}/services/events.svelte.js +0 -0
- /package/{package → dist}/services/group.svelte.d.ts +0 -0
- /package/{package → dist}/services/group.svelte.js +0 -0
- /package/{package → dist}/services/popup.svelte.d.ts +0 -0
- /package/{package → dist}/services/popup.svelte.js +0 -0
- /package/{package → dist}/styles/core.scss +0 -0
|
@@ -82,6 +82,9 @@
|
|
|
82
82
|
border-top-right-radius: 4px !important;
|
|
83
83
|
border-bottom-right-radius: 4px !important;
|
|
84
84
|
}
|
|
85
|
+
.select-button-group[aria-invalid=true] :global(button) {
|
|
86
|
+
border-color: var(--sui-error-border-color);
|
|
87
|
+
}
|
|
85
88
|
.select-button-group :global(button[aria-checked="true"]) {
|
|
86
89
|
color: var(--sui-highlight-foreground-color);
|
|
87
90
|
background-color: var(--sui-selected-background-color);
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* `aria-invalid` attribute.
|
|
20
20
|
* @property {boolean | 'mixed'} [checked] - Whether to check the widget. An alias of the
|
|
21
21
|
* `aria-checked` attribute.
|
|
22
|
-
* @property {string
|
|
22
|
+
* @property {string} [label] - Text label displayed next to the checkbox.
|
|
23
23
|
* @property {string} [aria-label] - `aria-label` attribute.
|
|
24
24
|
* @property {import('svelte').Snippet} [checkIcon] - Check icon slot content.
|
|
25
25
|
*/
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
{disabled}
|
|
89
89
|
{readonly}
|
|
90
90
|
{required}
|
|
91
|
-
{invalid}
|
|
91
|
+
aria-invalid={invalid}
|
|
92
92
|
aria-checked={checked}
|
|
93
93
|
aria-label={ariaLabel || undefined}
|
|
94
94
|
aria-labelledby={ariaLabel ? undefined : `${id}-label`}
|
|
@@ -174,6 +174,13 @@
|
|
|
174
174
|
.checkbox :global(button[aria-checked="false"]) {
|
|
175
175
|
color: transparent;
|
|
176
176
|
}
|
|
177
|
+
.checkbox :global(button[aria-invalid="true"]) {
|
|
178
|
+
border-color: var(--sui-error-border-color);
|
|
179
|
+
color: var(--sui-error-foreground-color);
|
|
180
|
+
}
|
|
181
|
+
.checkbox :global(button[aria-checked="true"][aria-invalid="true"]) {
|
|
182
|
+
background-color: var(--sui-error-background-color);
|
|
183
|
+
}
|
|
177
184
|
.checkbox label {
|
|
178
185
|
cursor: inherit;
|
|
179
186
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* @property {boolean} [selected] - Whether to allow selecting more than one `<GridRow>` and/or
|
|
14
14
|
* `<GridCell>`. An alias of the `aria-multiselectable` attribute.
|
|
15
15
|
* @property {boolean} [clickToSelect] - Whether to select a row by clicking on it.
|
|
16
|
-
* @property {HTMLElement
|
|
16
|
+
* @property {HTMLElement} [element] - A reference to the wrapper element.
|
|
17
17
|
* @property {import('svelte').Snippet} [children] - Primary slot content.
|
|
18
18
|
* @property {(event: CustomEvent) => void} [onChange] - Custom `Change` event handler.
|
|
19
19
|
*/
|
|
@@ -102,6 +102,9 @@
|
|
|
102
102
|
margin: 4px;
|
|
103
103
|
background-color: var(--sui-control-border-color);
|
|
104
104
|
}
|
|
105
|
+
[role=listbox][aria-invalid=true] {
|
|
106
|
+
border-color: var(--sui-error-border-color);
|
|
107
|
+
}
|
|
105
108
|
[role=listbox]:global(.tabs) {
|
|
106
109
|
padding: 0;
|
|
107
110
|
border-width: 0 1px 0 0;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @typedef {object} Props
|
|
13
|
-
* @property {HTMLElement
|
|
13
|
+
* @property {HTMLElement} [popupPositionBaseElement] - The base element of
|
|
14
14
|
* {@link popupPosition}. If omitted, this will be {@link buttonComponent}.
|
|
15
15
|
*/
|
|
16
16
|
|
|
@@ -42,9 +42,12 @@
|
|
|
42
42
|
|
|
43
43
|
<style>.progressbar {
|
|
44
44
|
overflow: hidden;
|
|
45
|
+
border-width: var(--sui-progressbar-border-width, 1px);
|
|
46
|
+
border-style: var(--sui-progressbar-border-style, solid);
|
|
47
|
+
border-color: var(--sui-progressbar-border-color, var(--sui-control-border-color));
|
|
45
48
|
border-radius: var(--sui-progressbar-border-radius, 16px);
|
|
46
49
|
width: var(--sui-progressbar-width, 240px);
|
|
47
|
-
height: var(--sui-progressbar-height,
|
|
50
|
+
height: var(--sui-progressbar-height, 10px);
|
|
48
51
|
background-color: var(--sui-progressbar-background-color, var(--sui-secondary-background-color));
|
|
49
52
|
}
|
|
50
53
|
.progressbar div {
|
|
@@ -86,6 +86,15 @@
|
|
|
86
86
|
gap: 8px;
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
+
.radio-group[aria-invalid=true] :global(button) {
|
|
90
|
+
border-color: var(--sui-error-border-color);
|
|
91
|
+
}
|
|
92
|
+
.radio-group[aria-invalid=true] :global(button[aria-checked="true"]) {
|
|
93
|
+
border-color: var(--sui-error-border-color);
|
|
94
|
+
}
|
|
95
|
+
.radio-group[aria-invalid=true] :global(button[aria-checked="true"]::before) {
|
|
96
|
+
background-color: var(--sui-error-border-color);
|
|
97
|
+
}
|
|
89
98
|
|
|
90
99
|
.inner {
|
|
91
100
|
display: contents;
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
* attribute.
|
|
18
18
|
* @property {boolean} [checked] - Whether to check the widget. An alias of the `aria-checked`
|
|
19
19
|
* attribute.
|
|
20
|
-
* @property {string
|
|
21
|
-
* @property {string
|
|
22
|
-
* @property {string
|
|
20
|
+
* @property {string} [name] - The `name` attribute on the `<button>` element.
|
|
21
|
+
* @property {string} [value] - The `value` attribute on the `<button>` element.
|
|
22
|
+
* @property {string} [label] - Text label displayed next to the checkbox.
|
|
23
23
|
* @property {import('svelte').Snippet} [children] - Primary slot content.
|
|
24
24
|
* @property {import('svelte').Snippet} [default] - Default slot content.
|
|
25
25
|
* @property {(event: CustomEvent) => void} [onChange] - Custom `Change` event handler.
|
|
@@ -122,8 +122,9 @@
|
|
|
122
122
|
aria-hidden={hidden}
|
|
123
123
|
aria-disabled={disabled}
|
|
124
124
|
aria-readonly={readonly}
|
|
125
|
+
aria-required={required}
|
|
126
|
+
aria-invalid={invalid}
|
|
125
127
|
aria-haspopup="listbox"
|
|
126
|
-
aria-activedescendant="selected-option"
|
|
127
128
|
>
|
|
128
129
|
<div role="none" class="label">
|
|
129
130
|
{value !== undefined ? label : $_('_sui.combobox.select_an_option')}
|
|
@@ -144,7 +145,6 @@
|
|
|
144
145
|
aria-controls="{id}-popup"
|
|
145
146
|
aria-expanded={isPopupOpen}
|
|
146
147
|
aria-haspopup="listbox"
|
|
147
|
-
aria-activedescendant="selected-option"
|
|
148
148
|
/>
|
|
149
149
|
{/if}
|
|
150
150
|
<Button
|
|
@@ -282,6 +282,10 @@
|
|
|
282
282
|
.combobox div[role=combobox]:hover, .combobox div[role=combobox]:focus {
|
|
283
283
|
background-color: var(--sui-hover-background-color);
|
|
284
284
|
}
|
|
285
|
+
.combobox div[role=combobox][aria-invalid=true] {
|
|
286
|
+
border-color: var(--sui-error-border-color);
|
|
287
|
+
background-color: var(--sui-error-background-color);
|
|
288
|
+
}
|
|
285
289
|
.combobox div[role=combobox] .label {
|
|
286
290
|
display: block;
|
|
287
291
|
overflow: hidden;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* @property {{ label: string, value: string, searchValue?: string }[]} options - Available
|
|
11
11
|
* options.
|
|
12
12
|
* @property {string[]} [values] - Selected option values.
|
|
13
|
-
* @property {number
|
|
13
|
+
* @property {number} [max] - Maximum number of selectable options.
|
|
14
14
|
* @property {string} [class] - The `class` attribute on the wrapper element.
|
|
15
15
|
* @property {boolean} [hidden] - Whether to hide the widget.
|
|
16
16
|
* @property {boolean} [disabled] - Whether to disable the widget. An alias of the `aria-disabled`
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
* @property {number} [min] - Minimum allowed value. An alias of the `aria-valuemin` attribute.
|
|
17
17
|
* @property {number} [max] - Maximum allowed value. An alias of the `aria-valuemax` attribute.
|
|
18
18
|
* @property {string} [sliderLabel] - `aria-label` on the slider.
|
|
19
|
-
* @property {[number, number]
|
|
20
|
-
* @property {[string, string]
|
|
19
|
+
* @property {[number, number]} [values] - Value list for a multi-thumb slider.
|
|
20
|
+
* @property {[string, string]} [sliderLabels] - `aria-label` on a multi-thumb slider.
|
|
21
21
|
* @property {number} [step] - Step option like `<input type="range">`.
|
|
22
22
|
* @property {(string[] | number[])} [optionLabels] - Visible labels on the slider.
|
|
23
23
|
* @property {boolean} [flex] - Make the text input container flexible.
|
|
@@ -304,6 +304,7 @@
|
|
|
304
304
|
class="sui slider {className}"
|
|
305
305
|
class:disabled
|
|
306
306
|
class:readonly
|
|
307
|
+
class:invalid
|
|
307
308
|
{hidden}
|
|
308
309
|
>
|
|
309
310
|
<div bind:this={base} role="none" class="base" onpointerdown={(event) => onPointerDown(event)}>
|
|
@@ -316,7 +317,7 @@
|
|
|
316
317
|
<div
|
|
317
318
|
role="slider"
|
|
318
319
|
tabindex={disabled ? -1 : 0}
|
|
319
|
-
aria-label={multiThumb ? sliderLabels?.[0]
|
|
320
|
+
aria-label={multiThumb ? sliderLabels?.[0] : sliderLabel}
|
|
320
321
|
aria-hidden={hidden}
|
|
321
322
|
aria-disabled={disabled}
|
|
322
323
|
aria-readonly={readonly}
|
|
@@ -332,7 +333,7 @@
|
|
|
332
333
|
<div
|
|
333
334
|
role="slider"
|
|
334
335
|
tabindex={disabled ? -1 : 0}
|
|
335
|
-
aria-label={sliderLabels?.[1]
|
|
336
|
+
aria-label={sliderLabels?.[1]}
|
|
336
337
|
aria-hidden={hidden}
|
|
337
338
|
aria-disabled={disabled}
|
|
338
339
|
aria-readonly={readonly}
|
|
@@ -363,7 +364,7 @@
|
|
|
363
364
|
position: relative;
|
|
364
365
|
display: inline-block;
|
|
365
366
|
margin: var(--sui-focus-ring-width);
|
|
366
|
-
padding:
|
|
367
|
+
padding: 4px 6px;
|
|
367
368
|
touch-action: none;
|
|
368
369
|
}
|
|
369
370
|
.slider:hover .base-bar {
|
|
@@ -375,7 +376,7 @@
|
|
|
375
376
|
|
|
376
377
|
.base {
|
|
377
378
|
position: relative;
|
|
378
|
-
width: var(--sui-slider-base-width,
|
|
379
|
+
width: var(--sui-slider-base-width, 240px);
|
|
379
380
|
height: calc(var(--sui-checkbox-height) / 2);
|
|
380
381
|
cursor: pointer;
|
|
381
382
|
}
|
|
@@ -385,7 +386,7 @@
|
|
|
385
386
|
border-style: solid;
|
|
386
387
|
border-color: var(--sui-control-border-color);
|
|
387
388
|
border-radius: var(--sui-checkbox-height);
|
|
388
|
-
background-color: var(--sui-
|
|
389
|
+
background-color: var(--sui-slider-background-color, var(--sui-secondary-background-color));
|
|
389
390
|
transition: all 200ms;
|
|
390
391
|
width: 100%;
|
|
391
392
|
height: 100%;
|
|
@@ -398,6 +399,9 @@
|
|
|
398
399
|
border-radius: var(--sui-checkbox-height);
|
|
399
400
|
background-color: var(--sui-primary-accent-color-light);
|
|
400
401
|
}
|
|
402
|
+
.invalid .slider-bar {
|
|
403
|
+
background-color: var(--sui-error-border-color);
|
|
404
|
+
}
|
|
401
405
|
|
|
402
406
|
[role=slider] {
|
|
403
407
|
position: absolute;
|
|
@@ -410,6 +414,9 @@
|
|
|
410
414
|
cursor: pointer;
|
|
411
415
|
transform: translate(calc((var(--sui-checkbox-height) / 2 - 1px) * -1), calc((var(--sui-checkbox-height) / 4 - 1px) * -1));
|
|
412
416
|
}
|
|
417
|
+
.invalid [role=slider] {
|
|
418
|
+
border-color: var(--sui-error-border-color);
|
|
419
|
+
}
|
|
413
420
|
|
|
414
421
|
.label {
|
|
415
422
|
position: absolute;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<script>
|
|
8
8
|
/**
|
|
9
9
|
* @typedef {object} Props
|
|
10
|
-
* @property {string
|
|
10
|
+
* @property {string} [label] - Text label displayed next to the switch.
|
|
11
11
|
* @property {string} [class] - The `class` attribute on the wrapper element.
|
|
12
12
|
* @property {boolean} [hidden] - Whether to hide the widget.
|
|
13
13
|
* @property {boolean} [disabled] - Whether to disable the widget. An alias of the `aria-disabled`
|
|
@@ -90,6 +90,9 @@
|
|
|
90
90
|
-webkit-user-select: none;
|
|
91
91
|
user-select: none;
|
|
92
92
|
}
|
|
93
|
+
button[aria-invalid=true] span {
|
|
94
|
+
background-color: var(--sui-error-border-color) !important;
|
|
95
|
+
}
|
|
93
96
|
button:hover[aria-checked=false] span {
|
|
94
97
|
background-color: var(--sui-hover-background-color);
|
|
95
98
|
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* attribute.
|
|
17
17
|
* @property {'horizontal' | 'vertical'} [orientation] - Orientation of the widget. An alias of
|
|
18
18
|
* the `aria-orientation` attribute.
|
|
19
|
-
* @property {string
|
|
19
|
+
* @property {string} [name] - The `data-name` attribute on the wrapper element.
|
|
20
20
|
* @property {import('svelte').Snippet} [children] - Primary slot content.
|
|
21
21
|
* @property {(event: CustomEvent) => void} [onChange] - Custom `Change` event handler.
|
|
22
22
|
*/
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export function initEditor(
|
|
1
|
+
export function initEditor({ components }?: {
|
|
2
|
+
components?: import("../../typedefs").TextEditorComponent[] | undefined;
|
|
3
|
+
} | undefined): import("lexical").LexicalEditor;
|
|
2
4
|
export function convertMarkdown(editor: import("lexical").LexicalEditor, value: string): Promise<void>;
|
|
3
5
|
export function focusEditor(editor: import("lexical").LexicalEditor): Promise<void>;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
CodeHighlightNode,
|
|
3
|
+
CodeNode,
|
|
4
|
+
$isCodeHighlightNode as isCodeHighlightNode,
|
|
5
|
+
$isCodeNode as isCodeNode,
|
|
6
|
+
registerCodeHighlighting,
|
|
7
|
+
} from '@lexical/code';
|
|
2
8
|
import { registerDragonSupport } from '@lexical/dragon';
|
|
3
9
|
import { createEmptyHistoryState, registerHistory } from '@lexical/history';
|
|
4
10
|
import {
|
|
@@ -31,6 +37,7 @@ import {
|
|
|
31
37
|
} from '@lexical/rich-text';
|
|
32
38
|
import { TableCellNode, TableNode, TableRowNode } from '@lexical/table';
|
|
33
39
|
import { $getNearestNodeOfType as getNearestNodeOfType } from '@lexical/utils';
|
|
40
|
+
import { sleep } from '@sveltia/utils/misc';
|
|
34
41
|
import {
|
|
35
42
|
COMMAND_PRIORITY_NORMAL,
|
|
36
43
|
ElementNode,
|
|
@@ -41,8 +48,11 @@ import {
|
|
|
41
48
|
$getSelection as getSelection,
|
|
42
49
|
$isRangeSelection as isRangeSelection,
|
|
43
50
|
} from 'lexical';
|
|
51
|
+
import prismComponents from 'prismjs/components';
|
|
44
52
|
import { blockButtonTypes, textFormatButtonTypes } from '.';
|
|
45
53
|
|
|
54
|
+
const allTransformers = [...TRANSFORMERS];
|
|
55
|
+
|
|
46
56
|
/**
|
|
47
57
|
* Lexical editor configuration.
|
|
48
58
|
* @type {import('lexical').CreateEditorArgs}
|
|
@@ -74,31 +84,66 @@ const editorConfig = {
|
|
|
74
84
|
listitem: 'nested',
|
|
75
85
|
},
|
|
76
86
|
},
|
|
87
|
+
code: 'code-block',
|
|
88
|
+
// https://github.com/facebook/lexical/blob/main/packages/lexical-website/docs/getting-started/theming.md
|
|
89
|
+
codeHighlight: {
|
|
90
|
+
atrule: 'token atrule',
|
|
91
|
+
attr: 'token attr',
|
|
92
|
+
boolean: 'token boolean',
|
|
93
|
+
builtin: 'token builtin',
|
|
94
|
+
cdata: 'token cdata',
|
|
95
|
+
char: 'token char',
|
|
96
|
+
class: 'token class',
|
|
97
|
+
'class-name': 'token class-name',
|
|
98
|
+
comment: 'token comment',
|
|
99
|
+
constant: 'token constant',
|
|
100
|
+
deleted: 'token deleted',
|
|
101
|
+
doctype: 'token doctype',
|
|
102
|
+
entity: 'token entity',
|
|
103
|
+
function: 'token function',
|
|
104
|
+
important: 'token important',
|
|
105
|
+
inserted: 'token inserted',
|
|
106
|
+
keyword: 'token keyword',
|
|
107
|
+
namespace: 'token namespace',
|
|
108
|
+
number: 'token number',
|
|
109
|
+
operator: 'token operator',
|
|
110
|
+
prolog: 'token prolog',
|
|
111
|
+
property: 'token property',
|
|
112
|
+
punctuation: 'token punctuation',
|
|
113
|
+
regex: 'token regex',
|
|
114
|
+
selector: 'token selector',
|
|
115
|
+
string: 'token string',
|
|
116
|
+
symbol: 'token symbol',
|
|
117
|
+
tag: 'token tag',
|
|
118
|
+
url: 'token url',
|
|
119
|
+
variable: 'token variable',
|
|
120
|
+
},
|
|
77
121
|
},
|
|
78
122
|
};
|
|
79
123
|
|
|
80
124
|
/**
|
|
81
|
-
*
|
|
82
|
-
* @
|
|
125
|
+
* Get the current selection’s block and inline level types.
|
|
126
|
+
* @returns {{ blockType: import('../../typedefs').TextEditorBlockType,
|
|
127
|
+
* inlineTypes: import('../../typedefs').TextEditorInlineType[] }} Types.
|
|
83
128
|
*/
|
|
84
|
-
const
|
|
129
|
+
const getSelectionTypes = () => {
|
|
85
130
|
const selection = getSelection();
|
|
86
131
|
|
|
87
132
|
if (!isRangeSelection(selection)) {
|
|
88
|
-
return;
|
|
133
|
+
return { blockType: 'paragraph', inlineTypes: [] };
|
|
89
134
|
}
|
|
90
135
|
|
|
91
136
|
const anchor = selection.anchor.getNode();
|
|
92
137
|
/** @type {ElementNode | null} */
|
|
93
138
|
let parent = null;
|
|
94
139
|
/** @type {import('../../typedefs').TextEditorInlineType[]} */
|
|
95
|
-
const
|
|
140
|
+
const inlineTypes = textFormatButtonTypes.filter((type) => selection.hasFormat(type));
|
|
96
141
|
|
|
97
142
|
if (anchor.getType() !== 'root') {
|
|
98
143
|
parent = anchor instanceof ElementNode ? anchor : getNearestNodeOfType(anchor, ElementNode);
|
|
99
144
|
|
|
100
145
|
if (isLinkNode(parent)) {
|
|
101
|
-
|
|
146
|
+
inlineTypes.push('link');
|
|
102
147
|
parent = getNearestNodeOfType(parent, ElementNode);
|
|
103
148
|
}
|
|
104
149
|
|
|
@@ -107,7 +152,7 @@ const onEditorUpdate = (editor) => {
|
|
|
107
152
|
}
|
|
108
153
|
}
|
|
109
154
|
|
|
110
|
-
const
|
|
155
|
+
const blockType = /** @type {import('../../typedefs').TextEditorBlockType} */ (
|
|
111
156
|
(() => {
|
|
112
157
|
if (!parent) {
|
|
113
158
|
return 'paragraph';
|
|
@@ -125,6 +170,10 @@ const onEditorUpdate = (editor) => {
|
|
|
125
170
|
return 'blockquote';
|
|
126
171
|
}
|
|
127
172
|
|
|
173
|
+
if (isCodeNode(parent) || isCodeHighlightNode(parent)) {
|
|
174
|
+
return 'code-block';
|
|
175
|
+
}
|
|
176
|
+
|
|
128
177
|
const type = parent.getType();
|
|
129
178
|
|
|
130
179
|
if (blockButtonTypes.includes(/** @type {any} */ (type))) {
|
|
@@ -135,15 +184,25 @@ const onEditorUpdate = (editor) => {
|
|
|
135
184
|
})()
|
|
136
185
|
);
|
|
137
186
|
|
|
187
|
+
return { blockType, inlineTypes };
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Listen to changes made on the editor and trigger the Update event.
|
|
192
|
+
* @param {import('lexical').LexicalEditor} editor - Editor instance.
|
|
193
|
+
*/
|
|
194
|
+
const onEditorUpdate = (editor) => {
|
|
195
|
+
const { blockType, inlineTypes } = getSelectionTypes();
|
|
196
|
+
|
|
138
197
|
editor.getRootElement()?.dispatchEvent(
|
|
139
198
|
new CustomEvent('Update', {
|
|
140
199
|
detail: {
|
|
141
200
|
value: convertToMarkdownString(
|
|
142
201
|
// Use underscores for italic text in Markdown instead of asterisks
|
|
143
|
-
|
|
202
|
+
allTransformers.filter((/** @type {any} */ { tag }) => tag !== '*'),
|
|
144
203
|
),
|
|
145
|
-
selectionBlockType,
|
|
146
|
-
selectionInlineTypes,
|
|
204
|
+
selectionBlockType: blockType,
|
|
205
|
+
selectionInlineTypes: inlineTypes,
|
|
147
206
|
},
|
|
148
207
|
}),
|
|
149
208
|
);
|
|
@@ -151,15 +210,29 @@ const onEditorUpdate = (editor) => {
|
|
|
151
210
|
|
|
152
211
|
/**
|
|
153
212
|
* Initialize the Lexical editor.
|
|
213
|
+
* @param {object} [options] - Options.
|
|
214
|
+
* @param {import('../../typedefs').TextEditorComponent[]} [options.components] - Editor components.
|
|
154
215
|
* @returns {import('lexical').LexicalEditor} Editor instance.
|
|
155
216
|
*/
|
|
156
|
-
export const initEditor = () => {
|
|
217
|
+
export const initEditor = ({ components } = {}) => {
|
|
218
|
+
components?.forEach(({ node, transformer }) => {
|
|
219
|
+
/** @type {any[]} */ (editorConfig.nodes).unshift(node);
|
|
220
|
+
allTransformers.unshift(transformer);
|
|
221
|
+
});
|
|
222
|
+
|
|
157
223
|
const editor = createEditor(editorConfig);
|
|
158
224
|
|
|
159
225
|
registerRichText(editor);
|
|
160
226
|
registerDragonSupport(editor);
|
|
161
227
|
registerHistory(editor, createEmptyHistoryState(), 1000);
|
|
162
228
|
|
|
229
|
+
registerCodeHighlighting(editor, {
|
|
230
|
+
defaultLanguage: 'plain',
|
|
231
|
+
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
232
|
+
tokenize: (code, language = 'plain') =>
|
|
233
|
+
window.Prism.tokenize(code, window.Prism.languages[language] ?? window.Prism.languages.plain),
|
|
234
|
+
});
|
|
235
|
+
|
|
163
236
|
editor.registerCommand(
|
|
164
237
|
TOGGLE_LINK_COMMAND,
|
|
165
238
|
(payload) => {
|
|
@@ -250,26 +323,47 @@ export const initEditor = () => {
|
|
|
250
323
|
* @returns {Promise<void>} Nothing.
|
|
251
324
|
* @throws {Error} Failed to convert the value to Lexical nodes.
|
|
252
325
|
*/
|
|
253
|
-
export const convertMarkdown = async (editor, value) =>
|
|
254
|
-
|
|
326
|
+
export const convertMarkdown = async (editor, value) => {
|
|
327
|
+
// Load Prism language support on demand; the `loadLanguages` Prism utility method cannot be used
|
|
328
|
+
await Promise.all(
|
|
329
|
+
[...value.matchAll(/^```(?<lang>.+?)\n/gm)].map(async ({ groups: { lang } = {} }) => {
|
|
330
|
+
if (!(lang in window.Prism.languages) && lang in prismComponents.languages) {
|
|
331
|
+
try {
|
|
332
|
+
await import(
|
|
333
|
+
// eslint-disable-next-line jsdoc/no-bad-blocks
|
|
334
|
+
/* @vite-ignore */ `https://unpkg.com/prismjs@1.29.0/components/prism-${lang}.min.js`
|
|
335
|
+
);
|
|
336
|
+
} catch {
|
|
337
|
+
//
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}),
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
return new Promise((resolve, reject) => {
|
|
255
344
|
editor.update(() => {
|
|
256
345
|
try {
|
|
257
|
-
convertFromMarkdownString(value,
|
|
346
|
+
convertFromMarkdownString(value, allTransformers);
|
|
258
347
|
resolve(void 0);
|
|
259
|
-
} catch {
|
|
260
|
-
reject(new Error('Failed to convert Markdown'));
|
|
348
|
+
} catch (ex) {
|
|
349
|
+
reject(new Error('Failed to convert Markdown', { cause: ex }));
|
|
261
350
|
}
|
|
262
351
|
});
|
|
263
352
|
});
|
|
353
|
+
};
|
|
264
354
|
|
|
265
355
|
/**
|
|
266
356
|
* Move focus to the editor so the user can start editing immediately.
|
|
267
357
|
* @param {import('lexical').LexicalEditor} editor - Editor instance.
|
|
268
358
|
* @returns {Promise<void>} Nothing.
|
|
269
359
|
*/
|
|
270
|
-
export const focusEditor = async (editor) =>
|
|
271
|
-
|
|
360
|
+
export const focusEditor = async (editor) => {
|
|
361
|
+
await sleep(100);
|
|
362
|
+
editor.getRootElement()?.focus();
|
|
363
|
+
|
|
364
|
+
return new Promise((resolve) => {
|
|
272
365
|
editor.focus(() => {
|
|
273
366
|
resolve(undefined);
|
|
274
367
|
});
|
|
275
368
|
});
|
|
369
|
+
};
|
|
@@ -73,6 +73,11 @@ export const availableButtons = {
|
|
|
73
73
|
icon: 'format_quote',
|
|
74
74
|
inline: false,
|
|
75
75
|
},
|
|
76
|
+
'code-block': {
|
|
77
|
+
labelKey: 'code_block',
|
|
78
|
+
icon: 'code_blocks',
|
|
79
|
+
inline: false,
|
|
80
|
+
},
|
|
76
81
|
};
|
|
77
82
|
/**
|
|
78
83
|
* @type {import('../../typedefs').TextEditorFormatType[]}
|
|
@@ -96,4 +101,5 @@ export const blockButtonTypes = [
|
|
|
96
101
|
'bulleted-list',
|
|
97
102
|
'numbered-list',
|
|
98
103
|
'blockquote',
|
|
104
|
+
'code-block',
|
|
99
105
|
];
|