@evotecit/canopyx 0.3.15 → 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 +2 -0
- package/CanopyX.Html/Assets/canopyx-flow-checks.js +5 -4
- package/CanopyX.Html/Assets/canopyx-flow-dialog.css +2 -0
- 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 +5 -5
- package/CanopyX.Html/Assets/canopyx-flow-facts.js +2 -0
- package/CanopyX.Html/Assets/canopyx-flow-module.mjs +5 -5
- package/CanopyX.Html/Assets/canopyx-flow.js +8 -7
- 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 +185 -131
- package/CanopyX.Html/Assets/canopyx-grid.css +228 -96
- package/CanopyX.Html/Assets/canopyx-grid.js +185 -131
- 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 +20 -15
- 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 +11 -2
- package/CanopyX.Html/Assets/canopyx-record-panel.js +18 -12
- package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +225 -164
- package/CanopyX.Html/Assets/canopyx-reporting.css +240 -107
- package/CanopyX.Html/Assets/canopyx-reporting.js +225 -164
- 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/flow.d.ts +6 -0
- package/JavaScript/grid.d.ts +153 -17
- package/JavaScript/hosts.d.ts +14 -1
- package/JavaScript/index.d.ts +4 -2
- package/JavaScript/live.d.ts +2 -0
- 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 +20 -4
- 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
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(function(global){"use strict";const installed=new WeakSet();const part={version:"
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"c3b57a7478b94a93",requires:["flow","flow-host"],install(context){if(installed.has(context.FLOW_IMPL))return;const{FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,numberFormat}=context;const{FlowView,FLOW_HOST,FLOW_LABELS,flowFail,flowIs,flowKeys,flowName,flowString,flowFlag,flowScalar,flowFits,flowField,flowOptions,flowCondition,flowRefs,flowTest,flowCopy,flowSameValue,flowEmpty,flowNormal,flowDate,flowFieldView}=FLOW_IMPL.core;const{EDIT_EDITORS,formRuleSpec,formCheck}=FORMS_IMPL;const FLOW_PART_LABELS={flowClose:"Close",flowDiscardQuestion:"Discard your answers?",flowDiscard:"Discard",flowKeepEditing:"Keep editing"};Object.assign(FLOW_LABELS,FLOW_PART_LABELS);const flowRelease=FlowView.prototype.destroy;FLOW_HOST.dialog={document(doc,model){const raw=doc.layout;if(!raw)return;model.container=raw.container??"inline";if(!["inline","dialog","drawer"].includes(model.container))flowFail("the flow layout has an unknown container");if(raw.launch!==undefined&&model.container==="inline")flowFail("only a dialog or drawer flow has a launch button");model.launch=flowString(raw.launch,80,"The launch label")}};Object.assign(FlowView.prototype,{destroy(){flowRelease.call(this);this.shell?.remove()},buildContainer(){const labels=this.labels,shell=this.shell=h("div","cx-flow-launcher"),launch=this.launcher=h("button","cx-flow-btn cx-primary cx-flow-launch");launch.type="button";setText(launch,this.model.launch||this.model.title);launch.setAttribute("aria-haspopup","dialog");const dialog=this.dialog=h("dialog","cx-flow-dialog" +(this.model.container==="drawer"?" cx-flow-drawer":""));dialog.setAttribute("aria-labelledby",this.id+"-title");const close=h("button","cx-flow-icon-btn cx-flow-close");close.type="button";setText(close,"×");close.setAttribute("aria-label",labels.flowClose);this.head.classList.add("cx-flow-head-close");this.head.appendChild(close);const confirm=this.discardBar=h("div","cx-flow-discard"),question=h("p"),discard=h("button","cx-flow-btn"),keep=h("button","cx-flow-btn cx-primary");confirm.setAttribute("role","alertdialog");confirm.setAttribute("aria-labelledby",this.id+"-discard");confirm.hidden=true;question.id=this.id+"-discard";setText(question,labels.flowDiscardQuestion);discard.type=keep.type="button";setText(discard,labels.flowDiscard);setText(keep,labels.flowKeepEditing);confirm.append(question,keep,discard);this.root.insertBefore(confirm,this.layout);dialog.appendChild(this.root);shell.append(launch,dialog);this.host.appendChild(shell);const signal=this.lifetime.signal;launch.addEventListener("click",()=>this.open(),{signal});close.addEventListener("click",()=>this.close(),{signal});dialog.addEventListener("cancel",event=>{event.preventDefault();this.close()},{signal});keep.addEventListener("click",()=>{confirm.hidden=true;this.stage.querySelector(".cx-flow-step-title")?.focus()},{signal});discard.addEventListener("click",()=>this.close(true),{signal})},cancelButton(){if(!this.dialog)return null;const cancel=h("button","cx-flow-btn cx-flow-quiet");cancel.type="button";setText(cancel,this.labels.flowCancel);cancel.addEventListener("click",()=>this.close());return cancel},open(){if(!this.dialog||this.dialog.open)return!!this.dialog;this.discardBar.hidden=true;this.dialog.showModal();this.measure();this.render();(this.stage.querySelector(".cx-flow-step-title")||this.root).focus({preventScroll:true});return true},close(force){if(!this.dialog?.open)return false;if(!force&&this.phase==="form"&&this.isDirty()){if(!this.emit("flowLeaving",{reason:"close"},"onLeaving",true))return false;this.discardBar.hidden=false;this.discardBar.querySelector(".cx-primary").focus();return false}
|
|
2
2
|
this.discardBar.hidden=true;this.dialog.close();if(force||this.phase!=="form"){this.panel=null;this.reset()}
|
|
3
3
|
this.launcher.focus();return true}});installed.add(context.FLOW_IMPL)}};(global.CanopyXParts||=[]).push(["flow-dialog",part])})(typeof window!=="undefined"?window:globalThis);
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
--cx-size-10px:10px;
|
|
37
37
|
--cx-size-11px:11px;
|
|
38
38
|
--cx-size-1d5px:1.5px;
|
|
39
|
-
--cx-size-21px:21px;
|
|
40
39
|
--cx-size-5px:5px;
|
|
41
40
|
--cx-size-280px:280px;
|
|
42
41
|
--cx-size-34px:34px;
|
|
@@ -48,17 +47,13 @@
|
|
|
48
47
|
--cx-size-16px:16px;
|
|
49
48
|
--cx-size-320px:320px;
|
|
50
49
|
--cx-size-2px:2px;
|
|
51
|
-
--cx-size-d8em:.8em;
|
|
52
|
-
--cx-size-d85em:.85em;
|
|
53
50
|
--cx-size-neg-2px:-2px;
|
|
54
51
|
--cx-size-180px:180px;
|
|
55
|
-
--cx-size-d92em:.92em;
|
|
56
52
|
--cx-size-9px:9px;
|
|
57
53
|
--cx-size-neg-3px:-3px;
|
|
58
54
|
--cx-size-18px:18px;
|
|
59
55
|
--cx-size-1d6px:1.6px;
|
|
60
56
|
--cx-size-999px:999px;
|
|
61
|
-
--cx-size-12em:12em;
|
|
62
57
|
--cx-size-100vh:100vh;
|
|
63
58
|
--cx-size-340px:340px;
|
|
64
59
|
--cx-size-20px:20px;
|
|
@@ -83,30 +78,36 @@
|
|
|
83
78
|
box-sizing:border-box;
|
|
84
79
|
display:flex;
|
|
85
80
|
flex-direction:column;
|
|
86
|
-
height:
|
|
81
|
+
height:480px;
|
|
87
82
|
min-height:0;
|
|
88
83
|
color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));
|
|
89
84
|
background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));
|
|
90
85
|
font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);
|
|
91
86
|
font-size:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem));
|
|
92
|
-
line-height:1.4;
|
|
87
|
+
line-height:var(--hfx-type-small-line,1.4);
|
|
93
88
|
}
|
|
89
|
+
.cx-host[data-cx-chrome="embedded"]{background:transparent;border:0;border-radius:0;}
|
|
90
|
+
.cx-host[data-cx-chrome="embedded"] > .cx-grid{border-inline:0;border-bottom:0;border-radius:0;background:transparent;}
|
|
91
|
+
.cx-host[data-cx-chrome="embedded"] > :is(.cx-grid-notice,.cx-grid-status,.cx-grid-pager){background:transparent;}
|
|
92
|
+
.cx-host[data-cx-chrome="embedded"] :is(.cx-toolbar,.cx-grid-query-summary,.cx-grid-status,.cx-grid-pager){padding-inline:var(--hfx-card-padding-x,calc(20px - var(--cx-compact,0) * 4px));}
|
|
93
|
+
.cx-host[data-cx-chrome="embedded"] :is(.cx-hrow,.cx-row) > :first-child{padding-inline-start:var(--hfx-card-padding-x,calc(20px - var(--cx-compact,0) * 4px));}
|
|
94
|
+
.cx-host[data-cx-chrome="embedded"] :is(.cx-hrow,.cx-row) > :last-child{padding-inline-end:var(--hfx-card-padding-x,calc(20px - var(--cx-compact,0) * 4px));}
|
|
94
95
|
.cx-host *,.cx-host *::before,.cx-host *::after{box-sizing:border-box;}
|
|
95
|
-
.cx-host .cx-button.cx-filter-chip{display:inline-flex;align-items:center;justify-content:flex-start;gap:var(--
|
|
96
|
-
.cx-filter-chip > .cx-chip-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
96
|
+
.cx-host .cx-button.cx-filter-chip{display:inline-flex;align-items:center;justify-content:flex-start;gap:var(--hfx-space-1-5,6px);min-width:0;}
|
|
97
|
+
.cx-filter-chip > .cx-chip-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:var(--hfx-type-small-line,1.4);}
|
|
97
98
|
.cx-filter-chip > .cx-chip-remove{flex:none;}
|
|
98
99
|
@media print{.cx-filter-chip > .cx-chip-label{white-space:normal;overflow:visible;text-overflow:clip;}}
|
|
99
100
|
@media not (forced-colors:active){
|
|
100
101
|
:where(.cx-host,.cx-host *){scrollbar-color:var(--cx-scrollbar-thumb) var(--cx-scrollbar-track);scrollbar-width:thin;}
|
|
101
102
|
.cx-host::-webkit-scrollbar,.cx-host ::-webkit-scrollbar{width:var(--cx-scrollbar-size);height:var(--cx-scrollbar-size);}
|
|
102
103
|
.cx-host::-webkit-scrollbar-track,.cx-host ::-webkit-scrollbar-track,.cx-host ::-webkit-scrollbar-corner{background:var(--cx-scrollbar-track);}
|
|
103
|
-
.cx-host::-webkit-scrollbar-thumb,.cx-host ::-webkit-scrollbar-thumb{background:var(--cx-scrollbar-thumb) padding-box;border:var(--
|
|
104
|
+
.cx-host::-webkit-scrollbar-thumb,.cx-host ::-webkit-scrollbar-thumb{background:var(--cx-scrollbar-thumb) padding-box;border:calc(var(--hfx-border-width,1px)*2) solid transparent;border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
|
|
104
105
|
.cx-host ::-webkit-scrollbar-thumb:hover{background-color:var(--cx-scrollbar-thumb-hover);}
|
|
105
106
|
}
|
|
106
107
|
.cx-sr-only{
|
|
107
|
-
--cx-size-1px:1px;--cx-size-neg-1px:-1px;
|
|
108
108
|
position:absolute !important;
|
|
109
|
-
width:
|
|
109
|
+
width:1px;height:1px;padding:0;
|
|
110
|
+
margin:calc(var(--hfx-border-width,1px)*-1);
|
|
110
111
|
overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
|
|
111
112
|
}
|
|
112
113
|
.cx-host[data-cx-density="compact"]{--cx-compact:1;}
|
|
@@ -115,6 +116,129 @@ overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
|
|
|
115
116
|
:where([data-cx-fallback-mode="light"],.cx-static[data-theme="light"],.cx-static[data-cx-theme="light"]){color-scheme:light;}
|
|
116
117
|
:where([data-cx-fallback-mode="dark"],.cx-static[data-theme="dark"],.cx-static[data-cx-theme="dark"]){color-scheme:dark;}
|
|
117
118
|
}
|
|
119
|
+
@layer hfx.components{
|
|
120
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close){
|
|
121
|
+
display:inline-flex;align-items:center;justify-content:center;gap:var(--hfx-space-1-5,6px);
|
|
122
|
+
min-block-size:var(--cx-ui-touch-target,var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px)));block-size:var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px));padding:0 var(--hfx-control-padding-x,calc(14px - var(--cx-compact,0) * 4px));
|
|
123
|
+
border:var(--hfx-border-width,1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));
|
|
124
|
+
background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));
|
|
125
|
+
font:var(--hfx-weight-medium,500) var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem)) var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);line-height:1;white-space:nowrap;cursor:pointer;
|
|
126
|
+
}
|
|
127
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):hover{background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));}
|
|
128
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):active{background:var(--hfx-color-active,light-dark(#ebebec,#2e3034));}
|
|
129
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):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);}
|
|
130
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-variant="primary"],[data-primary],.primary){
|
|
131
|
+
background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));color:var(--hfx-color-accent-contrast,light-dark(#ffffff,#0c0d10));
|
|
132
|
+
}
|
|
133
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-variant="primary"],[data-primary],.primary):hover{background:var(--hfx-color-accent-hover,light-dark(#0d6760,#4dd9c8));border-color:var(--hfx-color-accent-hover,light-dark(#0d6760,#4dd9c8));}
|
|
134
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-variant="ghost"],[data-ghost],.ghost){background:transparent;border-color:transparent;color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));}
|
|
135
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-variant="ghost"],[data-ghost],.ghost):hover{background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
|
|
136
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-variant="danger"],.danger){color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));border-color:var(--hfx-color-status-bad-border,light-dark(#eeacac,#814345));}
|
|
137
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([aria-pressed="true"],.active){
|
|
138
|
+
border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));
|
|
139
|
+
}
|
|
140
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is(:disabled,[aria-disabled="true"]),:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is(:disabled,[aria-disabled="true"]):hover{color:var(--hfx-color-text-disabled,light-dark(#a3a8b0,#5a5f68));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));border-color:var(--hfx-color-border,light-dark(#e2e4e7,#272a30));cursor:default;}
|
|
141
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-variant="ghost"],[data-ghost],.ghost):is(:disabled,[aria-disabled="true"]),:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-variant="ghost"],[data-ghost],.ghost):is(:disabled,[aria-disabled="true"]):hover{background:transparent;border-color:transparent;}
|
|
142
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-size="sm"],.sm){block-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 var(--hfx-space-2,0.5rem);}
|
|
143
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-size="lg"],.lg){block-size:var(--hfx-control-height-lg,calc(44px - var(--cx-compact,0) * 8px));min-block-size:var(--hfx-control-height-lg,calc(44px - var(--cx-compact,0) * 8px));}
|
|
144
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-icon],.icon){inline-size:var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px));padding:0;}
|
|
145
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close):is([data-icon],.icon):is([data-size="sm"],.sm){inline-size:var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px));}
|
|
146
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,[data-cx-open],.cx-overlay-close) :where(.badge,.cx-count){
|
|
147
|
+
display:inline-grid;place-items:center;min-inline-size:var(--hfx-badge-height,20px);block-size:var(--hfx-badge-height,20px);padding:0 var(--hfx-space-1,0.25rem);
|
|
148
|
+
border-radius:var(--hfx-radius-pill,999px);background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));color:var(--hfx-color-accent-contrast,light-dark(#ffffff,#0c0d10));
|
|
149
|
+
font-size:var(--hfx-type-caption-size,0.75rem);font-weight:var(--hfx-weight-semibold,600);
|
|
150
|
+
}
|
|
151
|
+
:where(.cx-input,.cx-select,.cx-textarea){
|
|
152
|
+
min-inline-size:0;block-size:var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px));padding:0 calc(var(--hfx-space-1,0.25rem)*2.5);
|
|
153
|
+
border:var(--hfx-border-width,1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));
|
|
154
|
+
background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font:inherit;font-size:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem));
|
|
155
|
+
}
|
|
156
|
+
:where(.cx-textarea){block-size:auto;min-block-size:calc(var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px))*2);padding-block:var(--hfx-space-2,0.5rem);}
|
|
157
|
+
:where(.cx-input,.cx-select,.cx-textarea)::placeholder{color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));opacity:1;}
|
|
158
|
+
:where(.cx-input,.cx-select,.cx-textarea):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);border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
|
|
159
|
+
:where(.cx-input,.cx-select,.cx-textarea):disabled{color:var(--hfx-color-text-disabled,light-dark(#a3a8b0,#5a5f68));background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));}
|
|
160
|
+
:where(.cx-input,.cx-select,.cx-textarea)[aria-invalid="true"]{border-color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
161
|
+
:where(.cx-input,.cx-select,.cx-textarea):is([data-size="sm"],.sm){block-size:var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px));padding:0 var(--hfx-space-2,0.5rem);}
|
|
162
|
+
:where(.cx-check){inline-size:var(--hfx-icon-md,16px);block-size:var(--hfx-icon-md,16px);margin:0;accent-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));flex:none;}
|
|
163
|
+
:where(.cx-toggle){
|
|
164
|
+
appearance:none;flex:none;position:relative;inline-size:calc(var(--hfx-icon-md,16px)*2.25);block-size:calc(var(--hfx-icon-md,16px)*1.25);margin:0;
|
|
165
|
+
border-radius:var(--hfx-radius-pill,999px);background:var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));cursor:pointer;
|
|
166
|
+
transition:background-color var(--hfx-motion-duration-fast,120ms) var(--hfx-motion-easing-standard,cubic-bezier(.2,0,0,1));
|
|
167
|
+
}
|
|
168
|
+
:where(.cx-toggle)::before{
|
|
169
|
+
content:"";position:absolute;inset-block-start:calc(var(--hfx-icon-md,16px)*.125);inset-inline-start:calc(var(--hfx-icon-md,16px)*.125);
|
|
170
|
+
inline-size:var(--hfx-icon-md,16px);block-size:var(--hfx-icon-md,16px);border-radius:var(--hfx-radius-pill,999px);background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));box-shadow:var(--hfx-elevation-1,0 1px 2px rgba(22,24,28,.06));
|
|
171
|
+
transition:transform var(--hfx-motion-duration-fast,120ms) var(--hfx-motion-easing-standard,cubic-bezier(.2,0,0,1));
|
|
172
|
+
}
|
|
173
|
+
:where(.cx-toggle):checked{background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
|
|
174
|
+
:where(.cx-toggle):checked::before{transform:translateX(var(--hfx-icon-md,16px));}
|
|
175
|
+
:where(:dir(rtl)) :where(.cx-toggle):checked::before{transform:translateX(calc(var(--hfx-icon-md,16px)*-1));}
|
|
176
|
+
:where(.cx-toggle):disabled{background:var(--hfx-color-border,light-dark(#e2e4e7,#272a30));cursor:default;}
|
|
177
|
+
:where(.cx-toggle,.cx-check):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);}
|
|
178
|
+
:where(.cx-segmented,.cx-seg){
|
|
179
|
+
display:inline-flex;align-items:center;gap:var(--hfx-space-0-5,2px);padding:var(--hfx-space-0-5,2px);
|
|
180
|
+
border:var(--hfx-border-width,1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));
|
|
181
|
+
}
|
|
182
|
+
:where(.cx-segmented,.cx-seg) > :where(button,[role="radio"]){
|
|
183
|
+
display:inline-flex;align-items:center;justify-content:center;gap:var(--hfx-space-1-5,6px);
|
|
184
|
+
block-size:calc(var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px)) - var(--hfx-space-1,0.25rem));padding:0 var(--hfx-space-3,0.75rem);border:0;border-radius:calc(var(--hfx-radius-control,var(--hfx-radius-md,6px)) - var(--hfx-space-0-5,2px));
|
|
185
|
+
background:transparent;color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));font:var(--hfx-weight-medium,500) var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem)) var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);cursor:pointer;white-space:nowrap;
|
|
186
|
+
}
|
|
187
|
+
:where(.cx-segmented,.cx-seg) > :where(button,[role="radio"]):hover{color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
|
|
188
|
+
:where(.cx-segmented,.cx-seg) > :where([aria-pressed="true"],[aria-checked="true"],.active,.on){background:var(--hfx-color-surface-raised,light-dark(#ffffff,#1e2126));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));box-shadow:var(--hfx-elevation-1,0 1px 2px rgba(22,24,28,.06));outline:var(--hfx-border-width,1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));outline-offset:calc(var(--hfx-border-width,1px)*-1);}
|
|
189
|
+
:where(.cx-segmented,.cx-seg) > :where(button,[role="radio"]):focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:calc(var(--hfx-focus-width,2px)*-1);}
|
|
190
|
+
:where(.cx-segmented,.cx-seg):is([data-size="sm"],.sm) > :where(button,[role="radio"]){block-size:calc(var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px)) - var(--hfx-space-1,0.25rem));padding:0 var(--hfx-space-2,0.5rem);}
|
|
191
|
+
:where(.cx-chip){
|
|
192
|
+
display:inline-flex;align-items:center;gap:var(--hfx-space-1-5,6px);max-inline-size:100%;block-size:var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px));padding:0 calc(var(--hfx-space-1,0.25rem)*2.5);
|
|
193
|
+
border:var(--hfx-border-width,1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-status,999px);
|
|
194
|
+
background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font:var(--hfx-weight-medium,500) var(--hfx-type-small-size,0.8125rem) var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);white-space:nowrap;
|
|
195
|
+
}
|
|
196
|
+
:where(button.cx-chip){cursor:pointer;}
|
|
197
|
+
:where(button.cx-chip):hover{background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));}
|
|
198
|
+
:where(.cx-chip):is([aria-pressed="true"],.active){border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));}
|
|
199
|
+
:where(.cx-chip):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);}
|
|
200
|
+
:where(.cx-pill,.p-pill){
|
|
201
|
+
display:inline-flex;align-items:center;gap:var(--hfx-space-1,0.25rem);block-size:var(--hfx-pill-height,22px);padding:0 var(--hfx-space-2,0.5rem);
|
|
202
|
+
border-radius:var(--hfx-radius-status,999px);background:var(--hfx-color-status-neutral-bg,light-dark(#eeeff0,#2a2c31));color:var(--hfx-color-status-neutral-fg,light-dark(#5b6069,#a0a5ae));
|
|
203
|
+
font:var(--hfx-weight-semibold,600) var(--hfx-type-caption-size,0.75rem) var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);white-space:nowrap;
|
|
204
|
+
outline:var(--hfx-border-width,1px) solid color-mix(in srgb,currentColor 24%,transparent);outline-offset:calc(var(--hfx-border-width,1px)*-1);
|
|
205
|
+
}
|
|
206
|
+
:where(.cx-pill,.p-pill):is(.cx-tone-info,.info){background:var(--hfx-color-status-info-bg,light-dark(#e4ecfa,#262f41));color:var(--hfx-color-status-info-fg,light-dark(#2b5fc0,#74a2f7));}
|
|
207
|
+
:where(.cx-pill,.p-pill):is(.cx-tone-success,.success){background:var(--hfx-color-status-good-bg,light-dark(#e2f0e9,#1f362f));color:var(--hfx-color-status-good-fg,light-dark(#177345,#4cc78a));}
|
|
208
|
+
:where(.cx-pill,.p-pill):is(.cx-tone-warning,.warning){background:var(--hfx-color-status-warn-bg,light-dark(#f8efde,#3b3322));color:var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640));}
|
|
209
|
+
:where(.cx-pill,.p-pill):is(.cx-tone-danger,.danger){background:var(--hfx-color-status-bad-bg,light-dark(#f9e4e4,#3c272a));color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
210
|
+
:where(.cx-pill,.p-pill).cx-toned{background:var(--cx-t-bg,color-mix(in srgb,var(--cx-t,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))) 12%,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));color:var(--cx-t,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
|
|
211
|
+
:where(.cx-disclosure){
|
|
212
|
+
flex:none;display:inline-grid;place-items:center;inline-size:var(--hfx-icon-md,16px);block-size:var(--hfx-icon-md,16px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));
|
|
213
|
+
transition:transform var(--hfx-motion-duration-fast,120ms) var(--hfx-motion-easing-standard,cubic-bezier(.2,0,0,1));
|
|
214
|
+
}
|
|
215
|
+
:where(.cx-disclosure)::before{
|
|
216
|
+
content:"";inline-size:calc(var(--hfx-icon-md,16px)*.4375);block-size:calc(var(--hfx-icon-md,16px)*.4375);
|
|
217
|
+
border-inline-end:calc(var(--hfx-border-width,1px)*1.6) solid currentColor;border-block-end:calc(var(--hfx-border-width,1px)*1.6) solid currentColor;transform:rotate(-45deg);
|
|
218
|
+
}
|
|
219
|
+
:where([aria-expanded="true"]) > :where(.cx-disclosure),:where(.cx-disclosure)[data-open]{transform:rotate(90deg);}
|
|
220
|
+
:where(:dir(rtl)) :where(.cx-disclosure)::before{transform:rotate(135deg);}
|
|
221
|
+
:where(.cx-empty-state){
|
|
222
|
+
display:grid;justify-items:center;gap:var(--hfx-space-2,0.5rem);padding:var(--hfx-space-6,2rem) var(--hfx-space-4,1rem);text-align:center;color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));
|
|
223
|
+
}
|
|
224
|
+
:where(.cx-empty-state) > :where(strong,h2,h3){color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font-size:var(--hfx-type-heading-size,0.9375rem);font-weight:var(--hfx-weight-semibold,600);}
|
|
225
|
+
:where(.cx-empty-state)[data-tone="danger"] > :where(strong,h2,h3){color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
226
|
+
:where(.cx-notice){
|
|
227
|
+
display:flex;align-items:center;gap:var(--hfx-space-2,0.5rem);padding:var(--hfx-space-2,0.5rem) var(--hfx-space-3,0.75rem);
|
|
228
|
+
border:var(--hfx-border-width,1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-inline-start:calc(var(--hfx-border-width,1px)*3) solid var(--cx-notice,var(--hfx-color-accent,light-dark(#11776f,#37c9b8)));
|
|
229
|
+
border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font-size:var(--hfx-type-small-size,0.8125rem);
|
|
230
|
+
}
|
|
231
|
+
:where(.cx-notice).cx-tone-info{--cx-notice:var(--hfx-color-status-info-fg,light-dark(#2b5fc0,#74a2f7));}
|
|
232
|
+
:where(.cx-notice).cx-tone-success{--cx-notice:var(--hfx-color-status-good-fg,light-dark(#177345,#4cc78a));}
|
|
233
|
+
:where(.cx-notice).cx-tone-warning{--cx-notice:var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640));}
|
|
234
|
+
:where(.cx-notice).cx-tone-danger{--cx-notice:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
|
|
235
|
+
@media (prefers-reduced-motion:reduce){:where(.cx-toggle,.cx-toggle::before,.cx-disclosure){transition:none;}}
|
|
236
|
+
@media (forced-colors:active){
|
|
237
|
+
:where(.cx-btn,.cx-button,.cx-ui-button,.cx-chip,.cx-segmented > *):is([aria-pressed="true"],[aria-checked="true"],.active){forced-color-adjust:none;background:Highlight;color:HighlightText;}
|
|
238
|
+
:where(.cx-toggle){border:var(--hfx-border-width,1px) solid ButtonText;}
|
|
239
|
+
:where(.cx-toggle):checked{background:Highlight;}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
118
242
|
.cx-host.cx-flow-host{min-height:0;display:block;background:transparent;}
|
|
119
243
|
.cx-host:where(.cx-flow-host:not([data-cx-height])){height:auto;}
|
|
120
244
|
body.cx-page > .cx-host.cx-flow-host:not([data-cx-height]),body.cx-page > .cx-main > .cx-host.cx-flow-host:not([data-cx-height]){height:auto;padding:0;}
|
|
@@ -58,7 +58,7 @@ function gridDateInputMoment(text,local){const match=/^(\d{4})-(\d{2})-(\d{2})T(
|
|
|
58
58
|
if(!match)return null;const moment=gridMomentFromParts(Number(match[1]),Number(match[2]),Number(match[3]),Number(match[4]),Number(match[5]),Number(match[6]||0),local);if(moment)moment.setTime(moment.getTime()+ Number((match[7]||"").padEnd(3,"0")));return moment}
|
|
59
59
|
function gridFreeze(value){if(value&&typeof value==="object"&&!Object.isFrozen(value)){Object.values(value).forEach(gridFreeze);Object.freeze(value)}
|
|
60
60
|
return value}
|
|
61
|
-
const PART_URL=typeof document!=="undefined"&&document.currentScript?.src;const PARTS={"forms":["0d77c25f4fa14425","canopyx-forms.3b18e30a2aeb56dd.js","canopyx-forms.e3a0e1f016287057.css"],"flow":["
|
|
61
|
+
const PART_URL=typeof document!=="undefined"&&document.currentScript?.src;const PARTS={"forms":["0d77c25f4fa14425","canopyx-forms.3b18e30a2aeb56dd.js","canopyx-forms.e3a0e1f016287057.css"],"flow":["93f8d2eb57cc1770","canopyx-flow.c3f65a21ced2d654.js","canopyx-flow.68af38159226dd08.css"],"flow-host":["6f335df747cc5f05","canopyx-flow-host.ea0be90307b19d0f.js","canopyx-flow-host.87b00b9ed5899f1f.css"],"flow-checks":["1710216916cb32a5","canopyx-flow-checks.5a3e04709a556310.js","canopyx-flow-checks.e97a4514fd32bde5.css"],"flow-options":["60450342239ded26","canopyx-flow-options.d31458a54aa4b1e7.js"],"flow-pick":["e5f79a9e81e93898","canopyx-flow-pick.e17b209908086225.js","canopyx-flow-pick.7ec005490120da23.css"],"flow-records":["d02b7dc1c7f75805","canopyx-flow-records.5efc3b14cf70b524.js","canopyx-flow-records.cf62ae7260a46ec4.css"],"flow-drafts":["40dc8e50169fa271","canopyx-flow-drafts.67fb3ab7fbc22606.js","canopyx-flow-drafts.f8535eb8992ea36a.css"],"flow-preview":["3d8ffe456323db95","canopyx-flow-preview.4731603add2f8e84.js","canopyx-flow-preview.f1c740bc97130a7d.css"],"flow-command":["a6c75cf736c93444","canopyx-flow-command.f3608c38cc18f333.js","canopyx-flow-command.279d6ad310e39e97.css"],"flow-tasks":["8d9ea504e81e8fcd","canopyx-flow-tasks.eeb43b791491b43b.js","canopyx-flow-tasks.5c0dc5743e02c670.css"],"flow-dialog":["c3b57a7478b94a93","canopyx-flow-dialog.a98f91c1fe0ade3b.js","canopyx-flow-dialog.98c7ea17adc9a223.css"],"flow-links":["2c14b19c9236e90d","canopyx-flow-links.7b6cfe42d28b6067.js"],"flow-endpoint":["f5cddfc9545e0920","canopyx-flow-endpoint.b31146202bd76aac.js"],"flow-facts":["385b5e61ed487e16","canopyx-flow-facts.8dad3bc07a71fdb0.js"],"flow-consent":["22121778bc0d07c5","canopyx-flow-consent.749b97f13039bc71.js","canopyx-flow-consent.9f6580d3673ae8bf.css"]},PART_CODE=new Map(),SHARED_PARTS={},partName=name=>typeof name==="string"&&/^[a-z][a-z\d-]{0,31}$/.test(name);
|
|
62
62
|
function registerPart(name,part){if(!partName(name)||!part||typeof part.version!=="string"||typeof part.install!=="function"||
|
|
63
63
|
part.requires!==undefined&&!(Array.isArray(part.requires)&&part.requires.every(partName)))throw new Error("CanopyX: invalid part.");PART_CODE.set(name,part)}
|
|
64
64
|
function definePart(View,name,label,context){const parts=View.prototype.parts||={};return parts[name]={name,label,context,parts}}
|
|
@@ -67,12 +67,12 @@ script.textContent=trusted("Script",payload.textContent);script.nonce=payload.no
|
|
|
67
67
|
const load=(element,attribute,file,kind)=>new Promise((resolve,reject)=>{const url=new URL(file,runtime).href;element[attribute]=attribute==="src"?trusted("ScriptURL",url):url;element.onload=resolve;element.onerror=()=>{element.remove();reject(new Error("CanopyX: "+part.label+" "+kind+" unavailable."))};document.head.appendChild(withNonce(element))});const link=h("link");link.rel="stylesheet";const style=styleFile&&(part.styleReady||=load(link,"href",hashed?styleFile:"canopyx-"+part.name+".css","stylesheet")
|
|
68
68
|
.catch(error=>{part.styleReady=null;throw error}));const code=PART_CODE.get(part.name)?.version===part.version||(part.scriptReady||=load(script,"src",hashed?scriptFile:"canopyx-"+part.name+".js","script")
|
|
69
69
|
.finally(()=>script.remove()).catch(error=>{part.scriptReady=null;throw error}));await Promise.all([style,code])}}
|
|
70
|
-
const code=PART_CODE.get(part.name);if(code?.version!==part.version)throw new Error("CanopyX: "+part.label+" and runtime must come from the same build.");for(const name of code.requires||[])await loadPart(part.parts[name]);code.install(part.context())}).catch(error=>{part.ready=null;throw error})}
|
|
70
|
+
const code=PART_CODE.get(part.name);if(code?.version!==part.version)throw new Error("CanopyX: "+part.label+" and runtime must come from the same build.");for(const name of code.requires||[])await loadPart(part.parts[name]||SHARED_PARTS[name]);code.install(part.context())}).catch(error=>{part.ready=null;throw error})}
|
|
71
71
|
const partQueue=global.CanopyXParts=global.CanopyXParts||[];partQueue.forEach(entry=>registerPart(...entry));partQueue.length=0;partQueue.push=(...entries)=>{entries.forEach(entry=>registerPart(...entry));return 0};class FlowHost{}
|
|
72
|
-
const FORMS_IMPL={},FLOW_IMPL={},activeFlows=new WeakMap();const FORMS_PART=definePart(FlowHost,"forms","forms",()=>({FORMS_IMPL,h,setText,fill,gridFreeze,gridMomentFromParts,boundedPattern,foldText}));const FLOW_VIEWS=typeof FLOW_GRID_VIEWS==="object"?FLOW_GRID_VIEWS:Object.freeze({grid:null,tree:null,reporting:false});const FLOW_PART=definePart(FlowHost,"flow","flow view",()=>({FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,foldText,boundedPattern,numberFormat,gridFreeze}));const FLOW_FEATURES={};for(const name of["host","checks","options","pick","records","drafts","preview","command","tasks","dialog","links","endpoint","consent"])
|
|
73
|
-
FLOW_FEATURES[name]=definePart(FlowHost,"flow-"+name,"flow "+name,()=>({FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,numberFormat,FLOW_VIEWS}));if(typeof DataGrid==="function")DataGrid.prototype.parts.forms=FORMS_PART;const FLOW_DOC_PARTS={command:"command",presets:"drafts",draft:"drafts",deepLinks:"links",endpoint:"endpoint"},FLOW_DOC_PLAIN={draft:"none",deepLinks:false};function flowFeatures(doc,hooks){const names=new Set(),add=(name,on)=>on&&names.add(name),list=value=>Array.isArray(value)?value:[];const object=value=>value!==null&&typeof value==="object"&&!Array.isArray(value),has=(value,...keys)=>object(value)&&keys.some(key=>value[key]!==undefined);for(const[key,name]of Object.entries(FLOW_DOC_PARTS))add(name,doc[key]!==undefined&&doc[key]!==FLOW_DOC_PLAIN[key]);add("tasks",doc.mode==="tasks");add("dialog",has(doc.layout,"launch")||has(doc.layout,"container")&&doc.layout.container!=="inline");add("preview",list(doc.endpoint?.routes).includes("preview"));for(const step of list(doc.steps).filter(object)){add("checks",step.checks!==undefined);add("pick",step.type==="pick");add("preview",step.preview===true);add("consent",has(step,"confirm","acknowledge"));for(const block of[step,...list(step.sections)]){if(block!==step)add("options",has(block,"source","dependsOn"));for(const field of object(block)?list(block.fields):[]){add("options",has(field,"dependsOn")||has(field,"source")&&field.source!=="document");add("records",object(field)&&field.type==="records")}}}
|
|
72
|
+
const FORMS_IMPL={},FLOW_IMPL={},activeFlows=new WeakMap();const FORMS_PART=definePart(FlowHost,"forms","forms",()=>({FORMS_IMPL,h,setText,fill,gridFreeze,gridMomentFromParts,boundedPattern,foldText}));const FLOW_VIEWS=typeof FLOW_GRID_VIEWS==="object"?FLOW_GRID_VIEWS:Object.freeze({grid:null,tree:null,reporting:false});const FLOW_PART=definePart(FlowHost,"flow","flow view",()=>({FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,foldText,boundedPattern,numberFormat,gridFreeze}));const FLOW_FEATURES={};for(const name of["host","checks","options","pick","records","drafts","preview","command","tasks","dialog","links","endpoint","consent","facts"])
|
|
73
|
+
FLOW_FEATURES[name]=definePart(FlowHost,"flow-"+name,"flow "+name,()=>({FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,numberFormat,FLOW_VIEWS}));if(typeof DataGrid==="function")DataGrid.prototype.parts.forms=FORMS_PART;const FLOW_DOC_PARTS={command:"command",presets:"drafts",draft:"drafts",deepLinks:"links",endpoint:"endpoint"},FLOW_DOC_PLAIN={draft:"none",deepLinks:false};function flowFeatures(doc,hooks){const names=new Set(),add=(name,on)=>on&&names.add(name),list=value=>Array.isArray(value)?value:[];const object=value=>value!==null&&typeof value==="object"&&!Array.isArray(value),has=(value,...keys)=>object(value)&&keys.some(key=>value[key]!==undefined);for(const[key,name]of Object.entries(FLOW_DOC_PARTS))add(name,doc[key]!==undefined&&doc[key]!==FLOW_DOC_PLAIN[key]);add("tasks",doc.mode==="tasks");add("dialog",has(doc.layout,"launch")||has(doc.layout,"container")&&doc.layout.container!=="inline");add("preview",list(doc.endpoint?.routes).includes("preview"));for(const step of list(doc.steps).filter(object)){add("facts",step.facts!==undefined);add("checks",step.checks!==undefined);add("pick",step.type==="pick");add("preview",step.preview===true);add("consent",has(step,"confirm","acknowledge"));for(const block of[step,...list(step.sections)]){if(block!==step)add("options",has(block,"source","dependsOn"));for(const field of object(block)?list(block.fields):[]){add("options",has(field,"dependsOn")||has(field,"source")&&field.source!=="document");add("records",object(field)&&field.type==="records")}}}
|
|
74
74
|
hooks=object(hooks)?hooks:{};return{required:[...names],optional:[typeof hooks.preview==="function"&&"preview",object(hooks.presetStore)&&"drafts"].filter(name=>name&&!names.has(name))}}
|
|
75
|
-
const FLOW_ASYNC_METHODS=["next","back","goTo","setState","validate","submit","runCheck","refreshOptions","saveDraft","setPreset"];const FLOW_SYNC_METHODS=["getStep","getValues","setValues","getState","isDirty","reset","setFieldError","setProgress","complete","setStepState","open","close"];function createFlow(host,options){if(!host||!options||!options.flow||typeof options.flow!=="object")throw new Error("CanopyX: createFlow needs a host element and a flow document.");const existing=activeFlows.get(host);if(existing)return existing;const disposeTheme=watchTheme(host);let impl=null,destroyed=false,mountError=null;const destroyedError=()=>new Error("CanopyX: this flow has been destroyed.");const requireImpl=name=>{if(destroyed)throw destroyedError();if(!impl)throw new Error("CanopyX: flow is not ready; await api.ready before calling "+name+"().");return impl};const editors=Object.assign({},...[...PLUGINS.values()].map(item=>item.editors||{}));const{required,optional}=flowFeatures(options.flow,options.hooks);const ready=Promise.all([loadPart(FLOW_PART),...required.map(name=>loadPart(FLOW_FEATURES[name])),...optional.map(name=>loadPart(FLOW_FEATURES[name])
|
|
75
|
+
const FLOW_ASYNC_METHODS=["next","back","goTo","setState","validate","submit","runCheck","refreshOptions","saveDraft","setPreset"];const FLOW_SYNC_METHODS=["getStep","getValues","setValues","getState","isDirty","reset","setFieldError","setProgress","complete","setStepState","invalidateChecks","open","close"];function createFlow(host,options){if(!host||!options||!options.flow||typeof options.flow!=="object")throw new Error("CanopyX: createFlow needs a host element and a flow document.");const existing=activeFlows.get(host);if(existing)return existing;const disposeTheme=watchTheme(host);let impl=null,destroyed=false,mountError=null;const destroyedError=()=>new Error("CanopyX: this flow has been destroyed.");const requireImpl=name=>{if(destroyed)throw destroyedError();if(!impl)throw new Error("CanopyX: flow is not ready; await api.ready before calling "+name+"().");return impl};const editors=Object.assign({},...[...PLUGINS.values()].map(item=>item.editors||{}));const{required,optional}=flowFeatures(options.flow,options.hooks);const ready=Promise.all([loadPart(FLOW_PART),...required.map(name=>loadPart(FLOW_FEATURES[name])),...optional.map(name=>loadPart(FLOW_FEATURES[name])
|
|
76
76
|
.catch(error=>host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error,hook:"part"},bubbles:true}))))]).then(async()=>{if(destroyed)throw destroyedError();impl=FLOW_IMPL.create(host,options,editors);return impl.ready});const api={element:host,flow:options.flow,view:options.flow};for(const name of FLOW_SYNC_METHODS)api[name]=(...args)=>requireImpl(name)[name](...args);for(const name of FLOW_ASYNC_METHODS)api[name]=(...args)=>{if(destroyed)return Promise.reject(destroyedError());return ready.then(()=>requireImpl(name)[name](...args))};api.ready=ready.then(()=>{if(destroyed)throw destroyedError();return api});api.ready.catch(()=>{});api.destroy=()=>{if(destroyed)return;destroyed=true;disposeTheme();try{impl?.destroy()}
|
|
77
77
|
finally{impl=null;mountError?.remove();if(activeFlows.get(host)===api){activeFlows.delete(host);if(host.canopyx===api)delete host.canopyx;host.removeAttribute("data-canopyx-mounted");host.removeAttribute("data-cx-ready");host.removeAttribute("data-cx-error");host.classList.remove("cx-flow-host")}}};ready.catch(error=>{if(destroyed)return;const notice=mountError=h("div","cx-mount-error");notice.setAttribute("role","alert");setText(notice,error&&error.message?error.message:String(error));host.appendChild(notice);host.setAttribute("data-cx-error",notice.textContent);host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error},bubbles:true}))});Object.freeze(api);activeFlows.set(host,api);host.classList.add("cx-host","cx-flow-host");host.setAttribute("data-canopyx-mounted","true");host.canopyx=api;return api}
|
|
78
78
|
const FLOW_API={createFlow};const configured=new Map();const flowId=value=>typeof value==="string"&&/^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(value);
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"385b5e61ed487e16",requires:["flow"],install(context){if(installed.has(context.FLOW_IMPL))return;const{FLOW_IMPL,h,setText}=context;const{FlowView,FLOW_HOST,flowFail,flowKeys,flowString}=FLOW_IMPL.core;FLOW_HOST.facts={finish(model){for(const step of model.steps){const facts=step.raw.facts;if(facts===undefined)continue;if(step.type!=="info"||!Array.isArray(facts)||facts.length>32)flowFail("only information steps hold up to 32 read-only facts");step.facts=facts.map(fact=>{flowKeys(fact,["label","value"],"A flow fact");return{label:flowString(fact.label,200,"A fact label",true),value:flowString(fact.value,32768,"A fact value",true)}})}},render(section,facts){const list=h("dl","cx-flow-answers");for(const fact of facts){const item=h("div","cx-flow-answer"),label=h("dt"),value=h("dd","cx-flow-answer-value");setText(label,fact.label);setText(value,fact.value);item.append(label,value);list.appendChild(item)}
|
|
2
|
+
section.appendChild(list)}};const flowFactsShell=FlowView.prototype.stepShell;FlowView.prototype.stepShell=function(step){const section=flowFactsShell.call(this,step);if(step.facts?.length)FLOW_HOST.facts.render(section,step.facts);return section};installed.add(context.FLOW_IMPL)}};(global.CanopyXParts||=[]).push(["flow-facts",part])})(typeof window!=="undefined"?window:globalThis);
|
|
@@ -60,7 +60,7 @@ function gridDateInputMoment(text,local){const match=/^(\d{4})-(\d{2})-(\d{2})T(
|
|
|
60
60
|
if(!match)return null;const moment=gridMomentFromParts(Number(match[1]),Number(match[2]),Number(match[3]),Number(match[4]),Number(match[5]),Number(match[6]||0),local);if(moment)moment.setTime(moment.getTime()+ Number((match[7]||"").padEnd(3,"0")));return moment}
|
|
61
61
|
function gridFreeze(value){if(value&&typeof value==="object"&&!Object.isFrozen(value)){Object.values(value).forEach(gridFreeze);Object.freeze(value)}
|
|
62
62
|
return value}
|
|
63
|
-
const PART_URL=typeof document!=="undefined"&&document.currentScript?.src;const PARTS={"forms":["0d77c25f4fa14425","canopyx-forms.3b18e30a2aeb56dd.js","canopyx-forms.e3a0e1f016287057.css"],"flow":["
|
|
63
|
+
const PART_URL=typeof document!=="undefined"&&document.currentScript?.src;const PARTS={"forms":["0d77c25f4fa14425","canopyx-forms.3b18e30a2aeb56dd.js","canopyx-forms.e3a0e1f016287057.css"],"flow":["93f8d2eb57cc1770","canopyx-flow.c3f65a21ced2d654.js","canopyx-flow.68af38159226dd08.css"],"flow-host":["6f335df747cc5f05","canopyx-flow-host.ea0be90307b19d0f.js","canopyx-flow-host.87b00b9ed5899f1f.css"],"flow-checks":["1710216916cb32a5","canopyx-flow-checks.5a3e04709a556310.js","canopyx-flow-checks.e97a4514fd32bde5.css"],"flow-options":["60450342239ded26","canopyx-flow-options.d31458a54aa4b1e7.js"],"flow-pick":["e5f79a9e81e93898","canopyx-flow-pick.e17b209908086225.js","canopyx-flow-pick.7ec005490120da23.css"],"flow-records":["d02b7dc1c7f75805","canopyx-flow-records.5efc3b14cf70b524.js","canopyx-flow-records.cf62ae7260a46ec4.css"],"flow-drafts":["40dc8e50169fa271","canopyx-flow-drafts.67fb3ab7fbc22606.js","canopyx-flow-drafts.f8535eb8992ea36a.css"],"flow-preview":["3d8ffe456323db95","canopyx-flow-preview.4731603add2f8e84.js","canopyx-flow-preview.f1c740bc97130a7d.css"],"flow-command":["a6c75cf736c93444","canopyx-flow-command.f3608c38cc18f333.js","canopyx-flow-command.279d6ad310e39e97.css"],"flow-tasks":["8d9ea504e81e8fcd","canopyx-flow-tasks.eeb43b791491b43b.js","canopyx-flow-tasks.5c0dc5743e02c670.css"],"flow-dialog":["c3b57a7478b94a93","canopyx-flow-dialog.a98f91c1fe0ade3b.js","canopyx-flow-dialog.98c7ea17adc9a223.css"],"flow-links":["2c14b19c9236e90d","canopyx-flow-links.7b6cfe42d28b6067.js"],"flow-endpoint":["f5cddfc9545e0920","canopyx-flow-endpoint.b31146202bd76aac.js"],"flow-facts":["385b5e61ed487e16","canopyx-flow-facts.8dad3bc07a71fdb0.js"],"flow-consent":["22121778bc0d07c5","canopyx-flow-consent.749b97f13039bc71.js","canopyx-flow-consent.9f6580d3673ae8bf.css"]},PART_CODE=new Map(),SHARED_PARTS={},partName=name=>typeof name==="string"&&/^[a-z][a-z\d-]{0,31}$/.test(name);
|
|
64
64
|
function registerPart(name,part){if(!partName(name)||!part||typeof part.version!=="string"||typeof part.install!=="function"||
|
|
65
65
|
part.requires!==undefined&&!(Array.isArray(part.requires)&&part.requires.every(partName)))throw new Error("CanopyX: invalid part.");PART_CODE.set(name,part)}
|
|
66
66
|
function definePart(View,name,label,context){const parts=View.prototype.parts||={};return parts[name]={name,label,context,parts}}
|
|
@@ -69,12 +69,12 @@ script.textContent=trusted("Script",payload.textContent);script.nonce=payload.no
|
|
|
69
69
|
const load=(element,attribute,file,kind)=>new Promise((resolve,reject)=>{const url=new URL(file,runtime).href;element[attribute]=attribute==="src"?trusted("ScriptURL",url):url;element.onload=resolve;element.onerror=()=>{element.remove();reject(new Error("CanopyX: "+part.label+" "+kind+" unavailable."))};document.head.appendChild(withNonce(element))});const link=h("link");link.rel="stylesheet";const style=styleFile&&(part.styleReady||=load(link,"href",hashed?styleFile:"canopyx-"+part.name+".css","stylesheet")
|
|
70
70
|
.catch(error=>{part.styleReady=null;throw error}));const code=PART_CODE.get(part.name)?.version===part.version||(part.scriptReady||=load(script,"src",hashed?scriptFile:"canopyx-"+part.name+".js","script")
|
|
71
71
|
.finally(()=>script.remove()).catch(error=>{part.scriptReady=null;throw error}));await Promise.all([style,code])}}
|
|
72
|
-
const code=PART_CODE.get(part.name);if(code?.version!==part.version)throw new Error("CanopyX: "+part.label+" and runtime must come from the same build.");for(const name of code.requires||[])await loadPart(part.parts[name]);code.install(part.context())}).catch(error=>{part.ready=null;throw error})}
|
|
72
|
+
const code=PART_CODE.get(part.name);if(code?.version!==part.version)throw new Error("CanopyX: "+part.label+" and runtime must come from the same build.");for(const name of code.requires||[])await loadPart(part.parts[name]||SHARED_PARTS[name]);code.install(part.context())}).catch(error=>{part.ready=null;throw error})}
|
|
73
73
|
const partQueue=global.CanopyXParts=global.CanopyXParts||[];partQueue.forEach(entry=>registerPart(...entry));partQueue.length=0;partQueue.push=(...entries)=>{entries.forEach(entry=>registerPart(...entry));return 0};class FlowHost{}
|
|
74
|
-
const FORMS_IMPL={},FLOW_IMPL={},activeFlows=new WeakMap();const FORMS_PART=definePart(FlowHost,"forms","forms",()=>({FORMS_IMPL,h,setText,fill,gridFreeze,gridMomentFromParts,boundedPattern,foldText}));const FLOW_VIEWS=typeof FLOW_GRID_VIEWS==="object"?FLOW_GRID_VIEWS:Object.freeze({grid:null,tree:null,reporting:false});const FLOW_PART=definePart(FlowHost,"flow","flow view",()=>({FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,foldText,boundedPattern,numberFormat,gridFreeze}));const FLOW_FEATURES={};for(const name of["host","checks","options","pick","records","drafts","preview","command","tasks","dialog","links","endpoint","consent"])
|
|
75
|
-
FLOW_FEATURES[name]=definePart(FlowHost,"flow-"+name,"flow "+name,()=>({FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,numberFormat,FLOW_VIEWS}));if(typeof DataGrid==="function")DataGrid.prototype.parts.forms=FORMS_PART;const FLOW_DOC_PARTS={command:"command",presets:"drafts",draft:"drafts",deepLinks:"links",endpoint:"endpoint"},FLOW_DOC_PLAIN={draft:"none",deepLinks:false};function flowFeatures(doc,hooks){const names=new Set(),add=(name,on)=>on&&names.add(name),list=value=>Array.isArray(value)?value:[];const object=value=>value!==null&&typeof value==="object"&&!Array.isArray(value),has=(value,...keys)=>object(value)&&keys.some(key=>value[key]!==undefined);for(const[key,name]of Object.entries(FLOW_DOC_PARTS))add(name,doc[key]!==undefined&&doc[key]!==FLOW_DOC_PLAIN[key]);add("tasks",doc.mode==="tasks");add("dialog",has(doc.layout,"launch")||has(doc.layout,"container")&&doc.layout.container!=="inline");add("preview",list(doc.endpoint?.routes).includes("preview"));for(const step of list(doc.steps).filter(object)){add("checks",step.checks!==undefined);add("pick",step.type==="pick");add("preview",step.preview===true);add("consent",has(step,"confirm","acknowledge"));for(const block of[step,...list(step.sections)]){if(block!==step)add("options",has(block,"source","dependsOn"));for(const field of object(block)?list(block.fields):[]){add("options",has(field,"dependsOn")||has(field,"source")&&field.source!=="document");add("records",object(field)&&field.type==="records")}}}
|
|
74
|
+
const FORMS_IMPL={},FLOW_IMPL={},activeFlows=new WeakMap();const FORMS_PART=definePart(FlowHost,"forms","forms",()=>({FORMS_IMPL,h,setText,fill,gridFreeze,gridMomentFromParts,boundedPattern,foldText}));const FLOW_VIEWS=typeof FLOW_GRID_VIEWS==="object"?FLOW_GRID_VIEWS:Object.freeze({grid:null,tree:null,reporting:false});const FLOW_PART=definePart(FlowHost,"flow","flow view",()=>({FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,foldText,boundedPattern,numberFormat,gridFreeze}));const FLOW_FEATURES={};for(const name of["host","checks","options","pick","records","drafts","preview","command","tasks","dialog","links","endpoint","consent","facts"])
|
|
75
|
+
FLOW_FEATURES[name]=definePart(FlowHost,"flow-"+name,"flow "+name,()=>({FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,numberFormat,FLOW_VIEWS}));if(typeof DataGrid==="function")DataGrid.prototype.parts.forms=FORMS_PART;const FLOW_DOC_PARTS={command:"command",presets:"drafts",draft:"drafts",deepLinks:"links",endpoint:"endpoint"},FLOW_DOC_PLAIN={draft:"none",deepLinks:false};function flowFeatures(doc,hooks){const names=new Set(),add=(name,on)=>on&&names.add(name),list=value=>Array.isArray(value)?value:[];const object=value=>value!==null&&typeof value==="object"&&!Array.isArray(value),has=(value,...keys)=>object(value)&&keys.some(key=>value[key]!==undefined);for(const[key,name]of Object.entries(FLOW_DOC_PARTS))add(name,doc[key]!==undefined&&doc[key]!==FLOW_DOC_PLAIN[key]);add("tasks",doc.mode==="tasks");add("dialog",has(doc.layout,"launch")||has(doc.layout,"container")&&doc.layout.container!=="inline");add("preview",list(doc.endpoint?.routes).includes("preview"));for(const step of list(doc.steps).filter(object)){add("facts",step.facts!==undefined);add("checks",step.checks!==undefined);add("pick",step.type==="pick");add("preview",step.preview===true);add("consent",has(step,"confirm","acknowledge"));for(const block of[step,...list(step.sections)]){if(block!==step)add("options",has(block,"source","dependsOn"));for(const field of object(block)?list(block.fields):[]){add("options",has(field,"dependsOn")||has(field,"source")&&field.source!=="document");add("records",object(field)&&field.type==="records")}}}
|
|
76
76
|
hooks=object(hooks)?hooks:{};return{required:[...names],optional:[typeof hooks.preview==="function"&&"preview",object(hooks.presetStore)&&"drafts"].filter(name=>name&&!names.has(name))}}
|
|
77
|
-
const FLOW_ASYNC_METHODS=["next","back","goTo","setState","validate","submit","runCheck","refreshOptions","saveDraft","setPreset"];const FLOW_SYNC_METHODS=["getStep","getValues","setValues","getState","isDirty","reset","setFieldError","setProgress","complete","setStepState","open","close"];function createFlow(host,options){if(!host||!options||!options.flow||typeof options.flow!=="object")throw new Error("CanopyX: createFlow needs a host element and a flow document.");const existing=activeFlows.get(host);if(existing)return existing;const disposeTheme=watchTheme(host);let impl=null,destroyed=false,mountError=null;const destroyedError=()=>new Error("CanopyX: this flow has been destroyed.");const requireImpl=name=>{if(destroyed)throw destroyedError();if(!impl)throw new Error("CanopyX: flow is not ready; await api.ready before calling "+name+"().");return impl};const editors=Object.assign({},...[...PLUGINS.values()].map(item=>item.editors||{}));const{required,optional}=flowFeatures(options.flow,options.hooks);const ready=Promise.all([loadPart(FLOW_PART),...required.map(name=>loadPart(FLOW_FEATURES[name])),...optional.map(name=>loadPart(FLOW_FEATURES[name])
|
|
77
|
+
const FLOW_ASYNC_METHODS=["next","back","goTo","setState","validate","submit","runCheck","refreshOptions","saveDraft","setPreset"];const FLOW_SYNC_METHODS=["getStep","getValues","setValues","getState","isDirty","reset","setFieldError","setProgress","complete","setStepState","invalidateChecks","open","close"];function createFlow(host,options){if(!host||!options||!options.flow||typeof options.flow!=="object")throw new Error("CanopyX: createFlow needs a host element and a flow document.");const existing=activeFlows.get(host);if(existing)return existing;const disposeTheme=watchTheme(host);let impl=null,destroyed=false,mountError=null;const destroyedError=()=>new Error("CanopyX: this flow has been destroyed.");const requireImpl=name=>{if(destroyed)throw destroyedError();if(!impl)throw new Error("CanopyX: flow is not ready; await api.ready before calling "+name+"().");return impl};const editors=Object.assign({},...[...PLUGINS.values()].map(item=>item.editors||{}));const{required,optional}=flowFeatures(options.flow,options.hooks);const ready=Promise.all([loadPart(FLOW_PART),...required.map(name=>loadPart(FLOW_FEATURES[name])),...optional.map(name=>loadPart(FLOW_FEATURES[name])
|
|
78
78
|
.catch(error=>host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error,hook:"part"},bubbles:true}))))]).then(async()=>{if(destroyed)throw destroyedError();impl=FLOW_IMPL.create(host,options,editors);return impl.ready});const api={element:host,flow:options.flow,view:options.flow};for(const name of FLOW_SYNC_METHODS)api[name]=(...args)=>requireImpl(name)[name](...args);for(const name of FLOW_ASYNC_METHODS)api[name]=(...args)=>{if(destroyed)return Promise.reject(destroyedError());return ready.then(()=>requireImpl(name)[name](...args))};api.ready=ready.then(()=>{if(destroyed)throw destroyedError();return api});api.ready.catch(()=>{});api.destroy=()=>{if(destroyed)return;destroyed=true;disposeTheme();try{impl?.destroy()}
|
|
79
79
|
finally{impl=null;mountError?.remove();if(activeFlows.get(host)===api){activeFlows.delete(host);if(host.canopyx===api)delete host.canopyx;host.removeAttribute("data-canopyx-mounted");host.removeAttribute("data-cx-ready");host.removeAttribute("data-cx-error");host.classList.remove("cx-flow-host")}}};ready.catch(error=>{if(destroyed)return;const notice=mountError=h("div","cx-mount-error");notice.setAttribute("role","alert");setText(notice,error&&error.message?error.message:String(error));host.appendChild(notice);host.setAttribute("data-cx-error",notice.textContent);host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error},bubbles:true}))});Object.freeze(api);activeFlows.set(host,api);host.classList.add("cx-host","cx-flow-host");host.setAttribute("data-canopyx-mounted","true");host.canopyx=api;return api}
|
|
80
80
|
const FLOW_API={createFlow};const configured=new Map();const flowId=value=>typeof value==="string"&&/^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(value);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(global){"use strict";const installed=new WeakSet();const part={version:"
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"93f8d2eb57cc1770",requires:["forms"],install(context){if(installed.has(context.FLOW_IMPL))return;const{FLOW_IMPL,FORMS_IMPL,h,setText,fill,plural,foldText,boundedPattern,numberFormat,gridFreeze}=context;const{editParseNumber,EDIT_EDITORS,formRuleSpec,formCheck,FORM_LABELS}=FORMS_IMPL;const FLOW_LABELS={flowSteps:"Steps",flowStepOf:"Step {current} of {count}",flowStepAnnounce:"Step {current} of {count}, {title}",flowNext:"Next",flowBack:"Back",flowSubmit:"Submit",flowSubmitting:"Submitting…",flowReviewTitle:"Check your answers",flowChange:"Change",flowChangeField:"Change {field}",flowNotProvided:"Not provided",flowOptional:"(optional)",flowStepOptional:"Optional",flowStepComplete:"Complete",flowStepCurrent:"Current step",flowStepErrors:"Errors: {count}",flowStepLocked:"Complete the earlier steps first",flowStepNotStarted:"Not started",flowErrorSummary:"Fix these before you continue",flowReady:"Ready to submit",flowNotReady:"Errors to fix: {count}",flowWarnings:"Warnings: {count}",flowChangesOnly:"Show changes only",flowNoChanges:"No answers have changed.",flowWas:"Was: {value}",flowChangedCount:"Changed answers: {count}",flowSecretSet:"Set",flowSecretKept:"Unchanged",flowSecretNotSet:"Not set",flowSecretHint:"A value is saved. Leave blank to keep it.",flowSecretShow:"Show",flowSecretHide:"Hide",flowSecretReveal:"Show {field}",flowOn:"On",flowOff:"Off",flowAdd:"Add",flowAddItem:"Add to {field}",flowRemoveItem:"Remove {item}",flowItemLabel:"{field}, item {index}",flowSelectAll:"Select all",flowSelectNone:"Clear",flowSelectedCount:"{count} of {total} selected",flowUnit:"Unit",flowUnitSeconds:"seconds",flowUnitMinutes:"minutes",flowUnitHours:"hours",flowUnitDays:"days",flowSeconds:"[one]{count} second[other]{count} seconds",flowMinutes:"[one]{count} minute[other]{count} minutes",flowHours:"[one]{count} hour[other]{count} hours",flowDays:"[one]{count} day[other]{count} days",flowDurationInvalid:"{field} must be a whole number.",flowItemsMin:"{field} needs at least {min}.",flowItemsMax:"{field} allows at most {max}.",flowItemEmail:"“{item}” is not an email address.",flowItemHost:"“{item}” is not a host name.",flowItemIp:"“{item}” is not an IP address.",flowItemCidr:"“{item}” is not a network range.",flowItemUrl:"“{item}” is not a web address.",flowItemPattern:"“{item}” does not have the expected format.",flowSaved:"Saved",flowAccepted:"In progress",flowProgress:"{done} of {total}",flowConflict:"These settings changed while you were editing them.",flowReload:"Reload current settings",flowNotSubmitted:"The answers were not submitted.",flowNoHost:"No host received the answers.",flowStartAgain:"Start another",flowCopy:"Copy",flowCopied:"Copied",flowSavedIt:"I have saved it",flowShownOnce:"Shown only once. Copy it now."};function flowLabels(...sources){const labels={...FORM_LABELS,...FLOW_LABELS};for(const source of sources){if(source==null)continue;if(!flowIs(source))flowFail("labels must be an object of strings");for(const[name,text]of Object.entries(source)){if(!Object.hasOwn(labels,name))continue;if(typeof text!=="string"||!/\S/.test(text)) flowFail("label '" + name + "' must be a string with visible text");
|
|
2
2
|
labels[name]=text}}
|
|
3
3
|
return Object.freeze(labels)}
|
|
4
4
|
const FLOW_NAME=/^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
@@ -19,12 +19,12 @@ if(field.path!==undefined&&(typeof field.path!=="string"||!/^[A-Za-z0-9_-]+(\.[A
|
|
|
19
19
|
if(raw.keepWhenBlank!==undefined&&(type!=="secret"||typeof raw.keepWhenBlank!=="boolean"))bad("can keep a blank value only as a secret");if(raw.reveal!==undefined&&(type!=="secret"||typeof raw.reveal!=="boolean"))bad("has a reveal setting but is not a secret");if((raw.onText!==undefined||raw.offText!==undefined)&&type!=="toggle")bad("names on and off texts but is not a toggle");if(raw.rows!==undefined&&(type!=="textarea"||!Number.isInteger(raw.rows)||raw.rows<2||raw.rows>20))bad("needs 2 to 20 rows, as a text area only");if(raw.display!==undefined&&(type!=="choice"||!["cards","list"].includes(raw.display)))bad("has an unknown display");if(raw.editor!==undefined?type!=="custom"||typeof raw.editor!=="string"||!/^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(raw.editor) : type === "custom") bad("needs an editor name as a custom field only");
|
|
20
20
|
if(raw.step!==undefined&&type!=="number")bad("has a step but is not a number");if(raw.placeholder!==undefined&&!["text","number","lookup","textarea","list"].includes(type))bad("has a placeholder, which text, number, lookup, text area and list fields take");const choosing=["select","choice","multiChoice","lookup"].includes(type);if(raw.source!==undefined&&(raw.source!=="document"||!choosing)||raw.dependsOn!==undefined)flowHost("options").field(field,raw,choosing,bad);if(raw.options!==undefined&&!choosing)bad("has options but does not choose");if(choosing&&!field.host&&!(Array.isArray(raw.options)&&raw.options.length))bad("needs options");if(raw.options!==undefined&&!Array.isArray(raw.options))bad("needs a list of options");field.options=flowOptions(raw.options||[],bad);if((raw.columns!==undefined)!==(type==="records"))bad("needs columns as a records field only");if(type==="records")field.columns=flowHost("records").columns(raw.columns,bad);const list=type==="list"||type==="multiChoice"||type==="records"||type==="pick";if(list&&[rules.min,rules.max,rules.minLength,rules.maxLength,rules.pattern].some(value=>value!==undefined))bad("checks items, not lengths or ranges");if(!list&&[rules.minItems,rules.maxItems].some(value=>value!==undefined)||type!=="list"&&(rules.item!==undefined||rules.itemPattern!==undefined))bad("has rules only lists take");if((rules.min!==undefined||rules.max!==undefined)&&!["number","datetime","duration"].includes(type))bad("has a range but is not a number, date and time or duration");if([rules.minLength,rules.maxLength,rules.pattern].some(value=>value!==undefined)&&!["text","textarea","secret"].includes(type))bad("has lengths or a pattern, which text, text area and secret fields take");if(rules.minLength>rules.maxLength)bad("needs the shorter length first");const count=value=>value===undefined||Number.isInteger(value)&&value>=0&&value<=1000;if(!count(rules.minItems)||!count(rules.maxItems)||rules.minItems>rules.maxItems)bad("needs 0 to 1000 items, the fewest first");if(rules.item!==undefined&&!["email","host","ip","cidr","url"].includes(rules.item))bad("has an unknown item rule");let itemPattern=null;if(rules.itemPattern!==undefined)try{itemPattern=boundedPattern(rules.itemPattern,true,true)}catch(error){bad("has an invalid or unsafe item pattern")}
|
|
21
21
|
const range=type==="duration"?{min:rules.min===undefined?undefined:flowSeconds(rules.min),max:rules.max===undefined?undefined:flowSeconds(rules.max)}:rules;if(type==="duration"&&(range.min===null||range.max===null))bad("needs ISO 8601 durations as its range");if(type==="number"&&![rules.min,rules.max].every(bound=>bound===undefined||Number.isFinite(bound)&&Math.abs(bound)<=Number.MAX_SAFE_INTEGER))bad("needs numbers as its range");if(type==="datetime"&&![rules.min,rules.max].every(bound=>bound===undefined||flowFits({type:"datetime"},bound)))bad("needs ISO 8601 moments as its range");const low=type==="datetime"&&typeof range.min==="string"?Date.parse(range.min):range.min,high=type==="datetime"&&typeof range.max==="string"?Date.parse(range.max):range.max;if(low!==undefined&&high!==undefined&&low>high)bad("needs the lower limit first");const shared=formRuleSpec({step:raw.step,placeholder:raw.placeholder},{required:field.required,min:range.min,max:range.max,minLength:rules.minLength,maxLength:rules.maxLength,pattern:rules.pattern,message:rules.message},bad);field.spec=Object.freeze({id,pattern:shared.pattern,rules:shared.rules});field.items=Object.freeze({min:rules.minItems,max:rules.maxItems,rule:rules.item,pattern:itemPattern});const units=raw.units??["minutes","hours","days"];if(raw.units!==undefined&&type!=="duration"||!Array.isArray(units)||!units.length||units.some(unit=>!Object.hasOwn(FLOW_UNITS,unit))||new Set(units).size!==units.length)bad("has invalid duration units");field.units=Object.keys(FLOW_UNITS).filter(unit=>units.includes(unit));if(raw.default!==undefined&&(type==="secret"||list&&!Array.isArray(raw.default)||!flowFits(field,raw.default)))bad("has a default that does not fit it");field.start=raw.default===undefined?(list?[]:null):raw.default;model.fields.set(id,field);return field}
|
|
22
|
-
function flowRead(doc){flowKeys(doc,["kind","version","id","title","description","mode","layout","density","timeZone","steps","initial","storedSecrets","baseline","submit","labels","command","presets","draft","deepLinks","endpoint"],"A flow document");if(doc.kind!=="flow"||doc.version!==1)flowFail("
|
|
22
|
+
function flowRead(doc){flowKeys(doc,["kind","version","id","title","description","mode","layout","density","timeZone","steps","initial","storedSecrets","baseline","submit","labels","command","presets","draft","deepLinks","endpoint"],"A flow document");if(doc.kind!=="flow"||doc.version!==1)flowFail("expected flow document version 1");const model={id:flowName(doc.id,"The flow id"),title:flowString(doc.title,200,"The flow title",true),description:flowString(doc.description,1000,"The flow description"),mode:doc.mode??"linear",density:doc.density??"normal",local:doc.timeZone==="local",fields:new Map(),steps:[],sections:new Set(),checks:new Map()};if(!["linear","free","tasks"].includes(model.mode)||!["compact","normal","comfortable"].includes(model.density)||doc.timeZone!==undefined&&!["utc","local"].includes(doc.timeZone))flowFail("unknown flow mode, density or time zone");if(doc.layout!==undefined)flowKeys(doc.layout,["orientation","container","launch"],"The flow layout");model.orientation=doc.layout?.orientation??"auto";if(!["auto","horizontal","vertical"].includes(model.orientation))flowFail("the flow layout has an unknown orientation");if(!Array.isArray(doc.steps)||!doc.steps.length||doc.steps.length>64)flowFail("a flow needs 1 to 64 steps");for(const[index,raw]of doc.steps.entries()){flowKeys(raw,["id","title","description","type","fields","sections","when","optional","declaration","changesOnly","checks","group","pick","confirm","acknowledge","preview","facts"],"A flow step");const step={id:flowName(raw.id,"A step id"),title:flowString(raw.title,200,"A step title",raw.type!=="review"),description:flowString(raw.description,1000,"A step description"),type:raw.type??"form",optional:flowFlag(raw.optional,"optional"),declaration:flowString(raw.declaration,1000,"The declaration"),changesOnly:raw.changesOnly!==false,group:flowString(raw.group,200,"A step group"),blocks:[],checks:[],raw};if(model.steps.some(other=>other.id===step.id))flowFail("the step id '"+step.id+"' is used twice");if(!["form","info","review","pick"].includes(step.type))flowFail("step "+step.id+" has an unknown type");step.asks=step.type==="form"||step.type==="pick";if(step.type==="review"&&index!==doc.steps.length-1)flowFail("the review step must be the last step");if(step.type==="review"&&(raw.when!==undefined||raw.optional===true||raw.group!==undefined))flowFail("the review step takes no condition or group and is never optional");const reviewKey=["declaration","changesOnly","confirm","acknowledge","preview"].find(key=>raw[key]!==undefined);if(step.type!=="review"&&reviewKey)flowFail("only a review step has "+reviewKey);if(raw.changesOnly!==undefined&&typeof raw.changesOnly!=="boolean")flowFail("changesOnly must be true or false");if(step.type!=="form"&&(raw.fields!==undefined||raw.sections!==undefined))flowFail("only a form step has fields and sections");if((raw.pick!==undefined)!==(step.type==="pick"))flowFail("only pick steps require a pick");if(raw.fields!==undefined&&!Array.isArray(raw.fields)||raw.sections!==undefined&&!Array.isArray(raw.sections))flowFail("fields and sections must be arrays");if(raw.fields?.length)step.blocks.push({section:null,fields:raw.fields.map(field=>flowField(field,step,null,model))});if((raw.sections||[]).length>64)flowFail("step "+step.id+" holds at most 64 sections");for(const rawSection of raw.sections||[]){flowKeys(rawSection,["id","label","description","fields","when","source","dependsOn"],"A flow section");const section={id:flowName(rawSection.id,"A section id"),label:flowString(rawSection.label,200,"A section label",true),description:flowString(rawSection.description,1000,"A section description"),host:false,dependsOn:[],raw:rawSection};if(model.sections.has(section.id))flowFail("the section id '"+section.id+"' is used twice");model.sections.add(section.id);if(rawSection.source!==undefined||rawSection.dependsOn!==undefined)flowHost("options").section(section,rawSection);else if(!Array.isArray(rawSection.fields))flowFail("section "+section.id+" needs an array of fields");step.blocks.push({section,fields:(rawSection.fields||[]).map(field=>flowField(field,step,section,model))})}
|
|
23
23
|
if(step.type==="pick")flowHost("pick").read(raw.pick,step,model);if(step.type==="review"){step.preview=flowFlag(raw.preview,"preview");if(raw.confirm!==undefined||raw.acknowledge!==undefined)flowHost("consent").read(raw,step)}
|
|
24
24
|
if(raw.checks!==undefined)flowHost("checks").read(raw.checks,step,model);model.steps.push(step)}
|
|
25
25
|
const paths=new Set();for(const path of[...model.fields.values()].map(field=>field.path).filter(Boolean)){if(paths.has(path))flowFail("the path '"+path+"' is used twice");paths.add(path)}
|
|
26
26
|
for(const path of paths)for(let at=path.indexOf(".");at>0;at=path.indexOf(".",at+1))if(paths.has(path.slice(0,at)))flowFail("the path '"+path+"' lies inside '"+path.slice(0,at)+ "'");flowConditions(model);flowEach("finish",model);flowEditMode(doc,model);Object.assign(model,{container:"inline",command:null,presets:[],draft:"none",deepLinks:false,endpoint:null});flowEach("document",doc,model);if(doc.submit!==undefined)flowKeys(doc.submit,["label"],"The flow's submit");model.submitLabel=flowString(doc.submit?.label,80,"The submit label");model.labels=doc.labels;return model}
|
|
27
|
-
function flowEditMode(doc,model){if(doc.initial!==undefined){if(!flowIs(doc.initial))flowFail("initial must be an object of field values");for(const[id,value]of Object.entries(doc.initial)){const field=model.fields.get(id);if(!field||field.type==="secret"||!flowFits(field,value))flowFail("initial
|
|
27
|
+
function flowEditMode(doc,model){if(doc.initial!==undefined){if(!flowIs(doc.initial))flowFail("initial must be an object of field values");for(const[id,value]of Object.entries(doc.initial)){const field=model.fields.get(id);if(!field||field.type==="secret"||!flowFits(field,value))flowFail("initial value does not fit field "+id)}}
|
|
28
28
|
model.initial=doc.initial?{...doc.initial}:null;if(doc.storedSecrets!==undefined&&(!Array.isArray(doc.storedSecrets)||doc.storedSecrets.some(id=>model.fields.get(id)?.type!=="secret")||new Set(doc.storedSecrets).size!==doc.storedSecrets.length))
|
|
29
29
|
flowFail("storedSecrets lists only secret fields");model.stored=new Set(doc.storedSecrets||[]);if(doc.baseline!==undefined&&(typeof doc.baseline!=="string"||!doc.baseline.length||doc.baseline.length>256))flowFail("the baseline is 1 to 256 characters");model.baseline=doc.baseline??null;if(!model.initial&&(model.stored.size||model.baseline!==null))model.initial={}}
|
|
30
30
|
function flowOptions(raw,bad){if(raw.length>1000)bad("needs at most 1000 options");const options=raw.map(option=>{flowKeys(flowIs(option)?option:{value:option},["value","label","description","badge","disabledReason","group"],"An option");const item=flowIs(option)?option:{value:option};if(!flowScalar(item.value))bad("has an invalid option value");return Object.freeze({value:item.value,label:flowString(item.label,200,"An option label")??String(item.value),description:flowString(item.description,1000,"An option description"),badge:flowString(item.badge,40,"An option badge"),disabledReason:flowString(item.disabledReason,400,"A disabled reason"),group:flowString(item.group,200,"An option group")})});if(new Set(options.map(option=>option.value)).size!==options.length)bad("needs options with distinct values");return options}
|
|
@@ -97,7 +97,7 @@ stepFields(step){return step.blocks.flatMap(block=>block.fields).filter(field=>t
|
|
|
97
97
|
reviewStep(){const last=this.model.steps[this.model.steps.length-1];return last.type==="review"?last:null}
|
|
98
98
|
getValues(){const values={};for(const field of this.model.fields.values())if(field.type!=="secret"&&this.visible(field))values[field.id]=flowCopy(this.values.get(field.id)??null);return values}
|
|
99
99
|
answersChanged(){this.answerRevision++;this.retireOperation()}
|
|
100
|
-
beginOperation(){let cancel;const cancelled=new Promise(resolve=>
|
|
100
|
+
beginOperation(){let cancel;const cancelled=new Promise(resolve=>cancel=resolve);const abort=new AbortController();const generation=this.generation,revision=this.answerRevision,ticket={cancel:()=>{abort.abort();cancel()},signal:abort.signal};ticket.current=()=>!this.destroyed&&generation===this.generation&&revision===this.answerRevision&&this.operation===ticket;ticket.wait=work=>Promise.race([work,cancelled]);this.operation=ticket;this.busy=true;return ticket}
|
|
101
101
|
retireOperation(render=true){const ticket=this.operation;if(!ticket)return;this.operation=null;ticket.close?.();this.busy=false;ticket.cancel();if(render&&!this.destroyed&&this.phase==="form"&&this.actions)this.renderActions()}
|
|
102
102
|
changed(field,source){const fv=this.fields.get(field.id);if(!fv||this.destroyed||field.readOnly)return;const result=fv.read();if(fv.pending!==(result.error||null))this.answersChanged();fv.pending=result.error||null;if(result.error)this.completed.delete(field.step.id);if(field.type==="secret"){const before=this.secrets.get(field.id)??null;if(result.value)this.secrets.set(field.id,result.value);else this.secrets.delete(field.id);if(before!==(result.value||null)){this.answersChanged();this.forgetHost(field);this.emit("flowValueChanged",{field:field.id,source:"edit"},"onValueChange")}}else if(!result.error){const previous=this.values.get(field.id)??null;if(!flowSameValue(previous,result.value)){this.answersChanged();this.values.set(field.id,result.value);this.forgetHost(field);this.emit("flowValueChanged",{field:field.id,value:flowCopy(result.value),previous:flowCopy(previous),source:"edit"},"onValueChange")}}
|
|
103
103
|
if(source!=="blur"&&this.errors.has(field.id))this.checkField(field);this.refreshVisibility()}
|
|
@@ -145,7 +145,8 @@ flowEach("built",this,step,section);return section},async go(target,direction,qu
|
|
|
145
145
|
if(target!==from){this.emit("flowStepChanged",{from:from.id,to:target.id},"onStepChange");this.stepMoved?.()}
|
|
146
146
|
return true},async next(){if(this.busy||this.phase!=="form"||this.step===this.hub)return false;const step=this.step,steps=this.visibleSteps(),pressed=document.activeElement,generation=this.generation;if(step.asks){const ticket=this.beginOperation();this.renderActions();let result;try{result=await ticket.wait(this.validateStep(step,true,ticket.current));if(!ticket.current())return false}finally{if(ticket.current())this.retireOperation()}
|
|
147
147
|
if(this.destroyed||generation!==this.generation||this.step!==step||result.moved)return false;if(!result.valid){const stayed=document.activeElement===pressed||!this.root.contains(document.activeElement);this.renderRail();this.renderActions();this.showSummary(step,stayed);return false}
|
|
148
|
-
const summary=this.sections.get(step.id)?._cxSummary;if(summary)summary.hidden=true
|
|
148
|
+
const summary=this.sections.get(step.id)?._cxSummary;if(summary)summary.hidden=true}
|
|
149
|
+
this.completed.add(step.id);const review=this.reviewStep();const target=this.returnToReview&&review&&this.stepVisible(review)?review:this.hub||steps[steps.indexOf(step)+ 1];if(target===review)this.returnToReview=false;return this.go(target,"forward")},async back(){if(this.busy||this.phase!=="form")return false;const steps=this.visibleSteps(),at=steps.indexOf(this.step);return at>0?this.go(steps[at-1],"back"):false},async goTo(id){if(this.busy||this.phase!=="form")return false;const steps=this.visibleSteps(),target=steps.find(step=>step.id===id);if(!target)return false;const open=this.reachable(target,steps)?target:steps.find(step=>step.asks&&!this.completed.has(step.id))||target;return this.go(open,steps.indexOf(open)<steps.indexOf(this.step)?"back":"forward")},change(field){this.returnToReview=true;return this.go(field.step,"back").then(moved=>{if(moved){const fv=this.fields.get(field.id);if(fv)fv.focus()}
|
|
149
150
|
return moved})}});const FLOW_ITEM_RULES={email:value=>/^[^\s@]+@[^\s@]+\.[^\s@.]+$/.test(value),
|
|
150
151
|
host:value=>value.length<=253&&/^(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)*[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.?$/.test(value),
|
|
151
152
|
ip:value=>flowIPv4(value)||flowIPv6(value),cidr:value=>{const[address,prefix,extra]=value.split("/");return extra===undefined&&/^\d{1,3}$/.test(prefix || "") && (flowIPv4(address) && Number(prefix) <= 32 || flowIPv6(address) && Number(prefix) <= 128); },
|
|
@@ -185,7 +186,7 @@ const value=flowCopy(this.values.get(field.id)??null),from=flowNormal(this.initi
|
|
|
185
186
|
const proposal={kind:"flowSubmission",flow:model.id,version:1,mode:edit?"edit":"create"};if(model.baseline!==null)proposal.baseline=model.baseline;Object.assign(proposal,{values,secrets,changes,patch});flowEach("proposal",this,proposal);return proposal},async submit(){if(this.busy||this.phase!=="form")return null;const ticket=this.beginOperation(),current=ticket.current,wait=ticket.wait;this.banner=null;this.hostErrors.clear();this.hostStepErrors.clear();this.renderActions();try{const result=await wait(this.validateAll(current));if(!current())return null;if(!result.valid){const review=this.reviewStep();if(review&&this.stepVisible(review)){if(this.step!==review)await this.go(review,"forward");else{this.reviewStale=true;this.render()}}
|
|
186
187
|
else{const first=result.errors.find(error=>error.step);await this.go(this.model.steps.find(step=>step.id===first?.step)||this.step,"back");if(first?.step)this.showSummary(this.step)}
|
|
187
188
|
return null}
|
|
188
|
-
const proposal=this.submission(),secrets=new Map([...this.secrets].filter(([id])=>this.visible(this.model.fields.get(id)))),read=new Set();let answer,answered=false,open=true;const close=ticket.close=()=>{open=false;secrets.clear()};const detail=Object.assign(flowCopy(proposal),{respondWith:value=>{if(!answered&&open){answered=true;answer=Promise.resolve(value);answer.catch(()=>{})}},secret:id=>{if(!open||read.has(id)||!secrets.has(id))return null;read.add(id);return secrets.get(id)}});Object.freeze(detail);const go=this.emit("flowSubmit",detail,null,true);if(!go||!current()){close();return null}
|
|
189
|
+
const proposal=this.submission(),secrets=new Map([...this.secrets].filter(([id])=>this.visible(this.model.fields.get(id)))),read=new Set();let answer,answered=false,open=true;const close=ticket.close=()=>{open=false;secrets.clear()};const detail=Object.assign(flowCopy(proposal),{respondWith:value=>{if(!answered&&open){answered=true;answer=Promise.resolve(value);answer.catch(()=>{})}},secret:id=>{if(!open||read.has(id)||!secrets.has(id))return null;read.add(id);return secrets.get(id)}});Object.freeze(Object.defineProperty(detail,"signal",{value:ticket.signal}));const go=this.emit("flowSubmit",detail,null,true);if(!go||!current()){close();return null}
|
|
189
190
|
if(!answered&&typeof this.options.onSubmit==="function"){const value=await wait(this.hook("onSubmit",()=>this.options.onSubmit(detail)));if(!current()){close();return null}
|
|
190
191
|
if(value.failed){answered=true;answer={status:"error",message:value.failed}}
|
|
191
192
|
else if(value.value!==undefined){answered=true;answer=value.value}}
|
|
@@ -213,5 +214,5 @@ item.append(term,value);list.appendChild(item)}
|
|
|
213
214
|
panel.appendChild(list)}
|
|
214
215
|
if(answer.links.length){const links=h("ul","cx-flow-links");for(const link of answer.links){const item=h("li"),anchor=h("a","cx-flow-link");anchor.href=link.href;setText(anchor,link.label);item.appendChild(anchor);links.appendChild(item)}
|
|
215
216
|
panel.appendChild(links)}
|
|
216
|
-
const actions=h("div","cx-flow-actions cx-flow-panel-actions"),again=h("button","cx-flow-btn");again.type="button";setText(again,labels.flowStartAgain);const acknowledged=()=>{again.disabled=[...panel.querySelectorAll(".cx-flow-saved-it")].some(box=>!box.checked)};panel.addEventListener("change",acknowledged);acknowledged();again.addEventListener("click",()=>{this.panel=null;this.reset();this.stage.querySelector(".cx-flow-step-title")?.focus()});actions.appendChild(again);panel.appendChild(actions);return panel},progressPanel(answer){const panel=this.panelShell("progress",this.labels.flowAccepted),text=h("p","cx-flow-panel-text"),bar=h("progress","cx-flow-bar");setText(text,answer.message||"");bar.setAttribute("aria-labelledby",panel.firstChild.id);panel.append(text,bar);return panel}});function flowCreate(host,options,editors){const view=new FlowView(host,options,editors);const impl={ready:Promise.resolve().then(()=>{if(!view.destroyed)host.setAttribute("data-cx-ready","");view.emit("flowReady",{flow:view.model.id,step:view.step.id},"onReady");return impl}),next:()=>view.next(),back:()=>view.back(),goTo:id=>view.goTo(id),getStep:()=>view.getStep(),getValues:()=>view.getValues(),setValues:values=>view.setValues(values),getState:()=>view.getState(),setState:state=>view.setState(state),isDirty:()=>view.isDirty(),reset:()=>view.reset(),validate:id=>view.validate(id),setFieldError:(id,message)=>view.setFieldError(id,message),submit:()=>view.submit(),setProgress:progress=>view.setProgress(progress),complete:answer=>view.complete(answer),destroy:()=>view.destroy()};const part=(name,none)=>(...args)=>view[name]?view[name](...args):none??flowFail("this flow does not use "+name);return Object.assign(impl,{runCheck:part("runCheck"),refreshOptions:part("refreshOptions"),setStepState:part("setStepState"),setPreset:part("setPreset"),saveDraft:()=>part("saveDraft",false)(true),open:()=>part("open",false)(),close:()=>part("close",false)()})}
|
|
217
|
+
const actions=h("div","cx-flow-actions cx-flow-panel-actions"),again=h("button","cx-flow-btn");again.type="button";setText(again,labels.flowStartAgain);const acknowledged=()=>{again.disabled=[...panel.querySelectorAll(".cx-flow-saved-it")].some(box=>!box.checked)};panel.addEventListener("change",acknowledged);acknowledged();again.addEventListener("click",()=>{this.panel=null;this.reset();this.stage.querySelector(".cx-flow-step-title")?.focus()});actions.appendChild(again);panel.appendChild(actions);return panel},progressPanel(answer){const panel=this.panelShell("progress",this.labels.flowAccepted),text=h("p","cx-flow-panel-text"),bar=h("progress","cx-flow-bar");setText(text,answer.message||"");bar.setAttribute("aria-labelledby",panel.firstChild.id);panel.append(text,bar);return panel}});function flowCreate(host,options,editors){const view=new FlowView(host,options,editors);const impl={ready:Promise.resolve().then(()=>{if(!view.destroyed)host.setAttribute("data-cx-ready","");view.emit("flowReady",{flow:view.model.id,step:view.step.id},"onReady");return impl}),next:()=>view.next(),back:()=>view.back(),goTo:id=>view.goTo(id),getStep:()=>view.getStep(),getValues:()=>view.getValues(),setValues:values=>view.setValues(values),getState:()=>view.getState(),setState:state=>view.setState(state),isDirty:()=>view.isDirty(),reset:()=>view.reset(),validate:id=>view.validate(id),setFieldError:(id,message)=>view.setFieldError(id,message),submit:()=>view.submit(),setProgress:progress=>view.setProgress(progress),complete:answer=>view.complete(answer),destroy:()=>view.destroy()};const part=(name,none)=>(...args)=>view[name]?view[name](...args):none??flowFail("this flow does not use "+name);return Object.assign(impl,{runCheck:part("runCheck"),invalidateChecks:part("invalidateChecks"),refreshOptions:part("refreshOptions"),setStepState:part("setStepState"),setPreset:part("setPreset"),saveDraft:()=>part("saveDraft",false)(true),open:()=>part("open",false)(),close:()=>part("close",false)()})}
|
|
217
218
|
Object.assign(FLOW_IMPL,{create:flowCreate,core:{FlowView,FLOW_HOST,FLOW_LABELS,flowFail,flowIs,flowKeys,flowName,flowString,flowFlag,flowScalar,flowFits,flowField,flowOptions,flowCondition,flowRefs,flowTest,flowCopy,flowSameValue,flowEmpty,flowNormal,flowDate,flowFieldView}});installed.add(context.FLOW_IMPL)}};(global.CanopyXParts||=[]).push(["flow",part])})(typeof window!=="undefined"?window:globalThis);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
(function(global){"use strict";const installed=new WeakSet();const part={version:"
|
|
1
|
+
(function(global){"use strict";const installed=new WeakSet();const part={version:"5398e457a885ef0d",requires:["filter-editor","formatting"],install(context){if(installed.has(context.DataGrid.prototype))return;const{DataGrid,h,setText,fill,gridButton,gridVariant,gridOption,gridDateInputMoment,gridInputLabel,gridIcon,gridDecorateButton,announceMenu,formatCompile,formatToneVar,formatError,FORMAT_ICONS,FORMAT_TONE_ICONS,FORMAT_OPERATORS,svgIcon,overlayTheme}=context;const FORMAT_EDITOR_LABELS={formatRule:"Rule {number}",formatAddRule:"Add rule",formatEditRule:"Edit {rule}",formatDeleteRule:"Delete {rule}",formatMoveUp:"Move {rule} up",formatMoveDown:"Move {rule} down",formatEnableRule:"Apply {rule}",formatNoRules:"No formatting rules.",formatName:"Name",formatDescription:"Screen reader description",formatOnlyRowsWhere:"Only rows where",formatEveryRow:"Every row",formatNone:"None",formatApplyTo:"Apply to",formatTargetCell:"Cell",formatTargetRow:"Whole row",formatTargetColumns:"Chosen columns",formatStyle:"Style",formatHighlight:"Highlight",formatDataBar:"Data bar",formatColorScale:"Colour scale",formatBands:"Threshold bands",formatTone:"Tone",formatEmphasis:"Emphasis",formatFill:"Fill",formatTextOnly:"Text colour",formatStrong:"Bold fill",formatIcon:"Icon",formatNoIcon:"No icon",formatAutomatic:"Automatic",formatBadge:"Badge",formatCue:"Text cue",formatLowest:"Lowest",formatMidpoint:"Midpoint",formatHighest:"Highest",formatAddBand:"+ Band",formatRemoveBand:"Remove band",formatSave:"Save rule",formatCancel:"Cancel",formatShowLegend:"Show legend",formatInvalid:"Complete the rule before saving.",formatMatchCase:"Match case",formatToneDanger:"Danger",formatToneWarning:"Warning",formatToneSuccess:"Success",formatToneInfo:"Info",formatToneNeutral:"Neutral",formatToneMuted:"Muted",formatNotContains:"does not contain",formatEndsWith:"ends with",formatNotIn:"is none of",formatBetween:"between",formatLike:"matches wildcard",formatMatches:"matches pattern",formatOlderThan:"older than (days)",formatWithinLast:"within the last (days)",formatNotLike:"does not match wildcard",formatNotMatches:"does not match pattern",formatBetweenExclusive:"between (exclusive)"};function formatIconButton(label,icon,run){const button=gridDecorateButton(gridButton("",run),icon==="edit"?"more":icon,true);if(icon==="edit")button.querySelector("svg").replaceWith(svgIcon('<path d="M4 20h4L19 9l-4-4L4 16zM13.5 6.5l4 4"/>'));button.classList.add("icon");button.setAttribute("aria-label",label);button.title=label;return button}
|
|
2
2
|
function formatPreview(style){const swatch=h("span","cx-format-swatch"),stops=style.scale?style.scale.stops.map(stop=>stop.tone):style.bands?style.bands.map(band=>band.tone):null;swatch.setAttribute("aria-hidden","true");if(stops){swatch.classList.add("cx-fmt-gradient");swatch.style.setProperty("--cx-fmt-scale","linear-gradient(90deg,"+stops.map(formatToneVar).join(",")+ ")")}
|
|
3
3
|
else if(style.bar){swatch.classList.add("cx-fmt-barred");const bar=h("span","cx-fmt-bar");bar.style.setProperty("--cx-fmt-w","70%");bar.style.setProperty("--cx-fmt",formatToneVar(style.bar.tone||"info"));swatch.appendChild(bar)}
|
|
4
4
|
else if(style.tone){swatch.classList.add("cx-fmt-fill");swatch.style.setProperty("--cx-fmt",formatToneVar(style.tone));const name=!style.icon||style.icon==="auto"?FORMAT_TONE_ICONS[style.tone]||"dot":style.icon;if(name!=="none")setText(swatch,FORMAT_ICONS[name]||name)}else if(style.badge)setText(swatch,style.badge.slice(0,2));return swatch}
|
|
5
5
|
Object.assign(DataGrid.prototype,{showFormatEditor(){this.formatEditor?.close();if(!this.formatLabels.formatAddRule){const own={};for(const name of Object.keys(FORMAT_EDITOR_LABELS))own[name]=Object.hasOwn(this.labels,name)?this.labels[name]:FORMAT_EDITOR_LABELS[name];this.formatLabels={...this.formatLabels,...own}}
|
|
6
6
|
const labels=this.formatLabels,returnFocus=document.activeElement,phone=this.host.clientWidth<=640;const dialog=h("dialog","cx-host cx-grid-overlay cx-format-editor"),head=h("div","cx-drawer-h"),title=h("h4"),body=h("div","cx-format-body"),status=h("p","cx-grid-control-error"),foot=h("div","cx-pop-f");overlayTheme(this.host,dialog);dialog.classList.toggle("cx-phone",phone);title.id=this.id+"-format-title";title.tabIndex=-1;setText(title,labels.formatRules);dialog.setAttribute("aria-labelledby",title.id);status.setAttribute("role","status");head.append(title,formatIconButton(labels.formatCancel,"close",()=>dialog.close()));dialog.append(head,body,status,foot);document.body.appendChild(dialog);this.formatEditor=dialog;const editor={dialog,body,foot,status,title,rules:JSON.parse(JSON.stringify(this.getFormatRules()))};editor.apply=()=>this.setFormatRules(editor.rules).then(()=>{setText(status,"");return true},error=>{setText(status,error.message);return false});editor.list=focus=>this.renderFormatList(editor,focus);dialog.addEventListener("keydown",event=>{if(event.key==="Escape"){event.preventDefault();event.stopPropagation();if(editor.back)editor.back();else dialog.close()}});dialog.addEventListener("close",()=>{dialog.remove();if(this.formatEditor===dialog)this.formatEditor=null;if(!this.destroyed)(returnFocus?.isConnected&&returnFocus.checkVisibility?.()?returnFocus:this.grid).focus({preventScroll:true})},{once:true});const owner=new AbortController();this.lifetime.signal.addEventListener("abort",()=>dialog.close(),{once:true,signal:owner.signal});dialog.addEventListener("close",()=>owner.abort(),{once:true});announceMenu(dialog);dialog.showModal();editor.list();title.focus({preventScroll:true});return dialog},renderFormatList(editor,focus){const labels=this.formatLabels,{body,foot,rules}=editor,name=(rule,index)=>rule.label||fill(labels.formatRule,{number:index+1});editor.back=null;setText(editor.title,labels.formatRules);body.replaceChildren();foot.replaceChildren();const list=h("ol","cx-format-rules");list.setAttribute("aria-label",labels.formatRules);const change=(mutate,next)=>{mutate();editor.apply().then(ok=>{if(!ok)editor.rules=JSON.parse(JSON.stringify(this.getFormatRules()));editor.list(next)})};rules.forEach((rule,index)=>{const item=h("li","cx-format-item"),toggle=h("input"),text=h("span","cx-format-item-text"),title=h("b"),summary=h("span","cx-muted"),actions=h("span","cx-format-actions");const label=name(rule,index);toggle.type="checkbox";toggle.checked=rule.enabled!==false;toggle.setAttribute("aria-label",fill(labels.formatEnableRule,{rule:label}));toggle.addEventListener("change",()=>change(()=>{if(toggle.checked)delete rule.enabled;else rule.enabled=false},"toggle:"+index));setText(title,label);setText(summary,this.formatSummary(rule));text.append(title,summary);const move=(by,key)=>()=>change(()=>rules.splice(index+by,0,rules.splice(index,1)[0]),key+":" +(index+by));const up=formatIconButton(fill(labels.formatMoveUp,{rule:label}),"up",move(-1,"up")),down=formatIconButton(fill(labels.formatMoveDown,{rule:label}),"down",move(1,"down"));up.disabled=index===0;down.disabled=index===rules.length-1;const edit=formatIconButton(fill(labels.formatEditRule,{rule:label}),"edit",()=>this.renderFormatRule(editor,index));edit.dataset.cxFocus="edit:"+index;const remove=formatIconButton(fill(labels.formatDeleteRule,{rule:label}),"close",()=>change(()=>rules.splice(index,1),"add"));toggle.dataset.cxFocus="toggle:"+index;up.dataset.cxFocus="up:"+index;down.dataset.cxFocus="down:"+index;actions.append(up,down,edit,remove);item.append(toggle,formatPreview(rule.style||{}),text,actions);list.appendChild(item)});if(rules.length)body.appendChild(list);else{const empty=h("p","cx-muted");setText(empty,labels.formatNoRules);body.appendChild(empty)}
|
|
7
|
-
const add=gridButton(labels.formatAddRule,()=>this.renderFormatRule(editor,-1));add.classList.add("cx-link");add.dataset.cxFocus="add";add.disabled=rules.length>=64;const legend=h("input"),legendLabel=gridInputLabel(labels.formatShowLegend,legend);legend.type="checkbox";legend.checked=!!this.formatLegendShown;legendLabel.classList.add("cx-format-legend-switch");legend.addEventListener("change",()=>this.setFormatLegend(legend.checked));const done=gridButton(this.labels.gridDone,()=>editor.dialog.close());foot.append(add,legendLabel,done);const target=focus&&editor.dialog.querySelector('[data-cx-focus="'+focus+'"]');if(target&&!target.disabled)target.focus({preventScroll:true});else if(focus)add.focus({preventScroll:true})},formatSummary(rule){const labels=this.formatLabels,title=id=>this.columns.find(column=>column.id===id)?.title||id,style=rule.style||{};const target=rule.target==="row"?labels.formatTargetRow:rule.target==="columns"?(rule.columns||[]).map(title).join(", "):labels.formatTargetCell+" · "+title(rule.column);const kind=style.bar?labels.formatDataBar:style.scale?labels.formatColorScale:style.bands?labels.formatBands:labels.formatHighlight;return[target,kind,rule.when?null:labels.formatEveryRow].filter(Boolean).join(" · ")}});const FORMAT_TONES=["danger","warning","success","info","neutral","muted"];function formatField(text,control,className){const label=control.tagName==="DIV"?h("div"):gridInputLabel(text,control);if(control.tagName==="DIV"){const heading=h("span");setText(heading,text);heading.setAttribute("aria-hidden","true");label.append(heading,control)}
|
|
7
|
+
const add=gridButton(labels.formatAddRule,()=>this.renderFormatRule(editor,-1));add.classList.add("cx-link");add.dataset.cxFocus="add";add.disabled=rules.length>=64;const legend=h("input"),legendLabel=gridInputLabel(labels.formatShowLegend,legend);legend.type="checkbox";legend.checked=!!this.formatLegendShown;legendLabel.classList.add("cx-format-legend-switch");legend.addEventListener("change",()=>this.setFormatLegend(legend.checked));const done=gridVariant(gridButton(this.labels.gridDone,()=>editor.dialog.close()),"primary");foot.append(add,legendLabel,done);const target=focus&&editor.dialog.querySelector('[data-cx-focus="'+focus+'"]');if(target&&!target.disabled)target.focus({preventScroll:true});else if(focus)add.focus({preventScroll:true})},formatSummary(rule){const labels=this.formatLabels,title=id=>this.columns.find(column=>column.id===id)?.title||id,style=rule.style||{};const target=rule.target==="row"?labels.formatTargetRow:rule.target==="columns"?(rule.columns||[]).map(title).join(", "):labels.formatTargetCell+" · "+title(rule.column);const kind=style.bar?labels.formatDataBar:style.scale?labels.formatColorScale:style.bands?labels.formatBands:labels.formatHighlight;return[target,kind,rule.when?null:labels.formatEveryRow].filter(Boolean).join(" · ")}});const FORMAT_TONES=["danger","warning","success","info","neutral","muted"];function formatField(text,control,className){const label=control.tagName==="DIV"?h("div"):gridInputLabel(text,control);if(control.tagName==="DIV"){const heading=h("span");setText(heading,text);heading.setAttribute("aria-hidden","true");label.append(heading,control)}
|
|
8
8
|
label.classList.add("cx-format-field");if(className)label.classList.add(className);if(control.tagName==="SELECT"||control.tagName==="INPUT"&&control.type!=="checkbox")control.classList.add("cx-input");return label}
|
|
9
9
|
function formatSelect(options,value){const select=h("select");for(const[key,text]of options)select.appendChild(gridOption(key,text));if(value!==undefined&&options.some(option=>option[0]===value))select.value=value;return select}
|
|
10
10
|
function formatNumberInput(value,placeholder){const input=h("input");input.type="number";input.step="any";if(placeholder)input.placeholder=placeholder;if(value!==undefined&&value!==null)input.value=String(value);return input}
|