@oscarpalmer/oui 0.35.0 → 0.37.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/css/badge.css +18 -15
- package/dist/css/button.css +35 -31
- package/dist/css/color.css +20 -20
- package/dist/css/combobox.css +134 -35
- package/dist/css/content.css +29 -10
- package/dist/css/floatable.css +10 -10
- package/dist/css/form.css +393 -129
- package/dist/css/listbox.css +176 -0
- package/dist/css/message.css +13 -10
- package/dist/css/reset.css +29 -88
- package/dist/css/splitter.css +2 -2
- package/dist/css/tabs.css +103 -0
- package/dist/js/combobox/constants.combobox.d.mts +2 -2
- package/dist/js/combobox/constants.combobox.mjs +40 -33
- package/dist/js/combobox/dom.combobox.d.mts +8 -91
- package/dist/js/combobox/dom.combobox.mjs +204 -2
- package/dist/js/combobox/event.combobox.d.mts +14 -8
- package/dist/js/combobox/event.combobox.mjs +2 -2
- package/dist/js/combobox/index.d.mts +1 -1
- package/dist/js/combobox/index.mjs +20 -18
- package/dist/js/combobox/misc.combobox.d.mts +2 -2
- package/dist/js/combobox/misc.combobox.mjs +2 -2
- package/dist/js/combobox/models.combobox.d.mts +44 -2
- package/dist/js/combobox/state.combobox.d.mts +9 -10
- package/dist/js/combobox/state.combobox.mjs +2 -2
- package/dist/js/constants.combobox-DmRAMC64.d.mts +26 -0
- package/dist/js/constants.listbox-DRsXUxd3.d.mts +14 -0
- package/dist/js/focus-trap/focus-trap.embedded.mjs +6 -10
- package/dist/js/index-EfkUSals.d.mts +139 -0
- package/dist/js/index.d.mts +5 -2
- package/dist/js/index.mjs +5 -2
- package/dist/js/internal/attributable.mjs +4 -3
- package/dist/js/internal/draggable.mjs +16 -22
- package/dist/js/internal/listbox/listbox.constants.d.mts +11 -0
- package/dist/js/internal/listbox/listbox.constants.mjs +23 -0
- package/dist/js/internal/listbox/listbox.data.d.mts +20 -0
- package/dist/js/internal/listbox/listbox.data.mjs +2 -0
- package/dist/js/internal/listbox/listbox.dom.d.mts +66 -0
- package/dist/js/internal/listbox/listbox.dom.mjs +2 -0
- package/dist/js/internal/listbox/listbox.event.d.mts +5 -0
- package/dist/js/internal/listbox/listbox.event.mjs +63 -0
- package/dist/js/internal/listbox/listbox.form.d.mts +6 -0
- package/dist/js/internal/listbox/listbox.form.mjs +52 -0
- package/dist/js/internal/listbox/listbox.misc.d.mts +12 -0
- package/dist/js/internal/listbox/listbox.misc.mjs +2 -0
- package/dist/js/internal/listbox/listbox.model.d.mts +2 -0
- package/dist/js/internal/listbox/listbox.model.mjs +1 -0
- package/dist/js/internal/listbox/listbox.state.d.mts +7 -0
- package/dist/js/internal/listbox/listbox.state.mjs +40 -0
- package/dist/js/internal/misc.d.mts +6 -0
- package/dist/js/internal/misc.mjs +13 -0
- package/dist/js/internal/navigable.d.mts +11 -5
- package/dist/js/internal/navigable.mjs +44 -18
- package/dist/js/l10n-Bn-7RcwR.d.mts +20 -0
- package/dist/js/l10n.d.mts +2 -20
- package/dist/js/listbox/constants.listbox.d.mts +2 -0
- package/dist/js/listbox/constants.listbox.mjs +40 -0
- package/dist/js/listbox/event.listbox.d.mts +8 -0
- package/dist/js/listbox/event.listbox.mjs +2 -0
- package/dist/js/listbox/index.d.mts +116 -0
- package/dist/js/listbox/index.mjs +189 -0
- package/dist/js/listbox/misc.listbox.d.mts +2 -0
- package/dist/js/listbox/misc.listbox.mjs +2 -0
- package/dist/js/listbox/state.listbox.d.mts +11 -0
- package/dist/js/listbox/state.listbox.mjs +2 -0
- package/dist/js/listbox.data-BWd0PCy7.mjs +424 -0
- package/dist/js/listbox.model-CRReGOmu.d.mts +125 -0
- package/dist/js/misc.listbox-BI-XsTOf.mjs +197 -0
- package/dist/js/misc.listbox-gnoJhrTr.d.mts +20 -0
- package/dist/js/movable/movable.embedded.mjs +3 -6
- package/dist/js/resizable/resizable.embedded.mjs +16 -26
- package/dist/js/sortable/sortable.embedded.mjs +4 -2
- package/dist/js/splitter.mjs +15 -12
- package/dist/js/state.combobox-4xq0FPCF.mjs +365 -0
- package/dist/js/tabs.d.mts +25 -0
- package/dist/js/tabs.mjs +240 -0
- package/dist/js/tooltip.mjs +13 -12
- package/package.json +7 -3
- package/src/css/badge.scss +6 -18
- package/src/css/button.scss +6 -45
- package/src/css/color.scss +20 -20
- package/src/css/combobox.scss +21 -52
- package/src/css/content.scss +30 -3
- package/src/css/floatable.scss +17 -17
- package/src/css/form.scss +84 -72
- package/src/css/listbox.scss +120 -0
- package/src/css/message.scss +13 -28
- package/src/css/mixins.scss +253 -28
- package/src/css/reset.scss +37 -86
- package/src/css/splitter.scss +2 -2
- package/src/css/tabs.scss +85 -0
- package/src/js/combobox/constants.combobox.ts +46 -25
- package/src/js/combobox/dom.combobox.ts +36 -454
- package/src/js/combobox/event.combobox.ts +129 -218
- package/src/js/combobox/index.ts +37 -30
- package/src/js/combobox/misc.combobox.ts +30 -114
- package/src/js/combobox/models.combobox.ts +7 -47
- package/src/js/combobox/state.combobox.ts +126 -127
- package/src/js/focus-trap/focus-trap.embedded.ts +11 -19
- package/src/js/index.ts +2 -0
- package/src/js/internal/draggable.ts +29 -33
- package/src/js/internal/listbox/listbox.constants.ts +25 -0
- package/src/js/{combobox/data.combobox.ts → internal/listbox/listbox.data.ts} +94 -43
- package/src/js/internal/listbox/listbox.dom.ts +445 -0
- package/src/js/internal/listbox/listbox.event.ts +129 -0
- package/src/js/{combobox/form.combobox.ts → internal/listbox/listbox.form.ts} +13 -14
- package/src/js/internal/listbox/listbox.misc.ts +135 -0
- package/src/js/internal/listbox/listbox.model.ts +169 -0
- package/src/js/internal/listbox/listbox.state.ts +82 -0
- package/src/js/internal/misc.ts +27 -0
- package/src/js/internal/navigable.ts +80 -23
- package/src/js/l10n.ts +8 -8
- package/src/js/listbox/constants.listbox.ts +61 -0
- package/src/js/listbox/event.listbox.ts +106 -0
- package/src/js/listbox/index.ts +302 -0
- package/src/js/listbox/misc.listbox.ts +70 -0
- package/src/js/listbox/state.listbox.ts +196 -0
- package/src/js/movable/movable.embedded.ts +11 -13
- package/src/js/resizable/resizable.embedded.ts +25 -39
- package/src/js/splitter.ts +21 -18
- package/src/js/tabs.ts +447 -0
- package/src/js/tooltip.ts +20 -17
- package/dist/js/combobox/data.combobox.d.mts +0 -18
- package/dist/js/combobox/data.combobox.mjs +0 -2
- package/dist/js/combobox/form.combobox.d.mts +0 -6
- package/dist/js/combobox/form.combobox.mjs +0 -2
- package/dist/js/constants.combobox-h_kyDegw.d.mts +0 -248
- package/dist/js/data.combobox-B8HMkDOh.mjs +0 -1030
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { a as OuiListboxGroup, c as OuiListboxPreview, d as OuiListboxType, l as OuiListboxState, n as OuiListboxAutoComplete, s as OuiListboxOptions, t as OuiListboxAttributes } from "../../listbox.model-CRReGOmu.mjs";
|
|
2
|
+
//#region src/js/internal/listbox/listbox.dom.d.ts
|
|
3
|
+
type CreateListboxContent = {
|
|
4
|
+
element: HTMLDivElement;
|
|
5
|
+
filter?: CreateListboxFilter;
|
|
6
|
+
list: CreateListboxList;
|
|
7
|
+
message: HTMLDivElement;
|
|
8
|
+
value: HTMLSpanElement;
|
|
9
|
+
};
|
|
10
|
+
type CreateListboxContentParameters = {
|
|
11
|
+
attributes: OuiListboxAttributes;
|
|
12
|
+
autocomplete: OuiListboxAutoComplete;
|
|
13
|
+
element: HTMLElement;
|
|
14
|
+
id: string;
|
|
15
|
+
label: HTMLLabelElement;
|
|
16
|
+
listbox: boolean;
|
|
17
|
+
multiple: boolean;
|
|
18
|
+
select: HTMLSelectElement;
|
|
19
|
+
type: OuiListboxType;
|
|
20
|
+
};
|
|
21
|
+
type CreateListboxFilter = {
|
|
22
|
+
container: HTMLElement;
|
|
23
|
+
element: HTMLInputElement;
|
|
24
|
+
};
|
|
25
|
+
type CreateListboxGroupParameters = {
|
|
26
|
+
group: HTMLOptGroupElement;
|
|
27
|
+
groupOptions: HTMLOptionElement[];
|
|
28
|
+
original: CreateListboxContentParameters;
|
|
29
|
+
selected: HTMLElement[];
|
|
30
|
+
type: OuiListboxType;
|
|
31
|
+
};
|
|
32
|
+
type CreateListboxList = {
|
|
33
|
+
element: HTMLUListElement;
|
|
34
|
+
groups?: OuiListboxGroup[];
|
|
35
|
+
options: OuiListboxOptions;
|
|
36
|
+
};
|
|
37
|
+
type CreateListboxOptionParameters = {
|
|
38
|
+
group?: string;
|
|
39
|
+
index: number;
|
|
40
|
+
option: HTMLOptionElement;
|
|
41
|
+
original: CreateListboxContentParameters;
|
|
42
|
+
type: OuiListboxType;
|
|
43
|
+
};
|
|
44
|
+
type CreateListboxOptionsParameters = {
|
|
45
|
+
group?: string;
|
|
46
|
+
list: HTMLElement;
|
|
47
|
+
options: HTMLOptionElement[];
|
|
48
|
+
original: CreateListboxContentParameters;
|
|
49
|
+
selected: HTMLElement[];
|
|
50
|
+
type: OuiListboxType;
|
|
51
|
+
};
|
|
52
|
+
declare function createListboxContent(parameters: CreateListboxContentParameters): CreateListboxContent;
|
|
53
|
+
declare function createListboxFilter(parameters: CreateListboxContentParameters): CreateListboxFilter | undefined;
|
|
54
|
+
declare function createListboxGroup(parameters: CreateListboxGroupParameters): OuiListboxGroup;
|
|
55
|
+
declare function createListboxHeader(parameters: CreateListboxGroupParameters, group: HTMLOptGroupElement): HTMLElement;
|
|
56
|
+
declare function createListboxInput(parameters: CreateListboxContentParameters, value: string): HTMLInputElement;
|
|
57
|
+
declare function createListboxList(parameters: CreateListboxContentParameters): CreateListboxList;
|
|
58
|
+
declare function createListboxMessage(attribute: string): HTMLDivElement;
|
|
59
|
+
declare function createListboxOption(parameters: CreateListboxOptionParameters): HTMLElement;
|
|
60
|
+
declare function createListboxOptions(parameters: CreateListboxOptionsParameters): HTMLElement[];
|
|
61
|
+
declare function createListboxValueLabel(id: string): HTMLSpanElement;
|
|
62
|
+
declare function updateListboxMessage(state: OuiListboxState): void;
|
|
63
|
+
declare function updateListboxPreview<State extends OuiListboxState>(preview: OuiListboxPreview, state: State, active?: HTMLElement, scroll?: boolean): void;
|
|
64
|
+
declare function updateListboxValueLabel<State extends OuiListboxState>(state: State): void;
|
|
65
|
+
//#endregion
|
|
66
|
+
export { CreateListboxContent, CreateListboxContentParameters, CreateListboxFilter, CreateListboxList, createListboxContent, createListboxFilter, createListboxGroup, createListboxHeader, createListboxInput, createListboxList, createListboxMessage, createListboxOption, createListboxOptions, createListboxValueLabel, updateListboxMessage, updateListboxPreview, updateListboxValueLabel };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { _ as createListboxValueLabel, b as updateListboxValueLabel, c as createListboxContent, d as createListboxHeader, f as createListboxInput, g as createListboxOptions, h as createListboxOption, l as createListboxFilter, m as createListboxMessage, p as createListboxList, u as createListboxGroup, v as updateListboxMessage, y as updateListboxPreview } from "../../listbox.data-BWd0PCy7.mjs";
|
|
2
|
+
export { createListboxContent, createListboxFilter, createListboxGroup, createListboxHeader, createListboxInput, createListboxList, createListboxMessage, createListboxOption, createListboxOptions, createListboxValueLabel, updateListboxMessage, updateListboxPreview, updateListboxValueLabel };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { l as OuiListboxState } from "../../listbox.model-CRReGOmu.mjs";
|
|
2
|
+
//#region src/js/internal/listbox/listbox.event.d.ts
|
|
3
|
+
declare function processListboxKeydown<State extends OuiListboxState>(event: KeyboardEvent, state: State): void;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { processListboxKeydown };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { LISTBOX_KEYS } from "./listbox.constants.mjs";
|
|
2
|
+
import { S as getListboxVisibleOptions } from "../../listbox.data-BWd0PCy7.mjs";
|
|
3
|
+
import { clamp } from "@oscarpalmer/atoms/number";
|
|
4
|
+
//#region src/js/internal/listbox/listbox.event.ts
|
|
5
|
+
function processListboxKeydown(event, state) {
|
|
6
|
+
const ignore = state.disabled || state.readonly;
|
|
7
|
+
const isSelect = state.type === "select";
|
|
8
|
+
let preventDefault = ignore;
|
|
9
|
+
switch (true) {
|
|
10
|
+
case event.key === " ":
|
|
11
|
+
if (!state.disabled) state.callbacks.keydown.onActivation?.(state);
|
|
12
|
+
break;
|
|
13
|
+
case event.key === "Enter":
|
|
14
|
+
preventDefault = state.callbacks.keydown.preventActivation?.(state) ?? true;
|
|
15
|
+
if (preventDefault) state.callbacks.keydown.onEnter?.(state);
|
|
16
|
+
else if (!ignore && state.type === "select") state.callbacks.keydown.onActivation?.(state);
|
|
17
|
+
else if (!ignore) state.internals.form?.requestSubmit();
|
|
18
|
+
break;
|
|
19
|
+
case event.key === "Escape":
|
|
20
|
+
preventDefault = false;
|
|
21
|
+
state.callbacks.keydown.onEscape?.(state);
|
|
22
|
+
break;
|
|
23
|
+
case !isSelect && LISTBOX_KEYS.selection.has(event.key):
|
|
24
|
+
if (!ignore) state.callbacks.keydown.onSelection?.(state);
|
|
25
|
+
break;
|
|
26
|
+
case LISTBOX_KEYS.navigation.has(event.key):
|
|
27
|
+
if (!state.disabled) onNavigation(event, state);
|
|
28
|
+
break;
|
|
29
|
+
default:
|
|
30
|
+
preventDefault = false;
|
|
31
|
+
if (event.key === "Tab") state.callbacks.keydown.onTab?.(state);
|
|
32
|
+
}
|
|
33
|
+
if (preventDefault) {
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
event.stopPropagation();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function onNavigation(event, state) {
|
|
39
|
+
const skip = state.callbacks.keydown.skipNavigation?.(state) ?? false;
|
|
40
|
+
const visible = getListboxVisibleOptions(state);
|
|
41
|
+
if (visible.length === 0) return;
|
|
42
|
+
let next;
|
|
43
|
+
if (skip || state.active == null) next = state.active ?? visible.at(event.key === "ArrowDown" ? 0 : -1);
|
|
44
|
+
else {
|
|
45
|
+
const current = visible.findIndex((option) => option.id === state.active?.id);
|
|
46
|
+
let index;
|
|
47
|
+
switch (event.key) {
|
|
48
|
+
case "ArrowDown":
|
|
49
|
+
case "ArrowUp":
|
|
50
|
+
index = clamp(current + (event.key === "ArrowDown" ? 1 : -1), 0, visible.length - 1, true);
|
|
51
|
+
break;
|
|
52
|
+
case "PageDown":
|
|
53
|
+
case "PageUp": index = clamp(current + (event.key === "PageDown" ? 10 : -10), 0, visible.length - 1);
|
|
54
|
+
}
|
|
55
|
+
if (index != null) next = visible[index];
|
|
56
|
+
}
|
|
57
|
+
let preview;
|
|
58
|
+
if (state.type === "autocomplete" && (state.autocomplete.both || state.autocomplete.inline)) preview = "set";
|
|
59
|
+
else preview = "none";
|
|
60
|
+
state.callbacks.keydown.onNavigation(preview, state, next ?? state.active ?? visible[0]);
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { processListboxKeydown };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { l as OuiListboxState } from "../../listbox.model-CRReGOmu.mjs";
|
|
2
|
+
//#region src/js/internal/listbox/listbox.form.d.ts
|
|
3
|
+
declare function updateListboxForm<State extends OuiListboxState>(state: State, values: string[], emit?: boolean): void;
|
|
4
|
+
declare function updateListboxValidity(state: OuiListboxState): void;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { updateListboxForm, updateListboxValidity };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getLocalization, localize } from "../../l10n.mjs";
|
|
2
|
+
import { dispatch } from "@oscarpalmer/toretto/event";
|
|
3
|
+
//#region src/js/internal/listbox/listbox.form.ts
|
|
4
|
+
function updateListboxForm(state, values, emit) {
|
|
5
|
+
let value;
|
|
6
|
+
if (state.multiple) {
|
|
7
|
+
const { length } = values;
|
|
8
|
+
value = new FormData();
|
|
9
|
+
for (let index = 0; index < length; index += 1) value.append(state.name, values[index]);
|
|
10
|
+
} else value = values[0];
|
|
11
|
+
state.values.current = values;
|
|
12
|
+
state.internals.setFormValue(value, JSON.stringify(values));
|
|
13
|
+
state.callbacks.data.onForm(state);
|
|
14
|
+
updateListboxValidity(state);
|
|
15
|
+
if (emit ?? true) dispatch(state.host, "oui:change");
|
|
16
|
+
}
|
|
17
|
+
function updateListboxValidity(state) {
|
|
18
|
+
if (state.autocomplete.none && !state.listbox) {
|
|
19
|
+
const valueMissing = state.required && state.filter.element.value.length === 0;
|
|
20
|
+
const localization = getLocalization(state.localizations.global, state.host, "invalid", state.localizations.component);
|
|
21
|
+
state.internals.setValidity({ valueMissing }, localize(localization, {}, []));
|
|
22
|
+
state.internals.checkValidity();
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
let data = {};
|
|
26
|
+
let error;
|
|
27
|
+
let key;
|
|
28
|
+
let parameters = [];
|
|
29
|
+
switch (true) {
|
|
30
|
+
case state.required && state.options.selected.length === 0:
|
|
31
|
+
error = "badInput";
|
|
32
|
+
key = "input";
|
|
33
|
+
break;
|
|
34
|
+
case state.multiple && typeof state.max === "number" && state.options.selected.length > state.max:
|
|
35
|
+
data = { amount: state.max };
|
|
36
|
+
error = "rangeOverflow";
|
|
37
|
+
key = "max";
|
|
38
|
+
parameters = [state.max];
|
|
39
|
+
break;
|
|
40
|
+
case state.multiple && typeof state.min === "number" && state.options.selected.length < state.min:
|
|
41
|
+
data = { amount: state.min };
|
|
42
|
+
error = "rangeUnderflow";
|
|
43
|
+
key = "min";
|
|
44
|
+
parameters = [state.min];
|
|
45
|
+
}
|
|
46
|
+
const localization = key == null ? void 0 : getLocalization(state.localizations.global, state.host, key, state.localizations.component);
|
|
47
|
+
const message = localization == null ? void 0 : localize(localization, data, parameters);
|
|
48
|
+
state.internals.setValidity(error == null ? {} : { [error]: true }, message);
|
|
49
|
+
state.internals.checkValidity();
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { updateListboxForm, updateListboxValidity };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { l as OuiListboxState } from "../../listbox.model-CRReGOmu.mjs";
|
|
2
|
+
//#region src/js/internal/listbox/listbox.misc.d.ts
|
|
3
|
+
declare function generateListboxIds(prefix: string, select: HTMLSelectElement): void;
|
|
4
|
+
declare function getListboxVisibleOptions(state: OuiListboxState): HTMLElement[];
|
|
5
|
+
declare function setListboxDisabled<State extends OuiListboxState>(state: State, value: boolean): void;
|
|
6
|
+
declare function setListboxFilter<State extends OuiListboxState>(state: State, value: unknown): void;
|
|
7
|
+
declare function setListboxLimit<State extends OuiListboxState>(type: 'max' | 'min', state: State, value?: unknown): void;
|
|
8
|
+
declare function setListboxMultiple(element: HTMLElement, value: boolean): void;
|
|
9
|
+
declare function setListboxReadonly<State extends OuiListboxState>(state: State, value: boolean): void;
|
|
10
|
+
declare function setListboxRequired<State extends OuiListboxState>(state: State, value: boolean): void;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { generateListboxIds, getListboxVisibleOptions, setListboxDisabled, setListboxFilter, setListboxLimit, setListboxMultiple, setListboxReadonly, setListboxRequired };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { C as setListboxDisabled, D as setListboxReadonly, E as setListboxMultiple, O as setListboxRequired, S as getListboxVisibleOptions, T as setListboxLimit, w as setListboxFilter, x as generateListboxIds } from "../../listbox.data-BWd0PCy7.mjs";
|
|
2
|
+
export { generateListboxIds, getListboxVisibleOptions, setListboxDisabled, setListboxFilter, setListboxLimit, setListboxMultiple, setListboxReadonly, setListboxRequired };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as OuiListboxGroup, c as OuiListboxPreview, d as OuiListboxType, i as OuiListboxCallbacks, l as OuiListboxState, n as OuiListboxAutoComplete, o as OuiListboxLocalizations, r as OuiListboxAutoCompleteType, s as OuiListboxOptions, t as OuiListboxAttributes, u as OuiListboxStates } from "../../listbox.model-CRReGOmu.mjs";
|
|
2
|
+
export { OuiListboxAttributes, OuiListboxAutoComplete, OuiListboxAutoCompleteType, OuiListboxCallbacks, OuiListboxGroup, OuiListboxLocalizations, OuiListboxOptions, OuiListboxPreview, OuiListboxState, OuiListboxStates, OuiListboxType };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { l as OuiListboxState, u as OuiListboxStates } from "../../listbox.model-CRReGOmu.mjs";
|
|
2
|
+
//#region src/js/internal/listbox/listbox.state.d.ts
|
|
3
|
+
declare function attachListbox<State extends OuiListboxState>(state: State, states: OuiListboxStates<State>, onAttach: (state: State) => void): void;
|
|
4
|
+
declare function detachListbox<State extends OuiListboxState>(state: State, states: OuiListboxStates<State>, onDetach: (state: State) => void): void;
|
|
5
|
+
declare function initializeListboxState<State extends OuiListboxState>(state: State, states: OuiListboxStates<State>, onAttach: (state: State) => void): State;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { attachListbox, detachListbox, initializeListboxState };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { updateListboxForm } from "./listbox.form.mjs";
|
|
2
|
+
import { C as setListboxDisabled, D as setListboxReadonly, E as setListboxMultiple, O as setListboxRequired, T as setListboxLimit, b as updateListboxValueLabel, i as filterListboxOptions, v as updateListboxMessage, y as updateListboxPreview } from "../../listbox.data-BWd0PCy7.mjs";
|
|
3
|
+
import { getAttribute } from "@oscarpalmer/toretto/attribute";
|
|
4
|
+
//#region src/js/internal/listbox/listbox.state.ts
|
|
5
|
+
function attachListbox(state, states, onAttach) {
|
|
6
|
+
const { filter, host, label } = state;
|
|
7
|
+
label.element.htmlFor = filter.element.id;
|
|
8
|
+
label.element.id = `${state.id}_label`;
|
|
9
|
+
onAttach(state);
|
|
10
|
+
states.map.set(host, state);
|
|
11
|
+
states.set.add(state);
|
|
12
|
+
}
|
|
13
|
+
function detachListbox(state, states, onDetach) {
|
|
14
|
+
const { host, label, select } = state;
|
|
15
|
+
const listeners = state.listeners.splice(0);
|
|
16
|
+
const { length } = listeners;
|
|
17
|
+
for (let index = 0; index < length; index += 1) listeners[index]();
|
|
18
|
+
label.element.htmlFor = select.id;
|
|
19
|
+
label.element.id = label.id;
|
|
20
|
+
onDetach(state);
|
|
21
|
+
states.map.delete(host);
|
|
22
|
+
states.set.delete(state);
|
|
23
|
+
}
|
|
24
|
+
function initializeListboxState(state, states, onAttach) {
|
|
25
|
+
attachListbox(state, states, onAttach);
|
|
26
|
+
setListboxDisabled(state, state.disabled);
|
|
27
|
+
setListboxLimit("max", state, getAttribute(state.host, "max"));
|
|
28
|
+
setListboxLimit("min", state, getAttribute(state.host, "min"));
|
|
29
|
+
setListboxMultiple(state.host, state.multiple);
|
|
30
|
+
setListboxReadonly(state, state.readonly);
|
|
31
|
+
setListboxRequired(state, state.required);
|
|
32
|
+
filterListboxOptions(state);
|
|
33
|
+
updateListboxForm(state, state.values.current, false);
|
|
34
|
+
updateListboxMessage(state);
|
|
35
|
+
updateListboxValueLabel(state);
|
|
36
|
+
if (state.options.selected.length > 0) updateListboxPreview("none", state, state.options.selected[0], false);
|
|
37
|
+
return state;
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { attachListbox, detachListbox, initializeListboxState };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AnyAriaBooleanAttribute } from "@oscarpalmer/toretto/models";
|
|
2
|
+
//#region src/js/internal/misc.d.ts
|
|
3
|
+
declare function getAttributeValue<Value>(element: HTMLElement, attribute: string, possible: Set<Value>, defaultValue: Value): Value;
|
|
4
|
+
declare function getBooleanAriaValue(element: HTMLElement, attribute: AnyAriaBooleanAttribute): boolean;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { getAttributeValue, getBooleanAriaValue };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getAria } from "@oscarpalmer/toretto/aria";
|
|
2
|
+
import { getAttribute } from "@oscarpalmer/toretto/attribute";
|
|
3
|
+
//#region src/js/internal/misc.ts
|
|
4
|
+
function getAttributeValue(element, attribute, possible, defaultValue) {
|
|
5
|
+
const value = getAttribute(element, attribute);
|
|
6
|
+
return possible.has(value) ? value : defaultValue;
|
|
7
|
+
}
|
|
8
|
+
function getBooleanAriaValue(element, attribute) {
|
|
9
|
+
const value = getAria(element, attribute);
|
|
10
|
+
return value === true || value === "true";
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { getAttributeValue, getBooleanAriaValue };
|
|
@@ -8,24 +8,30 @@ declare class OuiNavigable {
|
|
|
8
8
|
orientation: OuiNavigableOrientation;
|
|
9
9
|
constructor(element: HTMLElement, options: OuiNavigableOptions);
|
|
10
10
|
destroy(): void;
|
|
11
|
+
navigate(index: number, focus?: boolean): void;
|
|
11
12
|
}
|
|
12
13
|
type OuiNavigableActive = {
|
|
13
14
|
element?: HTMLElement;
|
|
14
15
|
index: number;
|
|
15
16
|
};
|
|
17
|
+
type OuiNavigableCallback<ReturnType> = (event: KeyboardEvent, navigable: OuiNavigable) => ReturnType;
|
|
16
18
|
type OuiNavigableOptions = {
|
|
19
|
+
orientation?: OuiNavigableOrientation;
|
|
17
20
|
role?: AriaRole;
|
|
18
21
|
selector: string;
|
|
19
22
|
vertical: boolean;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
onActivate?: (navigable: OuiNavigable) => void;
|
|
24
|
+
onDeactivate?: OuiNavigableCallback<void>;
|
|
25
|
+
onNavigation?: (navigable: OuiNavigable) => void;
|
|
26
|
+
onPreventNavigation?: OuiNavigableCallback<boolean>;
|
|
27
|
+
onShouldActivate?: OuiNavigableCallback<boolean>;
|
|
28
|
+
onShouldDeactivate?: OuiNavigableCallback<boolean | undefined>;
|
|
24
29
|
};
|
|
25
30
|
type OuiNavigableOrientation = 'horizontal' | 'vertical';
|
|
26
31
|
declare function getNavigable(element: HTMLElement, options: OuiNavigableOptions): OuiNavigable;
|
|
32
|
+
declare function getNavigableOrientation(element: HTMLElement, vertical: boolean, aria?: boolean): OuiNavigableOrientation;
|
|
27
33
|
declare function updateNavigableFocus(navigable: OuiNavigable, focus: boolean, items?: HTMLElement[]): void;
|
|
28
34
|
declare const NAVIGABLE_KEYS_HORIZONTAL: Set<string>;
|
|
29
35
|
declare const NAVIGABLE_KEYS_VERTICAL: Set<string>;
|
|
30
36
|
//#endregion
|
|
31
|
-
export { NAVIGABLE_KEYS_HORIZONTAL, NAVIGABLE_KEYS_VERTICAL, OuiNavigable, OuiNavigableOptions, getNavigable, updateNavigableFocus };
|
|
37
|
+
export { NAVIGABLE_KEYS_HORIZONTAL, NAVIGABLE_KEYS_VERTICAL, OuiNavigable, OuiNavigableOptions, OuiNavigableOrientation, getNavigable, getNavigableOrientation, updateNavigableFocus };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { getAria, setRole } from "@oscarpalmer/toretto/aria";
|
|
2
|
-
import {
|
|
1
|
+
import { getAria, setAria, setRole } from "@oscarpalmer/toretto/aria";
|
|
2
|
+
import { on } from "@oscarpalmer/toretto/event";
|
|
3
|
+
import { getAttribute } from "@oscarpalmer/toretto/attribute";
|
|
3
4
|
import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
|
|
4
5
|
import { clamp } from "@oscarpalmer/atoms/number";
|
|
5
6
|
import { findAncestor } from "@oscarpalmer/toretto/find";
|
|
@@ -13,12 +14,19 @@ var OuiNavigable = class {
|
|
|
13
14
|
constructor(element, options) {
|
|
14
15
|
this.element = element;
|
|
15
16
|
this.options = options;
|
|
16
|
-
this.listeners = [
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
this.listeners = [
|
|
18
|
+
on(element, "click", (event) => {
|
|
19
|
+
onClick(this, event);
|
|
20
|
+
}, { passive: false }),
|
|
21
|
+
on(element, "focusin", (event) => {
|
|
22
|
+
onFocusin(this, event);
|
|
23
|
+
}),
|
|
24
|
+
on(element, "keydown", (event) => {
|
|
25
|
+
onKeydown(this, event);
|
|
26
|
+
}, { passive: false })
|
|
27
|
+
];
|
|
28
|
+
this.orientation = options?.orientation ?? getNavigableOrientation(element, options.vertical);
|
|
29
|
+
setAria(element, "orientation", this.orientation);
|
|
22
30
|
if (options.role != null) setRole(element, options.role);
|
|
23
31
|
}
|
|
24
32
|
destroy() {
|
|
@@ -27,6 +35,10 @@ var OuiNavigable = class {
|
|
|
27
35
|
this.active.element = void 0;
|
|
28
36
|
this.element = void 0;
|
|
29
37
|
}
|
|
38
|
+
navigate(index, focus) {
|
|
39
|
+
const items = getItems(this.element, this.options.selector);
|
|
40
|
+
if (index >= 0 && index < items.length) onNavigate(this, index, items, focus ?? false);
|
|
41
|
+
}
|
|
30
42
|
};
|
|
31
43
|
function getItems(container, selector) {
|
|
32
44
|
return [...container.querySelectorAll(selector)].filter(isValidItem);
|
|
@@ -34,13 +46,28 @@ function getItems(container, selector) {
|
|
|
34
46
|
function getNavigable(element, options) {
|
|
35
47
|
return new OuiNavigable(element, options);
|
|
36
48
|
}
|
|
37
|
-
function
|
|
38
|
-
const attribute = getAria(element, "orientation");
|
|
39
|
-
return ORIENTATIONS.has(attribute) ? attribute :
|
|
49
|
+
function getNavigableOrientation(element, vertical, aria) {
|
|
50
|
+
const attribute = aria ?? true ? getAria(element, "orientation") : getAttribute(element, "orientation");
|
|
51
|
+
return ORIENTATIONS.has(attribute) ? attribute : vertical ? ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL;
|
|
40
52
|
}
|
|
41
53
|
function isValidItem(element) {
|
|
42
54
|
return "disabled" in element ? element.disabled !== true : true;
|
|
43
55
|
}
|
|
56
|
+
function onClick(navigable, event) {
|
|
57
|
+
const item = findAncestor(event, navigable.options.selector);
|
|
58
|
+
const items = getItems(navigable.element, navigable.options.selector);
|
|
59
|
+
const index = items.indexOf(item);
|
|
60
|
+
if (index === -1) return;
|
|
61
|
+
if (index !== navigable.active.index) onNavigate(navigable, index, items, false);
|
|
62
|
+
navigable.options.onActivate?.(navigable);
|
|
63
|
+
item.focus();
|
|
64
|
+
}
|
|
65
|
+
function onNavigate(navigable, index, items, focus) {
|
|
66
|
+
navigable.active.element = items[index];
|
|
67
|
+
navigable.active.index = index;
|
|
68
|
+
updateNavigableFocus(navigable, focus, items);
|
|
69
|
+
navigable.options.onNavigation?.(navigable);
|
|
70
|
+
}
|
|
44
71
|
function onFocusin(navigable, event) {
|
|
45
72
|
const item = findAncestor(event, navigable.options.selector);
|
|
46
73
|
if (!isHTMLOrSVGElement(item) || !isValidItem(item)) return;
|
|
@@ -63,7 +90,10 @@ function onKeydown(navigable, event) {
|
|
|
63
90
|
const mustActivate = KEYS_ACTIVATE.has(event.key);
|
|
64
91
|
const shouldActivate = navigable.options.onShouldActivate?.(event, navigable) === true;
|
|
65
92
|
if (mustActivate || shouldActivate || navigable.options.onPreventNavigation?.(event, navigable) === true) event.stopPropagation();
|
|
66
|
-
if (mustActivate || shouldActivate)
|
|
93
|
+
if (mustActivate || shouldActivate) {
|
|
94
|
+
navigable.options.onActivate?.(navigable);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
67
97
|
const items = getItems(navigable.element, navigable.options.selector);
|
|
68
98
|
const { length } = items;
|
|
69
99
|
if (length === 0) return;
|
|
@@ -76,10 +106,7 @@ function onKeydown(navigable, event) {
|
|
|
76
106
|
index = clamp(navigable.active.index + (KEYS_NEXT.has(event.key) ? 1 : -1), 0, length - 1, true);
|
|
77
107
|
}
|
|
78
108
|
}
|
|
79
|
-
if (index
|
|
80
|
-
navigable.active.element = items[index];
|
|
81
|
-
navigable.active.index = index;
|
|
82
|
-
updateNavigableFocus(navigable, true, items);
|
|
109
|
+
if (index != null && index !== navigable.active.index) onNavigate(navigable, index, items, true);
|
|
83
110
|
}
|
|
84
111
|
function updateNavigableFocus(navigable, focus, items) {
|
|
85
112
|
const updated = items ?? getItems(navigable.element, navigable.options.selector);
|
|
@@ -88,7 +115,6 @@ function updateNavigableFocus(navigable, focus, items) {
|
|
|
88
115
|
for (let index = 0; index < length; index += 1) updated[index].tabIndex = index === navigable.active.index ? 0 : -1;
|
|
89
116
|
navigable.active.element ??= updated[navigable.active.index];
|
|
90
117
|
if (focus) navigable.active.element?.focus();
|
|
91
|
-
dispatch(navigable.active.element, "navigable:change", { detail: { ...navigable.active } });
|
|
92
118
|
}
|
|
93
119
|
const KEYS_ABSOLUTE = /* @__PURE__ */ new Set(["End", "Home"]);
|
|
94
120
|
const KEYS_ACTIVATE = /* @__PURE__ */ new Set(["Enter", " "]);
|
|
@@ -105,4 +131,4 @@ const ORIENTATION_HORIZONTAL = "horizontal";
|
|
|
105
131
|
const ORIENTATION_VERTICAL = "vertical";
|
|
106
132
|
const ORIENTATIONS = /* @__PURE__ */ new Set([ORIENTATION_HORIZONTAL, ORIENTATION_VERTICAL]);
|
|
107
133
|
//#endregion
|
|
108
|
-
export { NAVIGABLE_KEYS_HORIZONTAL, NAVIGABLE_KEYS_VERTICAL, OuiNavigable, getNavigable, updateNavigableFocus };
|
|
134
|
+
export { NAVIGABLE_KEYS_HORIZONTAL, NAVIGABLE_KEYS_VERTICAL, OuiNavigable, getNavigable, getNavigableOrientation, updateNavigableFocus };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { GenericCallback } from "@oscarpalmer/atoms/models";
|
|
2
|
+
//#region src/js/l10n.d.ts
|
|
3
|
+
type LocalizationParameters<Localization> = Localization extends GenericCallback ? Parameters<Localization> : never;
|
|
4
|
+
declare class OuiLocalizations<Localizations extends OuiLocalizationsValues> {
|
|
5
|
+
readonly defaults: Localizations;
|
|
6
|
+
readonly keys: Set<keyof Localizations>;
|
|
7
|
+
readonly values: Record<string, Partial<Localizations>>;
|
|
8
|
+
constructor(defaults: Localizations);
|
|
9
|
+
get<Key extends keyof Localizations>(element: Element, key: Key, localizations: Record<string, Partial<Localizations>>): string | GenericCallback;
|
|
10
|
+
set(language: string, localizations: Partial<Localizations>): void;
|
|
11
|
+
set(localizations: Record<string, Partial<Localizations>>): void;
|
|
12
|
+
}
|
|
13
|
+
type OuiLocalizationsValues = Record<string, string | GenericCallback>;
|
|
14
|
+
declare function getLanguage(element: Element): string;
|
|
15
|
+
declare function getLocalization<Localizations extends OuiLocalizationsValues, Key extends keyof Localizations>(localizations: OuiLocalizations<Localizations>, element: Element, key: Key, value: Record<string, Partial<Localizations>>): Localizations[Key] | GenericCallback;
|
|
16
|
+
declare function getLocalizations<Localizations extends OuiLocalizationsValues>(defaults: Localizations): OuiLocalizations<Localizations>;
|
|
17
|
+
declare function localize<Localizations extends OuiLocalizationsValues, Key extends keyof Localizations, Localization extends Localizations[Key]>(localization: Localization, data: Record<string, unknown>, parameters: LocalizationParameters<Localization>): string;
|
|
18
|
+
declare function updateLocalizations<Localizations extends OuiLocalizationsValues>(instance: OuiLocalizations<Localizations>, values: Record<string, Partial<Localizations>>, destination: Record<string, Partial<Localizations>>, onAfter?: () => void): void;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { getLocalizations as a, getLocalization as i, OuiLocalizationsValues as n, localize as o, getLanguage as r, updateLocalizations as s, OuiLocalizations as t };
|
package/dist/js/l10n.d.mts
CHANGED
|
@@ -1,20 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type LocalizationParameters<Localization> = Localization extends GenericCallback ? Parameters<Localization> : never;
|
|
4
|
-
type OuiLocalizationValues = Record<string, string | GenericCallback>;
|
|
5
|
-
declare class OuiLocalizations<Localizations extends OuiLocalizationValues> {
|
|
6
|
-
readonly defaults: Localizations;
|
|
7
|
-
readonly keys: Set<keyof Localizations>;
|
|
8
|
-
readonly values: Record<string, Partial<Localizations>>;
|
|
9
|
-
constructor(defaults: Localizations);
|
|
10
|
-
get<Key extends keyof Localizations>(element: Element, key: Key, localizations: Record<string, Partial<Localizations>>): string | GenericCallback;
|
|
11
|
-
set(language: string, localizations: Partial<Localizations>): void;
|
|
12
|
-
set(localizations: Record<string, Partial<Localizations>>): void;
|
|
13
|
-
}
|
|
14
|
-
declare function getLanguage(element: Element): string;
|
|
15
|
-
declare function getLocalization<Localizations extends OuiLocalizationValues, Key extends keyof Localizations>(localizations: OuiLocalizations<Localizations>, element: Element, key: Key, value: Record<string, Partial<Localizations>>): Localizations[Key] | GenericCallback;
|
|
16
|
-
declare function getLocalizations<Localizations extends OuiLocalizationValues>(defaults: Localizations): OuiLocalizations<Localizations>;
|
|
17
|
-
declare function localize<Localizations extends OuiLocalizationValues, Key extends keyof Localizations, Localization extends Localizations[Key]>(localization: Localization, data: Record<string, unknown>, parameters: LocalizationParameters<Localization>): string;
|
|
18
|
-
declare function updateLocalizations<Localizations extends OuiLocalizationValues>(instance: OuiLocalizations<Localizations>, values: Record<string, Partial<Localizations>>, destination?: Record<string, Partial<Localizations>>, onAfter?: () => void): void;
|
|
19
|
-
//#endregion
|
|
20
|
-
export { OuiLocalizations, getLanguage, getLocalization, getLocalizations, localize, updateLocalizations };
|
|
1
|
+
import { a as getLocalizations, i as getLocalization, n as OuiLocalizationsValues, o as localize, r as getLanguage, s as updateLocalizations, t as OuiLocalizations } from "./l10n-Bn-7RcwR.mjs";
|
|
2
|
+
export { OuiLocalizations, OuiLocalizationsValues, getLanguage, getLocalization, getLocalizations, localize, updateLocalizations };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/js/listbox/constants.listbox.ts
|
|
2
|
+
const LISTBOX_TAGNAME = "oui-listbox";
|
|
3
|
+
const attributeContent = `${LISTBOX_TAGNAME}-content`;
|
|
4
|
+
const attributeFilter = `${LISTBOX_TAGNAME}-filter`;
|
|
5
|
+
const attributeFilterInput = `${attributeFilter}-input`;
|
|
6
|
+
const attributeGroup = `${LISTBOX_TAGNAME}-group`;
|
|
7
|
+
const attributeHeader = `${LISTBOX_TAGNAME}-header`;
|
|
8
|
+
const attributeHidden = `${LISTBOX_TAGNAME}-hidden`;
|
|
9
|
+
const attributeList = `${LISTBOX_TAGNAME}-list`;
|
|
10
|
+
const attributeListEmpty = `${attributeList}-empty`;
|
|
11
|
+
const attributeMessage = `${LISTBOX_TAGNAME}-message`;
|
|
12
|
+
const attributeOption = `${LISTBOX_TAGNAME}-option`;
|
|
13
|
+
const attributeOptionActive = `${LISTBOX_TAGNAME}-option-active`;
|
|
14
|
+
const messageLabel = `<${LISTBOX_TAGNAME}> must contain a <label> element for the <select> element`;
|
|
15
|
+
const messageSelect = `<${LISTBOX_TAGNAME}> must contain a valid <select> element`;
|
|
16
|
+
const selectorFilter = `[${attributeFilterInput}]`;
|
|
17
|
+
const selectorOption = `[${attributeOption}]`;
|
|
18
|
+
const LISTBOX_ATTRIBUTES = {
|
|
19
|
+
active: attributeOptionActive,
|
|
20
|
+
content: attributeContent,
|
|
21
|
+
empty: attributeListEmpty,
|
|
22
|
+
filter: attributeFilter,
|
|
23
|
+
group: attributeGroup,
|
|
24
|
+
header: attributeHeader,
|
|
25
|
+
hidden: attributeHidden,
|
|
26
|
+
input: attributeFilterInput,
|
|
27
|
+
list: attributeList,
|
|
28
|
+
message: attributeMessage,
|
|
29
|
+
option: attributeOption
|
|
30
|
+
};
|
|
31
|
+
const LISTBOX_MESSAGES = {
|
|
32
|
+
label: messageLabel,
|
|
33
|
+
select: messageSelect
|
|
34
|
+
};
|
|
35
|
+
const LISTBOX_SELECTORS = {
|
|
36
|
+
filter: selectorFilter,
|
|
37
|
+
option: selectorOption
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { LISTBOX_ATTRIBUTES, LISTBOX_MESSAGES, LISTBOX_SELECTORS, LISTBOX_TAGNAME };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { c as OuiListboxPreview, l as OuiListboxState } from "../listbox.model-CRReGOmu.mjs";
|
|
2
|
+
//#region src/js/listbox/event.listbox.d.ts
|
|
3
|
+
declare function onListboxEnter(state: OuiListboxState): void;
|
|
4
|
+
declare function onListboxFilter(preview: OuiListboxPreview, state: OuiListboxState, _: boolean, active?: HTMLElement): void;
|
|
5
|
+
declare function onListboxNavigation(preview: OuiListboxPreview, state: OuiListboxState, active?: HTMLElement): void;
|
|
6
|
+
declare function onListboxToggle(state: OuiListboxState): void;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { onListboxEnter, onListboxFilter, onListboxNavigation, onListboxToggle };
|