@evotecit/canopyx 0.3.16 → 0.3.18
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/CanopyX.Html/Assets/canopyx-board.css +50 -0
- package/CanopyX.Html/Assets/canopyx-board.js +39 -0
- package/CanopyX.Html/Assets/canopyx-buckets.js +15 -0
- package/CanopyX.Html/Assets/canopyx-calculations.css +7 -0
- package/CanopyX.Html/Assets/canopyx-calculations.js +52 -0
- package/CanopyX.Html/Assets/canopyx-calendar-edit.js +3 -3
- package/CanopyX.Html/Assets/canopyx-calendar.css +5 -24
- package/CanopyX.Html/Assets/canopyx-calendar.js +14 -19
- package/CanopyX.Html/Assets/canopyx-cell-range.js +16 -14
- package/CanopyX.Html/Assets/canopyx-changes.css +6 -24
- package/CanopyX.Html/Assets/canopyx-changes.js +18 -15
- package/CanopyX.Html/Assets/canopyx-compare.css +37 -0
- package/CanopyX.Html/Assets/canopyx-compare.js +12 -0
- package/CanopyX.Html/Assets/canopyx-data.js +3 -3
- package/CanopyX.Html/Assets/canopyx-editing.css +2 -2
- package/CanopyX.Html/Assets/canopyx-editing.js +2 -2
- package/CanopyX.Html/Assets/canopyx-enhance.js +4 -4
- package/CanopyX.Html/Assets/canopyx-export.js +54 -13
- package/CanopyX.Html/Assets/canopyx-facets.css +14 -5
- package/CanopyX.Html/Assets/canopyx-facets.js +19 -15
- package/CanopyX.Html/Assets/canopyx-filter-editor.css +71 -85
- package/CanopyX.Html/Assets/canopyx-filter-editor.js +20 -16
- package/CanopyX.Html/Assets/canopyx-flow-checks.css +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-checks.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-dialog.css +2 -2
- package/CanopyX.Html/Assets/canopyx-flow-dialog.js +1 -1
- package/CanopyX.Html/Assets/canopyx-flow-entry.css +136 -12
- package/CanopyX.Html/Assets/canopyx-flow-entry.js +2 -2
- package/CanopyX.Html/Assets/canopyx-flow-module.mjs +2 -2
- package/CanopyX.Html/Assets/canopyx-format-editor.js +2 -2
- package/CanopyX.Html/Assets/canopyx-formatting.js +10 -9
- package/CanopyX.Html/Assets/canopyx-grid-module.mjs +182 -128
- package/CanopyX.Html/Assets/canopyx-grid.css +228 -96
- package/CanopyX.Html/Assets/canopyx-grid.js +182 -128
- package/CanopyX.Html/Assets/canopyx-grouping.css +22 -15
- package/CanopyX.Html/Assets/canopyx-grouping.js +24 -17
- package/CanopyX.Html/Assets/canopyx-interactive.css +197 -74
- package/CanopyX.Html/Assets/canopyx-interactive.js +38 -45
- package/CanopyX.Html/Assets/canopyx-labels-de.js +177 -9
- package/CanopyX.Html/Assets/canopyx-labels-es.js +177 -9
- package/CanopyX.Html/Assets/canopyx-labels-fr.js +176 -8
- package/CanopyX.Html/Assets/canopyx-labels-it.js +176 -8
- package/CanopyX.Html/Assets/canopyx-labels-pl.js +176 -8
- package/CanopyX.Html/Assets/canopyx-layouts.css +48 -20
- package/CanopyX.Html/Assets/canopyx-layouts.js +36 -14
- package/CanopyX.Html/Assets/canopyx-link.js +2 -2
- package/CanopyX.Html/Assets/canopyx-live.css +1 -3
- package/CanopyX.Html/Assets/canopyx-live.js +3 -3
- package/CanopyX.Html/Assets/canopyx-matrix.css +1 -8
- package/CanopyX.Html/Assets/canopyx-matrix.js +11 -11
- package/CanopyX.Html/Assets/canopyx-module.mjs +38 -45
- package/CanopyX.Html/Assets/canopyx-office-export.js +2936 -0
- package/CanopyX.Html/Assets/canopyx-path.css +45 -0
- package/CanopyX.Html/Assets/canopyx-path.js +28 -0
- package/CanopyX.Html/Assets/canopyx-pivot.css +75 -0
- package/CanopyX.Html/Assets/canopyx-pivot.js +72 -0
- package/CanopyX.Html/Assets/canopyx-plan.css +56 -0
- package/CanopyX.Html/Assets/canopyx-plan.js +67 -0
- package/CanopyX.Html/Assets/canopyx-presenters.js +2 -2
- package/CanopyX.Html/Assets/canopyx-record-panel.css +8 -7
- package/CanopyX.Html/Assets/canopyx-record-panel.js +15 -14
- package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +222 -161
- package/CanopyX.Html/Assets/canopyx-reporting.css +240 -107
- package/CanopyX.Html/Assets/canopyx-reporting.js +222 -161
- package/CanopyX.Html/Assets/canopyx-stack.css +35 -0
- package/CanopyX.Html/Assets/canopyx-stack.js +24 -0
- package/CanopyX.Html/Assets/canopyx-time-slider.css +18 -0
- package/CanopyX.Html/Assets/canopyx-time-slider.js +27 -0
- package/CanopyX.Html/Assets/canopyx-timeline.js +6 -5
- package/CanopyX.Html/Assets/canopyx-tree-tools.css +36 -35
- package/CanopyX.Html/Assets/canopyx-tree-tools.js +15 -12
- package/CanopyX.Html/Assets/canopyx-ui-menu.css +41 -0
- package/CanopyX.Html/Assets/canopyx-ui-menu.js +64 -0
- package/CanopyX.Html/Assets/canopyx-ui-navigation.css +73 -0
- package/CanopyX.Html/Assets/canopyx-ui-navigation.js +39 -0
- package/CanopyX.Html/Assets/canopyx-ui-overlays.css +79 -0
- package/CanopyX.Html/Assets/canopyx-ui-overlays.js +42 -0
- package/CanopyX.Html/Assets/canopyx-ui-picker.css +12 -0
- package/CanopyX.Html/Assets/canopyx-ui-picker.js +6 -0
- package/CanopyX.Html/Assets/canopyx-ui-stepper.css +174 -0
- package/CanopyX.Html/Assets/canopyx-ui-stepper.js +48 -0
- package/CanopyX.Html/Assets/canopyx-ui-tabs.css +153 -0
- package/CanopyX.Html/Assets/canopyx-ui-tabs.js +47 -0
- package/CanopyX.Html/Assets/canopyx-values.css +5 -0
- package/CanopyX.Html/Assets/canopyx-values.js +13 -0
- package/CanopyX.Html/Assets/canopyx-view-intents.css +12 -0
- package/CanopyX.Html/Assets/canopyx-view-intents.js +56 -0
- package/CanopyX.Html/Assets/canopyx.css +197 -71
- package/CanopyX.Html/Assets/canopyx.js +29 -19
- package/JavaScript/board.d.ts +30 -0
- package/JavaScript/changes.d.ts +4 -1
- package/JavaScript/facets.d.ts +5 -3
- package/JavaScript/grid.d.ts +150 -16
- package/JavaScript/hosts.d.ts +14 -1
- package/JavaScript/index.d.ts +4 -2
- package/JavaScript/locales/de.mjs +177 -9
- package/JavaScript/locales/es.mjs +177 -9
- package/JavaScript/locales/fr.mjs +176 -8
- package/JavaScript/locales/it.mjs +176 -8
- package/JavaScript/locales/pl.mjs +176 -8
- package/JavaScript/matrix.d.ts +4 -1
- package/JavaScript/path.d.ts +33 -0
- package/JavaScript/pivot.d.ts +135 -0
- package/JavaScript/plan.d.ts +23 -0
- package/JavaScript/protocol.d.ts +16 -3
- package/JavaScript/records.d.ts +2 -0
- package/JavaScript/stack.d.ts +28 -0
- package/JavaScript/time-slider.d.ts +58 -0
- package/JavaScript/ui.d.ts +261 -0
- package/JavaScript/view-intents.d.ts +45 -0
- package/README.md +22 -3
- package/ThirdParty/OfficeIMO/LICENSE +21 -0
- package/ThirdParty/OfficeIMO/README.md +13 -0
- package/package.json +76 -3
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"c86ee2a16b5a5a46",requires:["ui-overlays"],install(context){if(installed.has(context.UI_IMPL))return;const{UI_IMPL,UI_TOOLS,h,setText,fill,watchTheme,overlayTheme,hostHtml}=context;let uiMenuIdentity=0;const uiMenuItemSelector='[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]';const uiMenuModels=new WeakMap();UI_TOOLS.menuItems=(menu,items,options={})=>{menu.replaceChildren();const render=(container,entries)=>{for(const item of entries||[]){const kind=String(item.kind||item.type||'').toLowerCase();if(kind==='separator'||kind==='grouplabel'){const decoration=h('div',kind==='separator'?'cx-menu-separator':'cx-menu-group-label');decoration.setAttribute('role',kind==='separator'?'separator':'presentation');if(kind!=='separator')setText(decoration,item.label);container.append(decoration);continue}
|
|
2
|
+
const button=h('button','cx-menu-item');button.type='button';button.tabIndex=-1;button.id='cx-ui-menu-item-' + ++uiMenuIdentity;button.dataset.itemId=String(item.id);button.dataset.hfxPart='menu-item';const role=kind==='radio'||item.role==='menuitemradio'?'menuitemradio':
|
|
3
|
+
kind==='checkbox'||item.checked!=null?'menuitemcheckbox':'menuitem';button.setAttribute('role',role);if(role!=='menuitem')button.setAttribute('aria-checked',String(!!item.checked));if(item.disabled)button.setAttribute('aria-disabled','true');button.dataset.state=item.disabled?'disabled':item.checked?'selected':'';button.dataset.danger=String(!!item.danger);if(item.group!=null)button.dataset.radioGroup=String(item.group);const icon=h('span','cx-menu-icon');icon.setAttribute('aria-hidden','true');if(item.icon!=null){icon.dataset.icon=String(item.icon);const rendered=options.renderIcon?.(item.icon,item);if(rendered?.nodeType)icon.append(rendered.cloneNode(true));else if(rendered!=null)setText(icon,rendered)}
|
|
4
|
+
button.append(icon);const label=h('span','cx-menu-label');setText(label,item.label);button.append(label);if(item.badge!=null&&item.badge!==''){const badge=h('span','cx-menu-badge');badge.dataset.hfxPart='badge';setText(badge,item.badge);button.append(badge)}
|
|
5
|
+
if(item.shortcut){const shortcut=h('kbd');setText(shortcut,item.shortcut);button.append(shortcut)}
|
|
6
|
+
uiMenuModels.set(button,item);container.append(button);if(item.items?.length){button.setAttribute('aria-haspopup','menu');button.setAttribute('aria-expanded','false');const child=h('div','cx-menu');child.id=button.id+'-menu';child.hidden=true;child.setAttribute('role','menu');child.setAttribute('aria-labelledby',button.id);child.dataset.hfxPart='menu';child.dataset.state='closed';button.setAttribute('aria-controls',child.id);const chevron=h('span','cx-menu-chevron');chevron.setAttribute('aria-hidden','true');setText(chevron,'›');button.append(chevron);container.append(child);render(child,item.items)}}};render(menu,items)};function uiMenuTriangle(point,origin,box){if(!point||!origin||!box)return false;const x=Math.abs(box.left-origin.x)<Math.abs(box.right-origin.x)?box.left:box.right;const a=origin,b={x,y:box.top},c={x,y:box.bottom};const cross=(p,q,r)=>(p.x-r.x)*(q.y-r.y)-(q.x-r.x)*(p.y-r.y);const d=[cross(point,a,b),cross(point,b,c),cross(point,c,a)];return!(d.some(value=>value<0)&&d.some(value=>value>0))}
|
|
7
|
+
UI_IMPL.menu=(root,options={},signal)=>{const lifetime=new AbortController(),ownSignal=lifetime.signal;const trigger=options.trigger||document.getElementById(root.dataset.cxTrigger||root.getAttribute('aria-labelledby'));const surface=options.surface||root;const directionBefore=surface.getAttribute('dir'),rootDirectionBefore=root.getAttribute('dir');let entries=[],children=new Map(),active=null,hoverTimer,searchTimer,search='',destroyed=false;let pointer,origin,pending,graceUntil=0;root.classList.add('cx-menu');root.setAttribute('role','menu');root.tabIndex=-1;root.dataset.hfxPart='menu';if(!root.id)root.id='cx-ui-menu-' + ++uiMenuIdentity;if(trigger&&options.decorateTrigger!==false){if(!trigger.id)trigger.id=root.id+'-trigger';trigger.setAttribute('aria-haspopup','menu');trigger.setAttribute('aria-controls',root.id);trigger.setAttribute('aria-expanded','false');root.setAttribute('aria-labelledby',trigger.id)}
|
|
8
|
+
if(options.label){root.setAttribute('aria-label',options.label);root.removeAttribute('aria-labelledby')}
|
|
9
|
+
const overlay=UI_TOOLS.overlay(surface,{kind:options.surface?'drawer':'menu',trigger,host:options.host||trigger||root,portal:options.portal,anchored:options.anchored??!options.surface,decorateTrigger:options.decorateTrigger,placement:options.placement||root.dataset.placement||'bottom-start',modal:!!options.surface,dismissible:true,initialFocus:()=>root},ownSignal);const owned=element=>element?.closest('[role="menu"]')===root;function focus(item){if(!item){root.focus({preventScroll:true});return}
|
|
10
|
+
for(const entry of entries)entry.tabIndex=entry===item?0:-1;active=item;item.focus({preventScroll:true})}
|
|
11
|
+
function closeChildren(except){for(const[entry,controller]of children)if(entry!==except)controller.close('parent',false,true)}
|
|
12
|
+
function openChild(item,keyboard){if(item.getAttribute('aria-disabled')==='true')return;const child=children.get(item);closeChildren(item);if(child&&!child.opened())child.open({focus:keyboard?'first':'none'})}
|
|
13
|
+
function clearHover(){clearTimeout(hoverTimer);pending=null;origin=null}
|
|
14
|
+
function hover(item){clearTimeout(hoverTimer);pending=item;const attempt=()=>{if(destroyed||!overlay.opened||!pending)return;const opened=[...children.values()].find(child=>child.opened());if(opened&&Date.now()<graceUntil&&uiMenuTriangle(pointer,origin,opened.element.getBoundingClientRect())){hoverTimer=setTimeout(attempt,150);return}
|
|
15
|
+
focus(pending);openChild(pending,false);pending=null};hoverTimer=setTimeout(attempt,150)}
|
|
16
|
+
function syncState(item){item.dataset.state=item.getAttribute('aria-disabled')==='true'?'disabled':
|
|
17
|
+
item.getAttribute('aria-checked')==='true'?'selected':''}
|
|
18
|
+
function activate(item,event){if(!item||item.getAttribute('aria-disabled')==='true')return;if(children.has(item)){openChild(item,true);return}
|
|
19
|
+
const role=item.getAttribute('role'),model=uiMenuModels.get(item);if(role==='menuitemcheckbox'||role==='menuitemradio'){if(role==='menuitemradio'){for(const peer of entries)if(peer.getAttribute('role')===role&&peer.dataset.radioGroup===item.dataset.radioGroup){peer.setAttribute('aria-checked','false');syncState(peer)}}
|
|
20
|
+
item.setAttribute('aria-checked',String(role==='menuitemradio'||item.getAttribute('aria-checked')!=='true'));syncState(item)}
|
|
21
|
+
const checked=item.hasAttribute('aria-checked')?item.getAttribute('aria-checked')==='true':undefined;const selected={...(model||{id:item.dataset.itemId,label:item.querySelector('.cx-menu-label')?.textContent||item.textContent}),...(checked!==undefined?{checked}:{})};const detail={id:item.dataset.itemId,item:selected,checked,element:item,originalEvent:event};if(role!=='menuitemcheckbox')(options.closeAll||close)('select');UI_TOOLS.emit(options.eventRoot||root,'menu','select',detail);options.onSelect?.(detail.item,event,item,detail)}
|
|
22
|
+
function keydown(event){if(!owned(event.target))return;const index=entries.indexOf(event.target),rtl=getComputedStyle(root).direction==='rtl';const forward=rtl?'ArrowLeft':'ArrowRight',backward=rtl?'ArrowRight':'ArrowLeft';if(['ArrowDown','ArrowUp','Home','End'].includes(event.key)){event.preventDefault();clearHover();const at=event.key==='Home'?0:event.key==='End'?entries.length-1:
|
|
23
|
+
(index +(event.key==='ArrowDown'?1:-1)+ entries.length)%entries.length;closeChildren();focus(entries[at])}else if(event.key===forward){event.preventDefault();clearHover();openChild(event.target,true)}
|
|
24
|
+
else if(event.key===backward&&options.parentItem){event.preventDefault();close('back')}
|
|
25
|
+
else if(event.key==='Enter'||event.key===' '){event.preventDefault();activate(event.target,event)}
|
|
26
|
+
else if(event.key==='Tab'){clearHover();(options.closeAll||close)('tab',false);(options.tabTrigger||trigger)?.focus({preventScroll:true})}else if(event.key.length===1&&!event.ctrlKey&&!event.metaKey&&!event.altKey){event.preventDefault();clearTimeout(searchTimer);search +=event.key.toLocaleLowerCase();const term=[...search].every(letter=>letter===search[0])?search[0]:search;const start=term.length>1?Math.max(index,0):index+1;const ordered=entries.slice(start).concat(entries.slice(0,start));const found=ordered.find(item=>(item.querySelector('.cx-menu-label')?.textContent||item.textContent).trim().toLocaleLowerCase().startsWith(term));if(found){closeChildren();focus(found)}
|
|
27
|
+
searchTimer=setTimeout(()=>{search=''},700)}}
|
|
28
|
+
function refresh(){if(destroyed)return;clearHover();for(const child of children.values())child.destroy();children=new Map();entries=[...root.querySelectorAll(uiMenuItemSelector)].filter(owned);for(const entry of entries){entry.classList.add('cx-menu-item');entry.dataset.hfxPart='menu-item';entry.tabIndex=-1;if(entry.disabled){entry.disabled=false;entry.setAttribute('aria-disabled','true')}
|
|
29
|
+
syncState(entry);if(entry.hasAttribute('aria-checked')){let icon=entry.querySelector('.cx-menu-icon');if(!icon){icon=h('span','cx-menu-icon');icon.setAttribute('aria-hidden','true');entry.prepend(icon)}
|
|
30
|
+
if(icon.textContent.trim()==='✓')icon.textContent=''}
|
|
31
|
+
const icon=entry.querySelector('.cx-menu-icon[data-icon]');if(icon&&!uiMenuModels.has(entry)&&options.renderIcon){const rendered=options.renderIcon(icon.dataset.icon,{id:entry.dataset.itemId});if(rendered?.nodeType)icon.replaceChildren(rendered.cloneNode(true));else if(rendered!=null)setText(icon,rendered)}
|
|
32
|
+
const childRoot=document.getElementById(entry.getAttribute('aria-controls'));if(childRoot?.getAttribute('role')==='menu'){children.set(entry,UI_IMPL.menu(childRoot,{...options,surface:null,trigger:entry,decorateTrigger:true,label:undefined,parentItem:entry,placement:getComputedStyle(options.host||trigger||root).direction==='rtl'?'left':'right',tabTrigger:options.tabTrigger||trigger,eventRoot:options.eventRoot||root,closeAll:options.closeAll||close},ownSignal))}}
|
|
33
|
+
active=entries.includes(active)?active:null;if(overlay.opened&&root.contains(document.activeElement))focus(active||entries[0])}
|
|
34
|
+
function open(settings={}){if(destroyed)return false;clearHover();search='';clearTimeout(searchTimer);surface.dir=root.dir=getComputedStyle(options.host||trigger||root).direction;if(options.surface)root.hidden=false;if(!overlay.open(settings))return false;root.dataset.state='open';if(settings.focus==='none')trigger?.focus({preventScroll:true});else focus(settings.focus==='last'?entries.at(-1):entries[0]);return true}
|
|
35
|
+
function close(reason='close',restoreFocus,force=false){clearHover();return overlay.close(reason,restoreFocus,force)}
|
|
36
|
+
function destroy(){if(destroyed)return;destroyed=true;clearHover();clearTimeout(searchTimer);for(const child of children.values())child.destroy();children.clear();overlay.destroy();lifetime.abort();if(directionBefore===null)surface.removeAttribute('dir');else surface.setAttribute('dir',directionBefore);if(rootDirectionBefore===null)root.removeAttribute('dir');else root.setAttribute('dir',rootDirectionBefore);signal?.removeEventListener('abort',destroy)}
|
|
37
|
+
root.addEventListener('keydown',keydown,{signal:ownSignal});root.addEventListener('click',event=>{const item=event.target.closest(uiMenuItemSelector);if(owned(item)){event.preventDefault();clearHover();activate(item,event)}},{signal:ownSignal});root.addEventListener('pointerover',event=>{if(event.pointerType==='touch')return;const item=event.target.closest(uiMenuItemSelector);if(owned(item)&&!item.contains(event.relatedTarget))hover(item)},{signal:ownSignal});root.addEventListener('pointerout',event=>{const item=event.target.closest(uiMenuItemSelector);if(owned(item)&&!item.contains(event.relatedTarget)){origin=pointer||{x:event.clientX,y:event.clientY};graceUntil=Date.now()+ 750}},{signal:ownSignal});document.addEventListener('pointermove',event=>{if(!overlay.opened)return;pointer={x:event.clientX,y:event.clientY};if([...children.values()].some(child=>child.opened()&&child.element.contains(event.target)))clearHover();else if(!root.contains(event.target)&&![...children.values()].some(child=>child.opened()))clearHover()},{signal:ownSignal});surface.addEventListener(options.surface?'cx-drawer:close':'cx-menu:close',event=>{if(event.target!==surface)return;clearHover();search='';root.dataset.state='closed';for(const entry of entries)entry.tabIndex=-1},{signal:ownSignal});if(trigger&&options.bindTrigger!==false&&!options.parentItem){trigger.addEventListener('click',()=>overlay.opened?close():open(),{signal:ownSignal});trigger.addEventListener('keydown',event=>{if(['Enter',' ','ArrowDown','ArrowUp'].includes(event.key)){event.preventDefault();open({focus:event.key==='ArrowUp'?'last':'first'})}},{signal:ownSignal})}
|
|
38
|
+
signal?.addEventListener('abort',destroy,{once:true});refresh();if(signal?.aborted)destroy();return{element:root,open,close,refresh,destroy,opened:()=>overlay.opened}};UI_IMPL.contextMenu=(target,itemsOrFactory,options={})=>{const lifetime=new AbortController(),signal=lifetime.signal;const delegated=typeof target==='string',listener=delegated?document:target;const editable='a[href],area[href],input,textarea,select,[contenteditable]:not([contenteditable="false"]),[role="textbox"]';let current,pressTimer,press,suppressClick=false,destroyed=false,pressSelection=null;const nodeOf=event=>event?.target?.nodeType===1?event.target:event?.target?.parentElement;const match=event=>{const node=nodeOf(event),element=delegated?node?.closest(target):target.contains(node)?target:null;return element&&(options.match?options.match(event,element):element)};const keyboard=event=>event?.type==='keydown'||event?.type==='contextmenu'&&event.button!==2&&event.clientX===0&&event.clientY===0;const selected=event=>event?.type==='contextmenu'&&pressSelection!==null?!!pressSelection:!!document.getSelection()?.toString();const nativeMenu=event=>!!event&&((event.shiftKey&&!keyboard(event))||!!nodeOf(event)?.closest(editable)||selected(event));function clearPress(){clearTimeout(pressTimer);pressTimer=null;press=null}
|
|
39
|
+
function release(entry,reason){if(current!==entry)return;current=null;entry.surface.removeEventListener(entry.closeEvent,entry.closed);entry.surface.removeEventListener('contextmenu',entry.native);entry.controller?.destroy();entry.menu.remove();entry.sheet?.remove();for(const[name,value]of entry.before){const now=entry.anchor.getAttribute(name);if(now!==entry.written.get(name))continue;if(value===null)entry.anchor.removeAttribute(name);else entry.anchor.setAttribute(name,value)}
|
|
40
|
+
options.onClose?.({...entry.detail,reason})}
|
|
41
|
+
function close(reason='close',restoreFocus=true,force=false){clearPress();return current?current.controller.close(reason,restoreFocus,force):true}
|
|
42
|
+
function open(event,element,settings={}){if(destroyed||event?.defaultPrevented&&!settings.touch||nativeMenu(event)||!element?.isConnected)return false;const prepared=options.beforeOpen?.(event,element,settings);if(prepared===false||destroyed)return false;if(prepared?.nodeType===1)element=prepared;if(!element.isConnected)return false;const items=typeof itemsOrFactory==='function'?itemsOrFactory(event,element):itemsOrFactory;if(!items?.length||destroyed||!element.isConnected)return false;close('replace',false,true);const menu=h('div','cx-menu');menu.hidden=true;menu.dataset.contextMenu='';menu.setAttribute('role','menu');menu.dataset.hfxPart='menu';if(options.variant)menu.dataset.hfxVariant=options.variant;document.body.append(menu);UI_TOOLS.menuItems(menu,items,options);const touch=!!settings.touch,byKey=settings.keyboard??keyboard(event);const label=(typeof options.label==='function'?options.label(event,element):options.label)||
|
|
43
|
+
element.getAttribute('aria-label')||element.textContent.trim()||UI_TOOLS.labels(options.labels).stateDetails;let sheet;if(touch){sheet=h('dialog','cx-drawer cx-context-sheet');sheet.dataset.side='bottom';sheet.dataset.hfxPart='drawer';sheet.hidden=true;sheet.setAttribute('aria-label',label);document.body.append(sheet);sheet.append(menu)}
|
|
44
|
+
const anchor=options.anchor?.(event,element)||(byKey&&!options.match&&nodeOf(event))||element;const before=['tabindex'].map(name=>[name,anchor.getAttribute(name)]);if(!anchor.matches('button,input,select,textarea,a[href],[tabindex]'))anchor.tabIndex=-1;const surface=sheet||menu,detail={menu,surface,element,event,touch};const entry=current={menu,sheet,surface,anchor,before,detail,written:new Map(),closeEvent:sheet?'cx-drawer:close':'cx-menu:close'};entry.controller=UI_IMPL.menu(menu,{...options,trigger:anchor,host:options.host||element,eventRoot:options.eventRoot||options.host||element,surface:sheet,bindTrigger:false,decorateTrigger:false,label},signal);entry.closed=ev=>{if(ev.target===surface)release(entry,ev.detail.reason)};entry.native=ev=>{if(!nativeMenu(ev))ev.preventDefault()};surface.addEventListener(entry.closeEvent,entry.closed);surface.addEventListener('contextmenu',entry.native);entry.written=new Map(before.map(([name])=>[name,anchor.getAttribute(name)]));const opened=entry.controller.open({modal:touch,point:settings.point||
|
|
45
|
+
(!byKey&&!touch&&event?{x:event.clientX,y:event.clientY}:undefined)});if(current!==entry)return false;entry.written=new Map(before.map(([name])=>[name,anchor.getAttribute(name)]));if(!opened){release(entry,'cancel');return false}
|
|
46
|
+
options.onOpen?.(detail);return current===entry}
|
|
47
|
+
listener.addEventListener('contextmenu',event=>{if(event.defaultPrevented||nativeMenu(event))return;if(current?.surface.contains(event.target)){event.preventDefault();return}
|
|
48
|
+
const element=match(event);if(!element)return;if(suppressClick||press||event.pointerType==='touch'){event.preventDefault();return}
|
|
49
|
+
if(open(event,element)){event.preventDefault();if(pressSelection==='')document.getSelection()?.removeAllRanges()}},{signal});document.addEventListener('pointerdown',event=>{pressSelection=event.button===2?document.getSelection()?.toString()||'':null},{signal,capture:true});document.addEventListener('keydown',()=>{pressSelection=null},{signal,capture:true});listener.addEventListener('keydown',event=>{if(event.defaultPrevented||event.key!=='ContextMenu'&&!(event.key==='F10'&&event.shiftKey))return;const element=match(event);if(element&&open(event,element,{keyboard:true})){event.preventDefault();event.stopPropagation()}},{signal});listener.addEventListener('pointerdown',event=>{clearPress();suppressClick=false;const element=match(event);if(event.pointerType!=='touch'||!element||nativeMenu(event)||event.isPrimary===false||options.gesture?.(event,element)===false)return;press={id:event.pointerId,x:event.clientX,y:event.clientY};pressTimer=setTimeout(()=>{if(press&&open(event,element,{touch:true}))suppressClick=true;clearPress()},500)},{signal});document.addEventListener('pointermove',event=>{if(press&&event.pointerId===press.id&&Math.hypot(event.clientX-press.x,event.clientY-press.y)>10)clearPress()},{signal,passive:true});for(const type of['pointerup','pointercancel','scroll'])document.addEventListener(type,clearPress,{signal,capture:true,passive:true});listener.addEventListener('click',event=>{if(suppressClick&&match(event)){event.preventDefault();event.stopPropagation();suppressClick=false}},{signal,capture:true});if(options.closeOnFocusOutside)document.addEventListener('focusin',event=>{if(current&&!current.surface.contains(event.target)&&!current.anchor.contains(event.target))close('blur',false)},{signal});global.addEventListener('blur',clearPress,{signal});const dispose=()=>{if(!destroyed){destroyed=true;clearPress();close('destroy',false,true);lifetime.abort()}};dispose.open=open;dispose.close=close;return dispose};UI_IMPL.treeActions={start(hostControl){const signal=this.interactionUiLifetime.signal;this.grid.addEventListener("scroll",()=>{const panel=this.interactionPanel;if(panel&&(panel._cxScrollTop!==this.grid.scrollTop||panel._cxScrollLeft!==this.grid.scrollLeft))this.closeInteractionPanel(false)},{signal,passive:true});global.addEventListener("resize",()=>this.closeInteractionPanel(),{signal});this.actionMenuBinding=UI_IMPL.contextMenu(this.grid,(_event,row)=>{const w=row._w,items=this.actionMenuItems(w);return row._w===w&&this.rendered.get(w)===row?items:[]},{host:this.host,label:this.labels.actions,closeOnFocusOutside:true,match:event=>{const row=event.target.closest(".cx-row");return row&&this.grid.contains(row)&&!hostControl(event.target)?row:null},beforeOpen:(_event,row,settings)=>{const w=settings.node||row._w,revision=(this.uiWorkRevision||0)+(this.interactionPanel?1:0);if(!this.actionMenuEligible(w)||row._w!==w)return false;if(this.interactionPanel)this.closeInteractionPanel(false);if(this.interactionClosing||this.destroyed||(this.uiWorkRevision||0)!==revision)return false;this.render();return this.actionMenuEligible(w)&&(this.uiWorkRevision||0)===revision&&this.rendered.get(w)?.isConnected?this.rendered.get(w):false},onOpen:({menu,element})=>{this.interactionPanel=menu;this.panelNode=element._w;menu._cxScrollTop=this.grid.scrollTop;menu._cxScrollLeft=this.grid.scrollLeft;document.dispatchEvent(new CustomEvent("canopyx:closemenus",{detail:{source:menu}}))},onClose:({menu})=>{if(this.interactionPanel!==menu)return;this.interactionPanel=null;this.panelNode=null;this.uiWorkRevision=(this.uiWorkRevision||0)+ 1},onSelect:item=>{Promise.resolve().then(()=>item.run()).catch(error=>this.emit("error",{error}))}});signal.addEventListener("abort",()=>this.actionMenuBinding(),{once:true})},openInteractionPanel(w,anchor,role,label){const revision=(this.uiWorkRevision||0)+(this.interactionPanel?1:0);this.closeInteractionPanel(false);if(this.destroyed||this.interactionClosing||this.interactionPanel||(this.uiWorkRevision||0)!==revision)return null;this.render();anchor=this.rendered.get(w);if(this.destroyed||this.interactionClosing||this.interactionPanel||(this.uiWorkRevision||0)!==revision||!anchor?.isConnected)return null;const panel=this.interactionPanel=h("div","cx-interaction-panel"),lifetime=new AbortController();const signal=lifetime.signal;panel.setAttribute("role",role);panel.setAttribute("aria-label",label);panel.dataset.hfxPart="popover";panel.style.inset="auto";panel.style.margin="0";this.panelNode=w;this.host.appendChild(panel);panel._cxLifetime=lifetime;panel._cxOverlay=UI_TOOLS.overlay(panel,{host:this.host,trigger:anchor,kind:"popover",focus:false,decorateTrigger:false},signal);panel.addEventListener("pointerdown",()=>{panel._cxPointerFocus=panel.contains(document.activeElement)},{signal});const rememberFocus=event=>{if(event.target!==panel)return;const active=document.activeElement;panel._cxOwnedFocus=panel.contains(active)||panel._cxPointerFocus&&(active===document.body||active===document.documentElement)};for(const type of["cx-popover:cancel","cx-popover:beforeclose"])panel.addEventListener(type,rememberFocus,{signal});panel.addEventListener("cx-popover:close",event=>{if(event.target===panel&&this.interactionPanel===panel)this.closeInteractionPanel(event.detail.reason==="cancel")},{signal});this.interactionUiLifetime.signal.addEventListener("abort",()=>lifetime.abort(),{once:true,signal});panel._cxOverlay.open();return this.interactionPanel===panel&&!this.destroyed&&(this.uiWorkRevision||0)===revision?panel:null},closeInteractionPanel(restoreFocus=true){const panel=this.interactionPanel,controller=this.editorController,w=this.panelNode;if(!panel){this.actionMenuBinding?.close("replace",false,true);return null}
|
|
50
|
+
const active=document.activeElement;const owned=panel._cxOwnedFocus||panel.contains(active)||panel._cxPointerFocus&&(active===document.body||active===document.documentElement);if(panel.getAttribute("role")==="menu"){this.actionMenuBinding.close("close",false,true);const focus=owned?{node:w,revision:this.uiWorkRevision}:null;if(restoreFocus)this.restoreInteractionFocus(focus);return focus}
|
|
51
|
+
if(controller&&this.uiPendingOperation&&this.uiPendingOperation.controller===controller){this.uiPendingOperation=null;setText(this.live,"")}
|
|
52
|
+
this.uiWorkRevision=(this.uiWorkRevision||0)+ 1;const focus=owned?{node:w,revision:this.uiWorkRevision}:null;this.interactionPanel=null;this.panelNode=null;this.editorController=null;panel._cxLifetime.abort();panel.remove();this.abortInteractionController(controller);if(restoreFocus)this.restoreInteractionFocus(focus);return focus},placeInteractionPanel(anchor){const panel=this.interactionPanel;if(!panel||panel.getAttribute("role")==="menu")return;UI_TOOLS.position(panel,anchor,"bottom-start");panel._cxScrollTop=this.grid.scrollTop;panel._cxScrollLeft=this.grid.scrollLeft},async performInteraction(work,controller=null){this.uiWorkRevision=(this.uiWorkRevision||0)+ 1;const operation=this.uiPendingOperation={controller};setText(this.live,this.labels.interactionPending);try{const accepted=await work();if(!this.destroyed&&this.uiPendingOperation===operation)setText(this.live,accepted?"":this.labels.interactionRejected);return accepted}catch(error){if(!this.destroyed&&this.uiPendingOperation===operation)setText(this.live,fill(this.labels.interactionFailed,{error:error&&error.message||String(error)}));return false}finally{if(this.uiPendingOperation===operation)this.uiPendingOperation=null}},beginEdit(id,columnId,cellIsObject){if(this.destroyed||this.interactionClosing||this.initializing||this.restoring||!this.opts.onEdit)return false;const w=this.interactionNode(id),index=this.columns.findIndex(column=>column.id===columnId),column=this.columns[index];if(!w||!column||!column.editable||column.hidden||!this.eligible("canEdit",w.h,column))return false;const row=this.rendered.get(w);if(!row||!row.isConnected)return false;const label=fill(this.labels.editValue,{column:column.title});const panel=this.openInteractionPanel(w,row,"dialog",label);if(!panel)return false;const controller=this.editorController=new AbortController();const raw=this.cellOf(w.h,column,index),value=cellIsObject(raw)?raw.value:raw;const input=h("input","cx-editor");input.type=column.kind==="number"||typeof value==="number"?"number":typeof value==="boolean"?"checkbox":"text";if(input.type==="number"){input.step="any";input.required=true}
|
|
53
|
+
input.checked=value===true;input.value=value==null?"":String(value);input.setAttribute("aria-label",label);input.addEventListener("input",()=>input.setCustomValidity(""));const controls=h("div","cx-interaction-buttons");const save=h("button","cx-save"),cancel=h("button");save.type=cancel.type="button";setText(save,this.labels.saveEdit);setText(cancel,this.labels.cancelEdit);const title=h("div","cx-interaction-title");setText(title,label);controls.append(save,cancel);panel.append(title,input,controls);const submit=async()=>{if(save.disabled)return;let next=input.type==="checkbox"?input.checked:input.value;if(input.type==="number"){if(!input.value.trim()||!Number.isFinite(Number(input.value))){input.setCustomValidity(fill(this.labels.invalidEdit,{column:column.title}));input.reportValidity();return}
|
|
54
|
+
next=Number(input.value)}
|
|
55
|
+
input.setCustomValidity("");input.disabled=save.disabled=true;cancel.focus();const accepted=await this.performInteraction(()=>this.requestEdit(id,columnId,next,{signal:controller.signal,reason:"editor"}),controller);if(this.interactionPanel!==panel)return;if(accepted)this.closeInteractionPanel();else{input.disabled=save.disabled=false;input.focus()}};save.addEventListener("click",submit);cancel.addEventListener("click",()=>this.closeInteractionPanel());panel.addEventListener("keydown",event=>{if(event.key==="Enter"&&event.target===input){event.preventDefault();submit()}});this.placeInteractionPanel(row);input.focus();if(input.type!=="checkbox")input.select();return true},moveSources(w){if(!this.view.dragDrop||!this.opts.onDrop||this.destroyed||this.interactionClosing||this.initializing||this.restoring||!w||w.status||w.h.detail)return false;const nodes=this.selected.has(w)?Array.from(this.selected).filter(node=>!node.h.detail):[w];if(!nodes.length||!nodes.every(node=>this.keyMap.get(node.key)===node&&!node._invalidated&&this.eligible("canDrag",node.h)))return false;return nodes},markMove(w){const nodes=this.moveSources(w);if(!nodes)return false;this.moveNodes=nodes;this.cacheDirty=true;setText(this.live,this.labels.markMove);return true},moveTarget(w,placement="inside"){if(!this.moveNodes||!w||w.status||w.h.detail||this.destroyed)return false;const nodes=this.moveNodes;if(nodes.some(node=>node._invalidated||this.keyMap.get(node.key)!==node))return false;return!!this.prepareDrop(nodes.map(node=>node.key),w.key,placement)&&this.moveNodes===nodes},async moveTo(w,placement,reason="menu"){if(!this.moveTarget(w,placement))return false;const nodes=this.moveNodes;this.moveNodes=null;this.cacheDirty=true;return this.performInteraction(()=>this.requestDrop(nodes.map(node=>node.key),w.key,placement,{reason}))},actionMenuEligible(w){return!this.destroyed&&!this.interactionClosing&&!this.initializing&&!this.restoring&&
|
|
56
|
+
!!w&&!w.status&&!w.h.detail&&!w._invalidated&&this.keyMap.get(w.key)===w},actionMenuItems(w){if(!this.actionMenuEligible(w))return[];const items=[];if(this.opts.onEdit)for(const column of this.columns){if(column.editable&&!column.hidden)items.push({id:"edit:"+column.id,label:fill(this.labels.editValue,{column:column.title}),disabled:!this.eligible("canEdit",w.h,column),run:()=>this.beginEdit(w.key,column.id)})}
|
|
57
|
+
if(this.opts.onAction)for(const action of this.interactions.actions)items.push({id:"action:"+action.id,label:action.label,disabled:!this.eligible("isActionEnabled",w.h,action),run:()=>this.performInteraction(()=>this.requestAction(w.key,action.id,{reason:"menu"}))});if(this.view.dragDrop&&this.opts.onDrop){items.push({id:"move:mark",label:this.labels.markMove,disabled:!this.moveSources(w),run:()=>this.markMove(w)});if(this.moveNodes){for(const[placement,label]of[["inside","moveHere"],["before","moveBefore"],["after","moveAfter"]])
|
|
58
|
+
items.push({id:"move:"+placement,label:this.labels[label],disabled:!this.moveTarget(w,placement),run:()=>this.moveTo(w,placement)});items.push({id:"move:cancel",label:this.labels.cancelMove,run:()=>{this.moveNodes=null;this.cacheDirty=true}})}}
|
|
59
|
+
return this.actionMenuEligible(w)?items:[]},openActionMenu(w,anchor){if(!this.actionMenuEligible(w)||!anchor?.isConnected||!this.actionMenuBinding)return false;const hasItems=this.opts.onEdit&&this.columns.some(column=>column.editable&&!column.hidden)||
|
|
60
|
+
this.opts.onAction&&this.interactions.actions.length||this.view.dragDrop&&this.opts.onDrop;if(!hasItems)return false;const opened=this.actionMenuBinding.open(null,anchor,{keyboard:true,node:w});if(opened?.then){opened.catch(error=>{if(!this.destroyed)this.emit("error",{error})});return true}
|
|
61
|
+
return opened},onKey(event,hostControl){if(!event.defaultPrevented&&!event.isComposing&&!hostControl(event.target)&&event.ctrlKey&&event.shiftKey&&!event.altKey){const row=event.target.closest(".cx-row"),w=row&&row._w;if(event.key.toLowerCase()==="x"&&this.markMove(w)){event.preventDefault();event.stopPropagation();return true}
|
|
62
|
+
if(event.key.toLowerCase()==="v"&&this.moveTarget(w)){event.preventDefault();event.stopPropagation();this.moveTo(w,"inside","keyboard");return true}}
|
|
63
|
+
return false},};UI_IMPL.columnMenu=function(id,anchor,{gridIcon,gridQueryStart}){const grid=this,column=this.columns.find(item=>item.id===id);if(!column)return false;const title=fill(this.labels.gridColumnMenu,{column:column.title});return this.openGridPopover(anchor,"cx-column-menu",title,id,(panel,signal)=>{const actions=new Map();const icons=new Map([[this.labels.gridSortAscending,"up"],[this.labels.gridSortDescending,"down"],[this.labels.gridFilterColumn,"filter"],[this.labels.gridPinLeft,"pin"],[this.labels.gridPinRight,"pin"],[this.labels.gridFitContent,"fit"],[this.labels.gridHideColumn,"hide"]]);const paths={pin:'<path d="M9 4h6l-1 6 3 3H7l3-3zM12 13v7"/>',fit:'<path d="M4 12h16M7 9l-3 3 3 3M17 9l3 3-3 3M4 5v14M20 5v14"/>',hide:'<path d="M3 3l18 18M10.6 6.1A9.8 9.8 0 0 1 12 6c5 0 8.5 4.5 9 6-.3.8-1.2 2.3-2.6 3.6M6.4 7.6C4.6 8.9 3.4 10.8 3 12c.5 1.5 4 6 9 6 1.6 0 3-.4 4.3-1.1"/>'};const add=(label,action,disabled=false)=>{const button=h("button","cx-button cx-mi"),icon=h("span","ico cx-menu-icon"),name=icons.get(label);button.type="button";button.setAttribute("role","menuitem");button.disabled=disabled;button.dataset.itemId=String(actions.size);actions.set(button.dataset.itemId,action);icon.setAttribute("aria-hidden","true");if(name)icon.appendChild(gridIcon(name,paths[name]));const text=h("span","cx-menu-label");setText(text,label);button.append(icon,text);panel.appendChild(button)};const rule=()=>{const separator=h("hr","cx-menu-rule");separator.setAttribute("role","separator");panel.appendChild(separator)};const sort=direction=>this.setQuery(gridQueryStart(this.queryForChange(true),{sort:[...(this.queryForChange().sort||[]).filter(item=>item.column!==id),...(direction?[{column:id,direction}]:[])]}));add(this.labels.gridSortAscending,()=>sort("asc"),!column.sortable||this.view.reporting?.grouping?.column===id);add(this.labels.gridSortDescending,()=>sort("desc"),!column.sortable||this.view.reporting?.grouping?.column===id);add(this.labels.gridClearSort,()=>sort(null),!(this.getQuery()?.sort||[]).some(item=>item.column===id));rule();add(this.labels.gridFilterColumn,()=>{const target=this.resolveColumnAnchor(id,anchor);if(target)this.openColumnFilter(id,target)},column.filterable===false);rule();for(const[pin,label]of[["left","gridPinLeft"],["right","gridPinRight"],["none","gridUnpin"]])
|
|
64
|
+
add(this.labels[label],()=>this.setColumnPinned(id,pin));rule();add(this.labels.gridFitContent,()=>this.autoFitColumn(id),!this.acceptedQuery||!!this.pendingQuery);add(this.labels.gridFitAllColumns,()=>this.autoFitColumns(),!this.acceptedQuery||!!this.pendingQuery);add(this.labels.gridHideColumn,()=>this.setColumnVisible(id,false),this.columns.filter(item=>!item.hidden).length===1);this.appendColumnGroupActions?.(column,add,rule);return UI_IMPL.menu(panel,{host:this.host,trigger:anchor,anchored:false,label:title,bindTrigger:false,decorateTrigger:false,get tabTrigger(){return grid.resolveColumnAnchor(id,anchor)},onSelect:item=>{Promise.resolve().then(actions.get(item.id)).catch(error=>this.emit("error",{error}))}},signal)})};installed.add(context.UI_IMPL)}};(global.CanopyXParts||=[]).push(["ui-menu",part])})(typeof window!=="undefined"?window:globalThis);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
@layer hfx.components{
|
|
2
|
+
:where([data-cx-tabs],[data-cx-stepper]){
|
|
3
|
+
color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));
|
|
4
|
+
font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);
|
|
5
|
+
font-size:var(--hfx-type-body-size,0.875rem);
|
|
6
|
+
line-height:var(--hfx-type-body-line,1.5);
|
|
7
|
+
min-inline-size:0;
|
|
8
|
+
}
|
|
9
|
+
.cx-tabs [hidden],.cx-stepper-host [hidden]{display:none;}
|
|
10
|
+
.cx-navigation-print{display:none;}
|
|
11
|
+
@media print{
|
|
12
|
+
.cx-navigation-print{display:block;}
|
|
13
|
+
:is(.cx-tabpanel,.cx-step-panel):has(> .cx-navigation-print) > .cx-navigation-body{display:none;}
|
|
14
|
+
}
|
|
15
|
+
:where([data-cx-tabs],[data-cx-stepper]) :where(button,[tabindex]):focus-visible{
|
|
16
|
+
outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));
|
|
17
|
+
outline-offset:var(--hfx-focus-offset,2px);
|
|
18
|
+
}
|
|
19
|
+
.cx-navigation-loading,.cx-navigation-error,.cx-step-errors{
|
|
20
|
+
padding:var(--hfx-space-4,1rem);
|
|
21
|
+
border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));
|
|
22
|
+
}
|
|
23
|
+
.cx-navigation-loading{
|
|
24
|
+
display:flex;
|
|
25
|
+
align-items:center;
|
|
26
|
+
gap:var(--hfx-space-2,0.5rem);
|
|
27
|
+
background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));
|
|
28
|
+
color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));
|
|
29
|
+
min-block-size:var(--hfx-control-height-lg,calc(44px - var(--cx-compact,0) * 8px));
|
|
30
|
+
}
|
|
31
|
+
.cx-navigation-spinner{
|
|
32
|
+
inline-size:var(--hfx-icon-lg,20px);
|
|
33
|
+
block-size:var(--hfx-icon-lg,20px);
|
|
34
|
+
border:var(--hfx-indicator-width,2px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));
|
|
35
|
+
border-block-start-color:var(--hfx-color-accent-indicator,light-dark(#11776f,#37c9b8));
|
|
36
|
+
border-radius:50%;
|
|
37
|
+
animation:cx-navigation-spin var(--hfx-motion-duration-slow,320ms) linear infinite;
|
|
38
|
+
}
|
|
39
|
+
.cx-navigation-skeleton{display:grid;gap:var(--hfx-space-2,0.5rem);padding:var(--hfx-space-4,1rem);}
|
|
40
|
+
.cx-navigation-skeleton > span{block-size:var(--hfx-type-body-size,0.875rem);background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
|
|
41
|
+
.cx-navigation-skeleton > span:nth-child(2){inline-size:75%;}
|
|
42
|
+
.cx-navigation-skeleton > span:nth-child(3){inline-size:50%;}
|
|
43
|
+
.cx-navigation-error,.cx-step-errors{
|
|
44
|
+
background:var(--hfx-color-status-bad-bg,light-dark(#f9e4e4,#3c272a));
|
|
45
|
+
color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));
|
|
46
|
+
border:var(--hfx-border-width,1px) solid var(--hfx-color-status-bad-border,light-dark(#eeacac,#814345));
|
|
47
|
+
margin-block-end:var(--hfx-space-3,0.75rem);
|
|
48
|
+
}
|
|
49
|
+
.cx-step-errors p{margin:0;font-weight:var(--hfx-weight-semibold,600);}
|
|
50
|
+
.cx-step-errors ul{margin-block:var(--hfx-space-2,0.5rem) 0;padding-inline-start:var(--hfx-space-5,1.5rem);}
|
|
51
|
+
.cx-navigation-retry{
|
|
52
|
+
background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));
|
|
53
|
+
color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));
|
|
54
|
+
border:var(--hfx-border-width,1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));
|
|
55
|
+
border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));
|
|
56
|
+
min-block-size:var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px));
|
|
57
|
+
padding-inline:var(--hfx-control-padding-x,calc(14px - var(--cx-compact,0) * 4px));
|
|
58
|
+
font:inherit;
|
|
59
|
+
cursor:pointer;
|
|
60
|
+
}
|
|
61
|
+
:where([data-cx-stepper]) .cx-visually-hidden{
|
|
62
|
+
position:absolute;
|
|
63
|
+
inline-size:var(--hfx-border-width,1px);
|
|
64
|
+
block-size:var(--hfx-border-width,1px);
|
|
65
|
+
overflow:hidden;
|
|
66
|
+
clip-path:inset(50%);
|
|
67
|
+
white-space:nowrap;
|
|
68
|
+
}
|
|
69
|
+
@keyframes cx-navigation-spin{to{transform:rotate(1turn);}}
|
|
70
|
+
@media (prefers-reduced-motion: reduce){
|
|
71
|
+
.cx-navigation-spinner{animation:none;}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"e7815ee277df3a57",requires:["ui-picker"],install(context){if(installed.has(context.UI_IMPL))return;const{UI_IMPL,UI_TOOLS,h,setText,fill,watchTheme,overlayTheme,hostHtml}=context;UI_TOOLS.navigation=(()=>{const focusable='a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';function owned(root,selector){return Array.from(root.querySelectorAll(selector)).filter(el=>el.closest('[data-cx-tabs],[data-cx-stepper]')===root)}
|
|
2
|
+
function scope(signal){const life=new AbortController();if(signal?.aborted)life.abort();else signal?.addEventListener('abort',()=>life.abort(),{once:true,signal:life.signal});return life}
|
|
3
|
+
function records(root,kind,options){const tabs=kind==='tabs';const buttons=owned(root,tabs?'[role="tab"]':'[data-step-id]');const panels=owned(root,tabs?'[role="tabpanel"]':'.cx-step-panel');return buttons.map((element,index)=>{const id=tabs?element.dataset.tabId:element.dataset.stepId;const config=(options[tabs?'tabs':'steps']||[]).find(item=>item.id===id)||{};const panel=tabs?panels.find(el=>el.id===element.getAttribute('aria-controls')):panels[index];const iconSlot=element.querySelector('[data-icon]');if(iconSlot&&options.renderIcon){const rendered=options.renderIcon(iconSlot.dataset.icon,{...config,id,index,element,panel});if(rendered?.nodeType)iconSlot.replaceChildren(rendered);else setText(iconSlot,typeof rendered==='string'?rendered:'')}
|
|
4
|
+
return{...config,id,index,element,panel,label:element.querySelector(tabs?'.cx-tab-label':'.cx-step-label')?.textContent||config.label||id,badge:element.querySelector('.cx-tab-badge')?.textContent||config.badge,icon:iconSlot?iconSlot.firstElementChild||iconSlot.textContent||undefined:config.icon,disabled:element.getAttribute('aria-disabled')==='true'||element.dataset.state==='disabled',optional:element.dataset.optional==='true',visited:element.dataset.visited==='true',state:element.dataset.state||'upcoming'}})}
|
|
5
|
+
function selection(root,prefix,options,life,read,commit){let version=0,pending;function cancel(){version++;pending?.abort();pending?.element?.removeAttribute('aria-busy')}
|
|
6
|
+
async function request(target,prepare,context){cancel();if(!target||target.disabled||life.signal.aborted)return false;const controller=new AbortController(),ticket=version;controller.element=target.element;pending=controller;const live=()=>ticket===version&&!controller.signal.aborted&&!life.signal.aborted;const from=read();const restoreFocus=()=>{if(context==='auto')return;const target=prefix==='tabs'?from?.element:from?.element.querySelector('button')||from?.panel?.querySelector('[data-hfx-part="title"],h3');target?.focus()};target.element.setAttribute('aria-busy','true');const abort=()=>controller.abort();life.signal.addEventListener('abort',abort,{once:true});try{if(prepare&&await wait(prepare(from,target,controller.signal,live),controller.signal)===false)return false;if(!live())return false;const guard=from!==target||context==='finish';if(guard&&!UI_TOOLS.emit(root,prefix,'beforechange',{from,to:target,signal:controller.signal},true)){if(live())restoreFocus();return false}
|
|
7
|
+
if(guard&&await wait(options.beforeChange?.(from,target,controller.signal),controller.signal)===false){if(live())restoreFocus();return false}
|
|
8
|
+
if(!live())return false;await wait(commit(from,target,controller.signal,live,context),controller.signal);return live()}catch(error){if(live()&&error?.name!=='AbortError')UI_TOOLS.emit(root,prefix,'error',{from,to:target,error});return false}finally{life.signal.removeEventListener('abort',abort);if(ticket===version)target.element.removeAttribute('aria-busy')}}
|
|
9
|
+
life.signal.addEventListener('abort',cancel,{once:true});return{request,cancel}}
|
|
10
|
+
function wait(value,signal){return new Promise((resolve,reject)=>{const task=Promise.resolve(value);const abort=()=>reject(new DOMException('Navigation cancelled','AbortError'));if(signal.aborted){task.catch(()=>{});abort();return}
|
|
11
|
+
signal.addEventListener('abort',abort,{once:true});task.then(result=>{signal.removeEventListener('abort',abort);resolve(result)},error=>{signal.removeEventListener('abort',abort);reject(error)})})}
|
|
12
|
+
function resolve(items,value){return typeof value==='number'?items[value]:items.find(item=>item.id===value)}
|
|
13
|
+
function position(labels,key,index,total){return fill(labels[key],{current:index+1,total})}
|
|
14
|
+
function panelTabStop(panel){if(panel?.getAttribute('role')==='tabpanel'){const hasFocusable=Array.from(panel.querySelectorAll(focusable)).some(el=>el.checkVisibility()&&!el.closest('[inert]'));panel.tabIndex=hasFocusable?-1:0}}
|
|
15
|
+
function pickerItems(items,selected,disabled=item=>item.disabled){return items.map(item=>({id:item.id,label:item.label,icon:item.icon,badge:item.badge,disabled:disabled(item),checked:item.id===selected}))}
|
|
16
|
+
function button(label,className){const el=document.createElement('button');el.type='button';el.className=className;setText(el,label);return el}
|
|
17
|
+
return{owned,scope,records,selection,resolve,position,panelTabStop,pickerItems,button,focusable}})();UI_TOOLS.navigation.deferred=(root,prefix,options,life,retry)=>{const bodies=new Map();const printCache=new Map(),projections=new Map();let printJob,destroyed=false;const n=UI_TOOLS.navigation,labels=UI_TOOLS.labels(options.labels);const templateFor=panel=>Array.from(panel.children).find(el=>el.tagName==='TEMPLATE');function bodyFor(item){if(!item.panel)return null;if(!bodies.has(item.panel)){const template=templateFor(item.panel);const body=document.createElement('div');body.className='cx-navigation-body';for(const child of Array.from(item.panel.childNodes)){if(child===template||child.nodeType===1&&child.matches('h3,[data-hfx-part="title"],.cx-step-print-state,.cx-step-errors,.cx-navigation-print'))continue;body.append(child)}
|
|
18
|
+
item.panel.append(body);bodies.set(item.panel,{body,template,loaded:false})}
|
|
19
|
+
return bodies.get(item.panel)}
|
|
20
|
+
function isDeferred(item){return!!item&&(item.deferred??(options.deferred||!!item.loader||!!item.panel?.querySelector('template')))}
|
|
21
|
+
async function load(item,signal,live){if(destroyed||life.signal.aborted||signal.aborted||!live())return false;if(!isDeferred(item)||!item.panel){n.panelTabStop(item.panel);return true}
|
|
22
|
+
const entry=bodyFor(item);if(entry.loaded&&(item.keepAlive??options.keepAlive)!==false)return true;removeProjection(item.panel);printCache.delete(item.panel);entry.loaded=false;const{body,template}=entry;body.replaceChildren();const status=document.createElement('div');status.className='cx-navigation-loading';status.setAttribute('role','status');const spinner=document.createElement('span');spinner.className='cx-navigation-spinner';spinner.setAttribute('aria-hidden','true');status.append(spinner,document.createTextNode(labels.stateLoading));const skeleton=h('div','cx-navigation-skeleton');skeleton.setAttribute('aria-hidden','true');skeleton.append(h('span'),h('span'),h('span'));body.append(status,skeleton);item.panel.setAttribute('aria-busy','true');item.panel.dataset.state='loading';const token={};token.done=new Promise(resolve=>{token.resolve=resolve});entry.pending=token;const interrupted=()=>{if(entry.pending!==token)return;token.resolve();if(destroyed||life.signal.aborted)return;item.panel.removeAttribute('aria-busy');const again=n.button(labels.stateRetry,'cx-navigation-retry');again.addEventListener('click',()=>retry(item.id),{signal:life.signal});body.replaceChildren(again);item.panel.dataset.state='selected'};signal.addEventListener('abort',interrupted,{once:true});try{const loader=item.loader||options.loader;const content=loader?await loader(item,signal):template?.content.cloneNode(true);if(entry.pending!==token||!live()||signal.aborted||life.signal.aborted)return false;body.replaceChildren();if(content!=null)UI_TOOLS.content(body,content);entry.loaded=true;item.panel.dataset.state='selected';UI_TOOLS.emit(root,prefix,'load',{item,panel:item.panel});n.panelTabStop(item.panel);return true}catch(error){if(entry.pending!==token||!live()||signal.aborted||life.signal.aborted)return false;item.panel.dataset.state='error';const alert=document.createElement('div');alert.setAttribute('role','alert');alert.className='cx-navigation-error';setText(alert,error?.message||labels.stateDetails);const again=n.button(labels.stateRetry,'cx-navigation-retry');again.addEventListener('click',()=>retry(item.id),{signal:life.signal});body.replaceChildren(alert,again);UI_TOOLS.emit(root,prefix,'error',{item,error});n.panelTabStop(item.panel);return false}finally{signal.removeEventListener('abort',interrupted);token.resolve();if(entry.pending===token){entry.pending=null;if(live())item.panel.removeAttribute('aria-busy')}}}
|
|
23
|
+
function leave(item){const entry=item&&bodies.get(item.panel);item?.panel?.removeAttribute('aria-busy');if(entry&&(item.keepAlive??options.keepAlive)===false){if(entry.loaded)printCache.set(item.panel,snapshot(entry.body));entry.body.replaceChildren();entry.loaded=false}}
|
|
24
|
+
function snapshot(body){const fragment=document.createDocumentFragment();for(const child of body.childNodes)fragment.append(cloneForPrint(child));return fragment}
|
|
25
|
+
function cloneForPrint(node){const copy=node.cloneNode(true),selector='input,textarea,select';const fields=el=>[...(el.matches?.(selector)?[el]:[]),...(el.querySelectorAll?.(selector)||[])];const source=fields(node),copies=fields(copy);source.forEach((field,index)=>{const target=copies[index];if(field.tagName==='SELECT')Array.from(field.options).forEach((option,i)=>{target.options[i].selected=option.selected});else{if(field.type!=='file')target.value=field.value;if(field.tagName==='INPUT')target.checked=field.checked}});return copy}
|
|
26
|
+
function removeProjection(panel){projections.get(panel)?.remove();projections.delete(panel)}
|
|
27
|
+
function printItems(){return n.records(root,prefix,{...options,renderIcon:undefined}).filter(item=>item.panel&&
|
|
28
|
+
(root.dataset.print!=='selected'||!item.panel.hidden))}
|
|
29
|
+
function project(item,content){removeProjection(item.panel);const projection=h('div','cx-navigation-print');projection.setAttribute('aria-hidden','true');projection.inert=true;if(content!=null)UI_TOOLS.content(projection,content?.nodeType?cloneForPrint(content):content);for(const field of projection.querySelectorAll('input,textarea,select,button')){field.removeAttribute('name');field.removeAttribute('form')}
|
|
30
|
+
for(const element of projection.querySelectorAll('[id]'))element.removeAttribute('id');bodyFor(item);item.panel.append(projection);projections.set(item.panel,projection)}
|
|
31
|
+
function projectLocal(){if(destroyed||life.signal.aborted)return;const items=printItems(),panels=new Set(items.map(item=>item.panel));for(const panel of projections.keys())if(!panels.has(panel)||bodies.get(panel)?.loaded)removeProjection(panel);for(const item of items){if(!isDeferred(item)||bodies.get(item.panel)?.loaded||projections.has(item.panel))continue;const content=printCache.get(item.panel)||(!(item.loader||options.loader)&&templateFor(item.panel)?.content);if(content)project(item,content)}}
|
|
32
|
+
function cancelPrint(clearCache=true){printJob?.controller.abort();printJob=null;for(const panel of projections.keys())removeProjection(panel);if(clearCache)printCache.clear()}
|
|
33
|
+
function waitForPrint(value,signal){return new Promise((resolve,reject)=>{const abort=()=>reject(new DOMException('Print preparation cancelled','AbortError'));const task=Promise.resolve(value);if(signal.aborted){task.catch(()=>{});abort();return}
|
|
34
|
+
signal.addEventListener('abort',abort,{once:true});task.then(resolve,reject).finally(()=>signal.removeEventListener('abort',abort))})}
|
|
35
|
+
async function preparePrint(){if(destroyed||life.signal.aborted)throw new DOMException('UI component destroyed','AbortError');if(printJob)return printJob.task;const job={controller:new AbortController()};printJob=job;const signal=job.controller.signal;job.task=(async()=>{projectLocal();for(const item of printItems()){if(!isDeferred(item))continue;const entry=bodies.get(item.panel);if(entry?.pending)await waitForPrint(entry.pending.done,signal);if(entry?.loaded||projections.has(item.panel))continue;const loader=item.loader||options.loader;const content=loader?await waitForPrint(loader(item,signal),signal):templateFor(item.panel)?.content;if(signal.aborted||destroyed||life.signal.aborted)throw new DOMException('Print preparation cancelled','AbortError');if(!printItems().some(current=>current.panel===item.panel)||bodies.get(item.panel)?.loaded)continue;project(item,content)}
|
|
36
|
+
projectLocal()})().catch(error=>{if(printJob===job)cancelPrint(false);throw error}).finally(()=>{if(printJob===job)printJob=null});return job.task}
|
|
37
|
+
function destroy(){if(destroyed)return;destroyed=true;cancelPrint();for(const[panel,entry]of bodies){panel.removeAttribute('aria-busy');entry.pending?.resolve()}
|
|
38
|
+
bodies.clear()}
|
|
39
|
+
window.addEventListener('beforeprint',projectLocal,{signal:life.signal});window.addEventListener('afterprint',cancelPrint,{signal:life.signal});life.signal.addEventListener('abort',destroy,{once:true});return{load,leave,destroy,isDeferred,preparePrint}};installed.add(context.UI_IMPL)}};(global.CanopyXParts||=[]).push(["ui-navigation",part])})(typeof window!=="undefined"?window:globalThis);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/* Component size options from the public anatomy. Colour,type and rhythm come from shared roles. */
|
|
2
|
+
@layer hfx.components{
|
|
3
|
+
:where(.cx-dialog,.cx-drawer,.cx-popover,.cx-tooltip,.cx-menu){
|
|
4
|
+
--cx-ui-dialog-sm:25rem;--cx-ui-dialog-md:35rem;--cx-ui-dialog-lg:50rem;
|
|
5
|
+
--cx-ui-drawer-sm:22.5rem;--cx-ui-drawer-md:30rem;--cx-ui-drawer-lg:45rem;
|
|
6
|
+
--cx-ui-popup-min:12.5rem;--cx-ui-popup-max:22.5rem;--cx-ui-menu-max:20rem;--cx-ui-tooltip-max:17.5rem;
|
|
7
|
+
--cx-ui-dialog-body-max:70dvh;--cx-ui-sheet-max:90dvh;--cx-ui-viewport-block:100dvh;--cx-ui-viewport-inline:100dvw;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
@layer hfx.components{
|
|
11
|
+
:where(.cx-tabs,.cx-stepper-host,.cx-dialog,.cx-drawer,.cx-popover,.cx-menu,.cx-tooltip,[data-cx-open]){box-sizing:border-box;font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);font-size:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
|
|
12
|
+
:where(.cx-tabs,.cx-stepper-host,.cx-dialog,.cx-drawer,.cx-popover,.cx-menu) *,:where(.cx-tabs,.cx-stepper-host,.cx-dialog,.cx-drawer,.cx-popover,.cx-menu) *::before{box-sizing:border-box;}
|
|
13
|
+
.cx-visually-hidden{position:absolute;inline-size:var(--hfx-border-width,1px);block-size:var(--hfx-border-width,1px);padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;}
|
|
14
|
+
:where(.cx-tabs,.cx-stepper-host,.cx-dialog,.cx-drawer,.cx-popover,.cx-menu) :focus-visible,[data-cx-open]:focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
|
|
15
|
+
.cx-dialog,.cx-drawer,.cx-popover{padding:0;border:var(--hfx-border-width,1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-overlay,var(--hfx-radius-lg,10px));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));background:var(--hfx-color-surface-raised,light-dark(#ffffff,#1e2126));box-shadow:var(--hfx-elevation-3,0 2px 4px rgba(22,24,28,.06),0 16px 36px -16px rgba(22,24,28,.28));overflow:hidden;}
|
|
16
|
+
.cx-dialog[open]{display:flex;flex-direction:column;max-block-size:calc(var(--cx-ui-viewport-block) - var(--hfx-space-4,1rem) * 2);}
|
|
17
|
+
.cx-dialog{inline-size:min(var(--cx-ui-dialog-md),calc(100% - var(--hfx-space-4,1rem) * 2));max-inline-size:none;}
|
|
18
|
+
.cx-dialog[data-size="sm"]{inline-size:min(var(--cx-ui-dialog-sm),calc(100% - var(--hfx-space-4,1rem) * 2));}
|
|
19
|
+
.cx-dialog[data-size="lg"]{inline-size:min(var(--cx-ui-dialog-lg),calc(100% - var(--hfx-space-4,1rem) * 2));}
|
|
20
|
+
:is(.cx-dialog,.cx-drawer)::backdrop{background:var(--hfx-color-overlay,light-dark(rgba(22,24,28,0.42),rgba(0,0,0,0.66)));}
|
|
21
|
+
:is(.cx-dialog,.cx-drawer,.cx-popover) [data-hfx-part="header"]{display:flex;flex:none;align-items:center;gap:var(--hfx-space-3,0.75rem);min-block-size:var(--hfx-card-header-height,calc(52px - var(--cx-compact,0) * 8px));padding:var(--hfx-space-4,1rem) var(--hfx-card-padding-x,calc(20px - var(--cx-compact,0) * 4px));border-block-end:var(--hfx-border-width,1px) solid transparent;}
|
|
22
|
+
:is(.cx-dialog,.cx-drawer,.cx-popover) [data-hfx-part="title"]{flex:1;margin:0;font-family:var(--hfx-font-display,"Segoe UI Variable Display","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);font-size:var(--hfx-type-heading-size,0.9375rem);font-weight:var(--hfx-weight-semibold,600);line-height:var(--hfx-type-heading-line,1.4);}
|
|
23
|
+
:is(.cx-dialog,.cx-drawer,.cx-popover) [data-hfx-part="body"]{flex:1;overflow:auto;min-block-size:0;padding:var(--hfx-card-padding-y,calc(16px - var(--cx-compact,0) * 4px)) var(--hfx-card-padding-x,calc(20px - var(--cx-compact,0) * 4px));max-block-size:var(--cx-ui-dialog-body-max);color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));font-size:var(--hfx-type-small-size,0.8125rem);line-height:var(--hfx-type-small-line,1.4);}
|
|
24
|
+
:is(.cx-dialog,.cx-drawer,.cx-popover) [data-hfx-part="footer"]{display:flex;flex:none;justify-content:flex-end;gap:var(--hfx-space-2,0.5rem);padding:var(--hfx-space-3,0.75rem) var(--hfx-card-padding-x,calc(20px - var(--cx-compact,0) * 4px));border-block-start:var(--hfx-border-width,1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));}
|
|
25
|
+
:is(.cx-dialog,.cx-drawer)[data-scrolled="true"] [data-hfx-part="header"]{border-block-end-color:var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
|
|
26
|
+
.cx-overlay-close{flex:none;inline-size:var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px));min-block-size:var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px));padding:0;background:transparent;border-color:transparent;font-size:0;}
|
|
27
|
+
.cx-overlay-close::before{content:"\00d7" / "";font-size:var(--hfx-icon-lg,20px);line-height:1;}
|
|
28
|
+
.cx-drawer{position:fixed;inset:0 0 0 auto;margin:0;inline-size:min(var(--cx-ui-drawer-md),100%);max-inline-size:none;block-size:var(--cx-ui-viewport-block);max-block-size:none;border-radius:var(--hfx-radius-none,0);}
|
|
29
|
+
.cx-drawer[open]{display:flex;flex-direction:column;}
|
|
30
|
+
.cx-drawer [data-hfx-part="body"]{flex:1;max-block-size:none;}
|
|
31
|
+
.cx-drawer[data-size="sm"]{inline-size:min(var(--cx-ui-drawer-sm),100%);}
|
|
32
|
+
.cx-drawer[data-size="lg"]{inline-size:min(var(--cx-ui-drawer-lg),100%);}
|
|
33
|
+
.cx-drawer{z-index:var(--hfx-z-drawer,1100);}
|
|
34
|
+
.cx-drawer[data-side="start"]{inset-inline-start:0;inset-inline-end:auto;}
|
|
35
|
+
.cx-drawer[data-side="end"]{inset-inline-start:auto;inset-inline-end:0;}
|
|
36
|
+
.cx-drawer[data-side="bottom"]{inset-block-start:auto;inset-block-end:0;inline-size:100%;block-size:auto;max-block-size:var(--cx-ui-sheet-max);border-start-start-radius:var(--hfx-radius-overlay,var(--hfx-radius-lg,10px));border-start-end-radius:var(--hfx-radius-overlay,var(--hfx-radius-lg,10px));}
|
|
37
|
+
.cx-drawer[data-side="bottom"]::before{content:"";display:block;flex:none;inline-size:var(--hfx-space-6,2rem);block-size:var(--hfx-space-1,0.25rem);margin:var(--hfx-space-2,0.5rem) auto 0;background:var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-pill,999px);}
|
|
38
|
+
.cx-drawer[data-phone="true"]{inset:0;inline-size:100%;block-size:var(--cx-ui-viewport-block);max-block-size:none;border-radius:var(--hfx-radius-none,0);}
|
|
39
|
+
.cx-drawer[data-phone="true"] [data-hfx-part="header"]{padding-block:var(--hfx-space-1,0.25rem);}
|
|
40
|
+
.cx-drawer[data-phone="true"] [data-hfx-part="header"]:has(> :nth-child(4)){padding-block:var(--hfx-space-3,0.75rem);flex-wrap:wrap;justify-content:flex-start;gap:var(--hfx-space-2,0.5rem);}
|
|
41
|
+
.cx-drawer[data-phone="true"] [data-hfx-part="header"]:has(> :nth-child(4)) > button{flex:none;}
|
|
42
|
+
.cx-drawer[data-phone="true"] [data-hfx-part="header"]:has(> :nth-child(4)) > :first-child{flex:1 0 100%;min-inline-size:0;}
|
|
43
|
+
.cx-drawer[data-phone="true"] [data-hfx-part="header"]:has(> :nth-child(4)) [data-hfx-part="title"]{inline-size:100%;}
|
|
44
|
+
.cx-drawer[data-phone="true"] [data-hfx-part="body"]{padding-block-start:var(--hfx-space-1,0.25rem);}
|
|
45
|
+
.cx-drawer[data-phone="true"] [data-hfx-part="body"] > :first-child{margin-block-start:0;}
|
|
46
|
+
:is(.cx-dialog,.cx-drawer)[data-phone="true"]{--cx-ui-touch-target:calc(var(--hfx-space-5,1.5rem) + var(--hfx-space-6,2rem));}
|
|
47
|
+
:is(.cx-dialog,.cx-drawer)[data-phone="true"] :is(.cx-button,.cx-btn,.cx-ui-button,.cx-overlay-close){min-block-size:var(--cx-ui-touch-target);min-inline-size:var(--cx-ui-touch-target);}
|
|
48
|
+
.cx-dialog[data-phone="true"]{position:fixed;inset:auto 0 0;margin:0;inline-size:100%;max-block-size:var(--cx-ui-viewport-block);border-end-start-radius:var(--hfx-radius-none,0);border-end-end-radius:var(--hfx-radius-none,0);}
|
|
49
|
+
.cx-popover{position:fixed;inset:auto;margin:var(--hfx-space-1-5,6px);min-inline-size:var(--cx-ui-popup-min);max-inline-size:min(var(--cx-ui-popup-max),calc(var(--cx-ui-viewport-inline) - var(--hfx-space-4,1rem) * 2));max-block-size:calc(var(--cx-ui-viewport-block) - var(--hfx-space-4,1rem) * 2);box-shadow:var(--hfx-elevation-2,0 1px 2px rgba(22,24,28,.05),0 6px 18px -10px rgba(22,24,28,.18));z-index:var(--hfx-z-popover,1000);}
|
|
50
|
+
.cx-popover [data-hfx-part="header"]{min-block-size:0;padding:var(--hfx-space-3,0.75rem) var(--hfx-space-4,1rem) var(--hfx-space-1,0.25rem);}
|
|
51
|
+
.cx-popover [data-hfx-part="body"]{padding:var(--hfx-space-1,0.25rem) var(--hfx-space-4,1rem) var(--hfx-space-3,0.75rem);}
|
|
52
|
+
.cx-tooltip{position:fixed;inset:auto;margin:var(--hfx-space-1-5,6px);max-inline-size:var(--cx-ui-tooltip-max);padding:var(--hfx-space-1,0.25rem) var(--hfx-space-2,0.5rem);border-radius:var(--hfx-radius-sm,4px);border:0;background:var(--hfx-color-surface-inverse,light-dark(#16181c,#f2f3f5));color:var(--hfx-color-text-inverse,light-dark(#ffffff,#0c0d10));font-size:var(--hfx-type-caption-size,0.75rem);line-height:var(--hfx-type-caption-line,1.35);box-shadow:var(--hfx-elevation-2,0 1px 2px rgba(22,24,28,.05),0 6px 18px -10px rgba(22,24,28,.18));z-index:var(--hfx-z-tooltip,1300);overflow:visible;}
|
|
53
|
+
.cx-tooltip::after{content:"";position:absolute;inline-size:var(--hfx-space-2,0.5rem);block-size:var(--hfx-space-2,0.5rem);background:inherit;transform:rotate(45deg);inset-inline-start:calc(50% - var(--hfx-space-1,0.25rem));inset-block-start:calc(-1 * var(--hfx-space-1,0.25rem));}
|
|
54
|
+
.cx-tooltip[data-side="top"]::after{inset-block-start:auto;inset-block-end:calc(-1 * var(--hfx-space-1,0.25rem));}
|
|
55
|
+
.cx-tooltip[data-side="left"]::after{inset-inline-start:auto;inset-inline-end:calc(-1 * var(--hfx-space-1,0.25rem));inset-block-start:calc(50% - var(--hfx-space-1,0.25rem));}
|
|
56
|
+
.cx-tooltip[data-side="right"]::after{inset-inline-start:calc(-1 * var(--hfx-space-1,0.25rem));inset-block-start:calc(50% - var(--hfx-space-1,0.25rem));}
|
|
57
|
+
:where(.cx-dialog,.cx-drawer,.cx-popover,.cx-tooltip)[hidden]{display:none!important;}
|
|
58
|
+
@media (prefers-reduced-motion:no-preference){
|
|
59
|
+
:is(.cx-dialog,.cx-drawer,.cx-popover,.cx-tooltip){transition:opacity var(--hfx-motion-duration-fast,120ms) var(--hfx-motion-easing-exit,cubic-bezier(.4,0,1,1)),transform var(--hfx-motion-duration-fast,120ms) var(--hfx-motion-easing-exit,cubic-bezier(.4,0,1,1)),display var(--hfx-motion-duration-fast,120ms) allow-discrete,overlay var(--hfx-motion-duration-fast,120ms) allow-discrete;}
|
|
60
|
+
:is(.cx-dialog,.cx-popover,.cx-tooltip)[data-state="closed"]{opacity:0;transform:scale(.98);}
|
|
61
|
+
:is(.cx-dialog,.cx-drawer,.cx-popover,.cx-tooltip)[data-state="open"]{opacity:1;transform:none;}
|
|
62
|
+
.cx-drawer[data-state="closed"]{transform:translateX(100%);}
|
|
63
|
+
.cx-drawer[data-side="start"][data-state="closed"],.cx-drawer[data-side="end"]:dir(rtl)[data-state="closed"]{transform:translateX(-100%);}
|
|
64
|
+
.cx-drawer[data-side="start"]:dir(rtl)[data-state="closed"]{transform:translateX(100%);}
|
|
65
|
+
.cx-drawer:is([data-side="bottom"],[data-phone="true"])[data-state="closed"],.cx-dialog[data-phone="true"][data-state="closed"]{transform:translateY(100%);}
|
|
66
|
+
:is(.cx-dialog,.cx-drawer)::backdrop{transition:opacity var(--hfx-motion-duration-base,200ms) var(--hfx-motion-easing-standard,cubic-bezier(.2,0,0,1)),display var(--hfx-motion-duration-fast,120ms) allow-discrete,overlay var(--hfx-motion-duration-fast,120ms) allow-discrete;}
|
|
67
|
+
:is(.cx-dialog,.cx-drawer)[data-state="closed"]::backdrop{opacity:0;}
|
|
68
|
+
.cx-dialog[open],.cx-drawer[open],.cx-popover:popover-open{animation:cx-ui-appear var(--hfx-motion-duration-base,200ms) var(--hfx-motion-easing-enter,cubic-bezier(0,0,.2,1));}
|
|
69
|
+
.cx-drawer[open]{animation:cx-ui-slide-end var(--hfx-motion-duration-slow,320ms) var(--hfx-motion-easing-enter,cubic-bezier(0,0,.2,1));}
|
|
70
|
+
.cx-drawer[data-side="start"][open],.cx-drawer[data-side="end"]:dir(rtl)[open]{animation-name:cx-ui-slide-start;}
|
|
71
|
+
.cx-drawer[data-side="start"]:dir(rtl)[open]{animation-name:cx-ui-slide-end;}
|
|
72
|
+
.cx-drawer[data-side="bottom"][open],.cx-drawer[data-phone="true"][open],.cx-dialog[data-phone="true"][open]{animation-name:cx-ui-slide-bottom;}
|
|
73
|
+
@keyframes cx-ui-appear{from{opacity:0;transform:scale(.98);}to{opacity:1;transform:none;}}
|
|
74
|
+
@keyframes cx-ui-slide-end{from{transform:translateX(100%);}to{transform:none;}}
|
|
75
|
+
@keyframes cx-ui-slide-start{from{transform:translateX(-100%);}to{transform:none;}}
|
|
76
|
+
@keyframes cx-ui-slide-bottom{from{transform:translateY(100%);}to{transform:none;}}
|
|
77
|
+
}
|
|
78
|
+
@media print{:where(.cx-dialog,.cx-drawer,.cx-popover,.cx-tooltip,.cx-menu){display:none!important;}}
|
|
79
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"68a7687b9c3c8a28",install(context){if(installed.has(context.UI_IMPL))return;const{UI_IMPL,UI_TOOLS,h,setText,fill,watchTheme,overlayTheme,hostHtml}=context;const UI_LABELS={tabsMore:"More",tabsMoreSelected:"More: {label}",tabsScrollPrevious:"Previous tabs",tabsScrollNext:"Next tabs",tabsSection:"Section",tabsPosition:"{current} of {total}",tabsPause:"Pause",tabsPlay:"Play",tabsMotionDisabled:"Automatic tabs are disabled by reduced motion",stepperStepOf:"Step {current} of {total}",stepperBack:"Back",stepperNext:"Next",stepperFinish:"Finish",stepperSkip:"Skip",stepperSaveDraft:"Save draft",stepperAllSteps:"All steps",stepperOptional:"Optional",stepperCompleted:"Completed",stepperSkipped:"Skipped",stepperIssues:"{count} issues to fix",stepperIssue:"1 issue to fix",dialogClose:"Close",drawerClose:"Close",drawerPrevious:"Previous record",drawerNext:"Next record",stateLoading:"Loading…",stateRetry:"Retry",stateDetails:"Details"};const uiFocusSelector='button:not([disabled]),a[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';Object.assign(UI_TOOLS,{labels:values=>Object.assign({},UI_LABELS,values),content:(element,value)=>{if(value?.nodeType)element.replaceChildren(value);else hostHtml(element,value,null,"detail")},emit:(root,prefix,name,detail,cancelable=false)=>root.dispatchEvent(new CustomEvent("cx-"+prefix+":"+name,{detail,bubbles:true,cancelable})),focusables:root=>[...root.querySelectorAll(uiFocusSelector)].filter(element=>element.checkVisibility()&&!element.closest("[inert]")),observe(root,changed,signal){let width=-1,frame=0;const read=()=>{const next=root.getBoundingClientRect().width;if(next!==width){width=next;changed(width)}};const observer=new ResizeObserver(()=>{frame||=requestAnimationFrame(()=>{frame=0;read()})});observer.observe(root);read();const dispose=()=>{observer.disconnect();cancelAnimationFrame(frame)};signal?.addEventListener("abort",dispose,{once:true});return dispose},theme(host,element){const previous=new Map([...element.style].map(name=>[name,element.style.getPropertyValue(name)]));overlayTheme(host,element);for(const[name,value]of previous)if(name.startsWith("--hfx-")||name.startsWith("--cx-"))element.style.setProperty(name,value);const written=new Map([...element.style].map(name=>[name,element.style.getPropertyValue(name)]));return()=>{for(const[name,value]of written)if(element.style.getPropertyValue(name)===value){if(previous.has(name))element.style.setProperty(name,previous.get(name));else element.style.removeProperty(name)}}},position(element,anchor,placement="bottom-start",point){const viewport=global.visualViewport,width=viewport?.width||document.documentElement.clientWidth,height=viewport?.height||global.innerHeight;const offsetX=viewport?.offsetLeft||0,offsetY=viewport?.offsetTop||0;const style=getComputedStyle(element),gap=parseFloat(style.marginTop)||0,marginX=parseFloat(style.marginLeft)||0;const edge=Math.max(8,gap);const box=element.getBoundingClientRect(),target=point?{left:point.x,right:point.x,top:point.y,bottom:point.y}:anchor.getBoundingClientRect();const rtl=getComputedStyle(anchor).direction==="rtl",side=placement.split("-")[0],align=placement.split("-")[1]||"center";let x=(target.left+target.right-box.width)/ 2, y = target.bottom + gap, actual = side;
|
|
2
|
+
if(side==="top")y=target.top-box.height-gap;if(side==="left"||side==="right"){x=side==="left"?target.left-box.width-gap:target.right+gap;y=target.top}
|
|
3
|
+
else if(align!=="center")x=(align==="start")!==rtl?target.left:target.right-box.width;if(side==="top"&&y<offsetY){y=target.bottom+gap;actual="bottom"}
|
|
4
|
+
else if(side==="bottom"&&y+box.height>height+offsetY){y=target.top-box.height-gap;actual="top"}
|
|
5
|
+
else if(side==="right"&&x+box.width>width+offsetX){x=target.left-box.width-gap;actual="left"}
|
|
6
|
+
else if(side==="left"&&x<offsetX){x=target.right+gap;actual="right"}
|
|
7
|
+
x=Math.max(offsetX+edge,Math.min(x,offsetX+width-box.width-edge));y=Math.max(offsetY+edge,Math.min(y,offsetY+height-box.height-edge));const ratio=global.devicePixelRatio||1,snap=value=>Math.round(value*ratio)/ ratio;
|
|
8
|
+
element.style.left=snap(x)- marginX+"px";element.style.top=snap(y)- gap+"px";element.dataset.side=actual}});const uiOverlayStack=[];let uiModalLocks=0,uiScrollBefore="";function uiLockScroll(lock){if(lock){if(uiModalLocks++===0){uiScrollBefore=document.documentElement.style.overflow;document.documentElement.style.overflow="hidden"}}
|
|
9
|
+
else if(uiModalLocks&&--uiModalLocks===0&&document.documentElement.style.overflow==="hidden")document.documentElement.style.overflow=uiScrollBefore}
|
|
10
|
+
function uiTopOverlay(){return uiOverlayStack.at(-1)}
|
|
11
|
+
function uiOverlayKey(event){if(event.defaultPrevented)return;const top=uiTopOverlay();if(!top)return;if(event.key==="Escape"){event.preventDefault();event.stopImmediatePropagation();top.close("cancel")}
|
|
12
|
+
else if(event.key==="Tab"&&top.modal){const list=UI_TOOLS.focusables(top.element),first=list[0],last=list.at(-1);if(!list.length){event.preventDefault();top.element.focus()}
|
|
13
|
+
else if(event.shiftKey&&(document.activeElement===first||document.activeElement===top.element)){event.preventDefault();last.focus()}
|
|
14
|
+
else if(!event.shiftKey&&document.activeElement===last){event.preventDefault();first.focus()}}}
|
|
15
|
+
function uiOverlayPointer(event){const top=uiTopOverlay();if(!top)return;const box=top.element.getBoundingClientRect(),backdrop=event.target===top.element&&(event.clientX<box.left||event.clientX>box.right||event.clientY<box.top||event.clientY>box.bottom);if(!backdrop&&top.element.contains(event.target)||top.trigger?.contains(event.target))return;if(top.dismissible)top.close("outside",false)}
|
|
16
|
+
function uiStackPush(entry){if(!uiOverlayStack.length){document.addEventListener("keydown",uiOverlayKey);document.addEventListener("pointerdown",uiOverlayPointer,true)}
|
|
17
|
+
uiOverlayStack.push(entry)}
|
|
18
|
+
function uiStackRemove(entry){const at=uiOverlayStack.indexOf(entry);if(at>=0)uiOverlayStack.splice(at,1);if(!uiOverlayStack.length){document.removeEventListener("keydown",uiOverlayKey);document.removeEventListener("pointerdown",uiOverlayPointer,true)}}
|
|
19
|
+
UI_TOOLS.owns=(container,node)=>{if(container.contains(node))return true;for(const entry of uiOverlayStack){if(!entry.element.contains(node))continue;for(let owner=entry;owner;owner=owner.parent)
|
|
20
|
+
if(container.contains(owner.element)||owner.trigger&&container.contains(owner.trigger))return true}
|
|
21
|
+
return false};UI_TOOLS.overlay=(element,options={},signal)=>{const kind=options.kind||"popover",originalParent=element.parentNode,nextSibling=element.nextSibling;const triggerOf=()=>options.trigger||document.getElementById(element.dataset.cxTrigger||"");const decorateTrigger=()=>options.decorateTrigger!==false&&kind!=="tooltip"&&
|
|
22
|
+
!["row","gridcell","rowheader","treeitem"].includes(triggerOf()?.getAttribute("role"));let opened=false,modal=false,returnFocus=null,restoreTheme=null,inerted=[],reposition=null,generation=0;const nativeCloses=[];const styleBefore={left:element.style.left,top:element.style.top},hadTabindex=element.getAttribute("tabindex");const ariaModalBefore=element.getAttribute("aria-modal");const entry={element,get trigger(){return triggerOf()},get modal(){return modal},get dismissible(){return options.dismissible!==false},close};function closeNative(silent=false){nativeCloses.push({generation,silent});element.close()}
|
|
23
|
+
function close(reason="close",restoreFocus=options.focus!==false,force=false){if(!opened)return true;if(!force&&!UI_TOOLS.emit(element,kind,reason==="cancel"?"cancel":"beforeclose",{reason},true))return false;for(const child of uiOverlayStack.slice().reverse()){for(let parent=child.parent;parent;parent=parent.parent)if(parent===entry){child.close("parent",false,true);break}}
|
|
24
|
+
entry.parent=null;opened=false;uiStackRemove(entry);if(element.localName==="dialog"){if(element.open)closeNative();else if(reason!=="native")nativeCloses.push({generation,silent:false})}else if(element.matches(":popover-open"))element.hidePopover();element.hidden=true;element.dataset.state="closed";if(ariaModalBefore===null)element.removeAttribute("aria-modal");else element.setAttribute("aria-modal",ariaModalBefore);if(modal)uiLockScroll(false);for(const[node,value]of inerted)node.inert=value;inerted=[];modal=false;restoreTheme?.();restoreTheme=null;element.style.left=styleBefore.left;element.style.top=styleBefore.top;if(originalParent&&element.parentNode!==originalParent)originalParent.insertBefore(element,nextSibling?.parentNode===originalParent?nextSibling:null);if(entry.trigger&&decorateTrigger())entry.trigger.setAttribute("aria-expanded","false");reposition?.();reposition=null;if(restoreFocus){const target=returnFocus?.isConnected?returnFocus:triggerOf();target?.focus({preventScroll:true})}
|
|
25
|
+
UI_TOOLS.emit(element,kind,"close",{reason});return true}
|
|
26
|
+
function open(settings={}){if(signal?.aborted)return false;if(opened)close("reopen",false,true);generation++;const trigger=triggerOf(),host=options.host||trigger||originalParent||element;entry.parent=uiOverlayStack.slice().reverse().find(owner=>owner.element.contains(element)||
|
|
27
|
+
trigger&&owner.element.contains(trigger))||null;returnFocus=trigger||document.activeElement;modal=settings.modal??options.modal??false;restoreTheme=UI_TOOLS.theme(host,element);const parentDialog=trigger?.closest("dialog[open]");const portal=options.portal||parentDialog||trigger?.closest('main,[role="main"]')||document.body;if(element.localName!=="dialog"&&element.parentNode!==portal){const dir=element.getAttribute("dir"),value=element.style.getPropertyValue("direction"),priority=element.style.getPropertyPriority("direction");const direction=getComputedStyle(element).direction,undoTheme=restoreTheme;element.setAttribute("dir",direction);element.style.setProperty("direction",direction,priority);restoreTheme=()=>{const current=element.style.getPropertyValue("direction"),currentPriority=element.style.getPropertyPriority("direction");undoTheme();if(element.getAttribute("dir")===direction){if(dir===null)element.removeAttribute("dir");else element.setAttribute("dir",dir)}
|
|
28
|
+
if(current===direction&¤tPriority===priority){if(value)element.style.setProperty("direction",value,priority);else element.style.removeProperty("direction")}else if(current)element.style.setProperty("direction",current,currentPriority);else element.style.removeProperty("direction")};portal.appendChild(element)}
|
|
29
|
+
element.hidden=false;element.dataset.state="open";if(element.localName==="dialog"&&typeof element.showModal==="function"){if(modal)element.showModal();else element.show()}else if(typeof element.showPopover==="function"){element.setAttribute("popover","manual");element.showPopover()}else if(modal){for(const child of document.body.children)if(!child.contains(element)){inerted.push([child,child.inert]);child.inert=true}}
|
|
30
|
+
opened=true;if(modal)uiLockScroll(true);uiStackPush(entry);if(modal)element.setAttribute("aria-modal","true");else element.removeAttribute("aria-modal");if(trigger&&decorateTrigger())trigger.setAttribute("aria-expanded","true");if(options.anchored&&trigger){const placement=options.placement||element.dataset.placement;const position=()=>UI_TOOLS.position(element,trigger,placement,settings.point);position();global.addEventListener("resize",position);document.addEventListener("scroll",position,true);reposition=()=>{global.removeEventListener("resize",position);document.removeEventListener("scroll",position,true)}}
|
|
31
|
+
if(options.focus!==false){const target=typeof options.initialFocus==="function"?options.initialFocus(element):options.initialFocus;if(!element.hasAttribute("tabindex"))element.tabIndex=-1;(target||UI_TOOLS.focusables(element)[0]||element).focus({preventScroll:true})}
|
|
32
|
+
UI_TOOLS.emit(element,kind,"open",{});return true}
|
|
33
|
+
const cancel=event=>{event.preventDefault();if(uiTopOverlay()===entry)close("cancel")};element.addEventListener("cancel",cancel,{signal});const nativeClose=event=>{if(event.target!==element)return;const pending=nativeCloses.shift();if(pending?.silent||(pending&&pending.generation!==generation)||element.open){event.stopImmediatePropagation();return}
|
|
34
|
+
if(opened)close("native",options.focus!==false,true)};element.addEventListener("close",nativeClose,true);function setModal(value){if(!opened||modal===value)return;const active=document.activeElement;if(element.localName==="dialog"&&element.open){closeNative(true);if(value)element.showModal();else element.show()}
|
|
35
|
+
uiLockScroll(value);modal=value;if(value)element.setAttribute("aria-modal","true");else element.removeAttribute("aria-modal");if(active&&element.contains(active))active.focus({preventScroll:true})}
|
|
36
|
+
const destroy=()=>{close("destroy",false,true);element.removeEventListener("cancel",cancel);element.removeEventListener("close",nativeClose,true);if(hadTabindex===null)element.removeAttribute("tabindex");else element.setAttribute("tabindex",hadTabindex)};signal?.addEventListener("abort",destroy,{once:true});return{element,open,close,destroy,setModal,get opened(){return opened},get modal(){return modal}}};function uiDialog(root,options,signal,drawer){const labels=UI_TOOLS.labels(options.labels),trigger=options.trigger||document.getElementById(root.dataset.cxTrigger||"");const container=options.container||root.parentElement||document.body,alert=root.getAttribute("role")==="alertdialog";let phone=false;const overlay=UI_TOOLS.overlay(root,{kind:drawer?"drawer":"dialog",trigger,host:options.host||container,focus:options.focus,dismissible:options.dismissible??root.dataset.dismissible!=="false",initialFocus:options.initialFocus||(element=>
|
|
37
|
+
alert?element.querySelector('[data-cx-cancel],button:not([data-danger]):not([type="submit"])'):element.querySelector("input:not([type=hidden]),select,textarea"))},signal);const open=()=>overlay.open({modal:!drawer||phone||options.modal===true||root.dataset.modal==="true"});UI_TOOLS.observe(container,width=>{phone=width<640;root.dataset.phone=String(phone);root.classList.toggle("cx-phone",phone);if(drawer&&overlay.opened)overlay.setModal(phone||options.modal===true||root.dataset.modal==="true")},signal);trigger?.addEventListener("click",open,{signal});root.addEventListener("click",event=>{if(event.target.closest("[data-cx-close],[data-cx-cancel]"))overlay.close("cancel")},{signal});const body=root.querySelector('[data-hfx-part="body"]');body?.addEventListener("scroll",()=>{root.dataset.scrolled=String(body.scrollTop>0)},{signal});if(drawer)root.addEventListener("keydown",event=>{if(!options.records||/^(?:INPUT|TEXTAREA|SELECT)$/.test(event.target.tagName) || event.target.isContentEditable) return;
|
|
38
|
+
if(event.key==="ArrowUp"||event.key==="ArrowDown"){event.preventDefault();options.records(event.key==="ArrowUp"?-1:1)}},{signal});for(const button of root.querySelectorAll(".cx-overlay-close"))button.setAttribute("aria-label",drawer?labels.drawerClose:labels.dialogClose);return{...overlay,open,refresh(){},getState:()=>({open:overlay.opened,modal:overlay.modal})}}
|
|
39
|
+
UI_IMPL.dialog=(root,options,signal)=>uiDialog(root,options,signal,false);UI_IMPL.drawer=(root,options,signal)=>uiDialog(root,options,signal,true);UI_IMPL.popover=(root,options,signal)=>{const trigger=options.trigger||document.getElementById(root.dataset.cxTrigger||"");const overlay=UI_TOOLS.overlay(root,{...options,trigger,kind:"popover",anchored:true},signal);trigger?.addEventListener("click",()=>overlay.opened?overlay.close():overlay.open(),{signal});trigger?.addEventListener("keydown",event=>{if(event.key==="ArrowDown"){event.preventDefault();overlay.open()}},{signal});root.addEventListener("keydown",event=>{if(event.key!=="Tab")return;const items=UI_TOOLS.focusables(root),at=items.indexOf(document.activeElement);if(event.shiftKey&&at===0||!event.shiftKey&&at===items.length-1){const outside=UI_TOOLS.focusables(trigger?.closest("dialog[open]")||document).filter(item=>!root.contains(item));const next=event.shiftKey?trigger:outside[outside.indexOf(trigger)+ 1];if(overlay.close("tab",false)){event.preventDefault();(next||trigger)?.focus()}}},{signal});return overlay};UI_IMPL.tooltip=(root,options,signal)=>{const trigger=options.trigger||document.getElementById(root.dataset.cxTrigger||"");if(!trigger)throw new Error("CanopyX: tooltip needs a labelled trigger.");const overlay=UI_TOOLS.overlay(root,{...options,trigger,kind:"tooltip",anchored:true,placement:options.placement||root.dataset.placement||"top",focus:false},signal);const described=trigger.getAttribute("aria-describedby"),ids=new Set((described||"").split(/\s+/).filter(Boolean));
|
|
40
|
+
if(!root.id)root.id=trigger.id+"-tooltip";const hadDescription=ids.has(root.id);ids.add(root.id);trigger.setAttribute("aria-describedby",[...ids].join(" "));let showTimer,hideTimer;const hide=()=>{clearTimeout(showTimer);clearTimeout(hideTimer);if(document.activeElement!==trigger)hideTimer=setTimeout(()=>overlay.close("leave",false),100)};const show=delay=>{clearTimeout(showTimer);clearTimeout(hideTimer);showTimer=setTimeout(()=>overlay.open(),delay)};trigger.addEventListener("pointerenter",()=>show(400),{signal});trigger.addEventListener("pointerleave",hide,{signal});root.addEventListener("pointerenter",()=>clearTimeout(hideTimer),{signal});root.addEventListener("pointerleave",hide,{signal});trigger.addEventListener("focus",()=>{clearTimeout(hideTimer);overlay.open()},{signal});trigger.addEventListener("blur",hide,{signal});const destroy=()=>{clearTimeout(showTimer);clearTimeout(hideTimer);overlay.destroy();const current=new Set((trigger.getAttribute("aria-describedby")||"").split(/\s+/).filter(Boolean));
|
|
41
|
+
if(!hadDescription)current.delete(root.id);if(current.size)trigger.setAttribute("aria-describedby",[...current].join(" "));else trigger.removeAttribute("aria-describedby")};signal.addEventListener("abort",destroy,{once:true});return{...overlay,destroy}};UI_TOOLS.toolbarFlyout=(anchor,panel,isOpen,signal)=>{const trigger=anchor.querySelector(":scope > summary")||anchor;const pressed=new Set();let positionPending=false,releaseFrame=0;if(!panel.hasAttribute("role"))panel.setAttribute("role","dialog");if(!panel.hasAttribute("aria-label"))panel.setAttribute("aria-label",trigger.getAttribute("aria-label")||trigger.textContent.trim()||trigger.title);const overlay=UI_TOOLS.overlay(panel,{kind:"popover",trigger,host:anchor.closest(".cx-host")||anchor,portal:panel.parentNode,focus:false,decorateTrigger:false},signal);const position=()=>{if(signal.aborted||!isOpen())return;if(pressed.size||releaseFrame){positionPending=true;return}
|
|
42
|
+
positionPending=false;const box=trigger.getBoundingClientRect(),fixed=getComputedStyle(panel).position==="fixed";const below=Math.max(0,global.innerHeight-box.bottom-8),above=Math.max(0,box.top-8);const top=below<120&&above>below,room=top?above:below;panel.style.maxHeight=(panel.matches(".cx-fb,.cx-export-panel")?room:Math.min(320,room))+ "px";panel.style.bottom="auto";UI_TOOLS.position(panel,trigger,top?"top-start":"bottom-start");if(!fixed&&panel.offsetParent){const parent=panel.offsetParent,bounds=parent.getBoundingClientRect();panel.style.left=parseFloat(panel.style.left)- bounds.left+parent.scrollLeft-parent.clientLeft+"px";panel.style.top=parseFloat(panel.style.top)- bounds.top+parent.scrollTop-parent.clientTop+"px"}};panel.addEventListener("cx-popover:close",event=>{if(event.target!==panel)return;if(anchor.localName==="details")anchor.open=false;for(const inner of panel.querySelectorAll("details[open]"))inner.open=false;if(event.detail.reason==="cancel")trigger.focus({preventScroll:true})},{signal});panel.addEventListener("pointerdown",event=>pressed.add(event.pointerId),{signal});const release=event=>{if(!pressed.delete(event.pointerId))return;if(!releaseFrame)releaseFrame=global.requestAnimationFrame(()=>{releaseFrame=0;if(positionPending)position()})};for(const type of["pointerup","pointercancel"])global.addEventListener(type,release,{capture:true,signal});global.addEventListener("resize",position,{signal});global.addEventListener("scroll",position,{capture:true,signal});signal.addEventListener("abort",()=>{global.cancelAnimationFrame(releaseFrame);pressed.clear()},{once:true});return{position,open(){if(isOpen()&&!overlay.opened)overlay.open();position()},close(){overlay.close("toggle",false,true)}}};installed.add(context.UI_IMPL)}};(global.CanopyXParts||=[]).push(["ui-overlays",part])})(typeof window!=="undefined"?window:globalThis);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
@layer hfx.components{
|
|
2
|
+
.cx-picker{min-inline-size:0;font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);font-size:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem));}
|
|
3
|
+
.cx-picker-trigger{inline-size:100%;justify-content:flex-start;min-inline-size:0;text-align:start;}
|
|
4
|
+
.cx-picker-lead,.cx-picker-separator,.cx-picker-chevron{flex:none;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-weight:var(--hfx-weight-regular,400);}
|
|
5
|
+
.cx-picker-label{min-inline-size:0;overflow-wrap:anywhere;color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
|
|
6
|
+
.cx-picker-icon{display:inline-flex;flex:none;align-items:center;justify-content:center;inline-size:var(--hfx-icon-md,16px);block-size:var(--hfx-icon-md,16px);}
|
|
7
|
+
.cx-picker-icon > :is(svg,img){inline-size:100%;block-size:100%;}
|
|
8
|
+
.cx-picker-chevron{margin-inline-start:auto;}
|
|
9
|
+
.cx-picker-badge{flex:none;min-block-size:var(--hfx-badge-height,20px);padding:0 var(--hfx-space-1,0.25rem);border-radius:var(--hfx-radius-badge,var(--hfx-radius-sm,4px));background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));font-size:var(--hfx-type-caption-size,0.75rem);line-height:var(--hfx-type-caption-line,1.35);}
|
|
10
|
+
.cx-picker :is(.cx-picker-lead,.cx-picker-label,.cx-picker-separator,.cx-picker-icon,.cx-picker-badge)[hidden]{display:none;}
|
|
11
|
+
@media print{.cx-picker{display:none!important;}}
|
|
12
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"02ff3779dd1c1ef4",requires:["ui-menu"],install(context){if(installed.has(context.UI_IMPL))return;const{UI_IMPL,UI_TOOLS,h,setText,fill,watchTheme,overlayTheme,hostHtml}=context;let uiPickerIdentity=0;UI_TOOLS.picker=(root,options={})=>{const element=h('div','cx-picker');element.dataset.hfxPart='picker';const trigger=h('button','cx-picker-trigger cx-ui-button');trigger.type='button';const lead=h('span','cx-picker-lead'),separator=h('span','cx-picker-separator');separator.setAttribute('aria-hidden','true');setText(separator,'·');const icon=h('span','cx-picker-icon');icon.setAttribute('aria-hidden','true');const label=h('span','cx-picker-label'),badge=h('span','cx-picker-badge');badge.dataset.hfxPart='badge';const chevron=h('span','cx-picker-chevron');chevron.setAttribute('aria-hidden','true');setText(chevron,'▾');trigger.append(lead,separator,icon,label,badge,chevron);const menu=h('div','cx-menu');menu.hidden=true;menu.setAttribute('role','menu');menu.id='cx-ui-picker-menu-' + ++uiPickerIdentity;trigger.id=menu.id+'-trigger';element.append(trigger,menu);root.append(element);let state={...options},destroyed=false,selectionVersion=0;const renderIcon=value=>value?.nodeType?value.cloneNode(true):value;const controller=UI_IMPL.menu(menu,{trigger,host:root,renderIcon,async onSelect(item){const ticket=++selectionVersion;syncChecks();try{await state.onSelect?.(item.id)}
|
|
2
|
+
catch{}
|
|
3
|
+
finally{if(!destroyed&&ticket===selectionVersion)syncChecks()}}});function syncChecks(){for(const item of menu.querySelectorAll('[role="menuitemradio"]')){const checked=item.dataset.itemId===state.selected;item.setAttribute('aria-checked',String(checked));item.dataset.state=item.getAttribute('aria-disabled')==='true'?'disabled':checked?'selected':''}}
|
|
4
|
+
function update(next={}){if(destroyed)return;selectionVersion++;state={...state,...next};const items=state.items||[],selected=items.find(item=>item.id===state.selected);setText(lead,state.lead);lead.hidden=!state.lead;setText(label,selected?.label);label.hidden=!selected;separator.hidden=!state.lead||!selected;setText(badge,selected?.badge);badge.hidden=selected?.badge==null||selected.badge==='';icon.replaceChildren();icon.hidden=selected?.icon==null;if(selected?.icon?.nodeType)icon.append(selected.icon.cloneNode(true));else if(selected?.icon!=null)setText(icon,selected.icon);trigger.setAttribute('aria-label',[state.lead,selected?.label,selected?.badge].filter(value=>value!=null&&value!=='').join(' '));trigger.disabled=!items.length;element.dataset.state=!items.length?'disabled':selected?'selected':'';controller.close('update',false,true);UI_TOOLS.menuItems(menu,items.map(item=>({...item,kind:'radio',checked:item.id===state.selected})),{renderIcon});controller.refresh()}
|
|
5
|
+
function destroy(){if(destroyed)return;destroyed=true;selectionVersion++;controller.destroy();element.remove()}
|
|
6
|
+
update();return{element,update,destroy}};installed.add(context.UI_IMPL)}};(global.CanopyXParts||=[]).push(["ui-picker",part])})(typeof window!=="undefined"?window:globalThis);
|