@mattilsynet/design 2.2.26 → 2.2.28

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.
@@ -1,6 +1,6 @@
1
1
  import styles from "../styles.module.css.js";
2
2
  import { isBrowser, onLoaded, on, QUICK_EVENT, debounce } from "../utils.js";
3
- import "./app-toggle2.js";
3
+ import "./app-toggle.js";
4
4
  const CSS_APP = styles.app.split(" ")[0];
5
5
  const CSS_STICKY = styles.sticky.split(" ")[0];
6
6
  const CSS_TOGGLE = '[data-command="toggle-app-expanded"]';
@@ -1,5 +1,17 @@
1
- const script = 'if (\n typeof window !== "undefined" &&\n window.CSSStyleSheet &&\n document.adoptedStyleSheets\n)\n (() => {\n const key = "--mtds-app-expanded";\n const sheet = new CSSStyleSheet();\n const prev = () => !window.localStorage.getItem(key)?.includes("false");\n\n document.adoptedStyleSheets.push(sheet);\n window.mtdsToggleAppExpanded = (force) => {\n try {\n const next = force ?? !prev();\n sheet.replaceSync?.(`:root { ${key}: var(${key}--${next})}`);\n window.localStorage.setItem(key, next);\n } catch (_err) {} // localStorage is full or replaceSync is not supported\n };\n\n // Set and store initial state\n window.mtdsToggleAppExpanded(prev());\n })();\n';
2
- export {
3
- script as default
4
- };
1
+ if (typeof window !== "undefined" && window.CSSStyleSheet && document.adoptedStyleSheets)
2
+ (() => {
3
+ const key = "--mtds-app-expanded";
4
+ const sheet = new CSSStyleSheet();
5
+ const prev = () => !window.localStorage.getItem(key)?.includes("false");
6
+ document.adoptedStyleSheets.push(sheet);
7
+ window.mtdsToggleAppExpanded = (force) => {
8
+ try {
9
+ const next = force ?? !prev();
10
+ sheet.replaceSync?.(`:root { ${key}: var(${key}--${next})}`);
11
+ window.localStorage.setItem(key, next);
12
+ } catch (_err) {
13
+ }
14
+ };
15
+ window.mtdsToggleAppExpanded(prev());
16
+ })();
5
17
  //# sourceMappingURL=app-toggle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-toggle.js","sources":["../../designsystem/app/app-toggle.js?raw"],"sourcesContent":["export default \"if (\\n\\ttypeof window !== \\\"undefined\\\" &&\\n\\twindow.CSSStyleSheet &&\\n\\tdocument.adoptedStyleSheets\\n)\\n\\t(() => {\\n\\t\\tconst key = \\\"--mtds-app-expanded\\\";\\n\\t\\tconst sheet = new CSSStyleSheet();\\n\\t\\tconst prev = () => !window.localStorage.getItem(key)?.includes(\\\"false\\\");\\n\\n\\t\\tdocument.adoptedStyleSheets.push(sheet);\\n\\t\\twindow.mtdsToggleAppExpanded = (force) => {\\n\\t\\t\\ttry {\\n\\t\\t\\t\\tconst next = force ?? !prev();\\n\\t\\t\\t\\tsheet.replaceSync?.(`:root { ${key}: var(${key}--${next})}`);\\n\\t\\t\\t\\twindow.localStorage.setItem(key, next);\\n\\t\\t\\t} catch (_err) {} // localStorage is full or replaceSync is not supported\\n\\t\\t};\\n\\n\\t\\t// Set and store initial state\\n\\t\\twindow.mtdsToggleAppExpanded(prev());\\n\\t})();\\n\""],"names":[],"mappings":"AAAA,MAAA,SAAe;"}
1
+ {"version":3,"file":"app-toggle.js","sources":["../../designsystem/app/app-toggle.js"],"sourcesContent":["if (\n\ttypeof window !== \"undefined\" &&\n\twindow.CSSStyleSheet &&\n\tdocument.adoptedStyleSheets\n)\n\t(() => {\n\t\tconst key = \"--mtds-app-expanded\";\n\t\tconst sheet = new CSSStyleSheet();\n\t\tconst prev = () => !window.localStorage.getItem(key)?.includes(\"false\");\n\n\t\tdocument.adoptedStyleSheets.push(sheet);\n\t\twindow.mtdsToggleAppExpanded = (force) => {\n\t\t\ttry {\n\t\t\t\tconst next = force ?? !prev();\n\t\t\t\tsheet.replaceSync?.(`:root { ${key}: var(${key}--${next})}`);\n\t\t\t\twindow.localStorage.setItem(key, next);\n\t\t\t} catch (_err) {} // localStorage is full or replaceSync is not supported\n\t\t};\n\n\t\t// Set and store initial state\n\t\twindow.mtdsToggleAppExpanded(prev());\n\t})();\n"],"names":[],"mappings":"AAAA,IACC,OAAO,WAAW,eAClB,OAAO,iBACP,SAAS;AAET,GAAC,MAAM;AACN,UAAM,MAAM;AACZ,UAAM,QAAQ,IAAI,cAAa;AAC/B,UAAM,OAAO,MAAM,CAAC,OAAO,aAAa,QAAQ,GAAG,GAAG,SAAS,OAAO;AAEtE,aAAS,mBAAmB,KAAK,KAAK;AACtC,WAAO,wBAAwB,CAAC,UAAU;AACzC,UAAI;AACH,cAAM,OAAO,SAAS,CAAC,KAAI;AAC3B,cAAM,cAAc,WAAW,GAAG,SAAS,GAAG,KAAK,IAAI,IAAI;AAC3D,eAAO,aAAa,QAAQ,KAAK,IAAI;AAAA,MACtC,SAAS,MAAM;AAAA,MAAC;AAAA,IACjB;AAGA,WAAO,sBAAsB,MAAM;AAAA,EACpC,GAAC;"}
@@ -1,17 +1,5 @@
1
- if (typeof window !== "undefined" && window.CSSStyleSheet && document.adoptedStyleSheets)
2
- (() => {
3
- const key = "--mtds-app-expanded";
4
- const sheet = new CSSStyleSheet();
5
- const prev = () => !window.localStorage.getItem(key)?.includes("false");
6
- document.adoptedStyleSheets.push(sheet);
7
- window.mtdsToggleAppExpanded = (force) => {
8
- try {
9
- const next = force ?? !prev();
10
- sheet.replaceSync?.(`:root { ${key}: var(${key}--${next})}`);
11
- window.localStorage.setItem(key, next);
12
- } catch (_err) {
13
- }
14
- };
15
- window.mtdsToggleAppExpanded(prev());
16
- })();
1
+ const script = 'if (\n typeof window !== "undefined" &&\n window.CSSStyleSheet &&\n document.adoptedStyleSheets\n)\n (() => {\n const key = "--mtds-app-expanded";\n const sheet = new CSSStyleSheet();\n const prev = () => !window.localStorage.getItem(key)?.includes("false");\n\n document.adoptedStyleSheets.push(sheet);\n window.mtdsToggleAppExpanded = (force) => {\n try {\n const next = force ?? !prev();\n sheet.replaceSync?.(`:root { ${key}: var(${key}--${next})}`);\n window.localStorage.setItem(key, next);\n } catch (_err) {} // localStorage is full or replaceSync is not supported\n };\n\n // Set and store initial state\n window.mtdsToggleAppExpanded(prev());\n })();\n';
2
+ export {
3
+ script as default
4
+ };
17
5
  //# sourceMappingURL=app-toggle2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-toggle2.js","sources":["../../designsystem/app/app-toggle.js"],"sourcesContent":["if (\n\ttypeof window !== \"undefined\" &&\n\twindow.CSSStyleSheet &&\n\tdocument.adoptedStyleSheets\n)\n\t(() => {\n\t\tconst key = \"--mtds-app-expanded\";\n\t\tconst sheet = new CSSStyleSheet();\n\t\tconst prev = () => !window.localStorage.getItem(key)?.includes(\"false\");\n\n\t\tdocument.adoptedStyleSheets.push(sheet);\n\t\twindow.mtdsToggleAppExpanded = (force) => {\n\t\t\ttry {\n\t\t\t\tconst next = force ?? !prev();\n\t\t\t\tsheet.replaceSync?.(`:root { ${key}: var(${key}--${next})}`);\n\t\t\t\twindow.localStorage.setItem(key, next);\n\t\t\t} catch (_err) {} // localStorage is full or replaceSync is not supported\n\t\t};\n\n\t\t// Set and store initial state\n\t\twindow.mtdsToggleAppExpanded(prev());\n\t})();\n"],"names":[],"mappings":"AAAA,IACC,OAAO,WAAW,eAClB,OAAO,iBACP,SAAS;AAET,GAAC,MAAM;AACN,UAAM,MAAM;AACZ,UAAM,QAAQ,IAAI,cAAa;AAC/B,UAAM,OAAO,MAAM,CAAC,OAAO,aAAa,QAAQ,GAAG,GAAG,SAAS,OAAO;AAEtE,aAAS,mBAAmB,KAAK,KAAK;AACtC,WAAO,wBAAwB,CAAC,UAAU;AACzC,UAAI;AACH,cAAM,OAAO,SAAS,CAAC,KAAI;AAC3B,cAAM,cAAc,WAAW,GAAG,SAAS,GAAG,KAAK,IAAI,IAAI;AAC3D,eAAO,aAAa,QAAQ,KAAK,IAAI;AAAA,MACtC,SAAS,MAAM;AAAA,MAAC;AAAA,IACjB;AAGA,WAAO,sBAAsB,MAAM;AAAA,EACpC,GAAC;"}
1
+ {"version":3,"file":"app-toggle2.js","sources":["../../designsystem/app/app-toggle.js?raw"],"sourcesContent":["export default \"if (\\n\\ttypeof window !== \\\"undefined\\\" &&\\n\\twindow.CSSStyleSheet &&\\n\\tdocument.adoptedStyleSheets\\n)\\n\\t(() => {\\n\\t\\tconst key = \\\"--mtds-app-expanded\\\";\\n\\t\\tconst sheet = new CSSStyleSheet();\\n\\t\\tconst prev = () => !window.localStorage.getItem(key)?.includes(\\\"false\\\");\\n\\n\\t\\tdocument.adoptedStyleSheets.push(sheet);\\n\\t\\twindow.mtdsToggleAppExpanded = (force) => {\\n\\t\\t\\ttry {\\n\\t\\t\\t\\tconst next = force ?? !prev();\\n\\t\\t\\t\\tsheet.replaceSync?.(`:root { ${key}: var(${key}--${next})}`);\\n\\t\\t\\t\\twindow.localStorage.setItem(key, next);\\n\\t\\t\\t} catch (_err) {} // localStorage is full or replaceSync is not supported\\n\\t\\t};\\n\\n\\t\\t// Set and store initial state\\n\\t\\twindow.mtdsToggleAppExpanded(prev());\\n\\t})();\\n\""],"names":[],"mappings":"AAAA,MAAA,SAAe;"}
package/mtds/app/app.js CHANGED
@@ -3,7 +3,7 @@ import clsx from "clsx";
3
3
  import { forwardRef } from "react";
4
4
  import { Button } from "../button/button.js";
5
5
  import styles from "../styles.module.css.js";
6
- import script from "./app-toggle.js";
6
+ import script from "./app-toggle2.js";
7
7
  const AppComp = forwardRef(function App2({ as, className, ...rest }, ref) {
8
8
  const Tag = as || "div";
9
9
  return /* @__PURE__ */ jsx(Tag, { className: clsx(styles.app, className), ref, ...rest });
@@ -26,7 +26,7 @@ class MTDSAtlasElement extends MTDSElement {
26
26
  "style",
27
27
  null,
28
28
  `@layer leaflet{${LeafletCSS}}
29
- @layer mt.v2-2-26design{${css}`
29
+ @layer mt.v2-2-28design{${css}`
30
30
  ),
31
31
  tag("figure")
32
32
  );
@@ -45,7 +45,7 @@ class MTDSAtlasElement extends MTDSElement {
45
45
  // Prevent popup fades
46
46
  layers: [tiles],
47
47
  zoomControl: false,
48
- zoomSnap: 0
48
+ zoomSnap: 0.2
49
49
  });
50
50
  on(this, "pointerup,click", this.#skipClick);
51
51
  this.map.addControl(new L.Control.Attribution({ prefix: "" }));
@@ -1 +1 @@
1
- {"version":3,"file":"atlas-element.js","sources":["../../designsystem/atlas/atlas-element.ts"],"sourcesContent":["import L from \"leaflet\";\nimport LeafletCSS from \"leaflet/dist/leaflet.css?raw\";\nimport type {} from \"leaflet.markercluster\"; // Extend L namespace\nimport \"./cluster.js\";\nimport {\n\tattr,\n\tdefineElement,\n\tisBrowser,\n\tMTDSElement,\n\toff,\n\ton,\n\ttag,\n} from \"../utils\";\nimport css from \"./atlas.css?raw\";\nexport { L };\nexport { MTDSAtlasMarkerElement } from \"./atlas-marker\";\nexport { MTDSAtlasMatgeoElement } from \"./atlas-matgeo\";\nexport { MTDSAtlasWMSElement } from \"./atlas-wms\";\n\n// TODO: Add minimum zoom level for adding markers (minimum 17 som standard?)\n// TODO: Add search helper\n// TODO: Show matgeo-loading?\n// TODO: matgeo-autoload popover info\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"mtds-atlas\": MTDSAtlasElement;\n\t}\n}\n\nlet SKIP_CLICK: number | NodeJS.Timeout = 0;\nconst KARTVERKET_MAX_ZOOM = 18; // Kartverket does not support more than zoom level 18\nconst KARTVERKET_TILES_URL =\n\t\"https://cache.kartverket.no/v1/wmts/1.0.0/topo/default/webmercator/{z}/{y}/{x}.png\";\nconst BOUNDS_NORWAY: L.LatLngBoundsLiteral = [\n\t[57.5, 4.73],\n\t[71.5, 31.44],\n];\n\nexport class MTDSAtlasElement extends MTDSElement {\n\tcluster?: L.MarkerClusterGroup;\n\tmap?: L.Map;\n\n\tstatic get observedAttributes() {\n\t\treturn [\"data-view\", \"data-scrollzoom\"]; // Using ES2015 syntax for backwards compatibility\n\t}\n\tconstructor() {\n\t\tsuper();\n\t\tthis.attachShadow({ mode: \"open\" }).append(\n\t\t\ttag(\n\t\t\t\t\"style\",\n\t\t\t\tnull,\n\t\t\t\t`@layer leaflet{${LeafletCSS}}\\n@layer mt.design{${css}`,\n\t\t\t),\n\t\t\ttag(\"figure\"),\n\t\t);\n\t}\n\tconnectedCallback() {\n\t\tconst container = this.shadowRoot?.lastElementChild as HTMLElement;\n\t\tconst cluster = attr(this, \"data-cluster\") ?? \"false\";\n\t\tconst tiles = new L.TileLayer(KARTVERKET_TILES_URL, {\n\t\t\tattribution: \"&copy; Kartverket\",\n\t\t\tclassName: \"leaflet-kartverket-tiles\",\n\t\t\tmaxZoom: KARTVERKET_MAX_ZOOM,\n\t\t});\n\n\t\tthis.map = new L.Map(container, {\n\t\t\tattributionControl: false,\n\t\t\tfadeAnimation: false, // Prevent popup fades\n\t\t\tlayers: [tiles],\n\t\t\tzoomControl: false,\n\t\t\tzoomSnap: 0,\n\t\t});\n\n\t\ton(this, \"pointerup,click\", this.#skipClick); // Prevent clicks from bubbling up unless sent from Leaflet\n\t\tthis.map.addControl(new L.Control.Attribution({ prefix: \"\" }));\n\t\tthis.map.addControl(new L.Control.Zoom({ position: \"bottomright\" }));\n\t\tthis.map.on(\"popupopen popupclose\", this.#handlePopup, this);\n\t\tthis.cluster = new L.MarkerClusterGroup({\n\t\t\tzoomToBoundsOnClick: true,\n\t\t\tshowCoverageOnHover: false,\n\t\t\tdisableClusteringAtZoom:\n\t\t\t\tcluster === \"false\" ? 1 : Number(cluster) || KARTVERKET_MAX_ZOOM + 1,\n\t\t\ticonCreateFunction: (cluster: L.MarkerCluster) =>\n\t\t\t\tnew L.DivIcon({\n\t\t\t\t\thtml: `${cluster.getChildCount()}`,\n\t\t\t\t\tclassName: \"leaflet-cluster-icon\",\n\t\t\t\t\ticonSize: [30, 30],\n\t\t\t\t}),\n\t\t}).addTo(this.map);\n\n\t\t// Initial setup attributes\n\t\tfor (const name of MTDSAtlasElement.observedAttributes)\n\t\t\tthis.attributeChangedCallback(name, null, attr(this, name));\n\t}\n\tattributeChangedCallback(name: string, _prev?: null, next?: string | null) {\n\t\tif (name === \"data-view\") this.setView(next || \"\");\n\t\tif (name === \"data-scrollzoom\")\n\t\t\tthis.map?.scrollWheelZoom[next === \"false\" ? \"disable\" : \"enable\"]();\n\t}\n\tsetView(view: string | number[], opts?: L.FitBoundsOptions) {\n\t\tconst p = `${view}`.split(\",\").map(parseFloat).filter(Number.isFinite);\n\t\tconst b = this.cluster?.getBounds();\n\n\t\tif (p.length === 3) return this.map?.setView([p[0], p[1]], p[2], opts);\n\t\tif (view !== \"fit\") return this.map?.fitBounds(BOUNDS_NORWAY, opts);\n\t\tif (b?.isValid()) return this.map?.fitBounds(b.pad(0.1), opts);\n\t\tthis.cluster?.once(\"layeradd\", () => {\n\t\t\tsetTimeout(() => this.setView(\"fit\"), 50); // Add all markers before fitting\n\t\t});\n\t}\n\tlatLngFromPoint(x: number, y: number) {\n\t\t// @ts-expect-error -- Missing from Leaflet@2.0.0-alpha.1 types\n\t\treturn this.map?.pointerEventToLatLng({ clientX: x, clientY: y });\n\t}\n\tdisconnectedCallback() {\n\t\toff(this, \"pointerup,click\", this.#skipClick);\n\t\tthis.map?.remove();\n\t\tthis.map = this.cluster = undefined;\n\t}\n\t#handlePopup({ type, popup }: { type: string; popup: L.Popup }) {\n\t\tconst open = type === \"popupopen\";\n\t\tconst cont = popup.getElement()?.querySelector(\".leaflet-popup-content\");\n\t\tconst slot = cont?.querySelector<HTMLSlotElement>(\":scope > slot\");\n\t\tconst id = cont?.textContent?.match(/^#(\\S+)/)?.[1] || \"\";\n\t\tconst el = document.getElementById(slot?.name || id); // If content of popup is #id, replace with <slot>\n\n\t\tif (!el) return open && id && popup.close(); // Close popup if target element not found\n\t\tL.Util.setOptions(popup, { maxWidth: this.offsetWidth - 40 });\n\t\tattr(el, \"data-popover\", open ? attr(el, \"popover\") : null); // Store previous popover mode\n\t\tattr(el, \"popover\", open ? null : attr(el, \"data-popover\")); // But temporarily remove it so popover renders\n\t\tattr(el, \"slot\", open ? el.id : null); // Render popover in slot\n\t\tif (open) popup.setContent(tag(\"slot\", { name: el.id }));\n\t}\n\t#skipClick(event: Partial<MouseEvent>) {\n\t\tif (event.type === \"click\") SKIP_CLICK && event.stopPropagation?.();\n\t\telse if (document.body.classList.contains(\"leaflet-dragging\"))\n\t\t\tSKIP_CLICK = setTimeout(() => {\n\t\t\t\tSKIP_CLICK = 0;\n\t\t\t}, 50); // Was dragging, so skip succeeding click\n\t}\n}\n\ndefineElement(\"mtds-atlas\", MTDSAtlasElement);\n\nif (isBrowser())\n\tL.Marker.prototype.options.icon = new L.DivIcon({\n\t\thtml: '<div class=\"leaflet-marker-generated-slot\"><div class=\"leaflet-marker-generated-icon\"></div></div>',\n\t\ticonSize: [0, 0],\n\t});\n"],"names":["cluster"],"mappings":"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"}
1
+ {"version":3,"file":"atlas-element.js","sources":["../../designsystem/atlas/atlas-element.ts"],"sourcesContent":["import L from \"leaflet\";\nimport LeafletCSS from \"leaflet/dist/leaflet.css?raw\";\nimport type {} from \"leaflet.markercluster\"; // Extend L namespace\nimport \"./cluster.js\";\nimport {\n\tattr,\n\tdefineElement,\n\tisBrowser,\n\tMTDSElement,\n\toff,\n\ton,\n\ttag,\n} from \"../utils\";\nimport css from \"./atlas.css?raw\";\nexport { L };\nexport { MTDSAtlasMarkerElement } from \"./atlas-marker\";\nexport { MTDSAtlasMatgeoElement } from \"./atlas-matgeo\";\nexport { MTDSAtlasWMSElement } from \"./atlas-wms\";\n\n// TODO: Add minimum zoom level for adding markers (minimum 17 som standard?)\n// TODO: Add search helper (https://ws.geonorge.no/adresser/v1/openapi.json + https://ws.geonorge.no/adresser/v1/#/default/get_sok)\n// TODO: matgeo-autoload popover info\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"mtds-atlas\": MTDSAtlasElement;\n\t}\n}\n\nlet SKIP_CLICK: number | NodeJS.Timeout = 0;\nconst KARTVERKET_MAX_ZOOM = 18; // Kartverket does not support more than zoom level 18\nconst KARTVERKET_TILES_URL =\n\t\"https://cache.kartverket.no/v1/wmts/1.0.0/topo/default/webmercator/{z}/{y}/{x}.png\";\nconst BOUNDS_NORWAY: L.LatLngBoundsLiteral = [\n\t[57.5, 4.73],\n\t[71.5, 31.44],\n];\n\nexport class MTDSAtlasElement extends MTDSElement {\n\tcluster?: L.MarkerClusterGroup;\n\tmap?: L.Map;\n\n\tstatic get observedAttributes() {\n\t\treturn [\"data-view\", \"data-scrollzoom\"]; // Using ES2015 syntax for backwards compatibility\n\t}\n\tconstructor() {\n\t\tsuper();\n\t\tthis.attachShadow({ mode: \"open\" }).append(\n\t\t\ttag(\n\t\t\t\t\"style\",\n\t\t\t\tnull,\n\t\t\t\t`@layer leaflet{${LeafletCSS}}\\n@layer mt.design{${css}`,\n\t\t\t),\n\t\t\ttag(\"figure\"),\n\t\t);\n\t}\n\tconnectedCallback() {\n\t\tconst container = this.shadowRoot?.lastElementChild as HTMLElement;\n\t\tconst cluster = attr(this, \"data-cluster\") ?? \"false\";\n\t\tconst tiles = new L.TileLayer(KARTVERKET_TILES_URL, {\n\t\t\tattribution: \"&copy; Kartverket\",\n\t\t\tclassName: \"leaflet-kartverket-tiles\",\n\t\t\tmaxZoom: KARTVERKET_MAX_ZOOM,\n\t\t});\n\n\t\tthis.map = new L.Map(container, {\n\t\t\tattributionControl: false,\n\t\t\tfadeAnimation: false, // Prevent popup fades\n\t\t\tlayers: [tiles],\n\t\t\tzoomControl: false,\n\t\t\tzoomSnap: 0.2,\n\t\t});\n\n\t\ton(this, \"pointerup,click\", this.#skipClick); // Prevent clicks from bubbling up unless sent from Leaflet\n\t\tthis.map.addControl(new L.Control.Attribution({ prefix: \"\" }));\n\t\tthis.map.addControl(new L.Control.Zoom({ position: \"bottomright\" }));\n\t\tthis.map.on(\"popupopen popupclose\", this.#handlePopup, this);\n\t\tthis.cluster = new L.MarkerClusterGroup({\n\t\t\tzoomToBoundsOnClick: true,\n\t\t\tshowCoverageOnHover: false,\n\t\t\tdisableClusteringAtZoom:\n\t\t\t\tcluster === \"false\" ? 1 : Number(cluster) || KARTVERKET_MAX_ZOOM + 1,\n\t\t\ticonCreateFunction: (cluster: L.MarkerCluster) =>\n\t\t\t\tnew L.DivIcon({\n\t\t\t\t\thtml: `${cluster.getChildCount()}`,\n\t\t\t\t\tclassName: \"leaflet-cluster-icon\",\n\t\t\t\t\ticonSize: [30, 30],\n\t\t\t\t}),\n\t\t}).addTo(this.map);\n\n\t\t// Initial setup attributes\n\t\tfor (const name of MTDSAtlasElement.observedAttributes)\n\t\t\tthis.attributeChangedCallback(name, null, attr(this, name));\n\t}\n\tattributeChangedCallback(name: string, _prev?: null, next?: string | null) {\n\t\tif (name === \"data-view\") this.setView(next || \"\");\n\t\tif (name === \"data-scrollzoom\")\n\t\t\tthis.map?.scrollWheelZoom[next === \"false\" ? \"disable\" : \"enable\"]();\n\t}\n\tsetView(view: string | number[], opts?: L.FitBoundsOptions) {\n\t\tconst p = `${view}`.split(\",\").map(parseFloat).filter(Number.isFinite);\n\t\tconst b = this.cluster?.getBounds();\n\n\t\tif (p.length === 3) return this.map?.setView([p[0], p[1]], p[2], opts);\n\t\tif (view !== \"fit\") return this.map?.fitBounds(BOUNDS_NORWAY, opts);\n\t\tif (b?.isValid()) return this.map?.fitBounds(b.pad(0.1), opts);\n\t\tthis.cluster?.once(\"layeradd\", () => {\n\t\t\tsetTimeout(() => this.setView(\"fit\"), 50); // Add all markers before fitting\n\t\t});\n\t}\n\tlatLngFromPoint(x: number, y: number) {\n\t\t// @ts-expect-error -- Missing from Leaflet@2.0.0-alpha.1 types\n\t\treturn this.map?.pointerEventToLatLng({ clientX: x, clientY: y });\n\t}\n\tdisconnectedCallback() {\n\t\toff(this, \"pointerup,click\", this.#skipClick);\n\t\tthis.map?.remove();\n\t\tthis.map = this.cluster = undefined;\n\t}\n\t#handlePopup({ type, popup }: { type: string; popup: L.Popup }) {\n\t\tconst open = type === \"popupopen\";\n\t\tconst cont = popup.getElement()?.querySelector(\".leaflet-popup-content\");\n\t\tconst slot = cont?.querySelector<HTMLSlotElement>(\":scope > slot\");\n\t\tconst id = cont?.textContent?.match(/^#(\\S+)/)?.[1] || \"\";\n\t\tconst el = document.getElementById(slot?.name || id); // If content of popup is #id, replace with <slot>\n\n\t\tif (!el) return open && id && popup.close(); // Close popup if target element not found\n\t\tL.Util.setOptions(popup, { maxWidth: this.offsetWidth - 40 });\n\t\tattr(el, \"data-popover\", open ? attr(el, \"popover\") : null); // Store previous popover mode\n\t\tattr(el, \"popover\", open ? null : attr(el, \"data-popover\")); // But temporarily remove it so popover renders\n\t\tattr(el, \"slot\", open ? el.id : null); // Render popover in slot\n\t\tif (open) popup.setContent(tag(\"slot\", { name: el.id }));\n\t}\n\t#skipClick(event: Partial<MouseEvent>) {\n\t\tif (event.type === \"click\") SKIP_CLICK && event.stopPropagation?.();\n\t\telse if (document.body.classList.contains(\"leaflet-dragging\"))\n\t\t\tSKIP_CLICK = setTimeout(() => {\n\t\t\t\tSKIP_CLICK = 0;\n\t\t\t}, 50); // Was dragging, so skip succeeding click\n\t}\n}\n\ndefineElement(\"mtds-atlas\", MTDSAtlasElement);\n\nif (isBrowser())\n\tL.Marker.prototype.options.icon = new L.DivIcon({\n\t\thtml: '<div class=\"leaflet-marker-generated-slot\"><div class=\"leaflet-marker-generated-icon\"></div></div>',\n\t\ticonSize: [0, 0],\n\t});\n"],"names":["cluster"],"mappings":"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"}
@@ -724,4 +724,4 @@ path.leaflet-interactive:focus:not(:focus-visible) {
724
724
  .leaflet-popup:has(slot) .leaflet-popup-content-wrapper { display: contents } /* No need for styling this element */
725
725
  .leaflet-popup:has(slot) .leaflet-popup-content { margin: 0; font: inherit }
726
726
  `;let on=0;class rn extends ue{atlas;marker;static get observedAttributes(){return["hidden","draggable","data-latlng","popovertarget"]}connectedCallback(){queueMicrotask(()=>{const t=ce("slot",{name:`${++on}`}),e=new _.DivIcon({html:t,iconSize:[0,0]});this.atlas=this.closest("mtds-atlas")||void 0,this.marker=new _.Marker(this.#t(),{draggable:this.draggable,keyboard:!1,icon:e}),this.marker.bindPopup(()=>`#${Z(this,"popovertarget")}`),this.marker.on("dragend",this.#e),sn(this,"click,keydown",this),Z(this,"slot",`${on}`),Z(this,"role","button"),Z(this,"tabindex","0"),this.attributeChangedCallback("hidden")})}attributeChangedCallback(t){const e=this.marker,i=this.atlas?.cluster;if(t==="popovertarget"&&e?.getPopup()?.update(),t==="data-latlng"){const s=this.#t();e?.getLatLng().equals(s)||e?.setLatLng(s)}t==="draggable"&&e?.dragging?.[this.draggable?"enable":"disable"](),t==="hidden"&&e&&i&&i[this.hidden?"removeLayer":"addLayer"](e)}disconnectedCallback(){Ke(this,"click,keydown",this),this.marker?.unbindPopup().off("dragend",this.#e).remove(),this.marker=this.atlas=void 0}handleEvent(t){if(t.type==="click")return this.marker?.fire("click");t.key===" "&&t.preventDefault(),(t.key===" "||t.key==="Enter")&&this.click()}get latlng(){return Z(this,"data-latlng")||""}set latlng(t){Z(this,"data-latlng",t)}#t(){return this.latlng?.split(",").map(parseFloat)}#e(t){const i=t.target._icon?.firstElementChild?.assignedElements?.()?.[0],{lat:s,lng:o}=t.target.getLatLng();i&&(i.latlng=`${s},${o}`),i?.dispatchEvent(new CustomEvent("dragend",{detail:t,bubbles:!0}))}}pe("mtds-atlas-marker",rn);const lt=11102230246251565e-32,R=134217729,es=(3+8*lt)*lt;function Ye(n,t,e,i,s){let o,r,a,l,h=t[0],d=i[0],c=0,u=0;d>h==d>-h?(o=h,h=t[++c]):(o=d,d=i[++u]);let p=0;if(c<n&&u<e)for(d>h==d>-h?(r=h+o,a=o-(r-h),h=t[++c]):(r=d+o,a=o-(r-d),d=i[++u]),o=r,a!==0&&(s[p++]=a);c<n&&u<e;)d>h==d>-h?(r=o+h,l=r-o,a=o-(r-l)+(h-l),h=t[++c]):(r=o+d,l=r-o,a=o-(r-l)+(d-l),d=i[++u]),o=r,a!==0&&(s[p++]=a);for(;c<n;)r=o+h,l=r-o,a=o-(r-l)+(h-l),h=t[++c],o=r,a!==0&&(s[p++]=a);for(;u<e;)r=o+d,l=r-o,a=o-(r-l)+(d-l),d=i[++u],o=r,a!==0&&(s[p++]=a);return(o!==0||p===0)&&(s[p++]=o),p}function is(n,t){let e=t[0];for(let i=1;i<n;i++)e+=t[i];return e}function Wt(n){return new Float64Array(n)}const ns=(3+16*lt)*lt,ss=(2+12*lt)*lt,os=(9+64*lt)*lt*lt,Mt=Wt(4),an=Wt(8),ln=Wt(12),hn=Wt(16),j=Wt(4);function rs(n,t,e,i,s,o,r){let a,l,h,d,c,u,p,y,g,w,v,M,B,O,I,E,$,A;const T=n-s,N=e-s,U=t-o,q=i-o;O=T*q,u=R*T,p=u-(u-T),y=T-p,u=R*q,g=u-(u-q),w=q-g,I=y*w-(O-p*g-y*g-p*w),E=U*N,u=R*U,p=u-(u-U),y=U-p,u=R*N,g=u-(u-N),w=N-g,$=y*w-(E-p*g-y*g-p*w),v=I-$,c=I-v,Mt[0]=I-(v+c)+(c-$),M=O+v,c=M-O,B=O-(M-c)+(v-c),v=B-E,c=B-v,Mt[1]=B-(v+c)+(c-E),A=M+v,c=A-M,Mt[2]=M-(A-c)+(v-c),Mt[3]=A;let Q=is(4,Mt),ht=ss*r;if(Q>=ht||-Q>=ht||(c=n-T,a=n-(T+c)+(c-s),c=e-N,h=e-(N+c)+(c-s),c=t-U,l=t-(U+c)+(c-o),c=i-q,d=i-(q+c)+(c-o),a===0&&l===0&&h===0&&d===0)||(ht=os*r+es*Math.abs(Q),Q+=T*d+q*a-(U*h+N*l),Q>=ht||-Q>=ht))return Q;O=a*q,u=R*a,p=u-(u-a),y=a-p,u=R*q,g=u-(u-q),w=q-g,I=y*w-(O-p*g-y*g-p*w),E=l*N,u=R*l,p=u-(u-l),y=l-p,u=R*N,g=u-(u-N),w=N-g,$=y*w-(E-p*g-y*g-p*w),v=I-$,c=I-v,j[0]=I-(v+c)+(c-$),M=O+v,c=M-O,B=O-(M-c)+(v-c),v=B-E,c=B-v,j[1]=B-(v+c)+(c-E),A=M+v,c=A-M,j[2]=M-(A-c)+(v-c),j[3]=A;const me=Ye(4,Mt,4,j,an);O=T*d,u=R*T,p=u-(u-T),y=T-p,u=R*d,g=u-(u-d),w=d-g,I=y*w-(O-p*g-y*g-p*w),E=U*h,u=R*U,p=u-(u-U),y=U-p,u=R*h,g=u-(u-h),w=h-g,$=y*w-(E-p*g-y*g-p*w),v=I-$,c=I-v,j[0]=I-(v+c)+(c-$),M=O+v,c=M-O,B=O-(M-c)+(v-c),v=B-E,c=B-v,j[1]=B-(v+c)+(c-E),A=M+v,c=A-M,j[2]=M-(A-c)+(v-c),j[3]=A;const mn=Ye(me,an,4,j,ln);O=a*d,u=R*a,p=u-(u-a),y=a-p,u=R*d,g=u-(u-d),w=d-g,I=y*w-(O-p*g-y*g-p*w),E=l*h,u=R*l,p=u-(u-l),y=l-p,u=R*h,g=u-(u-h),w=h-g,$=y*w-(E-p*g-y*g-p*w),v=I-$,c=I-v,j[0]=I-(v+c)+(c-$),M=O+v,c=M-O,B=O-(M-c)+(v-c),v=B-E,c=B-v,j[1]=B-(v+c)+(c-E),A=M+v,c=A-M,j[2]=M-(A-c)+(v-c),j[3]=A;const gs=Ye(mn,ln,4,j,hn);return hn[gs-1]}function as(n,t,e,i,s,o){const r=(t-o)*(e-s),a=(n-s)*(i-o),l=r-a,h=Math.abs(r+a);return Math.abs(l)>=ns*h?l:-rs(n,t,e,i,s,o,h)}function ls(n,t){var e,i,s=0,o,r,a,l,h,d,c,u=n[0],p=n[1],y=t.length;for(e=0;e<y;e++){i=0;var g=t[e],w=g.length-1;if(d=g[0],d[0]!==g[w][0]&&d[1]!==g[w][1])throw new Error("First and last coordinates in a ring must be the same");for(r=d[0]-u,a=d[1]-p,i;i<w;i++){if(c=g[i+1],l=c[0]-u,h=c[1]-p,a===0&&h===0){if(l<=0&&r>=0||r<=0&&l>=0)return 0}else if(h>=0&&a<=0||h<=0&&a>=0){if(o=as(r,l,a,h,0,0),o===0)return 0;(o>0&&h>0&&a<=0||o<0&&h<=0&&a>0)&&s++}d=c,a=h,r=l}}return s%2!==0}function hs(n,t,e={}){const i={type:"Feature"};return(e.id===0||e.id)&&(i.id=e.id),e.bbox&&(i.bbox=e.bbox),i.properties={},i.geometry=n,i}function ds(n,t,e={}){if(!n)throw new Error("coordinates is required");if(!Array.isArray(n))throw new Error("coordinates must be an Array");if(n.length<2)throw new Error("coordinates must be at least 2 numbers long");if(!dn(n[0])||!dn(n[1]))throw new Error("coordinates must contain numbers");return hs({type:"Point",coordinates:n},t,e)}function dn(n){return!isNaN(n)&&n!==null&&!Array.isArray(n)}function cs(n){if(!n)throw new Error("coord is required");if(!Array.isArray(n)){if(n.type==="Feature"&&n.geometry!==null&&n.geometry.type==="Point")return[...n.geometry.coordinates];if(n.type==="Point")return[...n.coordinates]}if(Array.isArray(n)&&n.length>=2&&!Array.isArray(n[0])&&!Array.isArray(n[1]))return[...n];throw new Error("coord must be GeoJSON Point or an Array of numbers")}function us(n){return n.type==="Feature"?n.geometry:n}function ps(n,t,e={}){if(!n)throw new Error("point is required");if(!t)throw new Error("polygon is required");const i=cs(n),s=us(t),o=s.type,r=t.bbox;let a=s.coordinates;if(r&&_s(i,r)===!1)return!1;o==="Polygon"&&(a=[a]);let l=!1;for(var h=0;h<a.length;++h){const d=ls(i,a[h]);if(d===0)return!e.ignoreBoundary;d&&(l=!0)}return l}function _s(n,t){return t[0]<=n[0]&&t[1]<=n[1]&&t[2]>=n[0]&&t[3]>=n[1]}const cn="moveend zoomend refresh",un="https://matgeoservice-256616427209.europe-north1.run.app/ogc/features/collections";Ve()&&!window._matgeoCollections&&(window._matgeoCollections=fetch(un).then(n=>n.json()).then(n=>new Map(n.collections?.map(t=>[t.id,t]))));class pn extends ue{atlas;geojson;static get observedAttributes(){return["hidden","data-collection","data-color","popovertarget"]}constructor(){super(),this.refresh=Qn(this.refresh,300)}connectedCallback(){queueMicrotask(()=>{this.atlas=this.closest("mtds-atlas")||void 0,this.atlas?.map?.on(cn,this.refresh,this),this.geojson=new _.GeoJSON(null,{style:this.#t(),onEachFeature:(t,e)=>e.on("click",this.handleEvent,this)}).bindPopup(()=>`#${Z(this,"popovertarget")}`),this.refresh(),this.attributeChangedCallback("hidden")})}attributeChangedCallback(t){const e=this.geojson,i=this.atlas?.map;t==="popovertarget"&&e?.getPopup()?.update(),t==="data-color"&&e?.setStyle(this.#t()),t==="data-collection"&&this.refresh(),t==="hidden"&&e&&i&&i[this.hidden?"removeLayer":"addLayer"](e)}disconnectedCallback(){this.atlas?.map?.off(cn,this.refresh,this),this.geojson?.unbindPopup().remove(),this.geojson=this.atlas=void 0}refresh(t){!this.geojson||!this.atlas?.map?.hasLayer(this.geojson)||Xe().then(e=>{const i=Z(this,"data-collection")||"",s=t===!0?`&nocache=${Date.now()}`:"",o=this.atlas?.map?.getBounds().toBBoxString();e.has(i)?fetch(`${un}/${i}/items?bbox=${o}${s}`).then(r=>r.json()).then(r=>this.geojson?.clearLayers().addData(r)):console.warn(`mtds-atlas-matgeo: Please set a vaild \x1B[103mdata-collection="${Array.from(e.keys()).join(" | ")}"\x1B[m`)})}handleEvent(t){t.originalEvent.stopPropagation(),Xe().then(e=>{const i=[t.target],s={...t,targets:i,collections:e},o=ds([t.latlng.lng,t.latlng.lat]);this.atlas?.map?.eachLayer(r=>{if(r===t.target)return;(r.feature?.geometry&&ps(o,r.feature.geometry)||r instanceof _.Marker&&r.getLatLng().equals(t.latlng))&&i.push(r)}),this.dispatchEvent(new MouseEvent("click",t.originalEvent)),this.dispatchEvent(new CustomEvent("atlasfeatureclick",{detail:s,bubbles:!0}))})}async getCollection(){const t=Z(this,"data-collection")||"";return Xe().then(e=>e.get(t))}#t(){return{color:`var(--mtds-color-${Z(this,"data-color")||"main"}-base-default)`}}}pe("mtds-atlas-matgeo",pn);function Xe(){return window._matgeoCollections||Promise.resolve(new Map)}class _n extends ue{atlas;wms;static get observedAttributes(){return["hidden","data-url","popovertarget"]}connectedCallback(){queueMicrotask(()=>{this.atlas=this.closest("mtds-atlas")||void 0,this.refresh()})}attributeChangedCallback(t){t==="data-url"&&this.refresh(),t==="popovertarget"&&this.wms?.getPopup()?.update(),t==="hidden"&&this.wms&&(this.atlas?.map?.[this.hidden?"removeLayer":"addLayer"](this.wms),this.wms.bringToFront())}refresh(){const t=new URL(Z(this,"data-url")||""),e=Object.fromEntries(t.searchParams.entries());this.wms?.unbindPopup().remove(),this.wms=new _.TileLayer.WMS(`${t.origin}${t.pathname}`,e),this.attributeChangedCallback("hidden")}disconnectedCallback(){this.wms?.unbindPopup().remove(),this.wms=this.atlas=void 0}}pe("mtds-atlas-wms",_n);let Je=0;const fn=18,fs="https://cache.kartverket.no/v1/wmts/1.0.0/topo/default/webmercator/{z}/{y}/{x}.png",ms=[[57.5,4.73],[71.5,31.44]];class _e extends ue{cluster;map;static get observedAttributes(){return["data-view","data-scrollzoom"]}constructor(){super(),this.attachShadow({mode:"open"}).append(ce("style",null,`@layer leaflet{${Xn}}
727
- @layer mt.design{${ts}`),ce("figure"))}connectedCallback(){const t=this.shadowRoot?.lastElementChild,e=Z(this,"data-cluster")??"false",i=new _.TileLayer(fs,{attribution:"&copy; Kartverket",className:"leaflet-kartverket-tiles",maxZoom:fn});this.map=new _.Map(t,{attributionControl:!1,fadeAnimation:!1,layers:[i],zoomControl:!1,zoomSnap:0}),sn(this,"pointerup,click",this.#e),this.map.addControl(new _.Control.Attribution({prefix:""})),this.map.addControl(new _.Control.Zoom({position:"bottomright"})),this.map.on("popupopen popupclose",this.#t,this),this.cluster=new _.MarkerClusterGroup({zoomToBoundsOnClick:!0,showCoverageOnHover:!1,disableClusteringAtZoom:e==="false"?1:Number(e)||fn+1,iconCreateFunction:s=>new _.DivIcon({html:`${s.getChildCount()}`,className:"leaflet-cluster-icon",iconSize:[30,30]})}).addTo(this.map);for(const s of _e.observedAttributes)this.attributeChangedCallback(s,null,Z(this,s))}attributeChangedCallback(t,e,i){t==="data-view"&&this.setView(i||""),t==="data-scrollzoom"&&this.map?.scrollWheelZoom[i==="false"?"disable":"enable"]()}setView(t,e){const i=`${t}`.split(",").map(parseFloat).filter(Number.isFinite),s=this.cluster?.getBounds();if(i.length===3)return this.map?.setView([i[0],i[1]],i[2],e);if(t!=="fit")return this.map?.fitBounds(ms,e);if(s?.isValid())return this.map?.fitBounds(s.pad(.1),e);this.cluster?.once("layeradd",()=>{setTimeout(()=>this.setView("fit"),50)})}latLngFromPoint(t,e){return this.map?.pointerEventToLatLng({clientX:t,clientY:e})}disconnectedCallback(){Ke(this,"pointerup,click",this.#e),this.map?.remove(),this.map=this.cluster=void 0}#t({type:t,popup:e}){const i=t==="popupopen",s=e.getElement()?.querySelector(".leaflet-popup-content"),o=s?.querySelector(":scope > slot"),r=s?.textContent?.match(/^#(\S+)/)?.[1]||"",a=document.getElementById(o?.name||r);if(!a)return i&&r&&e.close();_.Util.setOptions(e,{maxWidth:this.offsetWidth-40}),Z(a,"data-popover",i?Z(a,"popover"):null),Z(a,"popover",i?null:Z(a,"data-popover")),Z(a,"slot",i?a.id:null),i&&e.setContent(ce("slot",{name:a.id}))}#e(t){t.type==="click"?Je&&t.stopPropagation?.():document.body.classList.contains("leaflet-dragging")&&(Je=setTimeout(()=>{Je=0},50))}}return pe("mtds-atlas",_e),Ve()&&(_.Marker.prototype.options.icon=new _.DivIcon({html:'<div class="leaflet-marker-generated-slot"><div class="leaflet-marker-generated-icon"></div></div>',iconSize:[0,0]})),G.L=_,G.MTDSAtlasElement=_e,G.MTDSAtlasMarkerElement=rn,G.MTDSAtlasMatgeoElement=pn,G.MTDSAtlasWMSElement=_n,Object.defineProperty(G,Symbol.toStringTag,{value:"Module"}),G}({});
727
+ @layer mt.design{${ts}`),ce("figure"))}connectedCallback(){const t=this.shadowRoot?.lastElementChild,e=Z(this,"data-cluster")??"false",i=new _.TileLayer(fs,{attribution:"&copy; Kartverket",className:"leaflet-kartverket-tiles",maxZoom:fn});this.map=new _.Map(t,{attributionControl:!1,fadeAnimation:!1,layers:[i],zoomControl:!1,zoomSnap:.2}),sn(this,"pointerup,click",this.#e),this.map.addControl(new _.Control.Attribution({prefix:""})),this.map.addControl(new _.Control.Zoom({position:"bottomright"})),this.map.on("popupopen popupclose",this.#t,this),this.cluster=new _.MarkerClusterGroup({zoomToBoundsOnClick:!0,showCoverageOnHover:!1,disableClusteringAtZoom:e==="false"?1:Number(e)||fn+1,iconCreateFunction:s=>new _.DivIcon({html:`${s.getChildCount()}`,className:"leaflet-cluster-icon",iconSize:[30,30]})}).addTo(this.map);for(const s of _e.observedAttributes)this.attributeChangedCallback(s,null,Z(this,s))}attributeChangedCallback(t,e,i){t==="data-view"&&this.setView(i||""),t==="data-scrollzoom"&&this.map?.scrollWheelZoom[i==="false"?"disable":"enable"]()}setView(t,e){const i=`${t}`.split(",").map(parseFloat).filter(Number.isFinite),s=this.cluster?.getBounds();if(i.length===3)return this.map?.setView([i[0],i[1]],i[2],e);if(t!=="fit")return this.map?.fitBounds(ms,e);if(s?.isValid())return this.map?.fitBounds(s.pad(.1),e);this.cluster?.once("layeradd",()=>{setTimeout(()=>this.setView("fit"),50)})}latLngFromPoint(t,e){return this.map?.pointerEventToLatLng({clientX:t,clientY:e})}disconnectedCallback(){Ke(this,"pointerup,click",this.#e),this.map?.remove(),this.map=this.cluster=void 0}#t({type:t,popup:e}){const i=t==="popupopen",s=e.getElement()?.querySelector(".leaflet-popup-content"),o=s?.querySelector(":scope > slot"),r=s?.textContent?.match(/^#(\S+)/)?.[1]||"",a=document.getElementById(o?.name||r);if(!a)return i&&r&&e.close();_.Util.setOptions(e,{maxWidth:this.offsetWidth-40}),Z(a,"data-popover",i?Z(a,"popover"):null),Z(a,"popover",i?null:Z(a,"data-popover")),Z(a,"slot",i?a.id:null),i&&e.setContent(ce("slot",{name:a.id}))}#e(t){t.type==="click"?Je&&t.stopPropagation?.():document.body.classList.contains("leaflet-dragging")&&(Je=setTimeout(()=>{Je=0},50))}}return pe("mtds-atlas",_e),Ve()&&(_.Marker.prototype.options.icon=new _.DivIcon({html:'<div class="leaflet-marker-generated-slot"><div class="leaflet-marker-generated-icon"></div></div>',iconSize:[0,0]})),G.L=_,G.MTDSAtlasElement=_e,G.MTDSAtlasMarkerElement=rn,G.MTDSAtlasMatgeoElement=pn,G.MTDSAtlasWMSElement=_n,Object.defineProperty(G,Symbol.toStringTag,{value:"Module"}),G}({});
@@ -1,4 +1,5 @@
1
1
  import { JSX } from 'react';
2
+ import { FlexProps } from '../react';
2
3
  import { PolymorphicComponentPropWithRef } from '../react-types';
3
4
  type ButtonBaseProps<Href> = {
4
5
  "data-arrow"?: "left" | "right" | true;
@@ -6,6 +7,7 @@ type ButtonBaseProps<Href> = {
6
7
  "data-nowrap"?: boolean;
7
8
  "data-variant"?: "primary" | "secondary" | "tertiary";
8
9
  "data-command"?: string;
10
+ "data-self"?: FlexProps["data-items"];
9
11
  href?: Href;
10
12
  popovertarget?: string;
11
13
  popovertargetaction?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","sources":["../../designsystem/button/button.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { forwardRef, type JSX } from \"react\";\nimport type {\n\tPolymorphicComponentPropWithRef,\n\tPolymorphicRef,\n} from \"../react-types\";\nimport styles from \"../styles.module.css\";\n\ntype ButtonBaseProps<Href> = {\n\t\"data-arrow\"?: \"left\" | \"right\" | true;\n\t\"data-justify\"?: \"start\" | \"center\" | \"end\" | \"right\" | \"left\";\n\t\"data-nowrap\"?: boolean;\n\t\"data-variant\"?: \"primary\" | \"secondary\" | \"tertiary\";\n\t\"data-command\"?: string;\n\thref?: Href;\n\tpopovertarget?: string;\n\tpopovertargetaction?: string;\n};\n\nexport type ButtonProps<\n\tHref,\n\tAs extends React.ElementType = Href extends string ? \"a\" : \"button\",\n> = PolymorphicComponentPropWithRef<As, ButtonBaseProps<Href>>;\n\ntype ButtonElement = ButtonProps<null, \"button\">;\ntype ButtonComponent = <\n\tHref,\n\tAs extends React.ElementType = Href extends string ? \"a\" : \"button\",\n>(\n\tprops: ButtonProps<Href, As>,\n) => JSX.Element;\n\nexport const Button: ButtonComponent = forwardRef<null>(function Button<\n\tHref,\n\tAs extends React.ElementType = Href extends string ? \"a\" : \"button\",\n>(\n\t{ as, className, type, ...rest }: ButtonProps<Href, As>,\n\tref?: PolymorphicRef<As>,\n) {\n\tconst Tag = as || (rest.href ? \"a\" : \"button\");\n\n\tif (Tag === \"button\" && (rest as ButtonElement)[\"aria-busy\"])\n\t\t(rest as ButtonElement).disabled = true; // Automatically disable button if aria-busy is set\n\n\treturn (\n\t\t<Tag\n\t\t\tsuppressHydrationWarning // aria-label might change on client when using data-tooltip\n\t\t\tclassName={clsx(styles.button, className)}\n\t\t\ttype={type ?? (Tag === \"button\" ? Tag : undefined)} // Default to type=\"button\" if not set and tag is button\n\t\t\tref={ref}\n\t\t\t{...rest}\n\t\t/>\n\t);\n}) as ButtonComponent; // Needed to tell Typescript this does not return ReactNode but acutally JSX.Element\n"],"names":["Button"],"mappings":";;;;AAgCO,MAAM,SAA0B,WAAiB,SAASA,QAIhE,EAAE,IAAI,WAAW,MAAM,GAAG,KAAA,GAC1B,KACC;AACD,QAAM,MAAM,OAAO,KAAK,OAAO,MAAM;AAErC,MAAI,QAAQ,YAAa,KAAuB,WAAW;AACzD,SAAuB,WAAW;AAEpC,SACC;AAAA,IAAC;AAAA,IAAA;AAAA,MACA,0BAAwB;AAAA,MACxB,WAAW,KAAK,OAAO,QAAQ,SAAS;AAAA,MACxC,MAAM,SAAS,QAAQ,WAAW,MAAM;AAAA,MACxC;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,EAAA;AAGP,CAAC;"}
1
+ {"version":3,"file":"button.js","sources":["../../designsystem/button/button.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { forwardRef, type JSX } from \"react\";\nimport type { FlexProps } from \"../react\";\nimport type {\n\tPolymorphicComponentPropWithRef,\n\tPolymorphicRef,\n} from \"../react-types\";\nimport styles from \"../styles.module.css\";\n\ntype ButtonBaseProps<Href> = {\n\t\"data-arrow\"?: \"left\" | \"right\" | true;\n\t\"data-justify\"?: \"start\" | \"center\" | \"end\" | \"right\" | \"left\";\n\t\"data-nowrap\"?: boolean;\n\t\"data-variant\"?: \"primary\" | \"secondary\" | \"tertiary\";\n\t\"data-command\"?: string;\n\t\"data-self\"?: FlexProps[\"data-items\"];\n\thref?: Href;\n\tpopovertarget?: string;\n\tpopovertargetaction?: string;\n};\n\nexport type ButtonProps<\n\tHref,\n\tAs extends React.ElementType = Href extends string ? \"a\" : \"button\",\n> = PolymorphicComponentPropWithRef<As, ButtonBaseProps<Href>>;\n\ntype ButtonElement = ButtonProps<null, \"button\">;\ntype ButtonComponent = <\n\tHref,\n\tAs extends React.ElementType = Href extends string ? \"a\" : \"button\",\n>(\n\tprops: ButtonProps<Href, As>,\n) => JSX.Element;\n\nexport const Button: ButtonComponent = forwardRef<null>(function Button<\n\tHref,\n\tAs extends React.ElementType = Href extends string ? \"a\" : \"button\",\n>(\n\t{ as, className, type, ...rest }: ButtonProps<Href, As>,\n\tref?: PolymorphicRef<As>,\n) {\n\tconst Tag = as || (rest.href ? \"a\" : \"button\");\n\n\tif (Tag === \"button\" && (rest as ButtonElement)[\"aria-busy\"])\n\t\t(rest as ButtonElement).disabled = true; // Automatically disable button if aria-busy is set\n\n\treturn (\n\t\t<Tag\n\t\t\tsuppressHydrationWarning // aria-label might change on client when using data-tooltip\n\t\t\tclassName={clsx(styles.button, className)}\n\t\t\ttype={type ?? (Tag === \"button\" ? Tag : undefined)} // Default to type=\"button\" if not set and tag is button\n\t\t\tref={ref}\n\t\t\t{...rest}\n\t\t/>\n\t);\n}) as ButtonComponent; // Needed to tell Typescript this does not return ReactNode but acutally JSX.Element\n"],"names":["Button"],"mappings":";;;;AAkCO,MAAM,SAA0B,WAAiB,SAASA,QAIhE,EAAE,IAAI,WAAW,MAAM,GAAG,KAAA,GAC1B,KACC;AACD,QAAM,MAAM,OAAO,KAAK,OAAO,MAAM;AAErC,MAAI,QAAQ,YAAa,KAAuB,WAAW;AACzD,SAAuB,WAAW;AAEpC,SACC;AAAA,IAAC;AAAA,IAAA;AAAA,MACA,0BAAwB;AAAA,MACxB,WAAW,KAAK,OAAO,QAAQ,SAAS;AAAA,MACxC,MAAM,SAAS,QAAQ,WAAW,MAAM;AAAA,MACxC;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,EAAA;AAGP,CAAC;"}
@@ -17,6 +17,7 @@ export declare const Pressed: Story;
17
17
  export declare const WithArrows: Story;
18
18
  export declare const WithIcons: Story;
19
19
  export declare const WithSpinner: Story;
20
+ export declare const WithFullWidth: Story;
20
21
  export declare const WithMenu: Story;
21
22
  export declare const WithTooltip: Story;
22
23
  export declare const InMenu: Story;
@@ -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.pageX}px, ${event.pageY}px)`;
90
+ TOOLTIP.style.transform = `translate(${event.clientX}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.pageX}px, ${event.pageY}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(${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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"}
@@ -12,7 +12,6 @@ function handleFieldMutation(validate) {
12
12
  if (field.isConnected) {
13
13
  const labels = [];
14
14
  const descriptions = [];
15
- const validationMsg = [];
16
15
  let combobox = null;
17
16
  let input = null;
18
17
  let valid = true;
@@ -23,19 +22,22 @@ function handleFieldMutation(validate) {
23
22
  else if (el.hasAttribute("data-description")) descriptions.push(el);
24
23
  else if (el.classList.contains(CSS_VALIDATION)) {
25
24
  valid = attr(el, "data-color") === "success" || !el.clientHeight;
26
- validationMsg.push(el);
27
25
  descriptions.unshift(el);
28
26
  } else if (el instanceof HTMLParagraphElement)
29
27
  descriptions.some((desc) => desc.contains(el)) || descriptions.push(el);
30
28
  }
31
29
  if (input) {
32
30
  const comboboxInput = combobox?.control;
33
- const shouldValidate = validate || comboboxInput?.validity.customError;
34
- if (shouldValidate && attr(field, "data-validation") === "form") {
31
+ const validateEl = (validate || comboboxInput?.validity.customError) && // Live re-evaluate combobox if invalid to correct validity before form sumbit
32
+ input.closest('[data-validation="form"]');
33
+ if (validateEl) {
35
34
  valid = comboboxInput?.getAttribute("aria-required") === "true" ? !!combobox?.items.length : input.validity.valid;
36
35
  if (!firstInvalid && !valid) firstInvalid = input;
37
- for (const el of validationMsg) attr(el, "hidden", valid ? "" : null);
38
36
  comboboxInput?.setCustomValidity(valid ? "" : "Invalid");
37
+ const validateElValid = !validateEl.querySelector(":invalid");
38
+ validateEl.querySelectorAll(`:scope > .${CSS_VALIDATION}`).forEach((el) => {
39
+ attr(el, "hidden", validateElValid ? "" : null);
40
+ });
39
41
  }
40
42
  for (const label of labels) label.htmlFor = useId(input);
41
43
  renderCombobox(combobox);
@@ -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(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 validateEl =\n\t\t\t\t\t(validate || comboboxInput?.validity.customError) && // Live re-evaluate combobox if invalid to correct validity before form sumbit\n\t\t\t\t\tinput.closest('[data-validation=\"form\"]');\n\n\t\t\t\tif (validateEl) {\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; // If checkbox, only one needs to be vaild when same name\n\n\t\t\t\t\tif (!firstInvalid && !valid) firstInvalid = input;\n\t\t\t\t\tcomboboxInput?.setCustomValidity(valid ? \"\" : \"Invalid\"); // Combobox does not have native validation\n\t\t\t\t\tconst validateElValid = !validateEl.querySelector(\":invalid\"); // Check if any invalid inputs inside field or fieldset\n\t\t\t\t\tvalidateEl\n\t\t\t\t\t\t.querySelectorAll(`:scope > .${CSS_VALIDATION}`)\n\t\t\t\t\t\t.forEach((el) => {\n\t\t\t\t\t\t\tattr(el, \"hidden\", validateElValid ? \"\" : null);\n\t\t\t\t\t\t});\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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"}
@@ -45,6 +45,10 @@ export type FieldComboboxProps = Omit<ReactUcombobox, "onChange" | "onInput"> &
45
45
  } & Pick<InputProps, "disabled" | "name" | "onChange" | "onInput" | "placeholder" | "readOnly" | "type" | "value"> & // Allow input props to be passed down
46
46
  Pick<FieldDatalistProps, "data-position" | "data-nofilter">;
47
47
  export type FieldLabelProps = React.ComponentPropsWithoutRef<"label">;
48
+ export type FieldDescriptionProps = React.ComponentPropsWithoutRef<"p">;
49
+ export type FieldCountProps = React.ComponentPropsWithoutRef<"p"> & {
50
+ "data-count": number;
51
+ };
48
52
  export declare const Field: FieldComponent & {
49
53
  Affixes: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
50
54
  Combobox: import('react').ForwardRefExoticComponent<Omit<FieldComboboxProps, "ref"> & import('react').RefAttributes<UHTMLComboboxElement>>;
@@ -53,6 +57,10 @@ export declare const Field: FieldComponent & {
53
57
  "data-position"?: Placement;
54
58
  } & import('react').RefAttributes<HTMLDataListElement>>;
55
59
  Option: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').OptionHTMLAttributes<HTMLOptionElement>, HTMLOptionElement>, "ref"> & import('react').RefAttributes<HTMLOptionElement>>;
60
+ Description: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import('react').RefAttributes<HTMLParagraphElement>>;
56
61
  Label: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "ref"> & import('react').RefAttributes<HTMLLabelElement>>;
62
+ Count: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & {
63
+ "data-count": number;
64
+ } & import('react').RefAttributes<HTMLParagraphElement>>;
57
65
  };
58
66
  export {};
@@ -41,9 +41,9 @@ const FieldComp = forwardRef(function Field2({
41
41
  children: /* @__PURE__ */ jsx(Fragment, { children: rest.options?.map(toOption).map(({ label: label2, value }) => /* @__PURE__ */ jsx("option", { value, children: label2 }, value)) })
42
42
  });
43
43
  return as ? /* @__PURE__ */ jsxs("div", { ...shared, children: [
44
- !!label && /* @__PURE__ */ jsx("label", { suppressHydrationWarning: true, children: label }),
44
+ !!label && /* @__PURE__ */ jsx(FieldLabel, { children: label }),
45
45
  !!helpText && /* @__PURE__ */ jsx(HelpText, { "aria-label": helpTextLabel, children: helpText }),
46
- !!description && /* @__PURE__ */ jsx("p", { suppressHydrationWarning: true, children: description }),
46
+ !!description && /* @__PURE__ */ jsx(FieldDescription, { children: description }),
47
47
  affixes ? /* @__PURE__ */ jsxs(FieldAffixes, { children: [
48
48
  !!prefix && /* @__PURE__ */ jsx("span", { children: prefix }),
49
49
  /* @__PURE__ */ jsx(
@@ -66,7 +66,7 @@ const FieldComp = forwardRef(function Field2({
66
66
  }
67
67
  ),
68
68
  !!validation && /* @__PURE__ */ jsx(Validation, { hidden: validationType === "form", children: validation }),
69
- !!count && /* @__PURE__ */ jsx("p", { suppressHydrationWarning: true, "data-count": count })
69
+ !!count && /* @__PURE__ */ jsx(FieldCount, { "data-count": count })
70
70
  ] }) : /* @__PURE__ */ jsx("div", { ref, ...shared, ...rest });
71
71
  });
72
72
  const FieldAffixes = forwardRef(
@@ -182,16 +182,27 @@ const FieldCombobox = forwardRef(
182
182
  );
183
183
  }
184
184
  );
185
+ const FieldLabel = forwardRef(
186
+ function FieldLabel2(rest, ref) {
187
+ return /* @__PURE__ */ jsx("label", { suppressHydrationWarning: true, ref, ...rest });
188
+ }
189
+ );
190
+ const FieldDescription = forwardRef(function FieldDescription2(rest, ref) {
191
+ return /* @__PURE__ */ jsx("p", { suppressHydrationWarning: true, ref, ...rest });
192
+ });
193
+ const FieldCount = forwardRef(
194
+ function FieldCount2(rest, ref) {
195
+ return /* @__PURE__ */ jsx("p", { suppressHydrationWarning: true, ref, ...rest });
196
+ }
197
+ );
185
198
  const Field = Object.assign(FieldComp, {
186
199
  Affixes: FieldAffixes,
187
200
  Combobox: FieldCombobox,
188
201
  Datalist: FieldDatalist,
189
202
  Option: FieldOption,
190
- Label: forwardRef(
191
- function FieldLabel(rest, ref) {
192
- return /* @__PURE__ */ jsx("label", { suppressHydrationWarning: true, ref, ...rest });
193
- }
194
- )
203
+ Description: FieldDescription,
204
+ Label: FieldLabel,
205
+ Count: FieldCount
195
206
  });
196
207
  export {
197
208
  Field,
@@ -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 && <label suppressHydrationWarning>{label}</label>}\n\t\t\t{!!helpText && <HelpText aria-label={helpTextLabel}>{helpText}</HelpText>}\n\t\t\t{!!description && <p suppressHydrationWarning>{description}</p>}\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 && <p suppressHydrationWarning 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\">;\nexport const Field = Object.assign(FieldComp, {\n\tAffixes: FieldAffixes,\n\tCombobox: FieldCombobox,\n\tDatalist: FieldDatalist,\n\tOption: FieldOption,\n\tLabel: forwardRef<HTMLLabelElement, FieldLabelProps>(\n\t\tfunction FieldLabel(rest, ref) {\n\t\t\treturn <label suppressHydrationWarning ref={ref} {...rest} />;\n\t\t},\n\t),\n});\n"],"names":["Field","label","FieldAffixes","FieldDatalist","FieldOption","FieldCombobox","children"],"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\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,2 +1,14 @@
1
- export type FieldsetProps = React.ComponentPropsWithoutRef<"fieldset">;
2
- export declare const Fieldset: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').FieldsetHTMLAttributes<HTMLFieldSetElement>, HTMLFieldSetElement>, "ref"> & import('react').RefAttributes<HTMLFieldSetElement>>;
1
+ export type FieldsetProps = React.ComponentPropsWithoutRef<"fieldset"> & {
2
+ "data-validation"?: "form";
3
+ };
4
+ export declare const FieldsetComp: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').FieldsetHTMLAttributes<HTMLFieldSetElement>, HTMLFieldSetElement>, "ref"> & {
5
+ "data-validation"?: "form";
6
+ } & import('react').RefAttributes<HTMLFieldSetElement>>;
7
+ export type FieldsetLegendProps = React.ComponentPropsWithoutRef<"legend">;
8
+ export type FieldsetDescriptionProps = React.ComponentPropsWithoutRef<"p">;
9
+ export declare const Fieldset: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').FieldsetHTMLAttributes<HTMLFieldSetElement>, HTMLFieldSetElement>, "ref"> & {
10
+ "data-validation"?: "form";
11
+ } & import('react').RefAttributes<HTMLFieldSetElement>> & {
12
+ Legend: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLLegendElement>, HTMLLegendElement>, "ref"> & import('react').RefAttributes<HTMLLegendElement>>;
13
+ Description: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import('react').RefAttributes<HTMLParagraphElement>>;
14
+ };