@mattilsynet/design 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,22 @@
1
- type Matomo = (string | number | boolean)[];
1
+ type Matomo = (string | number | boolean | ((this: Record<string, <T>() => T>) => void))[];
2
2
  declare global {
3
3
  interface Window {
4
4
  _paq?: Matomo[];
5
5
  _mtm?: Record<string, string | number>[];
6
+ _mtdsTracking?: AnalyticsActions["init"];
7
+ _mtdsUntrack?: () => void;
6
8
  }
7
9
  }
8
10
  export type AnalyticsActions = {
9
11
  init: {
10
- matomoId: number | string;
11
12
  enabled?: boolean | "debug";
12
- };
13
+ } & ({
14
+ matomoId: number | string;
15
+ matomoTagManagerId?: never;
16
+ } | {
17
+ matomoId?: never;
18
+ matomoTagManagerId: string;
19
+ });
13
20
  pageview: {
14
21
  url?: string;
15
22
  title?: string;
@@ -1,36 +1,101 @@
1
- import { IS_BROWSER as r } from "../utils.js";
2
- const s = "mattilsynet.matomo.cloud";
3
- let a = !0;
4
- function d(o, n = {}) {
5
- if (r) {
6
- if (window._paq || (window._paq = [], window._paq.push(["HeatmapSessionRecording::disable"]), window._paq.push(["enableLinkTracking"]), window._paq.push(["setTrackerUrl", `https://${s}/matomo.php`])), o === "init") {
7
- const { matomoId: e, enabled: t } = n;
8
- a = t ?? window.location.hostname === "localhost", window._paq.push(["setSiteId", e]), document.querySelector('script[src*="matomo.js"]') || document.head.append(
9
- Object.assign(document.createElement("script"), {
10
- async: !0,
11
- src: `https://cdn.matomo.cloud/${s}/matomo.js`
12
- })
13
- );
1
+ import d from "../styles.module.css.js";
2
+ import { onLoaded as w, IS_BROWSER as h, on as f, QUICK_EVENT as g, attr as i } from "../utils.js";
3
+ const _ = `.${d.breadcrumbs.split(" ")[0]}`, b = `.${d.chip.split(" ")[0]}`, y = `.${d.helptext.split(" ")[0]}`, S = `.${d.pagination.split(" ")[0]}`, T = 'summary,u-summary,a,button,[role="tab"],[role="button"]', k = "click,toggle,submit,change", m = "mattilsynet.matomo.cloud";
4
+ function q(e, a = {}) {
5
+ if (h) {
6
+ if (window._paq || (window._paq = [], window._paq.push(["HeatmapSessionRecording::disable"]), window._paq.push(["enableLinkTracking"]), window._paq.push(["setTrackerUrl", `https://${m}/matomo.php`])), window._mtm || (window._mtm = window._mtm || [], window._mtm.push({ "mtm.startTime": Date.now(), event: "mtm.Start" })), e === "init") {
7
+ window._mtdsTracking = {
8
+ enabled: window.location.hostname !== "localhost",
9
+ ...window._mtdsTracking,
10
+ ...a
11
+ };
12
+ const { enabled: t, matomoId: o, matomoTagManagerId: n } = window._mtdsTracking;
13
+ if (o && window._paq.push(["setSiteId", o]), t) {
14
+ const s = n ? `https://cdn.matomo.cloud/${m}/container_${n}.js` : `https://cdn.matomo.cloud/${m}/matomo.js`;
15
+ document.querySelector(`script[src="${s}"]`) || document.head.append(
16
+ Object.assign(document.createElement("script"), {
17
+ async: !0,
18
+ src: s
19
+ })
20
+ );
21
+ }
14
22
  }
15
- if (a === "debug") return console.info(`Analytics: "${o}"`, n);
16
- if (a !== !1)
17
- if (o === "pageview") {
18
- const { url: e, title: t } = n;
19
- window._paq.push(["setCustomUrl", e || location.href]), window._paq.push(["setDocumentTitle", t || document.title]), window._paq.push(["trackPageView"]);
20
- } else if (o === "event") {
21
- const { category: e, action: t, name: i, value: c } = n, p = ["trackEvent", e, t, i, c];
22
- window._paq.push(p.filter((l) => l !== void 0));
23
- } else if (o === "search") {
23
+ if (window._mtdsTracking?.enabled !== !1) {
24
+ if (window._mtdsTracking?.enabled === "debug")
25
+ return console.info(`analytics("${e}", `, a, ")");
26
+ if (e === "pageview") {
27
+ const { url: t, title: o } = a;
28
+ window._paq.push(["setCustomUrl", t || location.href]), window._paq.push(["setDocumentTitle", o || document.title]), window._paq.push(["trackPageView"]);
29
+ } else if (e === "event") {
30
+ const { category: t, action: o, name: n, value: s } = a, l = ["trackEvent", t, o, n, s];
31
+ let c = location.href;
32
+ window._paq.push([
33
+ function() {
34
+ c = this.getCurrentUrl();
35
+ }
36
+ ]), window._paq.push(["setCustomUrl", c.split("#")[0]]), window._paq.push(l.filter((u) => u !== void 0)), window._paq.push(["setCustomUrl", c]);
37
+ } else if (e === "search") {
24
38
  const {
25
- query: e,
26
- category: t = !1,
27
- results: i = !1
28
- } = n;
29
- window._paq.push(["trackSiteSearch", e, t, i]);
30
- } else o === "matomo" && window._paq.push(n);
39
+ query: t,
40
+ category: o = !1,
41
+ results: n = !1
42
+ } = a;
43
+ window._paq.push(["trackSiteSearch", t, o, n]);
44
+ } else e === "matomo" && window._paq.push(a);
45
+ }
31
46
  }
32
47
  }
48
+ const v = (e) => window._mtdsTracking?.enabled && setTimeout(C, 0, e), C = ({ type: e, target: a }) => {
49
+ const t = e === "click" ? a?.closest?.(T) : a;
50
+ if (!(t instanceof Element) || i(t, "data-analytics") === "ignore")
51
+ return;
52
+ let o = "click", n = "Button", s = p(t) || I(t) || i(t, "data-tooltip") || "";
53
+ if (e === "submit")
54
+ n = "Form", o = "submit", s = s || document.title;
55
+ else if (e === "toggle") {
56
+ if (!t.matches("dialog:modal")) return;
57
+ n = "Dialog", o = "open";
58
+ } else if (e === "change") {
59
+ const l = i(t, "type"), c = l === "checkbox" || l === "radio" ? t.closest("fieldset") : null;
60
+ n = "Form", o = "change", s = p(c || t) || r(c?.querySelector("legend")) || r(t?.labels?.[0]);
61
+ } else if (i(t, "role") === "tab")
62
+ n = "Tab", o = "navigate";
63
+ else if (i(t, "popovertarget")) {
64
+ if (!E(t)?.matches(":popover-open")) return;
65
+ n = t.closest(y) ? "HelpText" : "Popover", o = "open";
66
+ } else if (t.nodeName.endsWith("SUMMARY")) {
67
+ if (!t.parentElement.open) return;
68
+ n = "Details", o = "open";
69
+ } else if (i(t, "data-command") === "toggle-app-expanded") {
70
+ const l = x(t, "--mtds-tooltip-position") === "none";
71
+ n = "Sidebar", o = l ? "expand" : "minimize", s = l && i(t, "data-tooltip") || r(t);
72
+ } else if (t.closest(_))
73
+ n = "Breadcrumbs", o = "navigate";
74
+ else if (t.closest(S))
75
+ n = "Pagintation", o = "navigate";
76
+ else if (t.closest(b))
77
+ n = "Chip", o = t.hasAttribute("data-removable") ? "remove" : "click";
78
+ else if (t.closest("th[aria-sort]"))
79
+ n = "Table", o = "sort";
80
+ else if (t instanceof HTMLAnchorElement)
81
+ n = "Link", o = t.protocol === "mailto:" ? "email" : "navigate", t.hasAttribute("download") ? o = "download" : t.hash && t.href.startsWith(location.href.split("#")[0]) && (o = "anchor");
82
+ else if (t.hasAttribute("aria-expanded")) {
83
+ if (i(t, "aria-expanded") !== "true") return;
84
+ n = "Expand", o = "open";
85
+ }
86
+ q("event", {
87
+ category: i(t, "data-analytics-category") ?? n,
88
+ action: i(t, "data-analytics-action") ?? o,
89
+ name: i(t, "data-analytics-name") ?? s
90
+ });
91
+ }, r = (e) => e?.textContent?.trim() || "", p = (e) => e && i(e, "aria-label") || "", E = (e) => document.getElementById(i(e, "popovertarget") || ""), x = (e, a) => window.getComputedStyle(e).getPropertyValue(a)?.trim(), I = (e) => {
92
+ const a = r(e), t = r(e.querySelector("h1,h2,h3,h4,h5,h6"));
93
+ return a.startsWith(t) && t || a.slice(0, 100).trim();
94
+ };
95
+ w(() => {
96
+ f(document, k, v, g);
97
+ });
33
98
  export {
34
- d as analytics
99
+ q as analytics
35
100
  };
36
101
  //# sourceMappingURL=analytics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.js","sources":["../../designsystem/analytics/analytics.ts"],"sourcesContent":["import { IS_BROWSER } from \"../utils\";\n\nconst MATOMO = \"mattilsynet.matomo.cloud\";\nlet ENABLED: AnalyticsActions[\"init\"][\"enabled\"] = true;\n\ntype Matomo = (string | number | boolean)[];\ndeclare global {\n\tinterface Window {\n\t\t_paq?: Matomo[];\n\t\t_mtm?: Record<string, string | number>[];\n\t}\n}\n\n// window._paq = window._paq || [];\n// window._mtm = window._mtm || [];\n\n// window._paq.push([\"setCustomUrl\", `${document.location.href}&eirik`]);\n// window._paq.push([\"setDocumentTitle\", \"Eirik 3\"]);\n// window._mtm.push({\n// \tevent: \"mtm.Start\",\n// \t\"mtm.startTime\": new Date().getTime(),\n// \tcustomTitle: \"Eirik 1\",\n// \tcustomUrl: `${document.location.href}&eirik`,\n// });\n\n// window._mtm.push({\n// \tevent: \"mtm.PageView\",\n// \tcustomTitle: \"Eirik 2\",\n// \tcustomUrl: `${document.location.href}&eirik`,\n// });\n\n// const containerId = \"A9utKk3O\";\n\n// document.head.append(\n// \tObject.assign(document.createElement(\"script\"), {\n// \t\tsrc: `https://cdn.matomo.cloud/mattilsynet.matomo.cloud/container_${containerId}.js`,\n// \t\tasync: true,\n// \t\tonload: () => console.log(window._paq),\n// \t}),\n// );\n\nexport type AnalyticsActions = {\n\tinit: {\n\t\tmatomoId: number | string;\n\t\tenabled?: boolean | \"debug\";\n\t};\n\tpageview: {\n\t\turl?: string;\n\t\ttitle?: string;\n\t};\n\tevent: {\n\t\tcategory: string;\n\t\taction: string;\n\t\tname?: string;\n\t\tvalue?: number;\n\t};\n\tsearch: {\n\t\tquery: string;\n\t\tcategory?: string;\n\t\tresults?: number;\n\t};\n\tmatomo: Matomo;\n};\n\nexport function analytics<Action extends keyof AnalyticsActions>(\n\taction: Action,\n\targs = {} as AnalyticsActions[Action],\n) {\n\tif (!IS_BROWSER) return;\n\tif (!window._paq) {\n\t\twindow._paq = [];\n\t\twindow._paq.push([\"HeatmapSessionRecording::disable\"]); // Disable heatmaps by default as this require cookies\n\t\twindow._paq.push([\"enableLinkTracking\"]);\n\t\twindow._paq.push([\"setTrackerUrl\", `https://${MATOMO}/matomo.php`]);\n\t}\n\tif (action === \"init\") {\n\t\tconst { matomoId, enabled } = args as AnalyticsActions[\"init\"];\n\t\tENABLED = enabled ?? window.location.hostname === \"localhost\";\n\t\twindow._paq.push([\"setSiteId\", matomoId]);\n\t\tdocument.querySelector('script[src*=\"matomo.js\"]') ||\n\t\t\tdocument.head.append(\n\t\t\t\tObject.assign(document.createElement(\"script\"), {\n\t\t\t\t\tasync: true,\n\t\t\t\t\tsrc: `https://cdn.matomo.cloud/${MATOMO}/matomo.js`,\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\tif (ENABLED === \"debug\") return console.info(`Analytics: \"${action}\"`, args);\n\tif (ENABLED === false) return;\n\n\tif (action === \"pageview\") {\n\t\tconst { url, title } = args as AnalyticsActions[\"pageview\"];\n\t\twindow._paq.push([\"setCustomUrl\", url || location.href]);\n\t\twindow._paq.push([\"setDocumentTitle\", title || document.title]);\n\t\twindow._paq.push([\"trackPageView\"]);\n\t} else if (action === \"event\") {\n\t\tconst { category, action, name, value } = args as AnalyticsActions[\"event\"];\n\t\tconst event = [\"trackEvent\", category, action, name, value];\n\t\twindow._paq.push(event.filter((v) => v !== undefined));\n\t} else if (action === \"search\") {\n\t\tconst {\n\t\t\tquery,\n\t\t\tcategory = false,\n\t\t\tresults = false,\n\t\t} = args as AnalyticsActions[\"search\"];\n\t\twindow._paq.push([\"trackSiteSearch\", query, category, results]);\n\t} else if (action === \"matomo\") {\n\t\twindow._paq.push(args as AnalyticsActions[\"matomo\"]);\n\t}\n}\n"],"names":["MATOMO","ENABLED","analytics","action","args","IS_BROWSER","matomoId","enabled","url","title","category","name","value","event","v","query","results"],"mappings":";AAEA,MAAMA,IAAS;AACf,IAAIC,IAA+C;AA6D5C,SAASC,EACfC,GACAC,IAAO,IACN;AACD,MAAKC,GAOL;AAAA,QANK,OAAO,SACX,OAAO,OAAO,CAAC,GACf,OAAO,KAAK,KAAK,CAAC,kCAAkC,CAAC,GACrD,OAAO,KAAK,KAAK,CAAC,oBAAoB,CAAC,GACvC,OAAO,KAAK,KAAK,CAAC,iBAAiB,WAAWL,CAAM,aAAa,CAAC,IAE/DG,MAAW,QAAQ;AAChB,YAAA,EAAE,UAAAG,GAAU,SAAAC,EAAA,IAAYH;AACpB,MAAAH,IAAAM,KAAW,OAAO,SAAS,aAAa,aAClD,OAAO,KAAK,KAAK,CAAC,aAAaD,CAAQ,CAAC,GACxC,SAAS,cAAc,0BAA0B,KAChD,SAAS,KAAK;AAAA,QACb,OAAO,OAAO,SAAS,cAAc,QAAQ,GAAG;AAAA,UAC/C,OAAO;AAAA,UACP,KAAK,4BAA4BN,CAAM;AAAA,QACvC,CAAA;AAAA,MACF;AAAA,IAAA;AAGE,QAAAC,MAAY,QAAgB,QAAA,QAAQ,KAAK,eAAeE,CAAM,KAAKC,CAAI;AAC3E,QAAIH,MAAY;AAEhB,UAAIE,MAAW,YAAY;AACpB,cAAA,EAAE,KAAAK,GAAK,OAAAC,EAAA,IAAUL;AACvB,eAAO,KAAK,KAAK,CAAC,gBAAgBI,KAAO,SAAS,IAAI,CAAC,GACvD,OAAO,KAAK,KAAK,CAAC,oBAAoBC,KAAS,SAAS,KAAK,CAAC,GAC9D,OAAO,KAAK,KAAK,CAAC,eAAe,CAAC;AAAA,MAAA,WACxBN,MAAW,SAAS;AAC9B,cAAM,EAAE,UAAAO,GAAU,QAAAP,GAAQ,MAAAQ,GAAM,OAAAC,MAAUR,GACpCS,IAAQ,CAAC,cAAcH,GAAUP,GAAQQ,GAAMC,CAAK;AACnD,eAAA,KAAK,KAAKC,EAAM,OAAO,CAACC,MAAMA,MAAM,MAAS,CAAC;AAAA,MAAA,WAC3CX,MAAW,UAAU;AACzB,cAAA;AAAA,UACL,OAAAY;AAAA,UACA,UAAAL,IAAW;AAAA,UACX,SAAAM,IAAU;AAAA,QAAA,IACPZ;AACJ,eAAO,KAAK,KAAK,CAAC,mBAAmBW,GAAOL,GAAUM,CAAO,CAAC;AAAA,MAAA,MAC/D,CAAWb,MAAW,YACd,OAAA,KAAK,KAAKC,CAAkC;AAAA;AAErD;"}
1
+ {"version":3,"file":"analytics.js","sources":["../../designsystem/analytics/analytics.ts"],"sourcesContent":["import styles from \"../styles.module.css\";\nimport { attr, IS_BROWSER, on, onLoaded, QUICK_EVENT } from \"../utils\";\n\nconst CSS_BREADCRUMBS = `.${styles.breadcrumbs.split(\" \")[0]}`;\nconst CSS_CHIP = `.${styles.chip.split(\" \")[0]}`;\nconst CSS_HELPTEXT = `.${styles.helptext.split(\" \")[0]}`;\nconst CSS_PAGINATION = `.${styles.pagination.split(\" \")[0]}`;\nconst CLICKS = `summary,u-summary,a,button,[role=\"tab\"],[role=\"button\"]`;\nconst EVENTS = \"click,toggle,submit,change\";\nconst MATOMO = \"mattilsynet.matomo.cloud\";\n\ntype Matomo = (\n\t| string\n\t| number\n\t| boolean\n\t| ((this: Record<string, <T>() => T>) => void)\n)[];\ndeclare global {\n\tinterface Window {\n\t\t_paq?: Matomo[];\n\t\t_mtm?: Record<string, string | number>[];\n\t\t_mtdsTracking?: AnalyticsActions[\"init\"];\n\t\t_mtdsUntrack?: () => void;\n\t}\n}\n\nexport type AnalyticsActions = {\n\tinit: {\n\t\tenabled?: boolean | \"debug\";\n\t} & (\n\t\t| {\n\t\t\t\tmatomoId: number | string;\n\t\t\t\tmatomoTagManagerId?: never;\n\t\t }\n\t\t| {\n\t\t\t\tmatomoId?: never;\n\t\t\t\tmatomoTagManagerId: string;\n\t\t }\n\t);\n\tpageview: {\n\t\turl?: string;\n\t\ttitle?: string;\n\t};\n\tevent: {\n\t\tcategory: string;\n\t\taction: string;\n\t\tname?: string;\n\t\tvalue?: number;\n\t};\n\tsearch: {\n\t\tquery: string;\n\t\tcategory?: string;\n\t\tresults?: number;\n\t};\n\tmatomo: Matomo;\n};\n\nexport function analytics<Action extends keyof AnalyticsActions>(\n\taction: Action,\n\targs = {} as AnalyticsActions[Action],\n) {\n\tif (!IS_BROWSER) return;\n\tif (!window._paq) {\n\t\twindow._paq = [];\n\t\twindow._paq.push([\"HeatmapSessionRecording::disable\"]); // Disable heatmaps by default as this require cookies\n\t\twindow._paq.push([\"enableLinkTracking\"]);\n\t\twindow._paq.push([\"setTrackerUrl\", `https://${MATOMO}/matomo.php`]);\n\t}\n\tif (!window._mtm) {\n\t\twindow._mtm = window._mtm || []; // Prepare Matomo Tag Manager\n\t\twindow._mtm.push({ \"mtm.startTime\": Date.now(), event: \"mtm.Start\" });\n\t}\n\n\tif (action === \"init\") {\n\t\twindow._mtdsTracking = {\n\t\t\tenabled: window.location.hostname !== \"localhost\",\n\t\t\t...window._mtdsTracking,\n\t\t\t...args,\n\t\t} as AnalyticsActions[\"init\"];\n\t\tconst { enabled, matomoId, matomoTagManagerId } = window._mtdsTracking;\n\n\t\tif (matomoId) window._paq.push([\"setSiteId\", matomoId]);\n\t\tif (enabled) {\n\t\t\tconst src = matomoTagManagerId\n\t\t\t\t? `https://cdn.matomo.cloud/${MATOMO}/container_${matomoTagManagerId}.js`\n\t\t\t\t: `https://cdn.matomo.cloud/${MATOMO}/matomo.js`;\n\t\t\tdocument.querySelector(`script[src=\"${src}\"]`) ||\n\t\t\t\tdocument.head.append(\n\t\t\t\t\tObject.assign(document.createElement(\"script\"), {\n\t\t\t\t\t\tasync: true,\n\t\t\t\t\t\tsrc,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t}\n\t}\n\n\tif (window._mtdsTracking?.enabled === false) return;\n\tif (window._mtdsTracking?.enabled === \"debug\")\n\t\treturn console.info(`analytics(\"${action}\", `, args, \")\");\n\n\tif (action === \"pageview\") {\n\t\tconst { url, title } = args as AnalyticsActions[\"pageview\"];\n\t\twindow._paq.push([\"setCustomUrl\", url || location.href]);\n\t\twindow._paq.push([\"setDocumentTitle\", title || document.title]);\n\t\twindow._paq.push([\"trackPageView\"]);\n\t} else if (action === \"event\") {\n\t\tconst { category, action, name, value } = args as AnalyticsActions[\"event\"];\n\t\tconst event = [\"trackEvent\", category, action, name, value];\n\n\t\t// We do not want to track events with hash in URL as this causes hard-to-read data,\n\t\t// so temporarily remove the hash part, and add it back after the event is pushed\n\t\tlet url = location.href;\n\t\twindow._paq.push([\n\t\t\tfunction () {\n\t\t\t\turl = this.getCurrentUrl<string>();\n\t\t\t},\n\t\t]);\n\t\twindow._paq.push([\"setCustomUrl\", url.split(\"#\")[0]]); // Skip hash part of URL\n\t\twindow._paq.push(event.filter((v) => v !== undefined)); // Push event\n\t\twindow._paq.push([\"setCustomUrl\", url]); // Reverrt to original URL with hash\n\t} else if (action === \"search\") {\n\t\tconst {\n\t\t\tquery,\n\t\t\tcategory = false,\n\t\t\tresults = false,\n\t\t} = args as AnalyticsActions[\"search\"];\n\t\twindow._paq.push([\"trackSiteSearch\", query, category, results]);\n\t} else if (action === \"matomo\") {\n\t\twindow._paq.push(args as AnalyticsActions[\"matomo\"]);\n\t}\n}\n\nconst handleTrack = (event: Event) =>\n\twindow._mtdsTracking?.enabled && setTimeout(processTrack, 0, event); // Let other events process first\n\nconst processTrack = ({ type, target }: Event) => {\n\tconst el = type === \"click\" ? (target as Element)?.closest?.(CLICKS) : target;\n\tif (!(el instanceof Element) || attr(el, \"data-analytics\") === \"ignore\")\n\t\treturn;\n\n\tlet action = \"click\";\n\tlet category = \"Button\";\n\tlet name = label(el) || heading(el) || attr(el, \"data-tooltip\") || \"\";\n\n\tif (type === \"submit\") {\n\t\tcategory = \"Form\";\n\t\taction = \"submit\";\n\t\tname = name || document.title;\n\t} else if (type === \"toggle\") {\n\t\tif (!el.matches(\"dialog:modal\")) return; // Skip non-modal dialogs\n\t\tcategory = \"Dialog\";\n\t\taction = \"open\";\n\t} else if (type === \"change\") {\n\t\tconst type = attr(el, \"type\");\n\t\tconst group =\n\t\t\ttype === \"checkbox\" || type === \"radio\" ? el.closest(\"fieldset\") : null;\n\n\t\tcategory = \"Form\";\n\t\taction = \"change\";\n\t\tname =\n\t\t\tlabel(group || el) ||\n\t\t\ttext(group?.querySelector(\"legend\")) ||\n\t\t\ttext((el as HTMLInputElement)?.labels?.[0]);\n\t} else if (attr(el, \"role\") === \"tab\") {\n\t\tcategory = \"Tab\";\n\t\taction = \"navigate\";\n\t} else if (attr(el, \"popovertarget\")) {\n\t\tif (!popover(el)?.matches(\":popover-open\")) return; // Skip if not open\n\t\tcategory = el.closest(CSS_HELPTEXT) ? \"HelpText\" : \"Popover\";\n\t\taction = \"open\";\n\t} else if (el.nodeName.endsWith(\"SUMMARY\")) {\n\t\tif (!(el.parentElement as HTMLDetailsElement).open) return; // Skip if not open\n\t\tcategory = \"Details\";\n\t\taction = \"open\";\n\t} else if (attr(el, \"data-command\") === \"toggle-app-expanded\") {\n\t\tconst open = style(el, \"--mtds-tooltip-position\") === \"none\";\n\t\tcategory = \"Sidebar\";\n\t\taction = open ? \"expand\" : \"minimize\";\n\t\tname = (open && attr(el, \"data-tooltip\")) || text(el);\n\t} else if (el.closest(CSS_BREADCRUMBS)) {\n\t\tcategory = \"Breadcrumbs\";\n\t\taction = \"navigate\";\n\t} else if (el.closest(CSS_PAGINATION)) {\n\t\tcategory = \"Pagintation\";\n\t\taction = \"navigate\";\n\t} else if (el.closest(CSS_CHIP)) {\n\t\tcategory = \"Chip\";\n\t\taction = el.hasAttribute(\"data-removable\") ? \"remove\" : \"click\";\n\t} else if (el.closest(\"th[aria-sort]\")) {\n\t\tcategory = \"Table\";\n\t\taction = \"sort\";\n\t} else if (el instanceof HTMLAnchorElement) {\n\t\tcategory = \"Link\";\n\t\taction = el.protocol === \"mailto:\" ? \"email\" : \"navigate\";\n\t\tif (el.hasAttribute(\"download\")) action = \"download\";\n\t\telse if (el.hash && el.href.startsWith(location.href.split(\"#\")[0]))\n\t\t\taction = \"anchor\"; // Only track as anchor if same page\n\t} else if (el.hasAttribute(\"aria-expanded\")) {\n\t\tif (attr(el, \"aria-expanded\") !== \"true\") return; // Skip if not open\n\t\tcategory = \"Expand\";\n\t\taction = \"open\";\n\t}\n\n\t// Respect attributes and send\n\tanalytics(\"event\", {\n\t\tcategory: attr(el, \"data-analytics-category\") ?? category,\n\t\taction: attr(el, \"data-analytics-action\") ?? action,\n\t\tname: attr(el, \"data-analytics-name\") ?? name,\n\t});\n};\n\n// Utilities\nconst text = (el?: Element | null) => el?.textContent?.trim() || \"\";\nconst label = (el?: Element | null) => (el && attr(el, \"aria-label\")) || \"\";\nconst popover = (el: Element) =>\n\tdocument.getElementById(attr(el, \"popovertarget\") || \"\");\nconst style = (el: Element, key: string) =>\n\twindow.getComputedStyle(el).getPropertyValue(key)?.trim();\nconst heading = (el: Element) => {\n\tconst body = text(el);\n\tconst head = text(el.querySelector(\"h1,h2,h3,h4,h5,h6\")); // Note: head might be empty string ''\n\treturn (body.startsWith(head) && head) || body.slice(0, 100).trim(); // Limit to 100 characters\n};\n\nonLoaded(() => {\n\ton(document, EVENTS, handleTrack, QUICK_EVENT);\n});\n"],"names":["CSS_BREADCRUMBS","styles","CSS_CHIP","CSS_HELPTEXT","CSS_PAGINATION","CLICKS","EVENTS","MATOMO","analytics","action","args","IS_BROWSER","enabled","matomoId","matomoTagManagerId","src","url","title","category","name","value","event","v","query","results","handleTrack","processTrack","type","target","el","attr","label","heading","group","text","popover","open","style","key","body","head","onLoaded","on","QUICK_EVENT"],"mappings":"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"}
@@ -1,22 +1,20 @@
1
1
  import d from "../styles.module.css.js";
2
- import { IS_BROWSER as r, onLoaded as m, on as u, QUICK_EVENT as f, createOptimizedMutationObserver as p, attr as o } from "../utils.js";
3
- const g = d.dialog.split(" ")[0], h = r ? document.getElementsByClassName(
4
- g
2
+ import { IS_BROWSER as m, onLoaded as r, on as u, QUICK_EVENT as f, createOptimizedMutationObserver as g, attr as e } from "../utils.js";
3
+ const p = d.dialog.split(" ")[0], h = m ? document.getElementsByClassName(
4
+ p
5
5
  ) : [], b = () => {
6
6
  for (const t of h)
7
- t.isConnected && t.showModal && t.close && (t.matches('[open]:not([data-modal="false"]):not(:modal)') ? (o(t, "open", null), t.showModal()) : t.matches(":modal:not([open])") && (o(t, "open", ""), t.close()));
8
- }, C = ({ clientX: t, clientY: n, target: s }) => {
9
- const e = s?.closest?.("dialog");
10
- if (e) {
11
- if (s.closest('[data-command="close"]')) return e.close();
12
- if (o(e, "data-closedby") === "any") {
13
- const { top: l, right: i, bottom: a, left: c } = e.getBoundingClientRect();
14
- l <= n && n <= a && c <= t && t <= i || e.close();
15
- }
7
+ t.isConnected && t.showModal && t.close && (t.matches('[open]:not([data-modal="false"]):not(:modal)') ? (e(t, "open", null), t.showModal()) : t.matches(":modal:not([open])") && (e(t, "open", ""), t.close()));
8
+ }, C = ({ clientX: t, clientY: n, target: o }) => {
9
+ if (o instanceof HTMLDialogElement && e(o, "data-closedby") === "any") {
10
+ const { top: c, right: l, bottom: i, left: a } = o.getBoundingClientRect();
11
+ if (!(c <= n && n <= i && a <= t && t <= l)) return o.close();
16
12
  }
13
+ const s = o?.closest?.("dialog");
14
+ s && o?.closest?.('[data-command="close"]') && s.close();
17
15
  };
18
- m(() => {
19
- u(document, "click", C, f), p(b).observe(
16
+ r(() => {
17
+ u(document, "click", C, f), g(b).observe(
20
18
  document.documentElement,
21
19
  {
22
20
  attributeFilter: ["open"],
@@ -1 +1 @@
1
- {"version":3,"file":"dialog-observer.js","sources":["../../designsystem/dialog/dialog-observer.ts"],"sourcesContent":["import styles from \"../styles.module.css\";\nimport {\n\tattr,\n\tcreateOptimizedMutationObserver,\n\tIS_BROWSER,\n\ton,\n\tonLoaded,\n\tQUICK_EVENT,\n} from \"../utils\";\n\nconst CSS_DIALOG = styles.dialog.split(\" \")[0];\nconst DIALOGS = IS_BROWSER\n\t? (document.getElementsByClassName(\n\t\t\tCSS_DIALOG,\n\t\t) as HTMLCollectionOf<HTMLDialogElement>)\n\t: [];\n\nconst handleModal = () => {\n\tfor (const dialog of DIALOGS)\n\t\tif (dialog.isConnected && dialog.showModal && dialog.close) {\n\t\t\tif (dialog.matches('[open]:not([data-modal=\"false\"]):not(:modal)')) {\n\t\t\t\tattr(dialog, \"open\", null); // Using attribute instead of .close to avoid `close` event\n\t\t\t\tdialog.showModal();\n\t\t\t} else if (dialog.matches(\":modal:not([open])\")) {\n\t\t\t\tattr(dialog, \"open\", \"\"); // Set as open\n\t\t\t\tdialog.close(); // So we correclty can call .close, removing <dialog> from #top-layer\n\t\t\t}\n\t\t}\n};\n\nconst handleClick = ({ clientX: x, clientY: y, target: el }: MouseEvent) => {\n\tconst dialog = (el as Element)?.closest?.(\"dialog\");\n\n\tif (!dialog) return;\n\tif ((el as Element).closest('[data-command=\"close\"]')) return dialog.close();\n\tif (attr(dialog, \"data-closedby\") === \"any\") {\n\t\tconst { top, right, bottom, left } = dialog.getBoundingClientRect();\n\t\tconst isInside = top <= y && y <= bottom && left <= x && x <= right;\n\t\tif (!isInside) dialog.close();\n\t}\n};\n\nonLoaded(() => {\n\ton(document, \"click\", handleClick as EventListener, QUICK_EVENT);\n\tcreateOptimizedMutationObserver(handleModal).observe(\n\t\tdocument.documentElement,\n\t\t{\n\t\t\tattributeFilter: [\"open\"],\n\t\t\tattributes: true,\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t},\n\t);\n});\n"],"names":["CSS_DIALOG","styles","DIALOGS","IS_BROWSER","handleModal","dialog","attr","handleClick","x","y","el","top","right","bottom","left","onLoaded","on","QUICK_EVENT","createOptimizedMutationObserver"],"mappings":";;AAUA,MAAMA,IAAaC,EAAO,OAAO,MAAM,GAAG,EAAE,CAAC,GACvCC,IAAUC,IACZ,SAAS;AAAA,EACVH;AACD,IACC,CAAC,GAEEI,IAAc,MAAM;AACzB,aAAWC,KAAUH;AACpB,IAAIG,EAAO,eAAeA,EAAO,aAAaA,EAAO,UAChDA,EAAO,QAAQ,8CAA8C,KAC3DC,EAAAD,GAAQ,QAAQ,IAAI,GACzBA,EAAO,UAAU,KACPA,EAAO,QAAQ,oBAAoB,MACxCC,EAAAD,GAAQ,QAAQ,EAAE,GACvBA,EAAO,MAAM;AAGjB,GAEME,IAAc,CAAC,EAAE,SAASC,GAAG,SAASC,GAAG,QAAQC,QAAqB;AACrE,QAAAL,IAAUK,GAAgB,UAAU,QAAQ;AAElD,MAAKL,GACL;AAAA,QAAKK,EAAe,QAAQ,wBAAwB,EAAG,QAAOL,EAAO,MAAM;AAC3E,QAAIC,EAAKD,GAAQ,eAAe,MAAM,OAAO;AAC5C,YAAM,EAAE,KAAAM,GAAK,OAAAC,GAAO,QAAAC,GAAQ,MAAAC,EAAK,IAAIT,EAAO,sBAAsB;AAE9D,MADaM,KAAOF,KAAKA,KAAKI,KAAUC,KAAQN,KAAKA,KAAKI,KAC/CP,EAAO,MAAM;AAAA,IAAA;AAAA;AAE9B;AAEAU,EAAS,MAAM;AACX,EAAAC,EAAA,UAAU,SAAST,GAA8BU,CAAW,GAC/DC,EAAgCd,CAAW,EAAE;AAAA,IAC5C,SAAS;AAAA,IACT;AAAA,MACC,iBAAiB,CAAC,MAAM;AAAA,MACxB,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAAA,EAEX;AACD,CAAC;"}
1
+ {"version":3,"file":"dialog-observer.js","sources":["../../designsystem/dialog/dialog-observer.ts"],"sourcesContent":["import styles from \"../styles.module.css\";\nimport {\n\tattr,\n\tcreateOptimizedMutationObserver,\n\tIS_BROWSER,\n\ton,\n\tonLoaded,\n\tQUICK_EVENT,\n} from \"../utils\";\n\nconst CSS_DIALOG = styles.dialog.split(\" \")[0];\nconst DIALOGS = IS_BROWSER\n\t? (document.getElementsByClassName(\n\t\t\tCSS_DIALOG,\n\t\t) as HTMLCollectionOf<HTMLDialogElement>)\n\t: [];\n\nconst handleModal = () => {\n\tfor (const dialog of DIALOGS)\n\t\tif (dialog.isConnected && dialog.showModal && dialog.close) {\n\t\t\tif (dialog.matches('[open]:not([data-modal=\"false\"]):not(:modal)')) {\n\t\t\t\tattr(dialog, \"open\", null); // Using attribute instead of .close to avoid `close` event\n\t\t\t\tdialog.showModal();\n\t\t\t} else if (dialog.matches(\":modal:not([open])\")) {\n\t\t\t\tattr(dialog, \"open\", \"\"); // Set as open\n\t\t\t\tdialog.close(); // So we correclty can call .close, removing <dialog> from #top-layer\n\t\t\t}\n\t\t}\n};\n\nconst handleClick = ({ clientX: x, clientY: y, target: el }: MouseEvent) => {\n\tif (el instanceof HTMLDialogElement && attr(el, \"data-closedby\") === \"any\") {\n\t\tconst { top, right, bottom, left } = el.getBoundingClientRect();\n\t\tconst isInside = top <= y && y <= bottom && left <= x && x <= right;\n\t\tif (!isInside) return el.close();\n\t}\n\tconst dialog = (el as Element)?.closest?.(\"dialog\");\n\tconst close = dialog && (el as Element)?.closest?.('[data-command=\"close\"]');\n\tif (close) dialog.close();\n};\n\nonLoaded(() => {\n\ton(document, \"click\", handleClick as EventListener, QUICK_EVENT);\n\tcreateOptimizedMutationObserver(handleModal).observe(\n\t\tdocument.documentElement,\n\t\t{\n\t\t\tattributeFilter: [\"open\"],\n\t\t\tattributes: true,\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t},\n\t);\n});\n"],"names":["CSS_DIALOG","styles","DIALOGS","IS_BROWSER","handleModal","dialog","attr","handleClick","x","y","el","top","right","bottom","left","onLoaded","on","QUICK_EVENT","createOptimizedMutationObserver"],"mappings":";;AAUA,MAAMA,IAAaC,EAAO,OAAO,MAAM,GAAG,EAAE,CAAC,GACvCC,IAAUC,IACZ,SAAS;AAAA,EACVH;AACD,IACC,CAAC,GAEEI,IAAc,MAAM;AACzB,aAAWC,KAAUH;AACpB,IAAIG,EAAO,eAAeA,EAAO,aAAaA,EAAO,UAChDA,EAAO,QAAQ,8CAA8C,KAC3DC,EAAAD,GAAQ,QAAQ,IAAI,GACzBA,EAAO,UAAU,KACPA,EAAO,QAAQ,oBAAoB,MACxCC,EAAAD,GAAQ,QAAQ,EAAE,GACvBA,EAAO,MAAM;AAGjB,GAEME,IAAc,CAAC,EAAE,SAASC,GAAG,SAASC,GAAG,QAAQC,QAAqB;AAC3E,MAAIA,aAAc,qBAAqBJ,EAAKI,GAAI,eAAe,MAAM,OAAO;AAC3E,UAAM,EAAE,KAAAC,GAAK,OAAAC,GAAO,QAAAC,GAAQ,MAAAC,EAAK,IAAIJ,EAAG,sBAAsB;AAE9D,QAAI,EADaC,KAAOF,KAAKA,KAAKI,KAAUC,KAAQN,KAAKA,KAAKI,GACxC,QAAAF,EAAG,MAAM;AAAA,EAAA;AAE1B,QAAAL,IAAUK,GAAgB,UAAU,QAAQ;AAE9C,EADUL,KAAWK,GAAgB,UAAU,wBAAwB,OACzD,MAAM;AACzB;AAEAK,EAAS,MAAM;AACX,EAAAC,EAAA,UAAU,SAAST,GAA8BU,CAAW,GAC/DC,EAAgCd,CAAW,EAAE;AAAA,IAC5C,SAAS;AAAA,IACT;AAAA,MACC,iBAAiB,CAAC,MAAM;AAAA,MACxB,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAAA,EAEX;AACD,CAAC;"}
@@ -1,43 +1,44 @@
1
- import { UHTMLComboboxElement as g } from "../external/@u-elements/u-combobox/dist/u-combobox.js";
2
- import { UHTMLDataListElement as E } from "../external/@u-elements/u-datalist/dist/u-datalist.js";
1
+ import { UHTMLComboboxElement as h } from "../external/@u-elements/u-combobox/dist/u-combobox.js";
2
+ import { UHTMLDataListElement as S } from "../external/@u-elements/u-datalist/dist/u-datalist.js";
3
3
  import v from "../styles.module.css.js";
4
- import { onLoaded as I, onMutation as A, on as f, QUICK_EVENT as p, isInputLike as x, attr as n, useId as b, anchorPosition as m } from "../utils.js";
5
- const h = v.field.split(" ")[0], y = v.validation.split(" "), M = y[0], a = (t, o) => t.getPropertyValue(`--mtds-text-${o}`)?.slice(1, -1) || "";
6
- function T(t, o) {
7
- for (const s of t)
8
- if (s.isConnected) {
9
- const i = [], r = [], u = [];
4
+ import { onLoaded as M, onMutation as A, on as m, QUICK_EVENT as u, isInputLike as x, attr as n, useId as p, anchorPosition as b } from "../utils.js";
5
+ const g = v.field.split(" ")[0], y = v.validation.split(" "), H = y[0], s = (t, o) => t.getPropertyValue(`--mtds-text-${o}`)?.slice(1, -1) || "";
6
+ function L(t, o) {
7
+ for (const a of t)
8
+ if (a.isConnected) {
9
+ const i = [], r = [], f = [];
10
10
  let c = null, d = null, l = !0;
11
- for (const e of s.getElementsByTagName("*"))
12
- e instanceof HTMLLabelElement ? i.push(e) : e instanceof g ? c = e : x(e) && !e.hidden ? d = e : e.hasAttribute("data-description") ? r.push(e) : e.classList.contains(M) ? (l = n(e, "data-color") === "success" || !e.clientHeight, u.push(e), r.unshift(e)) : e instanceof HTMLParagraphElement && (r.some((C) => C.contains(e)) || r.push(e));
11
+ for (const e of a.getElementsByTagName("*"))
12
+ e instanceof HTMLLabelElement ? i.push(e) : e instanceof h ? c = e : x(e) && !e.hidden ? d = e : e.hasAttribute("data-description") ? r.push(e) : e.classList.contains(H) ? (l = n(e, "data-color") === "success" || !e.clientHeight, f.push(e), r.unshift(e)) : e instanceof HTMLParagraphElement && (r.some((I) => I.contains(e)) || r.push(e));
13
13
  if (d) {
14
- for (const e of i) e.htmlFor = b(d);
15
- if (o && n(s, "data-validation") === "form") {
14
+ for (const e of i) e.htmlFor = p(d);
15
+ if (o && n(a, "data-validation") === "form") {
16
16
  l = d.matches(":valid");
17
- for (const e of u) n(e, "hidden", l ? "" : null);
17
+ for (const e of f) n(e, "hidden", l ? "" : null);
18
18
  }
19
- H(c), S(d), L(d), n(d, "aria-describedby", r.map(b).join(" ") || null), n(d, "aria-invalid", `${!l}`);
19
+ N(c), E(d), T(d), n(d, "aria-describedby", r.map(p).join(" ") || null), n(d, "aria-invalid", `${!l}`);
20
20
  }
21
21
  }
22
22
  }
23
- function L(t) {
23
+ function T(t) {
24
24
  t instanceof HTMLTextAreaElement && (t.style.setProperty("--mtds-textarea-height", "auto"), t.style.setProperty(
25
25
  "--mtds-textarea-height",
26
26
  `${t.scrollHeight}px`
27
27
  ));
28
28
  }
29
- function H(t) {
30
- const { control: o, list: s } = t || {};
31
- if (t && s && o && !t.hasAttribute("data-sr-added")) {
29
+ function N(t) {
30
+ const { control: o, list: a } = t || {};
31
+ if (t && a && !t.hasAttribute("data-sr-added")) {
32
32
  const i = window.getComputedStyle(t);
33
- n(t, "data-sr-added", a(i, "combobox-added")), n(t, "data-sr-empty", a(i, "combobox-empty")), n(t, "data-sr-found", a(i, "combobox-found")), n(t, "data-sr-invalid", a(i, "combobox-invalid")), n(t, "data-sr-of", a(i, "combobox-of")), n(t, "data-sr-remove", a(i, "combobox-remove")), n(t, "data-sr-removed", a(i, "combobox-removed")), n(s, "data-sr-plural", a(i, "datalist-plural")), n(s, "data-sr-singular", a(i, "datalist-singular")), n(s, "popover", "manual"), n(o, "popovertarget", b(s));
33
+ n(t, "data-sr-added", s(i, "combobox-added")), n(t, "data-sr-empty", s(i, "combobox-empty")), n(t, "data-sr-found", s(i, "combobox-found")), n(t, "data-sr-invalid", s(i, "combobox-invalid")), n(t, "data-sr-of", s(i, "combobox-of")), n(t, "data-sr-remove", s(i, "combobox-remove")), n(t, "data-sr-removed", s(i, "combobox-removed")), n(a, "data-sr-plural", s(i, "datalist-plural")), n(a, "data-sr-singular", s(i, "datalist-singular"));
34
34
  }
35
+ a && o && !a.hasAttribute("popover") && (n(a, "popover", "manual"), n(o, "popovertarget", p(a)));
35
36
  }
36
- function S(t) {
37
- const o = t?.nextElementSibling, s = o && n(o, "data-count");
38
- if (o && s) {
39
- const i = Number(s) - t.value.length, r = i < 0, u = n(o, "aria-live") === "polite", c = window.getComputedStyle(o || t), d = a(c, "count-over"), l = a(c, "count-under");
40
- if (u !== r) {
37
+ function E(t) {
38
+ const o = t?.nextElementSibling, a = o && n(o, "data-count");
39
+ if (o && a) {
40
+ const i = Number(a) - t.value.length, r = i < 0, f = n(o, "aria-live") === "polite", c = window.getComputedStyle(o || t), d = s(c, "count-over"), l = s(c, "count-under");
41
+ if (f !== r) {
41
42
  n(o, "aria-live", r ? "polite" : "off");
42
43
  for (const e of y) o.classList.toggle(e, r);
43
44
  }
@@ -47,32 +48,29 @@ function S(t) {
47
48
  );
48
49
  }
49
50
  }
50
- function N({ target: t, newState: o }) {
51
- if (t instanceof E) {
51
+ function $({ target: t, newState: o }) {
52
+ if (t instanceof S) {
52
53
  const i = t.getRootNode()?.querySelector(
53
54
  `[popovertarget="${t.id}"]`
54
55
  );
55
- o === "closed" ? m(t, !1) : i && (t.style.width = `${i.clientWidth}px`, m(t, i, n(t, "data-position") ?? "bottom", !0));
56
+ o === "closed" ? b(t, !1) : i && (t.style.width = `${i.clientWidth}px`, b(t, i, n(t, "data-position") ?? "bottom", !0));
56
57
  }
57
58
  }
58
- function $({ target: t }) {
59
- if (x(t)) {
60
- S(t), L(t);
61
- const o = t.hasAttribute("list") && t.list;
62
- o && setTimeout(() => {
63
- m(o, t, n(o, "data-position") ?? "bottom", !0);
64
- }, 10);
65
- }
59
+ function D(t) {
60
+ x(t.target) && (E(t.target), T(t.target), C(t));
66
61
  }
67
- function w(t) {
68
- const o = t.target?.closest?.(`.${h}`);
69
- t.type === "invalid" && o && t.preventDefault(), T(document.getElementsByClassName(h), !0);
62
+ function P(t) {
63
+ const o = t.target?.closest?.(`.${g}`);
64
+ t.type === "invalid" && o && t.preventDefault(), L(document.getElementsByClassName(g), !0);
70
65
  }
71
- function D({ target: t }) {
72
- const o = t instanceof g && t.list;
73
- o && !o?.hidden && setTimeout(() => m(o, t, 2, !0), 10);
66
+ function C({ target: t }) {
67
+ const o = (t instanceof h || t instanceof HTMLInputElement) && t.list;
68
+ if (o && !o?.hidden) {
69
+ const a = n(o, "data-position") ?? "bottom";
70
+ setTimeout(() => b(o, t, a, !0), 10);
71
+ }
74
72
  }
75
- I(() => {
76
- A(document.documentElement, h, T), f(document, "comboboxbeforeselect", D, p), f(document, "input", $, p), f(document, "invalid,submit", w, !0), f(document, "toggle", N, p);
73
+ M(() => {
74
+ A(document.documentElement, g, L), m(document, "comboboxbeforeselect", C, u), m(document, "input", D, u), m(document, "invalid,submit", P, !0), m(document, "toggle", $, u);
77
75
  });
78
76
  //# sourceMappingURL=field-observer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"field-observer.js","sources":["../../designsystem/field/field-observer.ts"],"sourcesContent":["import { UHTMLComboboxElement } from \"@u-elements/u-combobox\";\nimport { UHTMLDataListElement } from \"@u-elements/u-datalist\";\nimport styles from \"../styles.module.css\";\nimport {\n\tanchorPosition,\n\tattr,\n\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];\n\nconst getText = (style: CSSStyleDeclaration, key: string) =>\n\tstyle.getPropertyValue(`--mtds-text-${key}`)?.slice(1, -1) || \"\"; // slice to trim quotes\n\nfunction handleMutation(fields: HTMLCollectionOf<Element>, validate?: boolean) {\n\tfor (const field of fields)\n\t\tif (field.isConnected) {\n\t\t\tconst labels: HTMLLabelElement[] = [];\n\t\t\tconst descs: Element[] = [];\n\t\t\tconst valids: 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\")) descs.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\tvalids.push(el);\n\t\t\t\t\tdescs.unshift(el);\n\t\t\t\t} else if (el instanceof HTMLParagraphElement)\n\t\t\t\t\tdescs.some((desc) => desc.contains(el)) || descs.push(el); // Only add if not already inside description\n\t\t\t}\n\n\t\t\tif (input) {\n\t\t\t\tfor (const label of labels) label.htmlFor = useId(input);\n\t\t\t\tif (validate && attr(field, \"data-validation\") === \"form\") {\n\t\t\t\t\tvalid = input.matches(\":valid\");\n\t\t\t\t\tfor (const el of valids) attr(el, \"hidden\", valid ? \"\" : null);\n\t\t\t\t}\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\", descs.map(useId).join(\" \") || null); // Remove if empty\n\t\t\t\tattr(input, \"aria-invalid\", `${!valid}`);\n\t\t\t}\n\t\t}\n}\n\n// iOS does not support field-sizing: content, so we need to manually resize\nfunction renderTextareaSize(textarea: Element) {\n\tif (textarea instanceof HTMLTextAreaElement) {\n\t\ttextarea.style.setProperty(\"--mtds-textarea-height\", \"auto\");\n\t\ttextarea.style.setProperty(\n\t\t\t\"--mtds-textarea-height\",\n\t\t\t`${textarea.scrollHeight}px`,\n\t\t);\n\t}\n}\n\n// Setup translations from CSS custom properties\nfunction renderCombobox(el: UHTMLComboboxElement | null) {\n\tconst { control, list } = el || {};\n\n\tif (el && list && control && !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\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 handleToggle({ target: el, newState }: Event & { newState?: string }) {\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\tel.style.width = `${anchor.clientWidth}px`;\n\t\t\tanchorPosition(el, anchor, attr(el, \"data-position\") ?? \"bottom\", true);\n\t\t}\n\t}\n}\n// Update when typing\nfunction handleInput({ target: el }: Event) {\n\tif (isInputLike(el)) {\n\t\trenderCounter(el);\n\t\trenderTextareaSize(el);\n\n\t\t// Reposition list datalist // TODO Enhance by using style.bottom?\n\t\tconst list = el.hasAttribute(\"list\") && el.list;\n\t\tif (list)\n\t\t\tsetTimeout(() => {\n\t\t\t\tanchorPosition(list, el, attr(list, \"data-position\") ?? \"bottom\", true);\n\t\t\t}, 10);\n\t}\n}\n\nfunction handleValdiation(event: Event) {\n\tconst field = (event.target as Element)?.closest?.(`.${CSS_FIELD}`);\n\n\tif (event.type === \"invalid\" && field) event.preventDefault(); // Prevent browsers from showing default validation bubbles\n\thandleMutation(document.getElementsByClassName(CSS_FIELD), true); // Update state\n}\n\n// Position combobox when changing content\nfunction handleSelect({ target: el }: Event) {\n\tconst list = el instanceof UHTMLComboboxElement && el.list;\n\tif (list && !list?.hidden)\n\t\tsetTimeout(() => anchorPosition(list, el, 2, true), 10); // Reposition list if not hidden\n}\n\nonLoaded(() => {\n\tonMutation(document.documentElement, CSS_FIELD, handleMutation);\n\ton(document, \"comboboxbeforeselect\", handleSelect, QUICK_EVENT);\n\ton(document, \"input\", handleInput, QUICK_EVENT);\n\ton(document, \"invalid,submit\", handleValdiation, true); // Use capture as invalid and submit does not bubble\n\ton(document, \"toggle\", handleToggle, QUICK_EVENT); // Use capture since toggle does not bubble\n});\n"],"names":["CSS_FIELD","styles","CSS_VALIDATIONS","CSS_VALIDATION","getText","style","key","handleMutation","fields","validate","field","labels","descs","valids","combobox","input","valid","el","UHTMLComboboxElement","isInputLike","attr","desc","label","useId","renderCombobox","renderCounter","renderTextareaSize","textarea","control","list","limit","remainder","nextInvalid","prevInvalid","over","under","css","handleToggle","newState","UHTMLDataListElement","anchor","anchorPosition","handleInput","handleValdiation","event","handleSelect","onLoaded","onMutation","on","QUICK_EVENT"],"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\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];\n\nconst getText = (style: CSSStyleDeclaration, key: string) =>\n\tstyle.getPropertyValue(`--mtds-text-${key}`)?.slice(1, -1) || \"\"; // slice to trim quotes\n\nfunction handleMutation(fields: HTMLCollectionOf<Element>, validate?: boolean) {\n\tfor (const field of fields)\n\t\tif (field.isConnected) {\n\t\t\tconst labels: HTMLLabelElement[] = [];\n\t\t\tconst descs: Element[] = [];\n\t\t\tconst valids: 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\")) descs.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\tvalids.push(el);\n\t\t\t\t\tdescs.unshift(el);\n\t\t\t\t} else if (el instanceof HTMLParagraphElement)\n\t\t\t\t\tdescs.some((desc) => desc.contains(el)) || descs.push(el); // Only add if not already inside description\n\t\t\t}\n\n\t\t\tif (input) {\n\t\t\t\tfor (const label of labels) label.htmlFor = useId(input);\n\t\t\t\tif (validate && attr(field, \"data-validation\") === \"form\") {\n\t\t\t\t\tvalid = input.matches(\":valid\");\n\t\t\t\t\tfor (const el of valids) attr(el, \"hidden\", valid ? \"\" : null);\n\t\t\t\t}\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\", descs.map(useId).join(\" \") || null); // Remove if empty\n\t\t\t\tattr(input, \"aria-invalid\", `${!valid}`);\n\t\t\t}\n\t\t}\n}\n\n// iOS does not support field-sizing: content, so we need to manually resize\nfunction renderTextareaSize(textarea: Element) {\n\tif (textarea instanceof HTMLTextAreaElement) {\n\t\ttextarea.style.setProperty(\"--mtds-textarea-height\", \"auto\");\n\t\ttextarea.style.setProperty(\n\t\t\t\"--mtds-textarea-height\",\n\t\t\t`${textarea.scrollHeight}px`,\n\t\t);\n\t}\n}\n\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 handleToggle({ target: el, newState }: Event & { newState?: string }) {\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\tel.style.width = `${anchor.clientWidth}px`;\n\t\t\tanchorPosition(el, anchor, attr(el, \"data-position\") ?? \"bottom\", true);\n\t\t}\n\t}\n}\n// Update when typing\nfunction handleInput(event: Event) {\n\tif (isInputLike(event.target)) {\n\t\trenderCounter(event.target);\n\t\trenderTextareaSize(event.target);\n\t\thandleDatalistPosition(event); // Reposition list datalist // TODO Enhance by using style.bottom?\n\t}\n}\n\nfunction handleValdiation(event: Event) {\n\tconst field = (event.target as Element)?.closest?.(`.${CSS_FIELD}`);\n\n\tif (event.type === \"invalid\" && field) event.preventDefault(); // Prevent browsers from showing default validation bubbles\n\thandleMutation(document.getElementsByClassName(CSS_FIELD), true); // Update state\n}\n\n// Position combobox when changing content\nfunction handleDatalistPosition({ target: el }: Event) {\n\tconst list =\n\t\t(el instanceof UHTMLComboboxElement || el instanceof HTMLInputElement) &&\n\t\tel.list;\n\tif (list && !list?.hidden) {\n\t\tconst position = attr(list, \"data-position\") ?? \"bottom\";\n\t\tsetTimeout(() => anchorPosition(list, el, position, true), 10); // Reposition list if not hidden\n\t}\n}\n\nonLoaded(() => {\n\tonMutation(document.documentElement, CSS_FIELD, handleMutation);\n\ton(document, \"comboboxbeforeselect\", handleDatalistPosition, QUICK_EVENT);\n\ton(document, \"input\", handleInput, QUICK_EVENT);\n\ton(document, \"invalid,submit\", handleValdiation, true); // Use capture as invalid and submit does not bubble\n\ton(document, \"toggle\", handleToggle, QUICK_EVENT); // Use capture since toggle does not bubble\n});\n"],"names":["CSS_FIELD","styles","CSS_VALIDATIONS","CSS_VALIDATION","getText","style","key","handleMutation","fields","validate","field","labels","descs","valids","combobox","input","valid","el","UHTMLComboboxElement","isInputLike","attr","desc","label","useId","renderCombobox","renderCounter","renderTextareaSize","textarea","control","list","limit","remainder","nextInvalid","prevInvalid","over","under","css","handleToggle","newState","UHTMLDataListElement","anchor","anchorPosition","handleInput","event","handleDatalistPosition","handleValdiation","position","onLoaded","onMutation","on","QUICK_EVENT"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { ReactUcombobox, UHTMLComboboxElement } from '@u-elements/u-combobox';
2
2
  import { JSX } from 'react';
3
+ import { InputProps } from '../react';
3
4
  import { PolymorphicComponentPropWithRef } from '../react-types';
4
5
  import { AnchorPosition } from '../utils';
5
6
  type FieldBaseProps = {
@@ -34,18 +35,16 @@ export type FieldComboboxSelected = {
34
35
  export type FieldComboboxProps = ReactUcombobox & {
35
36
  "data-creatable"?: boolean;
36
37
  "data-multiple"?: boolean;
37
- "data-nofilter"?: boolean;
38
38
  onAfterChange?: (e: CustomEvent<HTMLDataElement>) => void;
39
- onBeforeChange?: (e: CustomEvent<HTMLDataElement>) => void;
40
39
  onAfterSelect?: (e: CustomEvent<HTMLDataElement>) => void;
41
- onBeforeSelect?: (e: CustomEvent<HTMLDataElement>) => void;
40
+ onBeforeChange?: (e: CustomEvent<HTMLDataElement>) => void;
42
41
  onBeforeMatch?: (e: CustomEvent<HTMLOptionElement>) => void;
42
+ onBeforeSelect?: (e: CustomEvent<HTMLDataElement>) => void;
43
43
  onSelectedChange?: (selected: FieldComboboxSelected) => void;
44
- disabled?: boolean;
45
44
  options?: FieldComboboxSelected;
46
- readOnly?: boolean;
47
45
  selected?: FieldComboboxSelected;
48
- };
46
+ } & Pick<InputProps, "disabled" | "readOnly" | "placeholder" | "type" | "name"> & // Allow input props to be passed down
47
+ Pick<FieldDatalistProps, "data-position" | "data-nofilter">;
49
48
  export declare const Field: FieldComponent & {
50
49
  Affixes: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
51
50
  Combobox: React.ForwardRefExoticComponent<Omit<FieldComboboxProps, "ref"> & React.RefAttributes<UHTMLComboboxElement>>;