@threadlabs/looma 0.28.11 → 0.28.12
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/components/ui-editor-chip-editor/ui-editor-chip-editor.html +32 -0
- package/components/ui-editor-chip-editor/ui-editor-chip-editor.js +33 -0
- package/components/ui-radio-group/ui-radio-group.html +13 -1
- package/components/ui-swatch/ui-swatch.html +69 -0
- package/dist/index.js +38 -37
- package/package.json +1 -1
- package/styles/ui-editor-chip-editor.css +1 -0
- package/styles/ui-radio-group.css +9 -0
- package/styles/ui-swatch.css +76 -0
- package/vanilla/UiEditorChipEditor.d.ts +18 -0
- package/vanilla/UiEditorChipEditor.js +45 -0
- package/vanilla/UiRadioGroup.d.ts +1 -0
- package/vanilla/UiRadioGroup.js +18 -13
- package/vanilla/UiSwatch.d.ts +14 -0
- package/vanilla/UiSwatch.js +54 -0
- package/vanilla/index.js +2 -0
- package/vue/UiEditorChipEditor.d.ts +45 -0
- package/vue/UiEditorChipEditor.js +2 -0
- package/vue/UiEditorChipEditor.vue +163 -0
- package/vue/UiRadioGroup.d.ts +9 -0
- package/vue/UiRadioGroup.vue +44 -2
- package/vue/UiSwatch.d.ts +16 -0
- package/vue/UiSwatch.js +2 -0
- package/vue/UiSwatch.vue +150 -0
- package/vue/chunks/UiEditorChipEditor.js +157 -0
- package/vue/chunks/UiEditorImageToolbar.js +2 -2
- package/vue/chunks/UiEditorLinkCard.js +1 -1
- package/vue/chunks/UiEditorLinkForm.js +2 -2
- package/vue/chunks/UiRadioGroup.js +26 -3
- package/vue/chunks/UiSwatch.js +78 -0
- package/vue/components.css +461 -443
- package/vue/editor/index.js +24 -44
- package/vue/editor/primitives.d.ts +9 -1
- package/vue/index.d.ts +2 -0
- package/vue/index.js +6 -4
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/* Generated by HTML Next 1.0.0-alpha.51. Do not edit. */
|
|
@@ -36,6 +36,15 @@
|
|
|
36
36
|
clear: both;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
legend.sr-only {
|
|
40
|
+
position: absolute;
|
|
41
|
+
inline-size: 1px;
|
|
42
|
+
block-size: 1px;
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
clip-path: inset(50%);
|
|
45
|
+
white-space: nowrap;
|
|
46
|
+
}
|
|
47
|
+
|
|
39
48
|
:scope:where([data-component~="ui-radio-group"])[data-ui-radio-group-state~="invalid"] legend {
|
|
40
49
|
color: var(--_ui-radio-group-invalid-text);
|
|
41
50
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* Generated by HTML Next 1.0.0-alpha.51. Do not edit. */
|
|
2
|
+
@supports (-moz-appearance: none) {
|
|
3
|
+
:where([data-component], [data-slotted]) { --html-next-scope-owner: boundary; }
|
|
4
|
+
:where([data-slotted]:not([data-component])) { --html-next-scope-owner: projected !important; }
|
|
5
|
+
}
|
|
6
|
+
@supports (-moz-appearance: none) {
|
|
7
|
+
[data-component~="ui-swatch"] { --html-next-scope-owner: "ui-swatch" !important; }
|
|
8
|
+
}
|
|
9
|
+
@scope ([data-component~="ui-swatch"]) to ([data-component], [data-slotted]) {
|
|
10
|
+
@property --ui-swatch-size {
|
|
11
|
+
syntax: "*";
|
|
12
|
+
inherits: false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* A native radio drawn as a round dot. Inside a ui-radio-group the group names it, applies its
|
|
16
|
+
value, and moves between swatches with the arrow keys. */
|
|
17
|
+
:scope:where([data-component~="ui-swatch"]) {
|
|
18
|
+
--_surface: var(--ui-surface-subtle);
|
|
19
|
+
--_text: var(--ui-text-secondary);
|
|
20
|
+
|
|
21
|
+
appearance: none;
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
flex: 0 0 auto;
|
|
24
|
+
inline-size: var(--ui-swatch-size, 1.65rem);
|
|
25
|
+
block-size: var(--ui-swatch-size, 1.65rem);
|
|
26
|
+
margin: 0;
|
|
27
|
+
border: var(--ui-border-width) solid color-mix(in srgb, var(--_surface) 75%, var(--_text) 25%);
|
|
28
|
+
border-radius: 50%;
|
|
29
|
+
background: var(--_surface);
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
:scope:where([data-component~="ui-swatch"])[data-ui-swatch-state~="tone=blue"] {
|
|
34
|
+
--_surface: var(--ui-info-soft);
|
|
35
|
+
--_text: var(--ui-info-subtle-text);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
:scope:where([data-component~="ui-swatch"])[data-ui-swatch-state~="tone=green"] {
|
|
39
|
+
--_surface: var(--ui-success-soft);
|
|
40
|
+
--_text: var(--ui-success-subtle-text);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:scope:where([data-component~="ui-swatch"])[data-ui-swatch-state~="tone=yellow"] {
|
|
44
|
+
--_surface: var(--ui-warning-soft);
|
|
45
|
+
--_text: var(--ui-warning-subtle-text);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
:scope:where([data-component~="ui-swatch"])[data-ui-swatch-state~="tone=red"] {
|
|
49
|
+
--_surface: var(--ui-danger-soft);
|
|
50
|
+
--_text: var(--ui-danger-subtle-text);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
:scope:where([data-component~="ui-swatch"])[data-ui-swatch-state~="tone=purple"] {
|
|
54
|
+
--_surface: var(--ui-accent-soft);
|
|
55
|
+
--_text: var(--ui-accent-subtle-text);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* The chosen swatch and the focused one share one ring at the focus width (2px by default), in
|
|
59
|
+
the tone or the focus colour. */
|
|
60
|
+
:scope:where([data-component~="ui-swatch"]):checked {
|
|
61
|
+
outline: var(--ui-focus-width) solid var(--_text);
|
|
62
|
+
outline-offset: var(--ui-focus-width);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
:scope:where([data-component~="ui-swatch"]):focus-visible {
|
|
66
|
+
outline: var(--ui-focus-width) solid var(--ui-focus-ring, var(--ui-accent-solid));
|
|
67
|
+
outline-offset: var(--ui-focus-width);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
@scope ([data-component~="ui-swatch"]) to ([data-component]) {
|
|
71
|
+
/* A native radio drawn as a round dot. Inside a ui-radio-group the group names it, applies its
|
|
72
|
+
value, and moves between swatches with the arrow keys. */
|
|
73
|
+
|
|
74
|
+
/* The chosen swatch and the focused one share one ring at the focus width (2px by default), in
|
|
75
|
+
the tone or the focus colour. */
|
|
76
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Generated by HTML Next 1.0.0-alpha.51 for Vanilla DOM. Do not edit.
|
|
2
|
+
export interface UiEditorChipEditorEventMap {
|
|
3
|
+
label: CustomEvent<{ readonly label: string }>;
|
|
4
|
+
color: CustomEvent<{ readonly color: "neutral" | "blue" | "green" | "yellow" | "red" | "purple" }>;
|
|
5
|
+
done: CustomEvent<Readonly<Record<string, unknown>>>;
|
|
6
|
+
}
|
|
7
|
+
export interface UiEditorChipEditorElement extends HTMLDivElement {
|
|
8
|
+
addEventListener<K extends keyof UiEditorChipEditorEventMap>(type: K, listener: (this: UiEditorChipEditorElement, event: UiEditorChipEditorEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
9
|
+
removeEventListener<K extends keyof UiEditorChipEditorEventMap>(type: K, listener: (this: UiEditorChipEditorElement, event: UiEditorChipEditorEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
|
|
10
|
+
}
|
|
11
|
+
export interface UiEditorChipEditorProps {
|
|
12
|
+
color?: "neutral" | "blue" | "green" | "yellow" | "red" | "purple" | null;
|
|
13
|
+
label?: string | null;
|
|
14
|
+
attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
|
|
15
|
+
children?: readonly (string | Node)[];
|
|
16
|
+
slots?: Readonly<Record<string, readonly (string | Node)[]>>;
|
|
17
|
+
}
|
|
18
|
+
export declare function createUiEditorChipEditor(props?: UiEditorChipEditorProps): UiEditorChipEditorElement;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Generated by HTML Next 1.0.0-alpha.51 for Vanilla DOM. Do not edit.
|
|
2
|
+
import { attachGeneratedController, buildTemplate, toAttribute, writeAttribute, dispatchDeclared, detailCheck, formatOf, keywordFormat, acceptProps, manageProps, checkConstrained, checkFormat, checkObject, checkRecord, checkString, checkUnknown } from "@nextwebwg/html-next/generated-runtime";
|
|
3
|
+
import * as controller from "../components/ui-editor-chip-editor/ui-editor-chip-editor.js";
|
|
4
|
+
import "../styles/ui-editor-chip-editor.css";
|
|
5
|
+
|
|
6
|
+
const T0 = ["",[],["ui-stack",["gap","s"],["ui-input",["data-chip-label","","size","sm","placeholder","Set a label","aria-label","Chip text"]],["ui-radio-group",["label","Chip color","label-visibility","sr-only"],["ui-swatch",["tone","neutral"]],["ui-swatch",["tone","blue"]],["ui-swatch",["tone","green"]],["ui-swatch",["tone","yellow"]],["ui-swatch",["tone","red"]],["ui-swatch",["tone","purple"]]]]];
|
|
7
|
+
let P0;
|
|
8
|
+
const S = { n: [], t: [], f: import.meta.url, g: "ui-editor-chip-editor", d: { "label": [detailCheck(checkObject([["label", checkString, false]], false)), true, true, false], "color": [detailCheck(checkObject([["color", checkConstrained(checkFormat("keyword", keywordFormat), "keyword", {"values":["neutral","blue","green","yellow","red","purple"]}), false]], false)), true, true, false], "done": [detailCheck(checkRecord(checkUnknown)), true, true, false] }, x: dispatchDeclared };
|
|
9
|
+
const D = { props: { "color": { "required":false,"values":["neutral","blue","green","yellow","red","purple"],"default":"neutral", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "label": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" } } };
|
|
10
|
+
const C = (host) => controller.default(host);
|
|
11
|
+
|
|
12
|
+
export function createUiEditorChipEditor(options = {}, html) {
|
|
13
|
+
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
14
|
+
const element = document.createElement("div");
|
|
15
|
+
for (const [name, value] of Object.entries(attributes)) {
|
|
16
|
+
if (value === null || value === undefined || value === false) continue;
|
|
17
|
+
element.setAttribute(name, value === true ? "" : String(value));
|
|
18
|
+
}
|
|
19
|
+
if (!element.hasAttribute("role")) element.setAttribute("role", "dialog");
|
|
20
|
+
if (!element.hasAttribute("aria-label")) element.setAttribute("aria-label", "Edit chip");
|
|
21
|
+
element.setAttribute("data-component", "ui-editor-chip-editor");
|
|
22
|
+
element.append((P0 ??= buildTemplate(T0)).cloneNode(true));
|
|
23
|
+
const v = [null, null];
|
|
24
|
+
const B = acceptProps(element, D, S.n, v, componentProps, [], html);
|
|
25
|
+
const p0 = (r, c, d) => {
|
|
26
|
+
if (c & 2) {
|
|
27
|
+
const x0 = v[1];
|
|
28
|
+
const s0 = toAttribute(x0, "value");
|
|
29
|
+
if (s0 !== r.v0) writeAttribute(r.a0, "value", r.v0 = s0);
|
|
30
|
+
}
|
|
31
|
+
if (c & 1073741825) {
|
|
32
|
+
const x1 = v[0];
|
|
33
|
+
const s1 = toAttribute(x1, "value");
|
|
34
|
+
if (s1 !== r.v1) writeAttribute(r.a1, "value", r.v1 = s1);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const t0 = element.firstChild;
|
|
38
|
+
const t1 = t0.firstChild;
|
|
39
|
+
const t2 = t1.nextSibling;
|
|
40
|
+
const R = { a0: t1, a1: t2, v0: null, v1: null };
|
|
41
|
+
const I = { B };
|
|
42
|
+
attachGeneratedController(element, S, v, ((c, d) => p0(R, c, d)), C, undefined, I);
|
|
43
|
+
manageProps(I);
|
|
44
|
+
return element;
|
|
45
|
+
}
|
|
@@ -11,6 +11,7 @@ export interface UiRadioGroupProps {
|
|
|
11
11
|
disabled?: boolean | null;
|
|
12
12
|
invalid?: boolean | null;
|
|
13
13
|
label?: string | null;
|
|
14
|
+
labelVisibility?: "visible" | "sr-only" | null;
|
|
14
15
|
name?: string | null;
|
|
15
16
|
orientation?: "horizontal" | "vertical" | null;
|
|
16
17
|
required?: boolean | null;
|
package/vanilla/UiRadioGroup.js
CHANGED
|
@@ -7,7 +7,7 @@ const T0 = ["",[],["legend",[],0],4];
|
|
|
7
7
|
const T1 = ["",[]];
|
|
8
8
|
let P0, P1;
|
|
9
9
|
const S = { n: ["internalValue"], t: ["s"], f: import.meta.url, g: "ui-radio-group", d: { "select": [detailCheck(checkObject([["value", checkString, false], ["previousValue", checkString, false], ["trigger", checkConstrained(checkFormat("keyword", keywordFormat), "keyword", {"values":["keyboard","pointer","programmatic"]}), false]], false)), true, true, false], "change": [detailCheck(checkObject([["checked", checkBoolean, false], ["value", checkString, false], ["trigger", checkConstrained(checkFormat("keyword", keywordFormat), "keyword", {"values":["keyboard","pointer","programmatic"]}), false]], false)), true, true, false] }, x: dispatchDeclared };
|
|
10
|
-
const D = { props: { "disabled": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "invalid": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "label": { "required":false,"default":"Options", c: checkString, t: "string", j: 0, m: "s" }, "name": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" }, "orientation": { "required":false,"values":["horizontal","vertical"],"default":"horizontal", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "required": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "value": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" } } };
|
|
10
|
+
const D = { props: { "disabled": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "invalid": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "label": { "required":false,"default":"Options", c: checkString, t: "string", j: 0, m: "s" }, "labelVisibility": { "required":false,"values":["visible","sr-only"],"default":"visible", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "name": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" }, "orientation": { "required":false,"values":["horizontal","vertical"],"default":"horizontal", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "required": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "value": { "required":false,"default":"", c: checkString, t: "string", j: 0, m: "s" } } };
|
|
11
11
|
const C = (host) => controller.default(host);
|
|
12
12
|
|
|
13
13
|
export function createUiRadioGroup(options = {}, html) {
|
|
@@ -20,7 +20,7 @@ export function createUiRadioGroup(options = {}, html) {
|
|
|
20
20
|
if (!element.hasAttribute("role")) element.setAttribute("role", "radiogroup");
|
|
21
21
|
element.setAttribute("data-component", "ui-radio-group");
|
|
22
22
|
element.append((P0 ??= buildTemplate(T0)).cloneNode(true));
|
|
23
|
-
const v = ["", null, null, null, null, null, null, null];
|
|
23
|
+
const v = ["", null, null, null, null, null, null, null, null];
|
|
24
24
|
const B = acceptProps(element, D, S.n, v, componentProps, [], html);
|
|
25
25
|
const m1 = (d) => {
|
|
26
26
|
const n = (P1 ??= buildTemplate(T1)).cloneNode(true);
|
|
@@ -31,8 +31,8 @@ export function createUiRadioGroup(options = {}, html) {
|
|
|
31
31
|
const p1 = (r, c, d) => {
|
|
32
32
|
};
|
|
33
33
|
const p0 = (r, c, d) => {
|
|
34
|
-
if (c &
|
|
35
|
-
const x0 = v[
|
|
34
|
+
if (c & 128) {
|
|
35
|
+
const x0 = v[7];
|
|
36
36
|
const s0 = toAttribute(x0, "aria-required");
|
|
37
37
|
if (s0 !== r.v0) writeAttribute(r.n, "aria-required", r.v0 = s0);
|
|
38
38
|
}
|
|
@@ -46,24 +46,29 @@ export function createUiRadioGroup(options = {}, html) {
|
|
|
46
46
|
const s2 = toAttribute(x2, "disabled");
|
|
47
47
|
if (s2 !== r.v2) writeAttribute(r.n, "disabled", r.v2 = s2);
|
|
48
48
|
}
|
|
49
|
+
if (c & 16) {
|
|
50
|
+
const x3 = (v[4] === "sr-only");
|
|
51
|
+
const s3 = x3;
|
|
52
|
+
if (s3 !== r.v3) r.a1.classList.toggle("sr-only", r.v3 = s3);
|
|
53
|
+
}
|
|
49
54
|
if (c & 8) {
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
if (
|
|
55
|
+
const x4 = v[3];
|
|
56
|
+
const s4 = toText(x4);
|
|
57
|
+
if (s4 !== r.v4) r.a2.data = r.v4 = s4;
|
|
53
58
|
}
|
|
54
|
-
if (c &
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
59
|
+
if (c & 68) {
|
|
60
|
+
const x5 = hostState(["invalid","orientation"], [v[2], v[6]]);
|
|
61
|
+
const s5 = x5;
|
|
62
|
+
if (s5 !== r.v5) writeAttribute(r.n, "data-ui-radio-group-state", (r.v5 = s5) === "" ? null : s5);
|
|
58
63
|
}
|
|
59
|
-
if (r.f0 === undefined) { r.f0 = 1; const at = fillSlot(r.
|
|
64
|
+
if (r.f0 === undefined) { r.f0 = 1; const at = fillSlot(r.a3, r.e0, "", J, false, undefined, d);
|
|
60
65
|
if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b0 = m1(d); at.before(r.b0.n); } }
|
|
61
66
|
else if (r.b0 !== undefined) p1(r.b0, c, d);
|
|
62
67
|
};
|
|
63
68
|
const t0 = element.firstChild;
|
|
64
69
|
const t1 = t0.firstChild;
|
|
65
70
|
const t2 = t0.nextSibling;
|
|
66
|
-
const R = { n: element, a1: t1, v0: undefined, v1: undefined, v2: undefined, v3: "",
|
|
71
|
+
const R = { n: element, a1: t0, a2: t1, v0: undefined, v1: undefined, v2: undefined, v3: false, v4: "", v5: undefined, a3: t2, e0: t2.nextSibling, b0: undefined, f0: undefined };
|
|
67
72
|
const I = { B };
|
|
68
73
|
const J = project(I, children, slots);
|
|
69
74
|
I.R = new Set();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Generated by HTML Next 1.0.0-alpha.51 for Vanilla DOM. Do not edit.
|
|
2
|
+
export interface UiSwatchEventMap {
|
|
3
|
+
}
|
|
4
|
+
export interface UiSwatchElement extends HTMLInputElement {
|
|
5
|
+
addEventListener<K extends keyof UiSwatchEventMap>(type: K, listener: (this: UiSwatchElement, event: UiSwatchEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
6
|
+
removeEventListener<K extends keyof UiSwatchEventMap>(type: K, listener: (this: UiSwatchElement, event: UiSwatchEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
|
|
7
|
+
}
|
|
8
|
+
export interface UiSwatchProps {
|
|
9
|
+
tone?: "neutral" | "blue" | "green" | "yellow" | "red" | "purple" | null;
|
|
10
|
+
attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
|
|
11
|
+
children?: readonly (string | Node)[];
|
|
12
|
+
slots?: Readonly<Record<string, readonly (string | Node)[]>>;
|
|
13
|
+
}
|
|
14
|
+
export declare function createUiSwatch(props?: UiSwatchProps): UiSwatchElement;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Generated by HTML Next 1.0.0-alpha.51 for Vanilla DOM. Do not edit.
|
|
2
|
+
import { attachGeneratedController, readIndex, toAttribute, writeAttribute, computedCycle, formatOf, keywordFormat, hostState, acceptProps, manageProps, readonlyView, checkFormat } from "@nextwebwg/html-next/generated-runtime";
|
|
3
|
+
import "../styles/ui-swatch.css";
|
|
4
|
+
|
|
5
|
+
const S = { n: ["toneName"], t: ["?"], f: import.meta.url, g: "ui-swatch", k: 0, r: readonlyView };
|
|
6
|
+
const D = { props: { "tone": { "required":false,"values":["neutral","blue","green","yellow","red","purple"],"default":"neutral", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
|
|
7
|
+
|
|
8
|
+
export function createUiSwatch(options = {}, html) {
|
|
9
|
+
const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
|
|
10
|
+
const element = document.createElement("input");
|
|
11
|
+
for (const [name, value] of Object.entries(attributes)) {
|
|
12
|
+
if (value === null || value === undefined || value === false) continue;
|
|
13
|
+
element.setAttribute(name, value === true ? "" : String(value));
|
|
14
|
+
}
|
|
15
|
+
if (!element.hasAttribute("type")) element.setAttribute("type", "radio");
|
|
16
|
+
element.setAttribute("data-component", "ui-swatch");
|
|
17
|
+
const v = [undefined, null];
|
|
18
|
+
const B = acceptProps(element, D, S.n, v, componentProps, [], html);
|
|
19
|
+
const X = { e: 0, g: (j) => g(j), w: new Set() };
|
|
20
|
+
const ke = [];
|
|
21
|
+
const K = [() => readIndex({ "neutral": "Neutral", "blue": "Blue", "green": "Green", "yellow": "Yellow", "red": "Red", "purple": "Purple" }, v[1])];
|
|
22
|
+
const g = (j) => {
|
|
23
|
+
const i = j - 0;
|
|
24
|
+
if (ke[i] === X.e) return v[j];
|
|
25
|
+
if (ke[i] === -1) computedCycle();
|
|
26
|
+
ke[i] = -1;
|
|
27
|
+
let next;
|
|
28
|
+
try { next = K[i](); } catch (error) { ke[i] = undefined; throw error; }
|
|
29
|
+
ke[i] = X.e;
|
|
30
|
+
const previous = v[j];
|
|
31
|
+
if (!Object.is(previous, next)) { v[j] = next; X.n?.(j, previous, next); }
|
|
32
|
+
return next;
|
|
33
|
+
};
|
|
34
|
+
const p0 = (r, c, d) => {
|
|
35
|
+
if (c & 1073741826) {
|
|
36
|
+
const x0 = v[1];
|
|
37
|
+
const s0 = toAttribute(x0, "value");
|
|
38
|
+
if (s0 !== r.v0) writeAttribute(r.n, "value", r.v0 = s0);
|
|
39
|
+
const x1 = g(0);
|
|
40
|
+
const s1 = toAttribute(x1, "aria-label");
|
|
41
|
+
if (s1 !== r.v1) writeAttribute(r.n, "aria-label", r.v1 = s1);
|
|
42
|
+
}
|
|
43
|
+
if (c & 2) {
|
|
44
|
+
const x2 = hostState(["tone"], [v[1]]);
|
|
45
|
+
const s2 = x2;
|
|
46
|
+
if (s2 !== r.v2) writeAttribute(r.n, "data-ui-swatch-state", (r.v2 = s2) === "" ? null : s2);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const R = { n: element, v0: undefined, v1: undefined, v2: undefined };
|
|
50
|
+
const I = { B };
|
|
51
|
+
attachGeneratedController(element, S, v, ((c, d) => p0(R, c, d)), undefined, X, I);
|
|
52
|
+
manageProps(I);
|
|
53
|
+
return element;
|
|
54
|
+
}
|
package/vanilla/index.js
CHANGED
|
@@ -20,6 +20,7 @@ export * from "./UiDialog.js";
|
|
|
20
20
|
export * from "./UiDisclosure.js";
|
|
21
21
|
export * from "./UiEditable.js";
|
|
22
22
|
export * from "./UiEditorBlockActions.js";
|
|
23
|
+
export * from "./UiEditorChipEditor.js";
|
|
23
24
|
export * from "./UiEditorCodeLanguage.js";
|
|
24
25
|
export * from "./UiEditorImageToolbar.js";
|
|
25
26
|
export * from "./UiEditorInsertTableGrid.js";
|
|
@@ -66,6 +67,7 @@ export * from "./UiSidebar.js";
|
|
|
66
67
|
export * from "./UiSpinner.js";
|
|
67
68
|
export * from "./UiStack.js";
|
|
68
69
|
export * from "./UiStatusMessage.js";
|
|
70
|
+
export * from "./UiSwatch.js";
|
|
69
71
|
export * from "./UiSwitch.js";
|
|
70
72
|
export * from "./UiSwitcher.js";
|
|
71
73
|
export * from "./UiTable.js";
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { PropType } from 'vue';
|
|
2
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
3
|
+
color: {
|
|
4
|
+
type: PropType<"neutral" | "blue" | "green" | "yellow" | "red" | "purple" | null>;
|
|
5
|
+
default: string;
|
|
6
|
+
};
|
|
7
|
+
label: {
|
|
8
|
+
type: PropType<string | null>;
|
|
9
|
+
default: string;
|
|
10
|
+
};
|
|
11
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
|
+
done: (event: CustomEvent<Readonly<Record<string, unknown>>>) => any;
|
|
13
|
+
label: (event: CustomEvent<{
|
|
14
|
+
readonly label: string;
|
|
15
|
+
}>) => any;
|
|
16
|
+
color: (event: CustomEvent<{
|
|
17
|
+
readonly color: "neutral" | "blue" | "green" | "yellow" | "red" | "purple";
|
|
18
|
+
}>) => any;
|
|
19
|
+
"update:color": (value: string) => any;
|
|
20
|
+
"update:label": (value: string) => any;
|
|
21
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
22
|
+
color: {
|
|
23
|
+
type: PropType<"neutral" | "blue" | "green" | "yellow" | "red" | "purple" | null>;
|
|
24
|
+
default: string;
|
|
25
|
+
};
|
|
26
|
+
label: {
|
|
27
|
+
type: PropType<string | null>;
|
|
28
|
+
default: string;
|
|
29
|
+
};
|
|
30
|
+
}>> & Readonly<{
|
|
31
|
+
onDone?: ((event: CustomEvent<Readonly<Record<string, unknown>>>) => any) | undefined;
|
|
32
|
+
onLabel?: ((event: CustomEvent<{
|
|
33
|
+
readonly label: string;
|
|
34
|
+
}>) => any) | undefined;
|
|
35
|
+
onColor?: ((event: CustomEvent<{
|
|
36
|
+
readonly color: "neutral" | "blue" | "green" | "yellow" | "red" | "purple";
|
|
37
|
+
}>) => any) | undefined;
|
|
38
|
+
"onUpdate:color"?: ((value: string) => any) | undefined;
|
|
39
|
+
"onUpdate:label"?: ((value: string) => any) | undefined;
|
|
40
|
+
}>, {
|
|
41
|
+
label: string | null;
|
|
42
|
+
color: "blue" | "green" | "purple" | "red" | "yellow" | "neutral" | null;
|
|
43
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
44
|
+
declare const _default: typeof __VLS_export;
|
|
45
|
+
export default _default;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
<!-- Generated by HTML Next 1.0.0-alpha.51 for Vue 3.5. Do not edit. -->
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
import { computed, getCurrentInstance, ref, watchSyncEffect } from 'vue'
|
|
4
|
+
import type { PropType } from 'vue'
|
|
5
|
+
import {
|
|
6
|
+
checkHydratedRoot,
|
|
7
|
+
createDispatch,
|
|
8
|
+
nativeAttrs,
|
|
9
|
+
useComponentHost,
|
|
10
|
+
useReflectedProp,
|
|
11
|
+
} from './host'
|
|
12
|
+
import { checkedProp, propValidityState, vPropValidity } from './props'
|
|
13
|
+
import UiInput from './UiInput.vue'
|
|
14
|
+
import UiRadioGroup from './UiRadioGroup.vue'
|
|
15
|
+
import UiStack from './UiStack.vue'
|
|
16
|
+
import UiSwatch from './UiSwatch.vue'
|
|
17
|
+
|
|
18
|
+
defineOptions({ inheritAttrs: false })
|
|
19
|
+
|
|
20
|
+
const propValidityContract = {
|
|
21
|
+
props: {
|
|
22
|
+
color: {
|
|
23
|
+
type: { kind: 'terminal', name: 'keyword' },
|
|
24
|
+
required: false,
|
|
25
|
+
target: { attribute: 'value' },
|
|
26
|
+
description: 'The chip\'s colour, checked among the swatches.',
|
|
27
|
+
values: ['neutral', 'blue', 'green', 'yellow', 'red', 'purple'],
|
|
28
|
+
default: 'neutral',
|
|
29
|
+
},
|
|
30
|
+
label: {
|
|
31
|
+
type: { kind: 'terminal', name: 'string' },
|
|
32
|
+
required: false,
|
|
33
|
+
target: { attribute: 'value' },
|
|
34
|
+
description: 'The chip\'s text, shown in the field as the reader edits it.',
|
|
35
|
+
default: '',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
} as const
|
|
39
|
+
const props = defineProps({
|
|
40
|
+
color: {
|
|
41
|
+
type: null as unknown as PropType<
|
|
42
|
+
'neutral' | 'blue' | 'green' | 'yellow' | 'red' | 'purple' | null
|
|
43
|
+
>,
|
|
44
|
+
default: 'neutral',
|
|
45
|
+
},
|
|
46
|
+
label: { type: null as unknown as PropType<string | null>, default: '' },
|
|
47
|
+
})
|
|
48
|
+
const acceptedProps: Record<string, unknown> = { color: 'neutral', label: '' }
|
|
49
|
+
const checkedProps = computed(() => ({
|
|
50
|
+
color: checkedProp<'neutral' | 'blue' | 'green' | 'yellow' | 'red' | 'purple'>(
|
|
51
|
+
props['color'],
|
|
52
|
+
{ kind: 'terminal', name: 'keyword' },
|
|
53
|
+
false,
|
|
54
|
+
'color',
|
|
55
|
+
acceptedProps,
|
|
56
|
+
) as 'neutral' | 'blue' | 'green' | 'yellow' | 'red' | 'purple',
|
|
57
|
+
label: checkedProp<string>(
|
|
58
|
+
props['label'],
|
|
59
|
+
{ kind: 'terminal', name: 'string' },
|
|
60
|
+
false,
|
|
61
|
+
'label',
|
|
62
|
+
acceptedProps,
|
|
63
|
+
) as string,
|
|
64
|
+
}))
|
|
65
|
+
void checkedProps.value
|
|
66
|
+
watchSyncEffect(() => {
|
|
67
|
+
void checkedProps.value
|
|
68
|
+
})
|
|
69
|
+
const reflectedProp = useReflectedProp()
|
|
70
|
+
const hydrationInstance = getCurrentInstance()
|
|
71
|
+
const emit = defineEmits<{
|
|
72
|
+
'update:color': [value: string]
|
|
73
|
+
'update:label': [value: string]
|
|
74
|
+
label: [event: CustomEvent<{ readonly label: string }>]
|
|
75
|
+
color: [
|
|
76
|
+
event: CustomEvent<
|
|
77
|
+
{ readonly color: 'neutral' | 'blue' | 'green' | 'yellow' | 'red' | 'purple' }
|
|
78
|
+
>,
|
|
79
|
+
]
|
|
80
|
+
done: [event: CustomEvent<Readonly<Record<string, unknown>>>]
|
|
81
|
+
}>()
|
|
82
|
+
|
|
83
|
+
const root = ref<HTMLElement | null>(null)
|
|
84
|
+
checkHydratedRoot('div', 'ui-editor-chip-editor')
|
|
85
|
+
|
|
86
|
+
const isLabelDetail = (
|
|
87
|
+
detail: unknown,
|
|
88
|
+
): boolean => (detail !== null && typeof detail === 'object' && !Array.isArray(detail)
|
|
89
|
+
&& typeof (detail as Record<string, unknown>)['label'] === 'string'
|
|
90
|
+
&& Object.keys(detail as object).every((key) => ['label'].includes(key)))
|
|
91
|
+
const isColorDetail = (
|
|
92
|
+
detail: unknown,
|
|
93
|
+
): boolean => (detail !== null && typeof detail === 'object' && !Array.isArray(detail)
|
|
94
|
+
&& ((detail as Record<string, unknown>)['color'] === 'neutral'
|
|
95
|
+
|| (detail as Record<string, unknown>)['color'] === 'blue'
|
|
96
|
+
|| (detail as Record<string, unknown>)['color'] === 'green'
|
|
97
|
+
|| (detail as Record<string, unknown>)['color'] === 'yellow'
|
|
98
|
+
|| (detail as Record<string, unknown>)['color'] === 'red'
|
|
99
|
+
|| (detail as Record<string, unknown>)['color'] === 'purple')
|
|
100
|
+
&& Object.keys(detail as object).every((key) => ['color'].includes(key)))
|
|
101
|
+
const isDoneDetail = (
|
|
102
|
+
detail: unknown,
|
|
103
|
+
): boolean => (detail !== null && typeof detail === 'object' && !Array.isArray(detail)
|
|
104
|
+
&& Object.values(detail as object).every((item: unknown) => true))
|
|
105
|
+
const dispatch = createDispatch(root, emit as (name: string, detail: unknown) => void, {
|
|
106
|
+
checks: {
|
|
107
|
+
label: isLabelDetail,
|
|
108
|
+
color: isColorDetail,
|
|
109
|
+
done: isDoneDetail,
|
|
110
|
+
},
|
|
111
|
+
modeled: ['color', 'label'],
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
useComponentHost(() => import('../components/ui-editor-chip-editor/ui-editor-chip-editor.js'), {
|
|
115
|
+
root,
|
|
116
|
+
dispatch,
|
|
117
|
+
controllerSource: {
|
|
118
|
+
specifier: '../components/ui-editor-chip-editor/ui-editor-chip-editor.js',
|
|
119
|
+
definition: './components/ui-editor-chip-editor/ui-editor-chip-editor.html',
|
|
120
|
+
},
|
|
121
|
+
props: checkedProps,
|
|
122
|
+
propInputs: (name: string) => {
|
|
123
|
+
const incoming = hydrationInstance?.vnode.props
|
|
124
|
+
const kebab = name.replace(/[A-Z]/g, (letter) => '-' + letter.toLowerCase())
|
|
125
|
+
return incoming !== null && incoming !== undefined
|
|
126
|
+
? (incoming[name] ?? incoming[kebab] ?? null)
|
|
127
|
+
: null
|
|
128
|
+
},
|
|
129
|
+
propNames: ['color', 'label'],
|
|
130
|
+
propValidity: (name: string) =>
|
|
131
|
+
propValidityState({ contract: propValidityContract, values: { ...props } }, name),
|
|
132
|
+
})
|
|
133
|
+
</script>
|
|
134
|
+
|
|
135
|
+
<template>
|
|
136
|
+
<div
|
|
137
|
+
role="dialog"
|
|
138
|
+
aria-label="Edit chip"
|
|
139
|
+
v-bind="nativeAttrs($attrs)"
|
|
140
|
+
v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
|
|
141
|
+
:data-color="reflectedProp('color', 'color', checkedProps.color, undefined, false)"
|
|
142
|
+
:data-label="reflectedProp('label', 'label', checkedProps.label, undefined, false)"
|
|
143
|
+
ref="root"
|
|
144
|
+
>
|
|
145
|
+
<UiStack gap="s"><UiInput
|
|
146
|
+
data-chip-label=""
|
|
147
|
+
size="sm"
|
|
148
|
+
placeholder="Set a label"
|
|
149
|
+
aria-label="Chip text"
|
|
150
|
+
:value="checkedProps.label"
|
|
151
|
+
/>
|
|
152
|
+
<UiRadioGroup
|
|
153
|
+
label="Chip color"
|
|
154
|
+
label-visibility="sr-only"
|
|
155
|
+
:value="checkedProps.color"
|
|
156
|
+
><UiSwatch tone="neutral" />
|
|
157
|
+
<UiSwatch tone="blue" />
|
|
158
|
+
<UiSwatch tone="green" />
|
|
159
|
+
<UiSwatch tone="yellow" />
|
|
160
|
+
<UiSwatch tone="red" />
|
|
161
|
+
<UiSwatch tone="purple" /></UiRadioGroup></UiStack>
|
|
162
|
+
</div>
|
|
163
|
+
</template>
|
package/vue/UiRadioGroup.d.ts
CHANGED
|
@@ -16,6 +16,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
16
16
|
type: PropType<string | null>;
|
|
17
17
|
default: string;
|
|
18
18
|
};
|
|
19
|
+
labelVisibility: {
|
|
20
|
+
type: PropType<"visible" | "sr-only" | null>;
|
|
21
|
+
default: string;
|
|
22
|
+
};
|
|
19
23
|
name: {
|
|
20
24
|
type: PropType<string | null>;
|
|
21
25
|
default: string;
|
|
@@ -57,6 +61,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
57
61
|
type: PropType<string | null>;
|
|
58
62
|
default: string;
|
|
59
63
|
};
|
|
64
|
+
labelVisibility: {
|
|
65
|
+
type: PropType<"visible" | "sr-only" | null>;
|
|
66
|
+
default: string;
|
|
67
|
+
};
|
|
60
68
|
name: {
|
|
61
69
|
type: PropType<string | null>;
|
|
62
70
|
default: string;
|
|
@@ -92,6 +100,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
92
100
|
label: string | null;
|
|
93
101
|
invalid: boolean | null;
|
|
94
102
|
disabled: boolean | null;
|
|
103
|
+
labelVisibility: "visible" | "sr-only" | null;
|
|
95
104
|
orientation: "vertical" | "horizontal" | null;
|
|
96
105
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
97
106
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|