@digdir/designsystemet-web 1.19.1 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/_vendors/@oddbird/popover-polyfill/dist/popover-fn.cjs +2 -2
- package/dist/cjs/_vendors/@oddbird/popover-polyfill/dist/popover-fn.cjs.map +1 -1
- package/dist/cjs/clickdelegatefor/clickdelegatefor.cjs +1 -1
- package/dist/cjs/clickdelegatefor/clickdelegatefor.cjs.map +1 -1
- package/dist/cjs/field/field.cjs +1 -1
- package/dist/cjs/field/field.cjs.map +1 -1
- package/dist/cjs/fieldset/fieldset.cjs +1 -1
- package/dist/cjs/fieldset/fieldset.cjs.map +1 -1
- package/dist/cjs/packages/web/package.cjs +1 -1
- package/dist/cjs/popover/popover.cjs +1 -1
- package/dist/cjs/popover/popover.cjs.map +1 -1
- package/dist/cjs/suggestion/suggestion.cjs +1 -1
- package/dist/cjs/suggestion/suggestion.cjs.map +1 -1
- package/dist/cjs/tooltip/tooltip.cjs +1 -1
- package/dist/cjs/tooltip/tooltip.cjs.map +1 -1
- package/dist/esm/_vendors/@oddbird/popover-polyfill/dist/popover-fn.js +2 -2
- package/dist/esm/_vendors/@oddbird/popover-polyfill/dist/popover-fn.js.map +1 -1
- package/dist/esm/clickdelegatefor/clickdelegatefor.js +1 -1
- package/dist/esm/clickdelegatefor/clickdelegatefor.js.map +1 -1
- package/dist/esm/field/field.js +1 -1
- package/dist/esm/field/field.js.map +1 -1
- package/dist/esm/fieldset/fieldset.js +1 -1
- package/dist/esm/fieldset/fieldset.js.map +1 -1
- package/dist/esm/packages/web/package.js +1 -1
- package/dist/esm/popover/popover.js +1 -1
- package/dist/esm/popover/popover.js.map +1 -1
- package/dist/esm/suggestion/suggestion.js +1 -1
- package/dist/esm/suggestion/suggestion.js.map +1 -1
- package/dist/esm/tooltip/tooltip.js +1 -1
- package/dist/esm/tooltip/tooltip.js.map +1 -1
- package/dist/index.js +95 -52
- package/dist/umd/index.js +8 -7
- package/dist/umd/index.js.map +1 -1
- package/package.json +8 -5
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ARIA_DESC as e,ARIA_LABEL as t,QUICK_EVENT as n,announce as r,attr as i,attrOrCSS as a,getComposedTarget as o,getRoot as s,isBrowser as c,on as l,onHotReload as u,onMutation as d,tag as f,warn as p}from"../utils/utils.js";import"../popover/popover.js";let m,h,g,_,v=0;const y=`data-color`,b=`data-color-scheme`,x=`data-size`,S=`data-tooltip`,C=c()&&/iPad|iPhone|iPod/.test(navigator.userAgent),w=`[${y}]`,T=`[${b}]`,E=`[${x}]`,D=`[${S}]`,O=e=>{e&&!(e instanceof HTMLElement)&&p(`setTooltipElement expects an HTMLElement, got: `,e),P(),v=0,m=e||void 0},k=(e=document)=>{for(let t of e?.querySelectorAll(D)||[])j(t)},A=(e,t)=>{if(!t)return k();for(let e of t)if(e.target!==m)if(e.attributeName===S)j(e.target);else for(let t of e.addedNodes)t.nodeType===1&&(t.hasAttribute(S)?j(t):k(t))},j=(n,o=!0)=>{let c=a(n,S)||``;if(c[0]===`#`&&(c=s(n).getElementById(c.slice(1))?.textContent?.trim()||``),c!==(n.getAttribute(`aria-label`)||n.getAttribute(`aria-description`))){let r=i(n,`role`)!==`img`&&n.textContent?.trim();i(n,S,c),i(n,t,r?null:c),i(n,e,r?c:null),n.tabIndex===-1&&p(`Missing tabindex="0" attribute on: `,n)}n===_&&m?.textContent!==c&&(m&&(m.textContent=c),c&&o&&document.activeElement===n&&r(c))},M=e=>{let t=o(e);if(!t||g===t||m?.contains(t))return;g=t;let n=g?.closest?.(D)||void 0;if(_!==n&&(_&&P(),_=n,n)){if(e.type===`focus`||C||300>Date.now()-v)return N();e.type===`mousemove`&&(h=setTimeout(N,300))}},N=()=>{if(!_)return P();m||=f(`div`,{class:`ds-tooltip`}),m.isConnected||document.body.appendChild(m);let e=_.closest(w),t=_.closest(T),n=_.closest(E),r=e!==t&&e?.contains(t);i(m,`popover`,`manual`),i(m,b,t?.getAttribute(b)||null),i(m,y,r&&e?.getAttribute(y)||null),i(m,x,n?.getAttribute(x)||null),j(_,!1),m.showPopover(),m.dispatchEvent(new CustomEvent(`ds-toggle-source`,{bubbles:!0,composed:!0,detail:_}))},P=e=>{(e?.type!==`keydown`||e?.key===`Escape`)&&(_&&m?.isConnected&&m.popover&&m.hidePopover(),e||(v=Date.now()),clearTimeout(h),_=void 0)};u(`tooltip`,()=>[l(document,`focus mousemove`,M,n),l(document,`keydown`,P,n),d(document,A,{attributeFilter:[S],attributes:!0,childList:!0,subtree:!0})]);export{k as initTooltips,O as setTooltipElement};
|
|
1
|
+
import{ARIA_DESC as e,ARIA_LABEL as t,QUICK_EVENT as n,announce as r,attr as i,attrOrCSS as a,getComposedTarget as o,getRoot as s,isBrowser as c,on as l,onHotReload as u,onMutation as d,tag as f,warn as p}from"../utils/utils.js";import"../popover/popover.js";let m,h,g,_,v=0;const y=`data-color`,b=`data-color-scheme`,x=`data-size`,S=`data-tooltip`,C=c()&&/iPad|iPhone|iPod/.test(navigator.userAgent),w=`[${y}]`,T=`[${b}]`,E=`[${x}]`,D=`[${S}]`,O=e=>{e&&!(e instanceof HTMLElement)&&p(`setTooltipElement expects an HTMLElement, got: `,e),P(),v=0,m=e||void 0},k=(e=document)=>{for(let t of e?.querySelectorAll(D)||[])j(t)},A=(e,t)=>{if(!t)return k();for(let e of t)if(e.target!==m){if(e.attributeName===S)j(e.target);else for(let t of e.addedNodes)t.nodeType===1&&(t.hasAttribute(S)?j(t):k(t))}},j=(n,o=!0)=>{let c=a(n,S)||``;if(c[0]===`#`&&(c=s(n).getElementById(c.slice(1))?.textContent?.trim()||``),c!==(n.getAttribute(`aria-label`)||n.getAttribute(`aria-description`))){let r=i(n,`role`)!==`img`&&n.textContent?.trim();i(n,S,c),i(n,t,r?null:c),i(n,e,r?c:null),n.tabIndex===-1&&p(`Missing tabindex="0" attribute on: `,n)}n===_&&m?.textContent!==c&&(m&&(m.textContent=c),c&&o&&document.activeElement===n&&r(c))},M=e=>{let t=o(e);if(!t||g===t||m?.contains(t))return;g=t;let n=g?.closest?.(D)||void 0;if(_!==n&&(_&&P(),_=n,n)){if(e.type===`focus`||C||300>Date.now()-v)return N();e.type===`mousemove`&&(h=setTimeout(N,300))}},N=()=>{if(!_)return P();m||=f(`div`,{class:`ds-tooltip`}),m.isConnected||document.body.appendChild(m);let e=_.closest(w),t=_.closest(T),n=_.closest(E),r=e!==t&&e?.contains(t);i(m,`popover`,`manual`),i(m,b,t?.getAttribute(b)||null),i(m,y,r&&e?.getAttribute(y)||null),i(m,x,n?.getAttribute(x)||null),j(_,!1),m.showPopover(),m.dispatchEvent(new CustomEvent(`ds-toggle-source`,{bubbles:!0,composed:!0,detail:_}))},P=e=>{(e?.type!==`keydown`||e?.key===`Escape`)&&(_&&m?.isConnected&&m.popover&&m.hidePopover(),e||(v=Date.now()),clearTimeout(h),_=void 0)};u(`tooltip`,()=>[l(document,`focus mousemove`,M,n),l(document,`keydown`,P,n),d(document,A,{attributeFilter:[S],attributes:!0,childList:!0,subtree:!0})]);export{k as initTooltips,O as setTooltipElement};
|
|
2
2
|
//# sourceMappingURL=tooltip.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip.js","names":[],"sources":["../../../src/tooltip/tooltip.ts"],"sourcesContent":["import '../popover/popover'; // Ensure popover is imported when using individual imports, since tooltip relies on it\nimport {\n ARIA_DESC,\n ARIA_LABEL,\n announce,\n attr,\n attrOrCSS,\n getComposedTarget,\n getRoot,\n isBrowser,\n on,\n onHotReload,\n onMutation,\n QUICK_EVENT,\n tag,\n warn,\n} from '../utils/utils';\n\nlet TIP: HTMLElement | undefined;\nlet TIMER: ReturnType<typeof setTimeout> | undefined;\nlet TARGET: Element | undefined; // Used to speed up mousemove handling\nlet OPEN: Element | undefined;\nlet LAST_HIDE = 0;\nconst ATTR_COLOR = 'data-color';\nconst ATTR_SCHEME = 'data-color-scheme';\nconst ATTR_SIZE = 'data-size';\nconst ATTR_TOOLTIP = 'data-tooltip';\nconst DELAY_HOVER = 300;\nconst DELAY_SKIP = 300;\nconst IS_IOS = isBrowser() && /iPad|iPhone|iPod/.test(navigator.userAgent); // Needed to omit DELAY_HOVER since iOS triggers mousemove before click\nconst SELECTOR_COLOR = `[${ATTR_COLOR}]`;\nconst SELECTOR_SCHEME = `[${ATTR_SCHEME}]`;\nconst SELECTOR_SIZE = `[${ATTR_SIZE}]`;\nconst SELECTOR_TOOLTIP = `[${ATTR_TOOLTIP}]`;\n\n/**\n * setTooltipElement\n * @description Allows setting a custom tooltip element. It does not need to, and should not, be injected to document.body, as we inject on hover to ensure React hydration works as expected.\n * @param el The HTMLElement to use as tooltip\n */\nexport const setTooltipElement = (el?: HTMLElement | null) => {\n if (el && !(el instanceof HTMLElement))\n warn('setTooltipElement expects an HTMLElement, got: ', el);\n hide(); // Reset when changing source\n LAST_HIDE = 0; // Reset last hide time to re-enable delay\n TIP = el || undefined;\n};\n\nexport const initTooltips = (\n scope: Element | ShadowRoot | Document | null = document,\n) => {\n for (const el of scope?.querySelectorAll(SELECTOR_TOOLTIP) || [])\n setupText(el);\n};\n\n// Initial run has no MutationRecords, so we set records to [null] to ensure we run the querySelectorAll for any existing elements with data-tooltip\nconst handleMutations = (_: Document, records?: MutationRecord[]) => {\n if (!records) return initTooltips();\n for (const r of records) {\n if (r.target === TIP) continue; // Ignore mutations on tooltip itself\n if (r.attributeName === ATTR_TOOLTIP) setupText(r.target as Element);\n else\n for (const el of r.addedNodes as NodeListOf<Element>) {\n if (el.nodeType !== 1) continue;\n if (el.hasAttribute(ATTR_TOOLTIP)) setupText(el);\n else initTooltips(el); // Check for any child elements with data-tooltip\n }\n }\n};\n\nconst setupText = (el: Element, canAnnounce = true) => {\n let text = attrOrCSS(el, ATTR_TOOLTIP) || '';\n\n // Allow using another element as source.\n // Note: Only checks on initial mutation, as we do not want to keep checking if the source element is removed or changed,\n // since this would be a performance issue. If the source element is removed, the tooltip will be empty and not shown.\n if (text[0] === '#')\n text = getRoot(el).getElementById(text.slice(1))?.textContent?.trim() || '';\n\n if (text !== (el.getAttribute(ARIA_LABEL) || el.getAttribute(ARIA_DESC))) {\n const hasText = attr(el, 'role') !== 'img' && el.textContent?.trim(); // If role=\"img\", ignore text\n attr(el, ATTR_TOOLTIP, text); // Set data-tooltip attribute to speed up future mutations\n attr(el, ARIA_LABEL, hasText ? null : text); // Set aria-label if element does not have text\n attr(el, ARIA_DESC, hasText ? text : null); // Set aria-description if element has text\n if ((el as HTMLElement).tabIndex === -1)\n warn('Missing tabindex=\"0\" attribute on: ', el);\n }\n if (el === OPEN && TIP?.textContent !== text) {\n if (TIP) TIP.textContent = text; // Update tooltip text if it is already open\n if (text && canAnnounce && document.activeElement === el) announce(text); // Only announce if focus is on the source\n }\n};\n\nconst handleInterest = (e: Event) => {\n const target = getComposedTarget(e);\n if (!target || TARGET === target || TIP?.contains(target as Node)) return; // Same target, or allow tooltip to be hovered (following https://www.w3.org/TR/WCAG21/#content-on-hover-or-focus)\n TARGET = target;\n\n const source = TARGET?.closest?.(SELECTOR_TOOLTIP) || undefined;\n if (OPEN === source) return; // Same source, no need to update\n if (OPEN) hide(); // Reset previous tooltip, since we are moving to a new source\n OPEN = source;\n\n if (!source) return; // No source, no need to show tooltip\n if (e.type === 'focus' || IS_IOS || DELAY_SKIP > Date.now() - LAST_HIDE)\n return show(); // Instantly show if focus or if we just closed a tooltip\n if (e.type === 'mousemove') TIMER = setTimeout(show, DELAY_HOVER); // Delay mouse showing tooltip if not already shown\n};\n\nconst show = () => {\n if (!OPEN) return hide(); // If no new anchor, cleanup previous autoUpdate\n if (!TIP) TIP = tag('div', { class: 'ds-tooltip' });\n if (!TIP.isConnected) document.body.appendChild(TIP);\n\n const color = OPEN.closest(SELECTOR_COLOR); // Match source color of source element\n const scheme = OPEN.closest(SELECTOR_SCHEME); // Match source color-scheme of source element\n const size = OPEN.closest(SELECTOR_SIZE); // Match source size of source element\n const isReset = color !== scheme && color?.contains(scheme as Node); // If data-scheme is closer to target, it will reset data-color\n\n attr(TIP, 'popover', 'manual'); // Ensure popover behavior\n attr(TIP, ATTR_SCHEME, scheme?.getAttribute(ATTR_SCHEME) || null); // Fallback to null to reset if not scheme found\n attr(TIP, ATTR_COLOR, (isReset && color?.getAttribute(ATTR_COLOR)) || null); // Fallback to null to reset if not scheme found\n attr(TIP, ATTR_SIZE, size?.getAttribute(ATTR_SIZE) || null); // Fallback to null to reset if not size found\n setupText(OPEN, false); // If mutation observer is not triggered, ensure tooltip text is updated\n TIP.showPopover();\n TIP.dispatchEvent(\n new CustomEvent('ds-toggle-source', {\n bubbles: true,\n composed: true, // Enable bubbling out of shadow DOM boundaries\n detail: OPEN, // Since showPopover({ source }) is not supported in all browsers yet\n }),\n );\n};\n\nconst hide = (event?: Partial<KeyboardEvent>) => {\n if (event?.type === 'keydown' && event?.key !== 'Escape') return;\n if (OPEN && TIP?.isConnected && TIP.popover) TIP.hidePopover(); // Only hide if connected and activated\n if (!event) LAST_HIDE = Date.now(); // If closing with keyboard, do not show next tooltip instantly\n clearTimeout(TIMER);\n OPEN = undefined;\n};\n\nonHotReload('tooltip', () => [\n on(document, 'focus mousemove', handleInterest, QUICK_EVENT),\n on(document, 'keydown', hide, QUICK_EVENT),\n onMutation(document, handleMutations, {\n attributeFilter: [ATTR_TOOLTIP],\n attributes: true,\n childList: true,\n subtree: true,\n }),\n]);\n"],"mappings":"mQAkBA,IAAI,EACA,EACA,EACA,EACA,EAAY,EAChB,MAAM,EAAa,aACb,EAAc,oBACd,EAAY,YACZ,EAAe,eAGf,EAAS,EAAU,GAAK,mBAAmB,KAAK,UAAU,SAAS,EACnE,EAAiB,IAAI,EAAW,GAChC,EAAkB,IAAI,EAAY,GAClC,EAAgB,IAAI,EAAU,GAC9B,EAAmB,IAAI,EAAa,GAO7B,EAAqB,GAA4B,CACxD,GAAM,EAAE,aAAc,cACxB,EAAK,kDAAmD,CAAE,EAC5D,EAAK,EACL,EAAY,EACZ,EAAM,GAAM,IAAA,EACd,EAEa,GACX,EAAgD,WAC7C,CACH,IAAK,IAAM,KAAM,GAAO,iBAAiB,CAAgB,GAAK,CAAC,EAC7D,EAAU,CAAE,CAChB,EAGM,GAAmB,EAAa,IAA+B,CACnE,GAAI,CAAC,EAAS,OAAO,EAAa,EAClC,IAAK,IAAM,KAAK,EACV,KAAE,SAAW,EACjB,
|
|
1
|
+
{"version":3,"file":"tooltip.js","names":[],"sources":["../../../src/tooltip/tooltip.ts"],"sourcesContent":["import '../popover/popover'; // Ensure popover is imported when using individual imports, since tooltip relies on it\nimport {\n ARIA_DESC,\n ARIA_LABEL,\n announce,\n attr,\n attrOrCSS,\n getComposedTarget,\n getRoot,\n isBrowser,\n on,\n onHotReload,\n onMutation,\n QUICK_EVENT,\n tag,\n warn,\n} from '../utils/utils';\n\nlet TIP: HTMLElement | undefined;\nlet TIMER: ReturnType<typeof setTimeout> | undefined;\nlet TARGET: Element | undefined; // Used to speed up mousemove handling\nlet OPEN: Element | undefined;\nlet LAST_HIDE = 0;\nconst ATTR_COLOR = 'data-color';\nconst ATTR_SCHEME = 'data-color-scheme';\nconst ATTR_SIZE = 'data-size';\nconst ATTR_TOOLTIP = 'data-tooltip';\nconst DELAY_HOVER = 300;\nconst DELAY_SKIP = 300;\nconst IS_IOS = isBrowser() && /iPad|iPhone|iPod/.test(navigator.userAgent); // Needed to omit DELAY_HOVER since iOS triggers mousemove before click\nconst SELECTOR_COLOR = `[${ATTR_COLOR}]`;\nconst SELECTOR_SCHEME = `[${ATTR_SCHEME}]`;\nconst SELECTOR_SIZE = `[${ATTR_SIZE}]`;\nconst SELECTOR_TOOLTIP = `[${ATTR_TOOLTIP}]`;\n\n/**\n * setTooltipElement\n * @description Allows setting a custom tooltip element. It does not need to, and should not, be injected to document.body, as we inject on hover to ensure React hydration works as expected.\n * @param el The HTMLElement to use as tooltip\n */\nexport const setTooltipElement = (el?: HTMLElement | null) => {\n if (el && !(el instanceof HTMLElement))\n warn('setTooltipElement expects an HTMLElement, got: ', el);\n hide(); // Reset when changing source\n LAST_HIDE = 0; // Reset last hide time to re-enable delay\n TIP = el || undefined;\n};\n\nexport const initTooltips = (\n scope: Element | ShadowRoot | Document | null = document,\n) => {\n for (const el of scope?.querySelectorAll(SELECTOR_TOOLTIP) || [])\n setupText(el);\n};\n\n// Initial run has no MutationRecords, so we set records to [null] to ensure we run the querySelectorAll for any existing elements with data-tooltip\nconst handleMutations = (_: Document, records?: MutationRecord[]) => {\n if (!records) return initTooltips();\n for (const r of records) {\n if (r.target === TIP) continue; // Ignore mutations on tooltip itself\n if (r.attributeName === ATTR_TOOLTIP) setupText(r.target as Element);\n else\n for (const el of r.addedNodes as NodeListOf<Element>) {\n if (el.nodeType !== 1) continue;\n if (el.hasAttribute(ATTR_TOOLTIP)) setupText(el);\n else initTooltips(el); // Check for any child elements with data-tooltip\n }\n }\n};\n\nconst setupText = (el: Element, canAnnounce = true) => {\n let text = attrOrCSS(el, ATTR_TOOLTIP) || '';\n\n // Allow using another element as source.\n // Note: Only checks on initial mutation, as we do not want to keep checking if the source element is removed or changed,\n // since this would be a performance issue. If the source element is removed, the tooltip will be empty and not shown.\n if (text[0] === '#')\n text = getRoot(el).getElementById(text.slice(1))?.textContent?.trim() || '';\n\n if (text !== (el.getAttribute(ARIA_LABEL) || el.getAttribute(ARIA_DESC))) {\n const hasText = attr(el, 'role') !== 'img' && el.textContent?.trim(); // If role=\"img\", ignore text\n attr(el, ATTR_TOOLTIP, text); // Set data-tooltip attribute to speed up future mutations\n attr(el, ARIA_LABEL, hasText ? null : text); // Set aria-label if element does not have text\n attr(el, ARIA_DESC, hasText ? text : null); // Set aria-description if element has text\n if ((el as HTMLElement).tabIndex === -1)\n warn('Missing tabindex=\"0\" attribute on: ', el);\n }\n if (el === OPEN && TIP?.textContent !== text) {\n if (TIP) TIP.textContent = text; // Update tooltip text if it is already open\n if (text && canAnnounce && document.activeElement === el) announce(text); // Only announce if focus is on the source\n }\n};\n\nconst handleInterest = (e: Event) => {\n const target = getComposedTarget(e);\n if (!target || TARGET === target || TIP?.contains(target as Node)) return; // Same target, or allow tooltip to be hovered (following https://www.w3.org/TR/WCAG21/#content-on-hover-or-focus)\n TARGET = target;\n\n const source = TARGET?.closest?.(SELECTOR_TOOLTIP) || undefined;\n if (OPEN === source) return; // Same source, no need to update\n if (OPEN) hide(); // Reset previous tooltip, since we are moving to a new source\n OPEN = source;\n\n if (!source) return; // No source, no need to show tooltip\n if (e.type === 'focus' || IS_IOS || DELAY_SKIP > Date.now() - LAST_HIDE)\n return show(); // Instantly show if focus or if we just closed a tooltip\n if (e.type === 'mousemove') TIMER = setTimeout(show, DELAY_HOVER); // Delay mouse showing tooltip if not already shown\n};\n\nconst show = () => {\n if (!OPEN) return hide(); // If no new anchor, cleanup previous autoUpdate\n if (!TIP) TIP = tag('div', { class: 'ds-tooltip' });\n if (!TIP.isConnected) document.body.appendChild(TIP);\n\n const color = OPEN.closest(SELECTOR_COLOR); // Match source color of source element\n const scheme = OPEN.closest(SELECTOR_SCHEME); // Match source color-scheme of source element\n const size = OPEN.closest(SELECTOR_SIZE); // Match source size of source element\n const isReset = color !== scheme && color?.contains(scheme as Node); // If data-scheme is closer to target, it will reset data-color\n\n attr(TIP, 'popover', 'manual'); // Ensure popover behavior\n attr(TIP, ATTR_SCHEME, scheme?.getAttribute(ATTR_SCHEME) || null); // Fallback to null to reset if not scheme found\n attr(TIP, ATTR_COLOR, (isReset && color?.getAttribute(ATTR_COLOR)) || null); // Fallback to null to reset if not scheme found\n attr(TIP, ATTR_SIZE, size?.getAttribute(ATTR_SIZE) || null); // Fallback to null to reset if not size found\n setupText(OPEN, false); // If mutation observer is not triggered, ensure tooltip text is updated\n TIP.showPopover();\n TIP.dispatchEvent(\n new CustomEvent('ds-toggle-source', {\n bubbles: true,\n composed: true, // Enable bubbling out of shadow DOM boundaries\n detail: OPEN, // Since showPopover({ source }) is not supported in all browsers yet\n }),\n );\n};\n\nconst hide = (event?: Partial<KeyboardEvent>) => {\n if (event?.type === 'keydown' && event?.key !== 'Escape') return;\n if (OPEN && TIP?.isConnected && TIP.popover) TIP.hidePopover(); // Only hide if connected and activated\n if (!event) LAST_HIDE = Date.now(); // If closing with keyboard, do not show next tooltip instantly\n clearTimeout(TIMER);\n OPEN = undefined;\n};\n\nonHotReload('tooltip', () => [\n on(document, 'focus mousemove', handleInterest, QUICK_EVENT),\n on(document, 'keydown', hide, QUICK_EVENT),\n onMutation(document, handleMutations, {\n attributeFilter: [ATTR_TOOLTIP],\n attributes: true,\n childList: true,\n subtree: true,\n }),\n]);\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { UHTMLComboboxElement } from "@u-elements/u-combobox";
|
|
|
4
4
|
import * as UTabs from "@u-elements/u-tabs";
|
|
5
5
|
export * from "@u-elements/u-datalist";
|
|
6
6
|
//#region package.json
|
|
7
|
-
var version = "1.
|
|
7
|
+
var version = "1.20.0";
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/utils/utils.ts
|
|
10
10
|
const ARIA_DESC = "aria-description";
|
|
@@ -212,9 +212,10 @@ const handleClickDelegateFor = (event) => {
|
|
|
212
212
|
const target = getComposedTarget(event);
|
|
213
213
|
const delegateTarget = event.button < 2 && getDelegateTarget(event);
|
|
214
214
|
if (!delegateTarget || delegateTarget.contains(target)) return;
|
|
215
|
+
for (const el of getComposedPath(target)) if (el.control === delegateTarget) return;
|
|
215
216
|
if (isNewTab && delegateTarget instanceof HTMLAnchorElement) return window.open(delegateTarget.href, void 0, delegateTarget.rel);
|
|
216
217
|
event.stopImmediatePropagation();
|
|
217
|
-
|
|
218
|
+
delegateTarget.click();
|
|
218
219
|
};
|
|
219
220
|
let HOVER;
|
|
220
221
|
let TARGET$1;
|
|
@@ -280,9 +281,14 @@ onHotReload("dialog", () => [
|
|
|
280
281
|
//#region src/fieldset/fieldset.ts
|
|
281
282
|
const FIELDSETS = isBrowser() ? document.getElementsByTagName("fieldset") : [];
|
|
282
283
|
const handleFieldsetMutations = () => {
|
|
283
|
-
for (const
|
|
284
|
-
if (
|
|
285
|
-
|
|
284
|
+
for (const fieldset of FIELDSETS) {
|
|
285
|
+
if (fieldset.hasAttribute("aria-labelledby")) continue;
|
|
286
|
+
let labelledby = "";
|
|
287
|
+
for (const el of fieldset.children) {
|
|
288
|
+
const name = el.nodeName;
|
|
289
|
+
if (name === "LEGEND" || el.getAttribute("data-field") === "description" || name === "P" && el.previousElementSibling?.nodeName === "LEGEND") labelledby += `${useId(el)} `;
|
|
290
|
+
}
|
|
291
|
+
attr(fieldset, ARIA_LABELLEDBY, labelledby.trim() || null);
|
|
286
292
|
}
|
|
287
293
|
};
|
|
288
294
|
onHotReload("fieldset", () => [onMutation(document, handleFieldsetMutations, {
|
|
@@ -699,7 +705,7 @@ function apply$1() {
|
|
|
699
705
|
//#region src/invokers/invokers.ts
|
|
700
706
|
if (isBrowser() && !isSupported$1()) apply$1();
|
|
701
707
|
//#endregion
|
|
702
|
-
//#region ../../node_modules/.pnpm/@oddbird+popover-polyfill@0.7.
|
|
708
|
+
//#region ../../node_modules/.pnpm/@oddbird+popover-polyfill@0.7.1_patch_hash=6227913935a153774e0e2569cb889d63767e7a5d572dbc6beeadfb2e77ed5c11/node_modules/@oddbird/popover-polyfill/dist/popover-fn.js
|
|
703
709
|
var ToggleEvent = class extends Event {
|
|
704
710
|
oldState;
|
|
705
711
|
newState;
|
|
@@ -1035,7 +1041,7 @@ function setInvokerAriaExpanded(el, force = false) {
|
|
|
1035
1041
|
var ShadowRoot2 = globalThis.ShadowRoot || function() {};
|
|
1036
1042
|
var DEFAULT_LAYER_NAME = "popover-polyfill";
|
|
1037
1043
|
function isSupported() {
|
|
1038
|
-
return typeof HTMLElement !== "undefined" && typeof HTMLElement.prototype === "object" && "popover" in HTMLElement.prototype;
|
|
1044
|
+
return typeof HTMLElement !== "undefined" && typeof HTMLElement.prototype === "object" && "popover" in HTMLElement.prototype && "showPopover" in HTMLElement.prototype;
|
|
1039
1045
|
}
|
|
1040
1046
|
function isPolyfilled() {
|
|
1041
1047
|
var _a;
|
|
@@ -1054,7 +1060,7 @@ function hasLayerSupport() {
|
|
|
1054
1060
|
function getStyles(layerName) {
|
|
1055
1061
|
var _a;
|
|
1056
1062
|
const useLayer = hasLayerSupport();
|
|
1057
|
-
const layerNameEscaped = (layerName ?? ((_a = window.POPOVER_POLYFILL_OPTIONS) == null ? void 0 : _a.layerName) ?? DEFAULT_LAYER_NAME).split(".").map(CSS.escape).join(".");
|
|
1063
|
+
const layerNameEscaped = (layerName ?? ((_a = window.POPOVER_POLYFILL_OPTIONS) == null ? void 0 : _a.layerName) ?? DEFAULT_LAYER_NAME).split(".").map((c) => CSS.escape(c)).join(".");
|
|
1058
1064
|
return `
|
|
1059
1065
|
${useLayer ? `@layer ${layerNameEscaped} {` : ""}
|
|
1060
1066
|
:where([popover]) {
|
|
@@ -1128,7 +1134,7 @@ function injectStyles(root, layerName) {
|
|
|
1128
1134
|
} catch {
|
|
1129
1135
|
popoverStyleSheet = false;
|
|
1130
1136
|
}
|
|
1131
|
-
if (popoverStyleSheet === false) {
|
|
1137
|
+
if (popoverStyleSheet === false || !root.adoptedStyleSheets) {
|
|
1132
1138
|
const sheet = document.createElement("style");
|
|
1133
1139
|
sheet.textContent = styles;
|
|
1134
1140
|
if (root instanceof Document) root.head.prepend(sheet);
|
|
@@ -1169,6 +1175,7 @@ function apply(opts) {
|
|
|
1169
1175
|
showPopover: {
|
|
1170
1176
|
enumerable: true,
|
|
1171
1177
|
configurable: true,
|
|
1178
|
+
writable: true,
|
|
1172
1179
|
value(options = {}) {
|
|
1173
1180
|
showPopover(this);
|
|
1174
1181
|
}
|
|
@@ -1176,6 +1183,7 @@ function apply(opts) {
|
|
|
1176
1183
|
hidePopover: {
|
|
1177
1184
|
enumerable: true,
|
|
1178
1185
|
configurable: true,
|
|
1186
|
+
writable: true,
|
|
1179
1187
|
value() {
|
|
1180
1188
|
hidePopover(this, true, true);
|
|
1181
1189
|
}
|
|
@@ -1183,6 +1191,7 @@ function apply(opts) {
|
|
|
1183
1191
|
togglePopover: {
|
|
1184
1192
|
enumerable: true,
|
|
1185
1193
|
configurable: true,
|
|
1194
|
+
writable: true,
|
|
1186
1195
|
value(options = {}) {
|
|
1187
1196
|
if (typeof options === "boolean") options = { force: options };
|
|
1188
1197
|
if (visibilityState.get(this) === "showing" && options.force === void 0 || options.force === false) hidePopover(this, true, true);
|
|
@@ -1282,7 +1291,7 @@ function apply(opts) {
|
|
|
1282
1291
|
const onKeydown = (event) => {
|
|
1283
1292
|
const key = event.key;
|
|
1284
1293
|
const target = event.target;
|
|
1285
|
-
if (!event.defaultPrevented && target && (key === "Escape" || key === "Esc")) hideAllPopoversUntil(target.ownerDocument, true, true);
|
|
1294
|
+
if (!event.defaultPrevented && target && (key === "Escape" || key === "Esc")) hideAllPopoversUntil(target.ownerDocument || target, true, true);
|
|
1286
1295
|
};
|
|
1287
1296
|
const addEventListeners = (root) => {
|
|
1288
1297
|
root.addEventListener("click", handleInvokerActivation);
|
|
@@ -1321,6 +1330,7 @@ function toggle(el, newState, oldState, source) {
|
|
|
1321
1330
|
const shiftProp = placement.match(/left|right/gi) ? "Height" : "Width";
|
|
1322
1331
|
const shiftLimit = source[`offset${shiftProp}`] / 2 + arrowSize;
|
|
1323
1332
|
if (placement === "none") return;
|
|
1333
|
+
let sized = false;
|
|
1324
1334
|
const options = {
|
|
1325
1335
|
strategy: "absolute",
|
|
1326
1336
|
placement,
|
|
@@ -1336,8 +1346,14 @@ function toggle(el, newState, oldState, source) {
|
|
|
1336
1346
|
crossAxis: false
|
|
1337
1347
|
})] : [],
|
|
1338
1348
|
...overscroll ? [size({ apply({ availableHeight }) {
|
|
1339
|
-
if (
|
|
1340
|
-
|
|
1349
|
+
if (sized) return;
|
|
1350
|
+
sized = true;
|
|
1351
|
+
const width = `${source.offsetWidth}px`;
|
|
1352
|
+
const maxHeight = `${Math.max(50, availableHeight - padding * 2)}px`;
|
|
1353
|
+
requestAnimationFrame(() => {
|
|
1354
|
+
if (overscroll === "fit" && el.style.width !== width) el.style.width = width;
|
|
1355
|
+
if (el.style.maxHeight !== maxHeight) el.style.maxHeight = maxHeight;
|
|
1356
|
+
});
|
|
1341
1357
|
} })] : []
|
|
1342
1358
|
]
|
|
1343
1359
|
};
|
|
@@ -1363,40 +1379,62 @@ const handleClick$1 = (e) => {
|
|
|
1363
1379
|
if (root instanceof ShadowRoot && !ROOTS.has(root)) ROOTS.set(root, on(root, "toggle", handleToggle, QUICK_EVENT));
|
|
1364
1380
|
};
|
|
1365
1381
|
onHotReload("popover", () => {
|
|
1366
|
-
const
|
|
1382
|
+
const descriptors = Object.getOwnPropertyDescriptors(HTMLElement.prototype);
|
|
1367
1383
|
const togglePopover = HTMLElement.prototype.togglePopover;
|
|
1368
1384
|
const showPopover = HTMLElement.prototype.showPopover;
|
|
1369
1385
|
const hidePopover = HTMLElement.prototype.hidePopover;
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1386
|
+
Object.defineProperties(HTMLElement.prototype, {
|
|
1387
|
+
togglePopover: {
|
|
1388
|
+
...descriptors.togglePopover,
|
|
1389
|
+
value(opt) {
|
|
1390
|
+
const isOpen = this.matches(":popover-open");
|
|
1391
|
+
const isBool = typeof opt === "boolean";
|
|
1392
|
+
const prev = isOpen ? "open" : "closed";
|
|
1393
|
+
const next = (isBool ? opt : opt?.force ?? !isOpen) ? "open" : "closed";
|
|
1394
|
+
const source = isBool ? void 0 : opt?.source;
|
|
1395
|
+
const result = togglePopover?.call(this, opt);
|
|
1396
|
+
toggle(this, next, prev, source);
|
|
1397
|
+
return result;
|
|
1398
|
+
}
|
|
1399
|
+
},
|
|
1400
|
+
showPopover: {
|
|
1401
|
+
...descriptors.showPopover,
|
|
1402
|
+
value(opt) {
|
|
1403
|
+
const prev = this.matches(":popover-open") ? "open" : "closed";
|
|
1404
|
+
const result = showPopover?.call(this, opt);
|
|
1405
|
+
toggle(this, "open", prev, opt?.source);
|
|
1406
|
+
return result;
|
|
1407
|
+
}
|
|
1408
|
+
},
|
|
1409
|
+
hidePopover: {
|
|
1410
|
+
...descriptors.hidePopover,
|
|
1411
|
+
value() {
|
|
1412
|
+
const prev = this.matches(":popover-open") ? "open" : "closed";
|
|
1413
|
+
const result = hidePopover?.call(this);
|
|
1414
|
+
toggle(this, "closed", prev);
|
|
1415
|
+
return result;
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
});
|
|
1392
1419
|
return [
|
|
1393
1420
|
on(document, "click", handleClick$1, QUICK_EVENT),
|
|
1394
1421
|
on(document, "pointerdown pointerup scroll", handleScrollbar, QUICK_EVENT),
|
|
1395
1422
|
on(document, "toggle ds-toggle-source", handleToggle, QUICK_EVENT),
|
|
1396
1423
|
() => {
|
|
1397
|
-
HTMLElement.prototype
|
|
1398
|
-
|
|
1399
|
-
|
|
1424
|
+
Object.defineProperties(HTMLElement.prototype, {
|
|
1425
|
+
togglePopover: {
|
|
1426
|
+
...descriptors.togglePopover,
|
|
1427
|
+
value: togglePopover
|
|
1428
|
+
},
|
|
1429
|
+
showPopover: {
|
|
1430
|
+
...descriptors.showPopover,
|
|
1431
|
+
value: showPopover
|
|
1432
|
+
},
|
|
1433
|
+
hidePopover: {
|
|
1434
|
+
...descriptors.hidePopover,
|
|
1435
|
+
value: hidePopover
|
|
1436
|
+
}
|
|
1437
|
+
});
|
|
1400
1438
|
for (const [, off] of ROOTS) off();
|
|
1401
1439
|
ROOTS.clear();
|
|
1402
1440
|
}
|
|
@@ -1688,9 +1726,12 @@ const render$2 = (self) => {
|
|
|
1688
1726
|
customElements.define("ds-error-summary", DSErrorSummaryElement);
|
|
1689
1727
|
//#endregion
|
|
1690
1728
|
//#region src/field/field.ts
|
|
1729
|
+
const ATTR_FIELD = "data-field";
|
|
1730
|
+
const ATTR_LIMIT = "data-limit";
|
|
1691
1731
|
const ATTR_INVALID = "aria-invalid";
|
|
1692
1732
|
const ATTR_DESCRIBEDBY = "aria-describedby";
|
|
1693
1733
|
const ATTR_INDETERMINATE = "data-indeterminate";
|
|
1734
|
+
const SELECTOR_VALIDATION = `:scope > [${ATTR_FIELD}="validation"]`;
|
|
1694
1735
|
const COUNTER_DEBOUNCE = isWindows() ? 800 : 200;
|
|
1695
1736
|
const WARNING_MULTIPLE_INPUTS = `Fields should only have one input element. Use <fieldset> to group multiple fields:`;
|
|
1696
1737
|
const handleFieldMutation = (field) => {
|
|
@@ -1706,22 +1747,22 @@ const handleFieldMutation = (field) => {
|
|
|
1706
1747
|
if (isInputLike(el)) if (field._input?.isConnected && field._input !== el) warn(WARNING_MULTIPLE_INPUTS, field);
|
|
1707
1748
|
else field._input = el;
|
|
1708
1749
|
else {
|
|
1709
|
-
const type = el.getAttribute(
|
|
1750
|
+
const type = el.getAttribute(ATTR_FIELD);
|
|
1710
1751
|
if (type === "counter") field._counter = el;
|
|
1711
1752
|
if (type === "validation") {
|
|
1712
1753
|
nextDescs.unshift(useId(el));
|
|
1713
1754
|
hasValidation = true;
|
|
1714
|
-
invalid = invalid ||
|
|
1755
|
+
invalid = invalid || isInvalidColor(el);
|
|
1715
1756
|
} else if (type) nextDescs.push(useId(el));
|
|
1716
1757
|
}
|
|
1717
1758
|
}
|
|
1718
1759
|
if (!field._input?.isConnected) return;
|
|
1719
1760
|
const input = field._input;
|
|
1720
1761
|
for (const label of labels) attr(label, "for", useId(input) || null);
|
|
1721
|
-
const fieldsetValidation = field.closest("fieldset")?.querySelector(
|
|
1762
|
+
const fieldsetValidation = field.closest("fieldset")?.querySelector(SELECTOR_VALIDATION);
|
|
1722
1763
|
if (fieldsetValidation && !fieldsetValidation?.hidden) {
|
|
1723
1764
|
hasValidation = true;
|
|
1724
|
-
invalid = invalid ||
|
|
1765
|
+
invalid = invalid || isInvalidColor(fieldsetValidation);
|
|
1725
1766
|
nextDescs.unshift(useId(fieldsetValidation));
|
|
1726
1767
|
}
|
|
1727
1768
|
const indeterminate = attr(input, ATTR_INDETERMINATE);
|
|
@@ -1732,7 +1773,7 @@ const handleFieldMutation = (field) => {
|
|
|
1732
1773
|
field._descs = nextDescs;
|
|
1733
1774
|
const hadValidation = field._validation;
|
|
1734
1775
|
if (hasValidation && !hadValidation && !input.hasAttribute(ATTR_INVALID)) {
|
|
1735
|
-
attr(input, ATTR_INVALID, "true");
|
|
1776
|
+
attr(input, ATTR_INVALID, invalid ? "true" : null);
|
|
1736
1777
|
field._validation = true;
|
|
1737
1778
|
} else if (!hasValidation && hadValidation) {
|
|
1738
1779
|
attr(input, ATTR_INVALID, null);
|
|
@@ -1745,9 +1786,12 @@ const TEXTS = {
|
|
|
1745
1786
|
under: "%d tegn igjen"
|
|
1746
1787
|
};
|
|
1747
1788
|
const debouncedCounterLiveRegion = debounce((input, text) => {
|
|
1748
|
-
if (document
|
|
1789
|
+
if (document?.activeElement === input) announce(text);
|
|
1749
1790
|
}, COUNTER_DEBOUNCE);
|
|
1750
|
-
const
|
|
1791
|
+
const isInvalidColor = (el) => {
|
|
1792
|
+
const color = el.getAttribute("data-color");
|
|
1793
|
+
return !color || color === "danger";
|
|
1794
|
+
};
|
|
1751
1795
|
const isInputLike = (el) => el instanceof HTMLElement && "validity" in el && !(el instanceof HTMLButtonElement) && el.type !== "hidden";
|
|
1752
1796
|
var DSFieldElement = class extends DSElement {
|
|
1753
1797
|
_counter;
|
|
@@ -1760,8 +1804,8 @@ var DSFieldElement = class extends DSElement {
|
|
|
1760
1804
|
this._unevents = on(this, "input", this, QUICK_EVENT);
|
|
1761
1805
|
this._unmutate = onMutation(this, () => handleFieldMutation(this), {
|
|
1762
1806
|
attributeFilter: [
|
|
1763
|
-
|
|
1764
|
-
|
|
1807
|
+
ATTR_FIELD,
|
|
1808
|
+
ATTR_LIMIT,
|
|
1765
1809
|
"hidden",
|
|
1766
1810
|
"id",
|
|
1767
1811
|
"value",
|
|
@@ -1775,13 +1819,14 @@ var DSFieldElement = class extends DSElement {
|
|
|
1775
1819
|
handleEvent(event) {
|
|
1776
1820
|
const { _counter, _input } = this;
|
|
1777
1821
|
if (_counter?.isConnected && _input) {
|
|
1778
|
-
const count = (Number(attr(_counter,
|
|
1822
|
+
const count = (Number(attr(_counter, ATTR_LIMIT)) || 0) - _input.value.length;
|
|
1779
1823
|
const state = count < 0 ? "over" : "under";
|
|
1780
1824
|
const label = (attrOrCSS(_counter, `data-${state}`) || TEXTS[state])?.replace("%d", `${Math.abs(count)}`);
|
|
1781
1825
|
if (!label) warn(`Missing data-${state} on:`, _counter);
|
|
1782
1826
|
attr(_counter, "data-label", label);
|
|
1783
1827
|
attr(_counter, "data-state", state);
|
|
1784
1828
|
attr(_counter, "data-color", count < 0 ? "danger" : null);
|
|
1829
|
+
attr(_input, "aria-invalid", count < 0 ? "true" : null);
|
|
1785
1830
|
if (event?.type === "input" && label) debouncedCounterLiveRegion(_input, label);
|
|
1786
1831
|
}
|
|
1787
1832
|
if (_input instanceof HTMLTextAreaElement) {
|
|
@@ -1902,14 +1947,12 @@ var DSSuggestionElement = class extends UHTMLComboboxElement {
|
|
|
1902
1947
|
const render = (self) => {
|
|
1903
1948
|
const { control, list } = self;
|
|
1904
1949
|
const datalist = list || self.querySelector("u-datalist");
|
|
1905
|
-
if (control)
|
|
1906
|
-
attr(control, "popovertarget", list ? useId(list) : null);
|
|
1907
|
-
if (!control.placeholder) attr(control, "placeholder", " ");
|
|
1908
|
-
}
|
|
1950
|
+
if (control) attr(control, "popovertarget", list ? useId(list) : null);
|
|
1909
1951
|
if (datalist) {
|
|
1910
1952
|
attr(datalist, "popover", "manual");
|
|
1911
1953
|
attr(datalist, "data-is-floating", "true");
|
|
1912
1954
|
}
|
|
1955
|
+
handleEmpty({ currentTarget: self });
|
|
1913
1956
|
};
|
|
1914
1957
|
const handleEmpty = ({ currentTarget: self }) => {
|
|
1915
1958
|
const { creatable, control, options } = self;
|