@mattilsynet/design 2.2.27 → 2.2.29
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/mtds/atlas/atlas-element.js +1 -1
- package/mtds/chart/chart-element.js +1 -1
- package/mtds/chart/chart-element.js.map +1 -1
- package/mtds/chip/chip.stories.d.ts +1 -0
- package/mtds/field/field-observer.js +6 -22
- package/mtds/field/field-observer.js.map +1 -1
- package/mtds/field/field.d.ts +0 -1
- package/mtds/field/field.js +4 -4
- package/mtds/field/field.js.map +1 -1
- package/mtds/fieldset/fieldset.stories.d.ts +1 -0
- package/mtds/fileupload/fileupload.stories.d.ts +1 -0
- package/mtds/index.iife.js +7 -7
- package/mtds/index.js +1 -0
- package/mtds/index.js.map +1 -1
- package/mtds/package.json.js +1 -1
- package/mtds/react-types.d.ts +1 -0
- package/mtds/styles.css +77 -63
- package/mtds/validation/validation-observer.d.ts +1 -0
- package/mtds/validation/validation-observer.js +37 -0
- package/mtds/validation/validation-observer.js.map +1 -0
- package/package.json +5 -4
|
@@ -87,7 +87,7 @@ function onMoveTooltip(event) {
|
|
|
87
87
|
const el = event.composedPath()[0];
|
|
88
88
|
const tip = el instanceof Element && el.getAttribute("aria-label") || "";
|
|
89
89
|
if (tip)
|
|
90
|
-
TOOLTIP.style.transform = `translate(${event.clientX}px, ${event.clientY}px)`;
|
|
90
|
+
TOOLTIP.style.transform = `translate(${Math.min(event.clientX, window.innerWidth - TOOLTIP.clientWidth - 10)}px, ${event.clientY}px)`;
|
|
91
91
|
if (tip !== TOOLTIP_TEXT) {
|
|
92
92
|
if (tip) TOOLTIP.textContent = tip;
|
|
93
93
|
TOOLTIP_TEXT = tip;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-element.js","sources":["../../designsystem/chart/chart-element.ts"],"sourcesContent":["import styles from \"../styles.module.css\";\nimport {\n\tattr,\n\tdefineElement,\n\tisBrowser,\n\tMTDSElement,\n\toff,\n\ton,\n\tonMutation,\n\tonResize,\n\ttag,\n} from \"../utils\";\nimport css from \"./chart.css?raw\";\nimport { toAxis } from \"./chart-axis\";\nimport { toBars } from \"./chart-bars\";\nimport { toLines } from \"./chart-lines\";\nimport { toPies } from \"./chart-pies\";\n\nexport type ChartData = ReturnType<typeof toData>;\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"mtds-chart\": MTDSChartElement;\n\t}\n}\n\nconst EVENTS = \"click,keydown,mousemove,mouseout\";\nconst TOOLTIP_ID = \"mtds-chart-tooltip\";\nconst TOOLTIP = isBrowser()\n\t? document.getElementById(TOOLTIP_ID) ||\n\t\ttag(\"div\", {\n\t\t\t\"aria-hidden\": \"true\",\n\t\t\tclass: styles._tooltip,\n\t\t\thidden: \"\",\n\t\t\tid: TOOLTIP_ID,\n\t\t})\n\t: null;\n\nexport class MTDSChartElement extends MTDSElement {\n\t#unmutate?: () => void;\n\t#unresize?: () => void;\n\n\tstatic get observedAttributes() {\n\t\treturn [\"data-variant\", \"data-aspect\"]; // Using ES2015 syntax for backwards compatibility\n\t}\n\tconstructor() {\n\t\tsuper();\n\t\tthis.attachShadow({ mode: \"open\" });\n\t}\n\tconnectedCallback() {\n\t\tthis.#unresize = onResize(() => this.handleResize(), this);\n\t\tthis.#unmutate = onMutation(() => this.attributeChangedCallback(), {\n\t\t\tattr: \"data-tooltip\",\n\t\t\troot: this,\n\t\t});\n\t\tthis.attributeChangedCallback(); // Initial setup\n\t\ton(this, EVENTS, this);\n\t}\n\tdisconnectedCallback() {\n\t\tif (TOOLTIP) TOOLTIP.hidden = true;\n\t\toff(this, EVENTS, this);\n\t\tthis.#unresize?.();\n\t\tthis.#unmutate?.();\n\t\tthis.#unmutate = this.#unresize = undefined;\n\t}\n\tattributeChangedCallback() {\n\t\tArray.from(this.shadowRoot?.children || []).map((el) => el.remove()); // Clear shadowRoot\n\n\t\tconst [variant, type] = (attr(this, \"data-variant\") || \"column\").split(\"-\");\n\t\tconst aspect = attr(this, \"data-aspect\") || undefined;\n\t\tconst data = toData(this.querySelector(\"table\"));\n\t\tconst style = tag(\"style\", {}, css);\n\t\tconst legend = tag(\"div\", {\n\t\t\t\"aria-hidden\": \"hidden\",\n\t\t\tclass: \"legends\",\n\t\t\trole: \"group\",\n\t\t});\n\t\tdata.slice(1).forEach(([{ value, style }]) => {\n\t\t\tlegend.appendChild(tag(\"div\", { class: \"legend\", style }, value));\n\t\t});\n\n\t\tconst { axis, groups, total } = toAxis(data, { aspect, type });\n\t\tif (variant === \"column\" || variant === \"bar\")\n\t\t\tgroups.append(...toBars(data));\n\t\tif (variant === \"line\" || variant === \"area\")\n\t\t\tgroups.append(toLines(data, { total, variant, type }));\n\t\tif (variant === \"doughnut\" || variant === \"pie\")\n\t\t\tthis.shadowRoot?.append(toPies(data, { aspect, variant }));\n\n\t\tthis.shadowRoot?.append(axis, legend, style); // Axis must be first\n\t}\n\thandleEvent(e: Event) {\n\t\tif (e.type === \"click\" || e.type === \"keydown\") onClick(e, this);\n\t\telse onMoveTooltip(e as MouseEvent);\n\t}\n\thandleResize() {\n\t\tconst axis = this.shadowRoot?.firstElementChild as HTMLElement | null;\n\t\tconst steps = axis?.firstElementChild as HTMLElement | null;\n\t\taxis?.classList.toggle(\"axisStepsYHalf\", (steps?.offsetHeight || 0) < 400);\n\t\taxis?.classList.toggle(\"axisStepsXHalf\", (steps?.offsetWidth || 0) < 500);\n\t}\n}\n\nfunction onClick(event: Event, self: MTDSChartElement) {\n\tif (event instanceof KeyboardEvent && event.key !== \"Enter\") return; // Only handle enter key\n\tconst el = event.composedPath()[0];\n\tconst table = self.querySelector(\"table\");\n\tconst [tr, td] =\n\t\t(el instanceof Element && attr(el, \"data-event\")?.split(\"-\").map(Number)) ||\n\t\t[];\n\n\ttable?.rows[tr]?.cells[td]?.querySelector<HTMLElement>(\"a,button\")?.click?.();\n}\n\nlet TOOLTIP_TEXT = \"\";\nfunction onMoveTooltip(event: MouseEvent) {\n\tif (!TOOLTIP) return;\n\tif (!TOOLTIP?.isConnected) document.body.append(TOOLTIP); // Ensure connected\n\n\tconst el = event.composedPath()[0];\n\tconst tip = (el instanceof Element && el.getAttribute(\"aria-label\")) || \"\";\n\n\tif (tip)\n\t\tTOOLTIP.style.transform = `translate(${event.clientX}px, ${event.clientY}px)`;\n\tif (tip !== TOOLTIP_TEXT) {\n\t\tif (tip) TOOLTIP.textContent = tip;\n\t\tTOOLTIP_TEXT = tip;\n\t\tTOOLTIP.hidden = !tip;\n\t}\n}\n\nconst text = (el?: Element | null) => el?.textContent?.trim() || \"\"; // Helper to get trimmed text\nconst toData = (table?: HTMLTableElement | null) =>\n\tArray.from(table?.rows || [], (row, rowIndex) =>\n\t\tArray.from(row.cells, (cell, cellIndex) => {\n\t\t\tconst rowHeading = text(row.cells[0]);\n\t\t\tconst colHeading = text(table?.rows[0].cells[cellIndex]);\n\t\t\tconst tooltip = `${rowHeading}: ${text(cell)}${colHeading ? ` (${colHeading})` : \"\"}`;\n\n\t\t\treturn {\n\t\t\t\tnumber: (cellIndex && rowIndex && Number.parseFloat(text(cell))) || 0, // First row and column is not a number\n\t\t\t\tevent: cell.querySelector(\"a,button\") && `${rowIndex}-${cellIndex}`, // Reference to proxy events\n\t\t\t\tstyle: `--color: var(--mtdsc-chart-color-${rowIndex}, var(--mtdsc-chart-color-base))`,\n\t\t\t\tvalue: text(cell),\n\t\t\t\ttooltip: attr(cell, \"data-tooltip\") || tooltip,\n\t\t\t};\n\t\t}),\n\t);\n\ndefineElement(\"mtds-chart\", MTDSChartElement);\n"],"names":["style"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"chart-element.js","sources":["../../designsystem/chart/chart-element.ts"],"sourcesContent":["import styles from \"../styles.module.css\";\nimport {\n\tattr,\n\tdefineElement,\n\tisBrowser,\n\tMTDSElement,\n\toff,\n\ton,\n\tonMutation,\n\tonResize,\n\ttag,\n} from \"../utils\";\nimport css from \"./chart.css?raw\";\nimport { toAxis } from \"./chart-axis\";\nimport { toBars } from \"./chart-bars\";\nimport { toLines } from \"./chart-lines\";\nimport { toPies } from \"./chart-pies\";\n\nexport type ChartData = ReturnType<typeof toData>;\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"mtds-chart\": MTDSChartElement;\n\t}\n}\n\nconst EVENTS = \"click,keydown,mousemove,mouseout\";\nconst TOOLTIP_ID = \"mtds-chart-tooltip\";\nconst TOOLTIP = isBrowser()\n\t? document.getElementById(TOOLTIP_ID) ||\n\t\ttag(\"div\", {\n\t\t\t\"aria-hidden\": \"true\",\n\t\t\tclass: styles._tooltip,\n\t\t\thidden: \"\",\n\t\t\tid: TOOLTIP_ID,\n\t\t})\n\t: null;\n\nexport class MTDSChartElement extends MTDSElement {\n\t#unmutate?: () => void;\n\t#unresize?: () => void;\n\n\tstatic get observedAttributes() {\n\t\treturn [\"data-variant\", \"data-aspect\"]; // Using ES2015 syntax for backwards compatibility\n\t}\n\tconstructor() {\n\t\tsuper();\n\t\tthis.attachShadow({ mode: \"open\" });\n\t}\n\tconnectedCallback() {\n\t\tthis.#unresize = onResize(() => this.handleResize(), this);\n\t\tthis.#unmutate = onMutation(() => this.attributeChangedCallback(), {\n\t\t\tattr: \"data-tooltip\",\n\t\t\troot: this,\n\t\t});\n\t\tthis.attributeChangedCallback(); // Initial setup\n\t\ton(this, EVENTS, this);\n\t}\n\tdisconnectedCallback() {\n\t\tif (TOOLTIP) TOOLTIP.hidden = true;\n\t\toff(this, EVENTS, this);\n\t\tthis.#unresize?.();\n\t\tthis.#unmutate?.();\n\t\tthis.#unmutate = this.#unresize = undefined;\n\t}\n\tattributeChangedCallback() {\n\t\tArray.from(this.shadowRoot?.children || []).map((el) => el.remove()); // Clear shadowRoot\n\n\t\tconst [variant, type] = (attr(this, \"data-variant\") || \"column\").split(\"-\");\n\t\tconst aspect = attr(this, \"data-aspect\") || undefined;\n\t\tconst data = toData(this.querySelector(\"table\"));\n\t\tconst style = tag(\"style\", {}, css);\n\t\tconst legend = tag(\"div\", {\n\t\t\t\"aria-hidden\": \"hidden\",\n\t\t\tclass: \"legends\",\n\t\t\trole: \"group\",\n\t\t});\n\t\tdata.slice(1).forEach(([{ value, style }]) => {\n\t\t\tlegend.appendChild(tag(\"div\", { class: \"legend\", style }, value));\n\t\t});\n\n\t\tconst { axis, groups, total } = toAxis(data, { aspect, type });\n\t\tif (variant === \"column\" || variant === \"bar\")\n\t\t\tgroups.append(...toBars(data));\n\t\tif (variant === \"line\" || variant === \"area\")\n\t\t\tgroups.append(toLines(data, { total, variant, type }));\n\t\tif (variant === \"doughnut\" || variant === \"pie\")\n\t\t\tthis.shadowRoot?.append(toPies(data, { aspect, variant }));\n\n\t\tthis.shadowRoot?.append(axis, legend, style); // Axis must be first\n\t}\n\thandleEvent(e: Event) {\n\t\tif (e.type === \"click\" || e.type === \"keydown\") onClick(e, this);\n\t\telse onMoveTooltip(e as MouseEvent);\n\t}\n\thandleResize() {\n\t\tconst axis = this.shadowRoot?.firstElementChild as HTMLElement | null;\n\t\tconst steps = axis?.firstElementChild as HTMLElement | null;\n\t\taxis?.classList.toggle(\"axisStepsYHalf\", (steps?.offsetHeight || 0) < 400);\n\t\taxis?.classList.toggle(\"axisStepsXHalf\", (steps?.offsetWidth || 0) < 500);\n\t}\n}\n\nfunction onClick(event: Event, self: MTDSChartElement) {\n\tif (event instanceof KeyboardEvent && event.key !== \"Enter\") return; // Only handle enter key\n\tconst el = event.composedPath()[0];\n\tconst table = self.querySelector(\"table\");\n\tconst [tr, td] =\n\t\t(el instanceof Element && attr(el, \"data-event\")?.split(\"-\").map(Number)) ||\n\t\t[];\n\n\ttable?.rows[tr]?.cells[td]?.querySelector<HTMLElement>(\"a,button\")?.click?.();\n}\n\nlet TOOLTIP_TEXT = \"\";\nfunction onMoveTooltip(event: MouseEvent) {\n\tif (!TOOLTIP) return;\n\tif (!TOOLTIP?.isConnected) document.body.append(TOOLTIP); // Ensure connected\n\n\tconst el = event.composedPath()[0];\n\tconst tip = (el instanceof Element && el.getAttribute(\"aria-label\")) || \"\";\n\n\tif (tip)\n\t\tTOOLTIP.style.transform = `translate(${Math.min(event.clientX, window.innerWidth - TOOLTIP.clientWidth - 10)}px, ${event.clientY}px)`;\n\tif (tip !== TOOLTIP_TEXT) {\n\t\tif (tip) TOOLTIP.textContent = tip;\n\t\tTOOLTIP_TEXT = tip;\n\t\tTOOLTIP.hidden = !tip;\n\t}\n}\n\nconst text = (el?: Element | null) => el?.textContent?.trim() || \"\"; // Helper to get trimmed text\nconst toData = (table?: HTMLTableElement | null) =>\n\tArray.from(table?.rows || [], (row, rowIndex) =>\n\t\tArray.from(row.cells, (cell, cellIndex) => {\n\t\t\tconst rowHeading = text(row.cells[0]);\n\t\t\tconst colHeading = text(table?.rows[0].cells[cellIndex]);\n\t\t\tconst tooltip = `${rowHeading}: ${text(cell)}${colHeading ? ` (${colHeading})` : \"\"}`;\n\n\t\t\treturn {\n\t\t\t\tnumber: (cellIndex && rowIndex && Number.parseFloat(text(cell))) || 0, // First row and column is not a number\n\t\t\t\tevent: cell.querySelector(\"a,button\") && `${rowIndex}-${cellIndex}`, // Reference to proxy events\n\t\t\t\tstyle: `--color: var(--mtdsc-chart-color-${rowIndex}, var(--mtdsc-chart-color-base))`,\n\t\t\t\tvalue: text(cell),\n\t\t\t\ttooltip: attr(cell, \"data-tooltip\") || tooltip,\n\t\t\t};\n\t\t}),\n\t);\n\ndefineElement(\"mtds-chart\", MTDSChartElement);\n"],"names":["style"],"mappings":"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"}
|
|
@@ -6,13 +6,11 @@ const CSS_FIELD = styles.field.split(" ")[0];
|
|
|
6
6
|
const CSS_VALIDATIONS = styles.validation.split(" ");
|
|
7
7
|
const CSS_VALIDATION = CSS_VALIDATIONS[0];
|
|
8
8
|
const FIELDS = isBrowser() ? document.getElementsByClassName(CSS_FIELD) : [];
|
|
9
|
-
function handleFieldMutation(
|
|
10
|
-
let firstInvalid = null;
|
|
9
|
+
function handleFieldMutation() {
|
|
11
10
|
for (const field of FIELDS)
|
|
12
11
|
if (field.isConnected) {
|
|
13
12
|
const labels = [];
|
|
14
13
|
const descriptions = [];
|
|
15
|
-
const validationMsg = [];
|
|
16
14
|
let combobox = null;
|
|
17
15
|
let input = null;
|
|
18
16
|
let valid = true;
|
|
@@ -23,20 +21,11 @@ function handleFieldMutation(validate) {
|
|
|
23
21
|
else if (el.hasAttribute("data-description")) descriptions.push(el);
|
|
24
22
|
else if (el.classList.contains(CSS_VALIDATION)) {
|
|
25
23
|
valid = attr(el, "data-color") === "success" || !el.clientHeight;
|
|
26
|
-
validationMsg.push(el);
|
|
27
24
|
descriptions.unshift(el);
|
|
28
25
|
} else if (el instanceof HTMLParagraphElement)
|
|
29
26
|
descriptions.some((desc) => desc.contains(el)) || descriptions.push(el);
|
|
30
27
|
}
|
|
31
28
|
if (input) {
|
|
32
|
-
const comboboxInput = combobox?.control;
|
|
33
|
-
const shouldValidate = validate || comboboxInput?.validity.customError;
|
|
34
|
-
if (shouldValidate && attr(field, "data-validation") === "form") {
|
|
35
|
-
valid = comboboxInput?.getAttribute("aria-required") === "true" ? !!combobox?.items.length : input.validity.valid;
|
|
36
|
-
if (!firstInvalid && !valid) firstInvalid = input;
|
|
37
|
-
for (const el of validationMsg) attr(el, "hidden", valid ? "" : null);
|
|
38
|
-
comboboxInput?.setCustomValidity(valid ? "" : "Invalid");
|
|
39
|
-
}
|
|
40
29
|
for (const label of labels) label.htmlFor = useId(input);
|
|
41
30
|
renderCombobox(combobox);
|
|
42
31
|
renderCounter(input);
|
|
@@ -45,8 +34,6 @@ function handleFieldMutation(validate) {
|
|
|
45
34
|
attr(input, "aria-invalid", `${!valid}`);
|
|
46
35
|
}
|
|
47
36
|
}
|
|
48
|
-
if (validate) firstInvalid?.focus();
|
|
49
|
-
return firstInvalid;
|
|
50
37
|
}
|
|
51
38
|
function renderTextareaSize(textarea) {
|
|
52
39
|
if (textarea instanceof HTMLTextAreaElement) {
|
|
@@ -87,14 +74,12 @@ function renderCounter(input) {
|
|
|
87
74
|
const style = window.getComputedStyle(el || input);
|
|
88
75
|
const over = getText(style, "count-over");
|
|
89
76
|
const under = getText(style, "count-under");
|
|
77
|
+
const label = `${(nextInvalid ? over : under).replace("%d", `${Math.abs(remainder)}`)}`;
|
|
90
78
|
if (prevInvalid !== nextInvalid) {
|
|
91
79
|
attr(el, "aria-live", nextInvalid ? "polite" : "off");
|
|
92
80
|
for (const css of CSS_VALIDATIONS) el.classList.toggle(css, nextInvalid);
|
|
93
81
|
}
|
|
94
|
-
el
|
|
95
|
-
"%d",
|
|
96
|
-
`${Math.abs(remainder)}`
|
|
97
|
-
);
|
|
82
|
+
attr(el, "aria-label", label);
|
|
98
83
|
}
|
|
99
84
|
}
|
|
100
85
|
function handleFieldToggle({ target: el, newState }) {
|
|
@@ -120,16 +105,15 @@ function handleFieldInput(event) {
|
|
|
120
105
|
}
|
|
121
106
|
}
|
|
122
107
|
function handleFieldValdiation(event) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (handleFieldMutation(true)) event.preventDefault();
|
|
108
|
+
if (event.target?.closest?.(`.${CSS_FIELD}`))
|
|
109
|
+
event.preventDefault();
|
|
126
110
|
}
|
|
127
111
|
onLoaded(() => [
|
|
128
112
|
onMutation(() => handleFieldMutation(), "class"),
|
|
129
113
|
on(document, "input", handleFieldInput, QUICK_EVENT),
|
|
130
114
|
on(document, "toggle", handleFieldToggle, QUICK_EVENT),
|
|
131
115
|
// Use capture since toggle does not bubble
|
|
132
|
-
on(document, "invalid
|
|
116
|
+
on(document, "invalid", handleFieldValdiation, true)
|
|
133
117
|
// Use capture as invalid and submit does not bubble
|
|
134
118
|
]);
|
|
135
119
|
//# sourceMappingURL=field-observer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-observer.js","sources":["../../designsystem/field/field-observer.ts"],"sourcesContent":["import { UHTMLComboboxElement } from \"@u-elements/u-combobox\";\nimport { UHTMLDataListElement } from \"@u-elements/u-datalist\";\nimport styles from \"../styles.module.css\";\nimport {\n\tanchorPosition,\n\tattr,\n\tisBrowser,\n\tisInputLike,\n\ton,\n\tonLoaded,\n\tonMutation,\n\tQUICK_EVENT,\n\tuseId,\n} from \"../utils\";\n\nconst CSS_FIELD = styles.field.split(\" \")[0];\nconst CSS_VALIDATIONS = styles.validation.split(\" \");\nconst CSS_VALIDATION = CSS_VALIDATIONS[0];\nconst FIELDS = isBrowser() ? document.getElementsByClassName(CSS_FIELD) : [];\n\nfunction handleFieldMutation(validate?: boolean) {\n\tlet firstInvalid: HTMLInputElement | null = null;\n\tfor (const field of FIELDS)\n\t\tif (field.isConnected) {\n\t\t\tconst labels: HTMLLabelElement[] = [];\n\t\t\tconst descriptions: Element[] = [];\n\t\t\tconst validationMsg: Element[] = [];\n\t\t\tlet combobox: UHTMLComboboxElement | null = null;\n\t\t\tlet input: HTMLInputElement | null = null;\n\t\t\tlet valid = true;\n\n\t\t\tfor (const el of field.getElementsByTagName(\"*\")) {\n\t\t\t\tif (el instanceof HTMLLabelElement) labels.push(el);\n\t\t\t\telse if (el instanceof UHTMLComboboxElement) combobox = el;\n\t\t\t\telse if (isInputLike(el) && !el.hidden) input = el;\n\t\t\t\telse if (el.hasAttribute(\"data-description\")) descriptions.push(el);\n\t\t\t\telse if (el.classList.contains(CSS_VALIDATION)) {\n\t\t\t\t\tvalid = attr(el, \"data-color\") === \"success\" || !el.clientHeight; // Only set invalid if Validation is visible\n\t\t\t\t\tvalidationMsg.push(el);\n\t\t\t\t\tdescriptions.unshift(el);\n\t\t\t\t} else if (el instanceof HTMLParagraphElement)\n\t\t\t\t\tdescriptions.some((desc) => desc.contains(el)) ||\n\t\t\t\t\t\tdescriptions.push(el); // Only add if not already inside description\n\t\t\t}\n\n\t\t\tif (input) {\n\t\t\t\tconst comboboxInput = combobox?.control;\n\t\t\t\tconst shouldValidate = validate || comboboxInput?.validity.customError; // Live re-evaluate combobox if invalid to correct validity before form sumbit\n\n\t\t\t\tif (shouldValidate && attr(field, \"data-validation\") === \"form\") {\n\t\t\t\t\tvalid =\n\t\t\t\t\t\tcomboboxInput?.getAttribute(\"aria-required\") === \"true\"\n\t\t\t\t\t\t\t? !!combobox?.items.length\n\t\t\t\t\t\t\t: input.validity.valid;\n\n\t\t\t\t\tif (!firstInvalid && !valid) firstInvalid = input;\n\t\t\t\t\tfor (const el of validationMsg) attr(el, \"hidden\", valid ? \"\" : null);\n\t\t\t\t\tcomboboxInput?.setCustomValidity(valid ? \"\" : \"Invalid\"); // Combobox does not have native validation\n\t\t\t\t}\n\t\t\t\tfor (const label of labels) label.htmlFor = useId(input);\n\t\t\t\trenderCombobox(combobox);\n\t\t\t\trenderCounter(input);\n\t\t\t\trenderTextareaSize(input);\n\t\t\t\tattr(input, \"aria-describedby\", descriptions.map(useId).join(\" \"));\n\t\t\t\tattr(input, \"aria-invalid\", `${!valid}`);\n\t\t\t}\n\t\t}\n\tif (validate) firstInvalid?.focus(); // Only move focus to first invalid field if validate was true\n\treturn firstInvalid;\n}\n\n// iOS does not support field-sizing: content, so we need to manually resize\nfunction renderTextareaSize(textarea: Element) {\n\tif (textarea instanceof HTMLTextAreaElement) {\n\t\ttextarea.style.setProperty(\"--mtds-textarea-height\", \"auto\");\n\t\ttextarea.style.setProperty(\n\t\t\t\"--mtds-textarea-height\",\n\t\t\t`${textarea.scrollHeight}px`,\n\t\t);\n\t}\n}\n\nconst getText = (style: CSSStyleDeclaration, key: string) =>\n\tstyle.getPropertyValue(`--mtds-text-${key}`)?.slice(1, -1) || \"\"; // slice to trim quotes\n\n// Setup translations from CSS custom properties\nfunction renderCombobox(el: UHTMLComboboxElement | null) {\n\tconst { control, list } = el || {};\n\n\tif (el && list && !el.hasAttribute(\"data-sr-added\")) {\n\t\tconst style = window.getComputedStyle(el);\n\t\tattr(el, \"data-sr-added\", getText(style, \"combobox-added\"));\n\t\tattr(el, \"data-sr-empty\", getText(style, \"combobox-empty\"));\n\t\tattr(el, \"data-sr-found\", getText(style, \"combobox-found\"));\n\t\tattr(el, \"data-sr-invalid\", getText(style, \"combobox-invalid\"));\n\t\tattr(el, \"data-sr-of\", getText(style, \"combobox-of\"));\n\t\tattr(el, \"data-sr-remove\", getText(style, \"combobox-remove\"));\n\t\tattr(el, \"data-sr-removed\", getText(style, \"combobox-removed\"));\n\t\tattr(list, \"data-sr-plural\", getText(style, \"datalist-plural\"));\n\t\tattr(list, \"data-sr-singular\", getText(style, \"datalist-singular\"));\n\t}\n\tif (list && control && !list.hasAttribute(\"popover\")) {\n\t\tattr(list, \"popover\", \"manual\");\n\t\tattr(control, \"popovertarget\", useId(list));\n\t}\n}\n\nfunction renderCounter(input: HTMLInputElement) {\n\tconst el = input?.nextElementSibling;\n\tconst limit = el && attr(el, \"data-count\");\n\n\tif (el && limit) {\n\t\tconst remainder = Number(limit) - input.value.length;\n\t\tconst nextInvalid = remainder < 0;\n\t\tconst prevInvalid = attr(el, \"aria-live\") === \"polite\";\n\t\tconst style = window.getComputedStyle(el || input);\n\t\tconst over = getText(style, \"count-over\");\n\t\tconst under = getText(style, \"count-under\");\n\n\t\tif (prevInvalid !== nextInvalid) {\n\t\t\tattr(el, \"aria-live\", nextInvalid ? \"polite\" : \"off\");\n\t\t\tfor (const css of CSS_VALIDATIONS) el.classList.toggle(css, nextInvalid);\n\t\t}\n\t\tel.textContent = (nextInvalid ? over : under).replace(\n\t\t\t\"%d\",\n\t\t\t`${Math.abs(remainder)}`,\n\t\t);\n\t}\n}\n\nfunction handleFieldToggle({ target: el, newState }: Partial<ToggleEvent>) {\n\tif (el instanceof UHTMLDataListElement) {\n\t\tconst root = el.getRootNode() as ShadowRoot | null;\n\t\tconst anchor = root?.querySelector<HTMLElement>(\n\t\t\t`[popovertarget=\"${el.id}\"]`,\n\t\t);\n\n\t\tif (newState === \"closed\") anchorPosition(el, false);\n\t\telse if (anchor)\n\t\t\tanchorPosition(el, anchor, {\n\t\t\t\tcontain({ availableHeight }) {\n\t\t\t\t\tel.style.width = `${anchor.clientWidth}px`;\n\t\t\t\t\tel.style.maxHeight = `${Math.max(50, availableHeight)}px`;\n\t\t\t\t},\n\t\t\t});\n\t}\n}\n// Update when typing\nfunction handleFieldInput(event: Event) {\n\tif (isInputLike(event.target)) {\n\t\trenderCounter(event.target);\n\t\trenderTextareaSize(event.target);\n\t}\n}\n\nfunction handleFieldValdiation(event: Event) {\n\tconst field = (event.target as Element)?.closest?.(`.${CSS_FIELD}`);\n\tif (event.type === \"invalid\" && field) event.preventDefault(); // Prevent browsers from showing default validation bubbles\n\tif (handleFieldMutation(true)) event.preventDefault(); // Prevent submit if invalid fields found\n}\n\nonLoaded(() => [\n\tonMutation(() => handleFieldMutation(), \"class\"),\n\ton(document, \"input\", handleFieldInput, QUICK_EVENT),\n\ton(document, \"toggle\", handleFieldToggle, QUICK_EVENT), // Use capture since toggle does not bubble\n\ton(document, \"invalid,submit\", handleFieldValdiation, true), // Use capture as invalid and submit does not bubble\n]);\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"field-observer.js","sources":["../../designsystem/field/field-observer.ts"],"sourcesContent":["import { UHTMLComboboxElement } from \"@u-elements/u-combobox\";\nimport { UHTMLDataListElement } from \"@u-elements/u-datalist\";\nimport styles from \"../styles.module.css\";\nimport {\n\tanchorPosition,\n\tattr,\n\tisBrowser,\n\tisInputLike,\n\ton,\n\tonLoaded,\n\tonMutation,\n\tQUICK_EVENT,\n\tuseId,\n} from \"../utils\";\n\nconst CSS_FIELD = styles.field.split(\" \")[0];\nconst CSS_VALIDATIONS = styles.validation.split(\" \");\nconst CSS_VALIDATION = CSS_VALIDATIONS[0];\nconst FIELDS = isBrowser() ? document.getElementsByClassName(CSS_FIELD) : [];\n\nfunction handleFieldMutation() {\n\tfor (const field of FIELDS)\n\t\tif (field.isConnected) {\n\t\t\tconst labels: HTMLLabelElement[] = [];\n\t\t\tconst descriptions: Element[] = [];\n\t\t\tconst validationMsg: Element[] = [];\n\t\t\tlet combobox: UHTMLComboboxElement | null = null;\n\t\t\tlet input: HTMLInputElement | null = null;\n\t\t\tlet valid = true;\n\n\t\t\tfor (const el of field.getElementsByTagName(\"*\")) {\n\t\t\t\tif (el instanceof HTMLLabelElement) labels.push(el);\n\t\t\t\telse if (el instanceof UHTMLComboboxElement) combobox = el;\n\t\t\t\telse if (isInputLike(el) && !el.hidden) input = el;\n\t\t\t\telse if (el.hasAttribute(\"data-description\")) descriptions.push(el);\n\t\t\t\telse if (el.classList.contains(CSS_VALIDATION)) {\n\t\t\t\t\tvalid = attr(el, \"data-color\") === \"success\" || !el.clientHeight; // Only set invalid if Validation is visible\n\t\t\t\t\tvalidationMsg.push(el);\n\t\t\t\t\tdescriptions.unshift(el);\n\t\t\t\t} else if (el instanceof HTMLParagraphElement)\n\t\t\t\t\tdescriptions.some((desc) => desc.contains(el)) ||\n\t\t\t\t\t\tdescriptions.push(el); // Only add if not already inside description\n\t\t\t}\n\n\t\t\tif (input) {\n\t\t\t\tfor (const label of labels) label.htmlFor = useId(input);\n\t\t\t\trenderCombobox(combobox);\n\t\t\t\trenderCounter(input);\n\t\t\t\trenderTextareaSize(input);\n\t\t\t\tattr(input, \"aria-describedby\", descriptions.map(useId).join(\" \"));\n\t\t\t\tattr(input, \"aria-invalid\", `${!valid}`);\n\t\t\t}\n\t\t}\n}\n\n// iOS does not support field-sizing: content, so we need to manually resize\nfunction renderTextareaSize(textarea: Element) {\n\tif (textarea instanceof HTMLTextAreaElement) {\n\t\ttextarea.style.setProperty(\"--mtds-textarea-height\", \"auto\");\n\t\ttextarea.style.setProperty(\n\t\t\t\"--mtds-textarea-height\",\n\t\t\t`${textarea.scrollHeight}px`,\n\t\t);\n\t}\n}\n\nconst getText = (style: CSSStyleDeclaration, key: string) =>\n\tstyle.getPropertyValue(`--mtds-text-${key}`)?.slice(1, -1) || \"\"; // slice to trim quotes\n\n// Setup translations from CSS custom properties\nfunction renderCombobox(el: UHTMLComboboxElement | null) {\n\tconst { control, list } = el || {};\n\n\tif (el && list && !el.hasAttribute(\"data-sr-added\")) {\n\t\tconst style = window.getComputedStyle(el);\n\t\tattr(el, \"data-sr-added\", getText(style, \"combobox-added\"));\n\t\tattr(el, \"data-sr-empty\", getText(style, \"combobox-empty\"));\n\t\tattr(el, \"data-sr-found\", getText(style, \"combobox-found\"));\n\t\tattr(el, \"data-sr-invalid\", getText(style, \"combobox-invalid\"));\n\t\tattr(el, \"data-sr-of\", getText(style, \"combobox-of\"));\n\t\tattr(el, \"data-sr-remove\", getText(style, \"combobox-remove\"));\n\t\tattr(el, \"data-sr-removed\", getText(style, \"combobox-removed\"));\n\t\tattr(list, \"data-sr-plural\", getText(style, \"datalist-plural\"));\n\t\tattr(list, \"data-sr-singular\", getText(style, \"datalist-singular\"));\n\t}\n\tif (list && control && !list.hasAttribute(\"popover\")) {\n\t\tattr(list, \"popover\", \"manual\");\n\t\tattr(control, \"popovertarget\", useId(list));\n\t}\n}\n\nfunction renderCounter(input: HTMLInputElement) {\n\tconst el = input?.nextElementSibling;\n\tconst limit = el && attr(el, \"data-count\");\n\n\tif (el && limit) {\n\t\tconst remainder = Number(limit) - input.value.length;\n\t\tconst nextInvalid = remainder < 0;\n\t\tconst prevInvalid = attr(el, \"aria-live\") === \"polite\";\n\t\tconst style = window.getComputedStyle(el || input);\n\t\tconst over = getText(style, \"count-over\");\n\t\tconst under = getText(style, \"count-under\");\n\t\tconst label = `${(nextInvalid ? over : under).replace(\"%d\", `${Math.abs(remainder)}`)}`;\n\n\t\tif (prevInvalid !== nextInvalid) {\n\t\t\tattr(el, \"aria-live\", nextInvalid ? \"polite\" : \"off\");\n\t\t\tfor (const css of CSS_VALIDATIONS) el.classList.toggle(css, nextInvalid);\n\t\t}\n\t\tattr(el, \"aria-label\", label);\n\t}\n}\n\nfunction handleFieldToggle({ target: el, newState }: Partial<ToggleEvent>) {\n\tif (el instanceof UHTMLDataListElement) {\n\t\tconst root = el.getRootNode() as ShadowRoot | null;\n\t\tconst anchor = root?.querySelector<HTMLElement>(\n\t\t\t`[popovertarget=\"${el.id}\"]`,\n\t\t);\n\n\t\tif (newState === \"closed\") anchorPosition(el, false);\n\t\telse if (anchor)\n\t\t\tanchorPosition(el, anchor, {\n\t\t\t\tcontain({ availableHeight }) {\n\t\t\t\t\tel.style.width = `${anchor.clientWidth}px`;\n\t\t\t\t\tel.style.maxHeight = `${Math.max(50, availableHeight)}px`;\n\t\t\t\t},\n\t\t\t});\n\t}\n}\n// Update when typing\nfunction handleFieldInput(event: Event) {\n\tif (isInputLike(event.target)) {\n\t\trenderCounter(event.target);\n\t\trenderTextareaSize(event.target);\n\t}\n}\n\nfunction handleFieldValdiation(event: Event) {\n\tif ((event.target as Element)?.closest?.(`.${CSS_FIELD}`))\n\t\tevent.preventDefault(); // Prevent browsers from showing default validation bubbles\n}\n\nonLoaded(() => [\n\tonMutation(() => handleFieldMutation(), \"class\"),\n\ton(document, \"input\", handleFieldInput, QUICK_EVENT),\n\ton(document, \"toggle\", handleFieldToggle, QUICK_EVENT), // Use capture since toggle does not bubble\n\ton(document, \"invalid\", handleFieldValdiation, true), // Use capture as invalid and submit does not bubble\n]);\n"],"names":[],"mappings":"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"}
|
package/mtds/field/field.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { JSX } from 'react';
|
|
|
4
4
|
import { InputProps } from '../input/input';
|
|
5
5
|
import { PolymorphicComponentPropWithRef } from '../react-types';
|
|
6
6
|
type FieldBaseProps = {
|
|
7
|
-
"data-validation"?: "form" | "false" | false;
|
|
8
7
|
count?: number;
|
|
9
8
|
description?: React.ReactNode;
|
|
10
9
|
error?: React.ReactNode;
|
package/mtds/field/field.js
CHANGED
|
@@ -10,7 +10,7 @@ import { Validation } from "../validation/validation.js";
|
|
|
10
10
|
const toOption = (o) => typeof o === "string" ? { label: o, value: o } : o;
|
|
11
11
|
const FieldComp = forwardRef(function Field2({
|
|
12
12
|
"data-size": size,
|
|
13
|
-
"data-validation":
|
|
13
|
+
"data-validation": dataValidation,
|
|
14
14
|
as,
|
|
15
15
|
className,
|
|
16
16
|
count,
|
|
@@ -30,7 +30,7 @@ const FieldComp = forwardRef(function Field2({
|
|
|
30
30
|
const validation = validationContent || error;
|
|
31
31
|
const shared = {
|
|
32
32
|
"data-size": size,
|
|
33
|
-
"data-validation":
|
|
33
|
+
"data-validation": dataValidation,
|
|
34
34
|
className: clsx(styles.field, className),
|
|
35
35
|
style
|
|
36
36
|
};
|
|
@@ -65,7 +65,7 @@ const FieldComp = forwardRef(function Field2({
|
|
|
65
65
|
...rest
|
|
66
66
|
}
|
|
67
67
|
),
|
|
68
|
-
!!validation && /* @__PURE__ */ jsx(Validation, {
|
|
68
|
+
!!validation && /* @__PURE__ */ jsx(Validation, { children: validation }),
|
|
69
69
|
!!count && /* @__PURE__ */ jsx(FieldCount, { "data-count": count })
|
|
70
70
|
] }) : /* @__PURE__ */ jsx("div", { ref, ...shared, ...rest });
|
|
71
71
|
});
|
|
@@ -174,7 +174,7 @@ const FieldCombobox = forwardRef(
|
|
|
174
174
|
type
|
|
175
175
|
}
|
|
176
176
|
),
|
|
177
|
-
/* @__PURE__ */ jsx("del", {
|
|
177
|
+
/* @__PURE__ */ jsx("del", { "aria-label": "Fjern tekst", suppressHydrationWarning: true })
|
|
178
178
|
] }),
|
|
179
179
|
!!options && /* @__PURE__ */ jsx(FieldDatalist, { "data-nofilter": nofilter, "data-position": position, children: options.map(toOption).map(({ children: children2, label, value }) => /* @__PURE__ */ jsx(FieldOption, { value, label, children: children2 ?? label }, value)) })
|
|
180
180
|
]
|
package/mtds/field/field.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.js","sources":["../../designsystem/field/field.tsx"],"sourcesContent":["\"use client\";\nimport type { Placement } from \"@floating-ui/dom\";\nimport type {\n\tReactUcombobox,\n\tUHTMLComboboxElement,\n} from \"@u-elements/u-combobox\";\nimport clsx from \"clsx\";\nimport type { JSX } from \"react\";\nimport { forwardRef, useEffect, useImperativeHandle, useRef } from \"react\";\nimport { HelpText } from \"../helptext/helptext\";\nimport { Input, type InputProps } from \"../input/input\";\nimport type {\n\tPolymorphicComponentPropWithRef,\n\tPolymorphicRef,\n} from \"../react-types\";\nimport styles from \"../styles.module.css\";\nimport { toCustomElementProps } from \"../utils\";\nimport { Validation } from \"../validation/validation\";\n\ntype FieldBaseProps = {\n\t\"data-validation\"?: \"form\" | \"false\" | false;\n\tcount?: number;\n\tdescription?: React.ReactNode;\n\terror?: React.ReactNode; // Kept for backwards compatibility\n\thelpText?: React.ReactNode;\n\thelpTextLabel?: string;\n\tlabel?: React.ReactNode;\n\toptions?: string[] | FieldComboboxSelected;\n\tprefix?: string;\n\treadOnly?: boolean; // Allow readoOnly also on <select>\n\tsuffix?: string;\n\tvalidation?: React.ReactNode;\n};\n\nexport type FieldProps<As extends React.ElementType = \"div\"> =\n\tPolymorphicComponentPropWithRef<As, FieldBaseProps>;\n\ntype FieldComponent = <As extends React.ElementType = \"div\">(\n\tprops: FieldProps<As>,\n) => JSX.Element;\n\nconst toOption = (\n\to: FieldComboboxSelected[number] | string,\n): FieldComboboxSelected[number] =>\n\ttypeof o === \"string\" ? { label: o, value: o } : o;\n\nexport const FieldComp: FieldComponent = forwardRef<null>(function Field<\n\tAs extends React.ElementType = \"div\",\n>(\n\t{\n\t\t\"data-size\": size,\n\t\t\"data-validation\": validationType,\n\t\tas,\n\t\tclassName,\n\t\tcount,\n\t\tdescription,\n\t\terror,\n\t\thelpText,\n\t\thelpTextLabel,\n\t\tlabel,\n\t\tprefix,\n\t\tstyle,\n\t\tsuffix,\n\t\tvalidation: validationContent,\n\t\t...rest\n\t}: FieldProps<As>,\n\tref?: PolymorphicRef<As>,\n) {\n\tconst Tag = as || \"div\";\n\tconst affixes = !!suffix || !!prefix;\n\tconst validation = validationContent || error; // error kept for backwards compatibility\n\tconst shared = {\n\t\t\"data-size\": size,\n\t\t\"data-validation\": validationType,\n\t\tclassName: clsx(styles.field, className),\n\t\tstyle,\n\t};\n\n\t// Render options if select\n\tif (as === \"select\" && !rest.children)\n\t\tObject.assign(rest, {\n\t\t\toptions: undefined, // Ensure options is not passed to DOM\n\t\t\tchildren: (\n\t\t\t\t<>\n\t\t\t\t\t{(rest.options as FieldBaseProps[\"options\"])\n\t\t\t\t\t\t?.map(toOption)\n\t\t\t\t\t\t.map(({ label, value }) => (\n\t\t\t\t\t\t\t<option key={value} value={value}>\n\t\t\t\t\t\t\t\t{label}\n\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t))}\n\t\t\t\t</>\n\t\t\t),\n\t\t});\n\n\t// Using suppressHydrationWarning to avoid Next.js vs field-observer.ts hydration conflict\n\treturn as ? (\n\t\t<div {...shared}>\n\t\t\t{!!label && <FieldLabel>{label}</FieldLabel>}\n\t\t\t{!!helpText && <HelpText aria-label={helpTextLabel}>{helpText}</HelpText>}\n\t\t\t{!!description && <FieldDescription>{description}</FieldDescription>}\n\t\t\t{affixes ? (\n\t\t\t\t<FieldAffixes>\n\t\t\t\t\t{!!prefix && <span>{prefix}</span>}\n\t\t\t\t\t<Tag\n\t\t\t\t\t\tclassName={styles.input}\n\t\t\t\t\t\tsuppressHydrationWarning\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\t{...rest}\n\t\t\t\t\t/>\n\t\t\t\t\t{!!suffix && <span>{suffix}</span>}\n\t\t\t\t</FieldAffixes>\n\t\t\t) : (\n\t\t\t\t<Tag\n\t\t\t\t\tclassName={typeof as === \"string\" ? styles.input : undefined}\n\t\t\t\t\tsuppressHydrationWarning\n\t\t\t\t\tref={ref}\n\t\t\t\t\t{...rest}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{!!validation && (\n\t\t\t\t<Validation hidden={validationType === \"form\"}>{validation}</Validation>\n\t\t\t)}\n\t\t\t{!!count && <FieldCount data-count={count} />}\n\t\t</div>\n\t) : (\n\t\t<div ref={ref} {...shared} {...rest} />\n\t);\n}) as FieldComponent; // Needed to tell Typescript this does not return ReactNode but acutally JSX.Element\n\nexport type FieldAffixProps = React.ComponentPropsWithoutRef<\"div\">;\nconst FieldAffixes = forwardRef<HTMLDivElement, FieldAffixProps>(\n\tfunction FieldAffixes({ className, ...rest }, ref) {\n\t\treturn (\n\t\t\t<div className={clsx(styles.affixes, className)} ref={ref} {...rest} />\n\t\t);\n\t},\n);\n\nexport type FieldDatalistProps = React.ComponentPropsWithoutRef<\"datalist\"> & {\n\t\"data-nofilter\"?: boolean;\n\t\"data-position\"?: Placement;\n};\n\nconst FieldDatalist = forwardRef<HTMLDataListElement, FieldDatalistProps>(\n\tfunction FieldDatalist({ \"data-nofilter\": filter, ...rest }, ref) {\n\t\treturn (\n\t\t\t<u-datalist\n\t\t\t\tdata-nofilter={!!filter || undefined} // Ensure data-nofilter is set correctly\n\t\t\t\tref={ref}\n\t\t\t\t{...toCustomElementProps(rest)}\n\t\t\t/>\n\t\t);\n\t},\n);\n\nexport type FieldOptionProps = React.ComponentPropsWithoutRef<\"option\">;\nconst FieldOption = forwardRef<HTMLOptionElement, FieldOptionProps>(\n\tfunction FieldOption(props, ref) {\n\t\treturn <u-option ref={ref} {...toCustomElementProps(props)} />;\n\t},\n);\n\nexport type FieldComboboxSelected = {\n\tlabel: string;\n\tvalue: string;\n\tchildren?: React.ReactNode;\n}[];\nexport type FieldComboboxProps = Omit<\n\tReactUcombobox,\n\t\"onChange\" | \"onInput\"\n> & {\n\t\"data-creatable\"?: boolean;\n\t\"data-multiple\"?: boolean;\n\tonAfterChange?: (e: CustomEvent<HTMLDataElement>) => void; // deprecated\n\tonAfterSelect?: (e: CustomEvent<HTMLDataElement>) => void; // Custom event to handle before change\n\tonBeforeChange?: (e: CustomEvent<HTMLDataElement>) => void; // deprecated\n\tonBeforeMatch?: (e: CustomEvent<HTMLOptionElement>) => void; // Custom event to handle before change\n\tonBeforeSelect?: (e: CustomEvent<HTMLDataElement>) => void; // Custom event to handle before change\n\tonSelectedChange?: (selected: FieldComboboxSelected) => void; // Allow onChange to be a function that returns void\n\toptions?: FieldComboboxSelected;\n\tselected?: FieldComboboxSelected; // Allow value to be a string or an array of strings for multiple select\n} & Pick<\n\t\tInputProps,\n\t\t| \"disabled\"\n\t\t| \"name\"\n\t\t| \"onChange\"\n\t\t| \"onInput\"\n\t\t| \"placeholder\"\n\t\t| \"readOnly\"\n\t\t| \"type\"\n\t\t| \"value\"\n\t> & // Allow input props to be passed down\n\tPick<FieldDatalistProps, \"data-position\" | \"data-nofilter\">; // Allow datalist props to be passed down\n\nconst FieldCombobox = forwardRef<UHTMLComboboxElement, FieldComboboxProps>(\n\tfunction FieldCombobox(\n\t\t{\n\t\t\t\"aria-required\": required,\n\t\t\t\"data-position\": position,\n\t\t\t\"data-nofilter\": nofilter,\n\t\t\t\"data-multiple\": multiple,\n\t\t\tonAfterChange,\n\t\t\tonAfterSelect,\n\t\t\tonBeforeChange,\n\t\t\tonBeforeMatch,\n\t\t\tonBeforeSelect,\n\t\t\tonSelectedChange,\n\t\t\tonInput,\n\t\t\tonChange,\n\t\t\tchildren,\n\t\t\tdisabled,\n\t\t\tname,\n\t\t\toptions,\n\t\t\tplaceholder,\n\t\t\treadOnly,\n\t\t\tselected,\n\t\t\ttype,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) {\n\t\tconst innerRef = useRef<UHTMLComboboxElement>(null);\n\t\tconst onSelected = useRef(onSelectedChange);\n\t\tonSelected.current = onSelectedChange; // Sync the latest onSelectedChange function\n\n\t\t// Deprecated props\n\t\tif (onAfterChange) {\n\t\t\tonAfterSelect = onAfterChange;\n\t\t\tconsole.warn(\n\t\t\t\t`Combobox onAfterChange is deprecated, use onAfterSelect instead.`,\n\t\t\t);\n\t\t}\n\t\tif (onBeforeChange) {\n\t\t\tonBeforeSelect = onBeforeChange;\n\t\t\tconsole.warn(\n\t\t\t\t`Combobox onBeforeChange is deprecated, use onBeforeSelect instead.`,\n\t\t\t);\n\t\t}\n\n\t\t// Using useEffect for React 18 and lower compatibility\n\t\tuseImperativeHandle(ref, () => innerRef.current as UHTMLComboboxElement); // Forward innerRef\n\t\tuseEffect(() => {\n\t\t\tconst self = innerRef.current;\n\t\t\tconst handleChange = (event: CustomEvent<HTMLDataElement>) => {\n\t\t\t\tconst handleSelected = onSelected.current;\n\t\t\t\tif (!onSelected) return; // No onSelectedChange function provided, let u-combobox handle it\n\t\t\t\tevent.preventDefault();\n\t\t\t\tconst { isConnected: remove, textContent, value } = event.detail;\n\t\t\t\tconst label = textContent?.trim() || \"\";\n\t\t\t\tconst prev = selected || [];\n\n\t\t\t\tif (remove) handleSelected?.(prev.filter((i) => i.value !== value));\n\t\t\t\telse if (multiple) handleSelected?.([...prev, { value, label }]);\n\t\t\t\telse handleSelected?.([{ value, label }]);\n\t\t\t};\n\n\t\t\tself?.addEventListener(\"comboboxbeforeselect\", handleChange);\n\t\t\treturn () =>\n\t\t\t\tself?.removeEventListener(\"comboboxbeforeselect\", handleChange);\n\t\t}, [multiple, selected]);\n\n\t\treturn (\n\t\t\t<u-combobox\n\t\t\t\tdata-multiple={multiple || undefined}\n\t\t\t\t{...toCustomElementProps({\n\t\t\t\t\toncomboboxbeforeselect: onBeforeSelect,\n\t\t\t\t\toncomboboxbeforematch: onBeforeMatch,\n\t\t\t\t\toncomboboxafterselect: onAfterSelect,\n\t\t\t\t\tref: innerRef,\n\t\t\t\t\t...props,\n\t\t\t\t})}\n\t\t\t>\n\t\t\t\t{selected?.map(({ children, label, value }) => (\n\t\t\t\t\t<data key={value} value={value} suppressHydrationWarning>\n\t\t\t\t\t\t{children ?? label}\n\t\t\t\t\t</data>\n\t\t\t\t))}\n\t\t\t\t{children || (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\taria-required={required}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\tname={name}\n\t\t\t\t\t\t\tonInput={onInput}\n\t\t\t\t\t\t\tonChange={onChange}\n\t\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<del {...toCustomElementProps({ \"aria-label\": \"Fjern tekst\" })} />\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t\t{!!options && (\n\t\t\t\t\t<FieldDatalist data-nofilter={nofilter} data-position={position}>\n\t\t\t\t\t\t{options.map(toOption).map(({ children, label, value }) => (\n\t\t\t\t\t\t\t<FieldOption key={value} value={value} label={label}>\n\t\t\t\t\t\t\t\t{children ?? label}\n\t\t\t\t\t\t\t</FieldOption>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</FieldDatalist>\n\t\t\t\t)}\n\t\t\t</u-combobox>\n\t\t);\n\t},\n);\n\nexport type FieldLabelProps = React.ComponentPropsWithoutRef<\"label\">;\nconst FieldLabel = forwardRef<HTMLLabelElement, FieldLabelProps>(\n\tfunction FieldLabel(rest, ref) {\n\t\treturn <label suppressHydrationWarning ref={ref} {...rest} />;\n\t},\n);\n\nexport type FieldDescriptionProps = React.ComponentPropsWithoutRef<\"p\">;\nconst FieldDescription = forwardRef<\n\tHTMLParagraphElement,\n\tFieldDescriptionProps\n>(function FieldDescription(rest, ref) {\n\treturn <p suppressHydrationWarning ref={ref} {...rest} />;\n});\n\nexport type FieldCountProps = React.ComponentPropsWithoutRef<\"p\"> & {\n\t\"data-count\": number;\n};\nconst FieldCount = forwardRef<HTMLParagraphElement, FieldCountProps>(\n\tfunction FieldCount(rest, ref) {\n\t\treturn <p suppressHydrationWarning ref={ref} {...rest} />;\n\t},\n);\n\nexport const Field = Object.assign(FieldComp, {\n\tAffixes: FieldAffixes,\n\tCombobox: FieldCombobox,\n\tDatalist: FieldDatalist,\n\tOption: FieldOption,\n\tDescription: FieldDescription,\n\tLabel: FieldLabel,\n\tCount: FieldCount,\n});\n"],"names":["Field","label","FieldAffixes","FieldDatalist","FieldOption","FieldCombobox","children","FieldLabel","FieldDescription","FieldCount"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"field.js","sources":["../../designsystem/field/field.tsx"],"sourcesContent":["\"use client\";\nimport type { Placement } from \"@floating-ui/dom\";\nimport type {\n\tReactUcombobox,\n\tUHTMLComboboxElement,\n} from \"@u-elements/u-combobox\";\nimport clsx from \"clsx\";\nimport type { JSX } from \"react\";\nimport { forwardRef, useEffect, useImperativeHandle, useRef } from \"react\";\nimport { HelpText } from \"../helptext/helptext\";\nimport { Input, type InputProps } from \"../input/input\";\nimport type {\n\tPolymorphicComponentPropWithRef,\n\tPolymorphicRef,\n} from \"../react-types\";\nimport styles from \"../styles.module.css\";\nimport { toCustomElementProps } from \"../utils\";\nimport { Validation } from \"../validation/validation\";\n\ntype FieldBaseProps = {\n\tcount?: number;\n\tdescription?: React.ReactNode;\n\terror?: React.ReactNode; // Kept for backwards compatibility\n\thelpText?: React.ReactNode;\n\thelpTextLabel?: string;\n\tlabel?: React.ReactNode;\n\toptions?: string[] | FieldComboboxSelected;\n\tprefix?: string;\n\treadOnly?: boolean; // Allow readoOnly also on <select>\n\tsuffix?: string;\n\tvalidation?: React.ReactNode;\n};\n\nexport type FieldProps<As extends React.ElementType = \"div\"> =\n\tPolymorphicComponentPropWithRef<As, FieldBaseProps>;\n\ntype FieldComponent = <As extends React.ElementType = \"div\">(\n\tprops: FieldProps<As>,\n) => JSX.Element;\n\nconst toOption = (\n\to: FieldComboboxSelected[number] | string,\n): FieldComboboxSelected[number] =>\n\ttypeof o === \"string\" ? { label: o, value: o } : o;\n\nexport const FieldComp: FieldComponent = forwardRef<null>(function Field<\n\tAs extends React.ElementType = \"div\",\n>(\n\t{\n\t\t\"data-size\": size,\n\t\t\"data-validation\": dataValidation,\n\t\tas,\n\t\tclassName,\n\t\tcount,\n\t\tdescription,\n\t\terror,\n\t\thelpText,\n\t\thelpTextLabel,\n\t\tlabel,\n\t\tprefix,\n\t\tstyle,\n\t\tsuffix,\n\t\tvalidation: validationContent,\n\t\t...rest\n\t}: FieldProps<As>,\n\tref?: PolymorphicRef<As>,\n) {\n\tconst Tag = as || \"div\";\n\tconst affixes = !!suffix || !!prefix;\n\tconst validation = validationContent || error; // error kept for backwards compatibility\n\tconst shared = {\n\t\t\"data-size\": size,\n\t\t\"data-validation\": dataValidation,\n\t\tclassName: clsx(styles.field, className),\n\t\tstyle,\n\t};\n\n\t// Render options if select\n\tif (as === \"select\" && !rest.children)\n\t\tObject.assign(rest, {\n\t\t\toptions: undefined, // Ensure options is not passed to DOM\n\t\t\tchildren: (\n\t\t\t\t<>\n\t\t\t\t\t{(rest.options as FieldBaseProps[\"options\"])\n\t\t\t\t\t\t?.map(toOption)\n\t\t\t\t\t\t.map(({ label, value }) => (\n\t\t\t\t\t\t\t<option key={value} value={value}>\n\t\t\t\t\t\t\t\t{label}\n\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t))}\n\t\t\t\t</>\n\t\t\t),\n\t\t});\n\n\t// Using suppressHydrationWarning to avoid Next.js vs field-observer.ts hydration conflict\n\treturn as ? (\n\t\t<div {...shared}>\n\t\t\t{!!label && <FieldLabel>{label}</FieldLabel>}\n\t\t\t{!!helpText && <HelpText aria-label={helpTextLabel}>{helpText}</HelpText>}\n\t\t\t{!!description && <FieldDescription>{description}</FieldDescription>}\n\t\t\t{affixes ? (\n\t\t\t\t<FieldAffixes>\n\t\t\t\t\t{!!prefix && <span>{prefix}</span>}\n\t\t\t\t\t<Tag\n\t\t\t\t\t\tclassName={styles.input}\n\t\t\t\t\t\tsuppressHydrationWarning\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\t{...rest}\n\t\t\t\t\t/>\n\t\t\t\t\t{!!suffix && <span>{suffix}</span>}\n\t\t\t\t</FieldAffixes>\n\t\t\t) : (\n\t\t\t\t<Tag\n\t\t\t\t\tclassName={typeof as === \"string\" ? styles.input : undefined}\n\t\t\t\t\tsuppressHydrationWarning\n\t\t\t\t\tref={ref}\n\t\t\t\t\t{...rest}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{!!validation && <Validation>{validation}</Validation>}\n\t\t\t{!!count && <FieldCount data-count={count} />}\n\t\t</div>\n\t) : (\n\t\t<div ref={ref} {...shared} {...rest} />\n\t);\n}) as FieldComponent; // Needed to tell Typescript this does not return ReactNode but acutally JSX.Element\n\nexport type FieldAffixProps = React.ComponentPropsWithoutRef<\"div\">;\nconst FieldAffixes = forwardRef<HTMLDivElement, FieldAffixProps>(\n\tfunction FieldAffixes({ className, ...rest }, ref) {\n\t\treturn (\n\t\t\t<div className={clsx(styles.affixes, className)} ref={ref} {...rest} />\n\t\t);\n\t},\n);\n\nexport type FieldDatalistProps = React.ComponentPropsWithoutRef<\"datalist\"> & {\n\t\"data-nofilter\"?: boolean;\n\t\"data-position\"?: Placement;\n};\n\nconst FieldDatalist = forwardRef<HTMLDataListElement, FieldDatalistProps>(\n\tfunction FieldDatalist({ \"data-nofilter\": filter, ...rest }, ref) {\n\t\treturn (\n\t\t\t<u-datalist\n\t\t\t\tdata-nofilter={!!filter || undefined} // Ensure data-nofilter is set correctly\n\t\t\t\tref={ref}\n\t\t\t\t{...toCustomElementProps(rest)}\n\t\t\t/>\n\t\t);\n\t},\n);\n\nexport type FieldOptionProps = React.ComponentPropsWithoutRef<\"option\">;\nconst FieldOption = forwardRef<HTMLOptionElement, FieldOptionProps>(\n\tfunction FieldOption(props, ref) {\n\t\treturn <u-option ref={ref} {...toCustomElementProps(props)} />;\n\t},\n);\n\nexport type FieldComboboxSelected = {\n\tlabel: string;\n\tvalue: string;\n\tchildren?: React.ReactNode;\n}[];\nexport type FieldComboboxProps = Omit<\n\tReactUcombobox,\n\t\"onChange\" | \"onInput\"\n> & {\n\t\"data-creatable\"?: boolean;\n\t\"data-multiple\"?: boolean;\n\tonAfterChange?: (e: CustomEvent<HTMLDataElement>) => void; // deprecated\n\tonAfterSelect?: (e: CustomEvent<HTMLDataElement>) => void; // Custom event to handle before change\n\tonBeforeChange?: (e: CustomEvent<HTMLDataElement>) => void; // deprecated\n\tonBeforeMatch?: (e: CustomEvent<HTMLOptionElement>) => void; // Custom event to handle before change\n\tonBeforeSelect?: (e: CustomEvent<HTMLDataElement>) => void; // Custom event to handle before change\n\tonSelectedChange?: (selected: FieldComboboxSelected) => void; // Allow onChange to be a function that returns void\n\toptions?: FieldComboboxSelected;\n\tselected?: FieldComboboxSelected; // Allow value to be a string or an array of strings for multiple select\n} & Pick<\n\t\tInputProps,\n\t\t| \"disabled\"\n\t\t| \"name\"\n\t\t| \"onChange\"\n\t\t| \"onInput\"\n\t\t| \"placeholder\"\n\t\t| \"readOnly\"\n\t\t| \"type\"\n\t\t| \"value\"\n\t> & // Allow input props to be passed down\n\tPick<FieldDatalistProps, \"data-position\" | \"data-nofilter\">; // Allow datalist props to be passed down\n\nconst FieldCombobox = forwardRef<UHTMLComboboxElement, FieldComboboxProps>(\n\tfunction FieldCombobox(\n\t\t{\n\t\t\t\"aria-required\": required,\n\t\t\t\"data-position\": position,\n\t\t\t\"data-nofilter\": nofilter,\n\t\t\t\"data-multiple\": multiple,\n\t\t\tonAfterChange,\n\t\t\tonAfterSelect,\n\t\t\tonBeforeChange,\n\t\t\tonBeforeMatch,\n\t\t\tonBeforeSelect,\n\t\t\tonSelectedChange,\n\t\t\tonInput,\n\t\t\tonChange,\n\t\t\tchildren,\n\t\t\tdisabled,\n\t\t\tname,\n\t\t\toptions,\n\t\t\tplaceholder,\n\t\t\treadOnly,\n\t\t\tselected,\n\t\t\ttype,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) {\n\t\tconst innerRef = useRef<UHTMLComboboxElement>(null);\n\t\tconst onSelected = useRef(onSelectedChange);\n\t\tonSelected.current = onSelectedChange; // Sync the latest onSelectedChange function\n\n\t\t// Deprecated props\n\t\tif (onAfterChange) {\n\t\t\tonAfterSelect = onAfterChange;\n\t\t\tconsole.warn(\n\t\t\t\t`Combobox onAfterChange is deprecated, use onAfterSelect instead.`,\n\t\t\t);\n\t\t}\n\t\tif (onBeforeChange) {\n\t\t\tonBeforeSelect = onBeforeChange;\n\t\t\tconsole.warn(\n\t\t\t\t`Combobox onBeforeChange is deprecated, use onBeforeSelect instead.`,\n\t\t\t);\n\t\t}\n\n\t\t// Using useEffect for React 18 and lower compatibility\n\t\tuseImperativeHandle(ref, () => innerRef.current as UHTMLComboboxElement); // Forward innerRef\n\t\tuseEffect(() => {\n\t\t\tconst self = innerRef.current;\n\t\t\tconst handleChange = (event: CustomEvent<HTMLDataElement>) => {\n\t\t\t\tconst handleSelected = onSelected.current;\n\t\t\t\tif (!onSelected) return; // No onSelectedChange function provided, let u-combobox handle it\n\t\t\t\tevent.preventDefault();\n\t\t\t\tconst { isConnected: remove, textContent, value } = event.detail;\n\t\t\t\tconst label = textContent?.trim() || \"\";\n\t\t\t\tconst prev = selected || [];\n\n\t\t\t\tif (remove) handleSelected?.(prev.filter((i) => i.value !== value));\n\t\t\t\telse if (multiple) handleSelected?.([...prev, { value, label }]);\n\t\t\t\telse handleSelected?.([{ value, label }]);\n\t\t\t};\n\n\t\t\tself?.addEventListener(\"comboboxbeforeselect\", handleChange);\n\t\t\treturn () =>\n\t\t\t\tself?.removeEventListener(\"comboboxbeforeselect\", handleChange);\n\t\t}, [multiple, selected]);\n\n\t\treturn (\n\t\t\t<u-combobox\n\t\t\t\tdata-multiple={multiple || undefined}\n\t\t\t\t{...toCustomElementProps({\n\t\t\t\t\toncomboboxbeforeselect: onBeforeSelect,\n\t\t\t\t\toncomboboxbeforematch: onBeforeMatch,\n\t\t\t\t\toncomboboxafterselect: onAfterSelect,\n\t\t\t\t\tref: innerRef,\n\t\t\t\t\t...props,\n\t\t\t\t})}\n\t\t\t>\n\t\t\t\t{selected?.map(({ children, label, value }) => (\n\t\t\t\t\t<data key={value} value={value} suppressHydrationWarning>\n\t\t\t\t\t\t{children ?? label}\n\t\t\t\t\t</data>\n\t\t\t\t))}\n\t\t\t\t{children || (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\taria-required={required}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\tname={name}\n\t\t\t\t\t\t\tonInput={onInput}\n\t\t\t\t\t\t\tonChange={onChange}\n\t\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<del aria-label=\"Fjern tekst\" suppressHydrationWarning />\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t\t{!!options && (\n\t\t\t\t\t<FieldDatalist data-nofilter={nofilter} data-position={position}>\n\t\t\t\t\t\t{options.map(toOption).map(({ children, label, value }) => (\n\t\t\t\t\t\t\t<FieldOption key={value} value={value} label={label}>\n\t\t\t\t\t\t\t\t{children ?? label}\n\t\t\t\t\t\t\t</FieldOption>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</FieldDatalist>\n\t\t\t\t)}\n\t\t\t</u-combobox>\n\t\t);\n\t},\n);\n\nexport type FieldLabelProps = React.ComponentPropsWithoutRef<\"label\">;\nconst FieldLabel = forwardRef<HTMLLabelElement, FieldLabelProps>(\n\tfunction FieldLabel(rest, ref) {\n\t\treturn <label suppressHydrationWarning ref={ref} {...rest} />;\n\t},\n);\n\nexport type FieldDescriptionProps = React.ComponentPropsWithoutRef<\"p\">;\nconst FieldDescription = forwardRef<\n\tHTMLParagraphElement,\n\tFieldDescriptionProps\n>(function FieldDescription(rest, ref) {\n\treturn <p suppressHydrationWarning ref={ref} {...rest} />;\n});\n\nexport type FieldCountProps = React.ComponentPropsWithoutRef<\"p\"> & {\n\t\"data-count\": number;\n};\nconst FieldCount = forwardRef<HTMLParagraphElement, FieldCountProps>(\n\tfunction FieldCount(rest, ref) {\n\t\treturn <p suppressHydrationWarning ref={ref} {...rest} />;\n\t},\n);\n\nexport const Field = Object.assign(FieldComp, {\n\tAffixes: FieldAffixes,\n\tCombobox: FieldCombobox,\n\tDatalist: FieldDatalist,\n\tOption: FieldOption,\n\tDescription: FieldDescription,\n\tLabel: FieldLabel,\n\tCount: FieldCount,\n});\n"],"names":["Field","label","FieldAffixes","FieldDatalist","FieldOption","FieldCombobox","children","FieldLabel","FieldDescription","FieldCount"],"mappings":"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"}
|