@antglobal/copilot-cards-web 0.0.20260828032020-dev.9 → 0.0.20260915071159-dev.1
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/README.md +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.js +609 -98
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ The package includes the core schema and action APIs, responsive rendering, Shad
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install @antglobal/copilot-cards-web@1.0.
|
|
10
|
+
npm install @antglobal/copilot-cards-web@1.0.9
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
`@antglobal/copilot-cards-core` is installed automatically.
|
package/dist/index.d.ts
CHANGED
|
@@ -107,6 +107,8 @@ declare function createResponsiveContext(isMobile: boolean, responsive?: Respons
|
|
|
107
107
|
*/
|
|
108
108
|
|
|
109
109
|
interface RenderCardOptions extends WebActionContextOptions {
|
|
110
|
+
/** Disable the whole card using the existing project disabled appearance. Default false. */
|
|
111
|
+
disabled?: boolean;
|
|
110
112
|
/** Enable mobile component layout explicitly (default false). */
|
|
111
113
|
isMobile?: boolean;
|
|
112
114
|
/** Optional mobile sizing conversion; omitted values preserve px output. */
|
|
@@ -117,6 +119,8 @@ interface RenderCardOptions extends WebActionContextOptions {
|
|
|
117
119
|
botId?: string;
|
|
118
120
|
}
|
|
119
121
|
interface CardInstance {
|
|
122
|
+
/** Toggle whole-card interaction without changing schema or component business rules. */
|
|
123
|
+
setDisabled: (disabled: boolean) => void;
|
|
120
124
|
/** Dispose the card: unmount all lifecycles, remove DOM, detach listeners. */
|
|
121
125
|
dispose: () => void;
|
|
122
126
|
/** Update variables and re-render. */
|
|
@@ -509,6 +513,8 @@ declare abstract class BaseElement extends HTMLElement {
|
|
|
509
513
|
* Subclasses must implement this to render their UI into `this.shadowRoot`.
|
|
510
514
|
*/
|
|
511
515
|
protected abstract render(): void;
|
|
516
|
+
/** @internal Close temporary interaction UI without clearing component values. */
|
|
517
|
+
closeTransientUI(): void;
|
|
512
518
|
/** Convert any content value to a safe display string. */
|
|
513
519
|
protected resolveContent(content: any): string;
|
|
514
520
|
/**
|
|
@@ -736,6 +742,7 @@ declare class CardImage extends BaseElement {
|
|
|
736
742
|
private bindEvents;
|
|
737
743
|
private openLightbox;
|
|
738
744
|
private closeLightbox;
|
|
745
|
+
closeTransientUI(): void;
|
|
739
746
|
disconnectedCallback(): void;
|
|
740
747
|
}
|
|
741
748
|
|
|
@@ -899,6 +906,7 @@ declare class CardSelect extends BaseElement {
|
|
|
899
906
|
private _onDocClick;
|
|
900
907
|
static readonly is = "ai-card-select";
|
|
901
908
|
protected render(): void;
|
|
909
|
+
closeTransientUI(): void;
|
|
902
910
|
disconnectedCallback(): void;
|
|
903
911
|
updateProps(props: Record<string, any>, isMobile?: boolean, responsive?: ResponsiveOptions): void;
|
|
904
912
|
private _setOpen;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getBuiltinIcon, cloneJsonData, createLifecycleManager, materializeCard, findAffectedRepeatOwners, createA2UIParameterResolver, createExpressionContext, replaceRootContents, getByJsonPointer, resolveA2UIDeep, resolveDeep, resolveExpressionValue,
|
|
1
|
+
import { getBuiltinIcon, cloneJsonData, createLifecycleManager, materializeCard, findAffectedRepeatOwners, createA2UIParameterResolver, createExpressionContext, replaceRootContents, getByJsonPointer, resolveA2UIDeep, resolveDeep, resolveExpressionValue, isBoundRenderTreeNode, resolveActionRef, hasExpression, resolveExpression, runActionSteps, normalizeSchema, validateSchema, requiresBindingMaterialization, parseSchema, StreamingParser, StreamingEngine, bindingTopologyFingerprint, findTemplateRepeatOwners, extractPartialSchema, runActionStep, registry } from '@antglobal/copilot-cards-core';
|
|
2
2
|
export { ActionRegistry, a2uiComponentToElement, a2uiToCommand, convertLegacySchema, createLifecycleManager, hasExpression, isA2UIEnvelope, isLegacySchema, normalizeSchema, parseSchema, registerActionHandler, registry, resolveActionRef, resolveDeep, resolveExpression, resolveExpressionValue, runActionStep, runActionSteps, validateSchema } from '@antglobal/copilot-cards-core';
|
|
3
3
|
import * as echarts from 'echarts/core';
|
|
4
4
|
import { LineChart, BarChart, PieChart, ScatterChart, FunnelChart, HeatmapChart } from 'echarts/charts';
|
|
@@ -713,6 +713,276 @@ function buildHeatmapOption(config) {
|
|
|
713
713
|
};
|
|
714
714
|
}
|
|
715
715
|
|
|
716
|
+
const DISABLED_MARKER = 'data-copilot-card-disabled';
|
|
717
|
+
function applyDisabledState(element, disabled) {
|
|
718
|
+
if (!disabled)
|
|
719
|
+
return;
|
|
720
|
+
element.setAttribute('data-disabled', 'true');
|
|
721
|
+
element.setAttribute(DISABLED_MARKER, 'true');
|
|
722
|
+
// Inline declarations work inside host ShadowRoots too. Use the shorthand
|
|
723
|
+
// to mask background images/gradients, matching the historical disabled state.
|
|
724
|
+
element.style.background = 'var(--card-disabled-background, #F5F5F5)';
|
|
725
|
+
element.style.color = 'var(--card-disabled-foreground, #C0C0C0)';
|
|
726
|
+
element.style.pointerEvents = 'none';
|
|
727
|
+
element.style.cursor = 'default';
|
|
728
|
+
}
|
|
729
|
+
function applyDisabledDescendants(element, disabled) {
|
|
730
|
+
if (!disabled)
|
|
731
|
+
return;
|
|
732
|
+
element.querySelectorAll('*').forEach((child) => {
|
|
733
|
+
child.setAttribute('data-disabled', 'true');
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
const controllers = new WeakMap();
|
|
738
|
+
const interactionCleanups = new WeakMap();
|
|
739
|
+
/** Cancel slot-owned gestures before capturing the disabled presentation. */
|
|
740
|
+
function registerCardDisableCleanup(element, cleanup) {
|
|
741
|
+
let callbacks = interactionCleanups.get(element);
|
|
742
|
+
if (!callbacks) {
|
|
743
|
+
callbacks = new Set();
|
|
744
|
+
interactionCleanups.set(element, callbacks);
|
|
745
|
+
}
|
|
746
|
+
callbacks.add(cleanup);
|
|
747
|
+
return () => { callbacks.delete(cleanup); };
|
|
748
|
+
}
|
|
749
|
+
function composedParent(node) {
|
|
750
|
+
return node.parentNode ?? (node instanceof ShadowRoot ? node.host : null);
|
|
751
|
+
}
|
|
752
|
+
function isCardDisabled(node) {
|
|
753
|
+
for (let current = node; current; current = composedParent(current)) {
|
|
754
|
+
if (current instanceof HTMLElement && controllers.get(current)?.isDisabled)
|
|
755
|
+
return true;
|
|
756
|
+
}
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
const BLOCKED_EVENTS = [
|
|
760
|
+
'click', 'dblclick', 'auxclick', 'contextmenu',
|
|
761
|
+
'beforeinput', 'input', 'change', 'submit', 'keydown', 'keyup',
|
|
762
|
+
'compositionstart', 'compositionupdate', 'compositionend',
|
|
763
|
+
'choice-request-change', 'choice-navigate',
|
|
764
|
+
];
|
|
765
|
+
const TOUCH_EVENTS = ['pointerdown', 'pointerup', 'touchstart', 'touchend', 'mousedown', 'mouseup'];
|
|
766
|
+
const TAB_TARGETS = [
|
|
767
|
+
'a[href]', 'area[href]', 'button', 'input', 'select', 'textarea', 'summary',
|
|
768
|
+
'iframe', 'object', 'embed', 'audio[controls]', 'video[controls]',
|
|
769
|
+
'[tabindex]', '[contenteditable]:not([contenteditable="false"])',
|
|
770
|
+
].join(',');
|
|
771
|
+
const VISUAL_ATTRIBUTES = ['data-disabled', 'data-copilot-card-disabled'];
|
|
772
|
+
const ownsStyle = (name) => name === 'background' || name.startsWith('background-')
|
|
773
|
+
|| name === 'color' || name === 'pointer-events' || name === 'cursor';
|
|
774
|
+
function restoreAttribute(element, name, value) {
|
|
775
|
+
if (value === null)
|
|
776
|
+
element.removeAttribute(name);
|
|
777
|
+
else
|
|
778
|
+
element.setAttribute(name, value);
|
|
779
|
+
}
|
|
780
|
+
function createCardDisabledController(container, initiallyDisabled = false) {
|
|
781
|
+
let disabled = false;
|
|
782
|
+
let disposed = false;
|
|
783
|
+
let epoch = 0;
|
|
784
|
+
let updateDepth = 0;
|
|
785
|
+
let applyingPresentation = false;
|
|
786
|
+
let previousAriaDisabled = null;
|
|
787
|
+
let snapshots = [];
|
|
788
|
+
let tabSnapshots = [];
|
|
789
|
+
let tabObserver;
|
|
790
|
+
const block = (event) => {
|
|
791
|
+
if (!disabled || disposed)
|
|
792
|
+
return;
|
|
793
|
+
event.preventDefault();
|
|
794
|
+
event.stopImmediatePropagation();
|
|
795
|
+
};
|
|
796
|
+
// Prevent component gesture handlers without cancelling the browser's scroll.
|
|
797
|
+
const stopGesture = (event) => {
|
|
798
|
+
if (disabled && !disposed)
|
|
799
|
+
event.stopImmediatePropagation();
|
|
800
|
+
};
|
|
801
|
+
const blockFocus = (event) => {
|
|
802
|
+
if (!disabled || disposed)
|
|
803
|
+
return;
|
|
804
|
+
const target = event.composedPath()[0] ?? event.target;
|
|
805
|
+
if (target instanceof HTMLElement)
|
|
806
|
+
target.blur();
|
|
807
|
+
event.stopImmediatePropagation();
|
|
808
|
+
};
|
|
809
|
+
function closeTransientUI(root) {
|
|
810
|
+
for (const element of root.querySelectorAll('*')) {
|
|
811
|
+
interactionCleanups.get(element)?.forEach(cleanup => cleanup());
|
|
812
|
+
const component = element;
|
|
813
|
+
component.closeTransientUI?.();
|
|
814
|
+
if (element.shadowRoot)
|
|
815
|
+
closeTransientUI(element.shadowRoot);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
function blurCardInput() {
|
|
819
|
+
let active = container.ownerDocument.activeElement;
|
|
820
|
+
while (active?.shadowRoot?.activeElement)
|
|
821
|
+
active = active.shadowRoot.activeElement;
|
|
822
|
+
if (!(active instanceof HTMLElement))
|
|
823
|
+
return;
|
|
824
|
+
for (let node = active; node; node = composedParent(node)) {
|
|
825
|
+
if (node === container) {
|
|
826
|
+
active.blur();
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
function excludeFromTabNavigation(root) {
|
|
832
|
+
const observer = tabObserver ?? (tabObserver = new MutationObserver(() => {
|
|
833
|
+
if (!disabled || disposed || updateDepth > 0)
|
|
834
|
+
return;
|
|
835
|
+
// Components such as streaming Markdown also update their own Shadow DOM.
|
|
836
|
+
restoreTabNavigation();
|
|
837
|
+
excludeFromTabNavigation(container);
|
|
838
|
+
}));
|
|
839
|
+
const targets = [];
|
|
840
|
+
const collect = (element) => {
|
|
841
|
+
if (element.matches(TAB_TARGETS)) {
|
|
842
|
+
targets.push(element);
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
// Browsers can put scroll containers in the Tab order without tabindex.
|
|
846
|
+
const style = element.ownerDocument.defaultView?.getComputedStyle(element);
|
|
847
|
+
if (style && [style.overflowX, style.overflowY].some(value => value === 'auto' || value === 'scroll')) {
|
|
848
|
+
targets.push(element);
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
const walk = (parent) => {
|
|
852
|
+
observer.observe(parent, { childList: true, subtree: true });
|
|
853
|
+
if (parent instanceof HTMLElement)
|
|
854
|
+
collect(parent);
|
|
855
|
+
for (const element of parent.querySelectorAll('*')) {
|
|
856
|
+
collect(element);
|
|
857
|
+
if (element.shadowRoot)
|
|
858
|
+
walk(element.shadowRoot);
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
// Collect before writing attributes so style reads stay in one batch.
|
|
862
|
+
walk(root);
|
|
863
|
+
for (const element of targets) {
|
|
864
|
+
tabSnapshots.push({ element, tabindex: element.getAttribute('tabindex') });
|
|
865
|
+
element.setAttribute('tabindex', '-1');
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
function restoreTabNavigation() {
|
|
869
|
+
tabObserver?.disconnect();
|
|
870
|
+
if (!disabled)
|
|
871
|
+
tabObserver = undefined;
|
|
872
|
+
for (const { element, tabindex } of tabSnapshots) {
|
|
873
|
+
restoreAttribute(element, 'tabindex', tabindex);
|
|
874
|
+
}
|
|
875
|
+
tabSnapshots = [];
|
|
876
|
+
}
|
|
877
|
+
function restorePresentation() {
|
|
878
|
+
restoreTabNavigation();
|
|
879
|
+
for (const { element, attributes, styles } of snapshots) {
|
|
880
|
+
VISUAL_ATTRIBUTES.forEach((name, index) => restoreAttribute(element, name, attributes[index]));
|
|
881
|
+
if (styles) {
|
|
882
|
+
Array.from(element.style).filter(ownsStyle).forEach(name => element.style.removeProperty(name));
|
|
883
|
+
styles.forEach(([name, value, priority]) => element.style.setProperty(name, value, priority));
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
snapshots = [];
|
|
887
|
+
}
|
|
888
|
+
function applyPresentation() {
|
|
889
|
+
if (!disabled || disposed || updateDepth > 0 || applyingPresentation)
|
|
890
|
+
return;
|
|
891
|
+
applyingPresentation = true;
|
|
892
|
+
try {
|
|
893
|
+
// Blur/popup callbacks can synchronously update or toggle the card.
|
|
894
|
+
// Always snapshot its current underlying presentation, never our overlay.
|
|
895
|
+
restorePresentation();
|
|
896
|
+
closeTransientUI(container);
|
|
897
|
+
blurCardInput();
|
|
898
|
+
if (!disabled || disposed)
|
|
899
|
+
return;
|
|
900
|
+
for (const element of container.querySelectorAll('*')) {
|
|
901
|
+
const isRoot = element.parentElement === container;
|
|
902
|
+
snapshots.push({
|
|
903
|
+
element,
|
|
904
|
+
attributes: VISUAL_ATTRIBUTES.map(name => element.getAttribute(name)),
|
|
905
|
+
styles: isRoot ? Array.from(element.style).filter(ownsStyle)
|
|
906
|
+
.map(name => [name, element.style.getPropertyValue(name), element.style.getPropertyPriority(name)]) : undefined,
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
for (const root of Array.from(container.children)) {
|
|
910
|
+
if (!(root instanceof HTMLElement))
|
|
911
|
+
continue;
|
|
912
|
+
applyDisabledState(root, true);
|
|
913
|
+
applyDisabledDescendants(root, true);
|
|
914
|
+
}
|
|
915
|
+
excludeFromTabNavigation(container);
|
|
916
|
+
}
|
|
917
|
+
finally {
|
|
918
|
+
applyingPresentation = false;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
function listen(enabled) {
|
|
922
|
+
for (const name of BLOCKED_EVENTS) {
|
|
923
|
+
if (enabled)
|
|
924
|
+
container.addEventListener(name, block, true);
|
|
925
|
+
else
|
|
926
|
+
container.removeEventListener(name, block, true);
|
|
927
|
+
}
|
|
928
|
+
for (const name of TOUCH_EVENTS) {
|
|
929
|
+
if (enabled)
|
|
930
|
+
container.addEventListener(name, stopGesture, { capture: true, passive: true });
|
|
931
|
+
else
|
|
932
|
+
container.removeEventListener(name, stopGesture, true);
|
|
933
|
+
}
|
|
934
|
+
if (enabled)
|
|
935
|
+
container.addEventListener('focus', blockFocus, true);
|
|
936
|
+
else
|
|
937
|
+
container.removeEventListener('focus', blockFocus, true);
|
|
938
|
+
}
|
|
939
|
+
const controller = {
|
|
940
|
+
get isDisabled() { return disabled && !disposed; },
|
|
941
|
+
get epoch() { return epoch; },
|
|
942
|
+
setDisabled(value) {
|
|
943
|
+
if (disposed || disabled === value)
|
|
944
|
+
return;
|
|
945
|
+
disabled = value;
|
|
946
|
+
epoch += 1;
|
|
947
|
+
if (disabled) {
|
|
948
|
+
previousAriaDisabled = container.getAttribute('aria-disabled');
|
|
949
|
+
container.setAttribute('aria-disabled', 'true');
|
|
950
|
+
listen(true);
|
|
951
|
+
blurCardInput();
|
|
952
|
+
applyPresentation();
|
|
953
|
+
}
|
|
954
|
+
else {
|
|
955
|
+
restorePresentation();
|
|
956
|
+
restoreAttribute(container, 'aria-disabled', previousAriaDisabled);
|
|
957
|
+
listen(false);
|
|
958
|
+
}
|
|
959
|
+
},
|
|
960
|
+
update(render) {
|
|
961
|
+
if (updateDepth === 0)
|
|
962
|
+
restorePresentation();
|
|
963
|
+
updateDepth += 1;
|
|
964
|
+
try {
|
|
965
|
+
return render();
|
|
966
|
+
}
|
|
967
|
+
finally {
|
|
968
|
+
updateDepth -= 1;
|
|
969
|
+
if (updateDepth === 0)
|
|
970
|
+
applyPresentation();
|
|
971
|
+
}
|
|
972
|
+
},
|
|
973
|
+
dispose() {
|
|
974
|
+
if (disposed)
|
|
975
|
+
return;
|
|
976
|
+
controller.setDisabled(false);
|
|
977
|
+
disposed = true;
|
|
978
|
+
controllers.delete(container);
|
|
979
|
+
},
|
|
980
|
+
};
|
|
981
|
+
controllers.set(container, controller);
|
|
982
|
+
controller.setDisabled(initiallyDisabled);
|
|
983
|
+
return controller;
|
|
984
|
+
}
|
|
985
|
+
|
|
716
986
|
/**
|
|
717
987
|
* Slot Layout Renderers — each slot key maps to a specific layout strategy.
|
|
718
988
|
*
|
|
@@ -1033,6 +1303,15 @@ function mergePresentationOwnership(...ownership) {
|
|
|
1033
1303
|
styleProperties: Array.from(new Set(ownership.flatMap(value => value.styleProperties))),
|
|
1034
1304
|
};
|
|
1035
1305
|
}
|
|
1306
|
+
const datePickerRowPaddingPatches = new WeakMap();
|
|
1307
|
+
/** Suspend an open date picker's row padding around renderer-owned style updates. */
|
|
1308
|
+
function registerDatePickerRowPaddingPatch(row, suspend) {
|
|
1309
|
+
datePickerRowPaddingPatches.set(row, suspend);
|
|
1310
|
+
return () => {
|
|
1311
|
+
if (datePickerRowPaddingPatches.get(row) === suspend)
|
|
1312
|
+
datePickerRowPaddingPatches.delete(row);
|
|
1313
|
+
};
|
|
1314
|
+
}
|
|
1036
1315
|
/** Patch renderer-owned shell presentation without overwriting layout state. */
|
|
1037
1316
|
function patchElementShellPresentation(current, previous, desired, ...preservedOwnership) {
|
|
1038
1317
|
const ownership = mergePresentationOwnership(...preservedOwnership);
|
|
@@ -1068,43 +1347,49 @@ function patchElementShellPresentation(current, previous, desired, ...preservedO
|
|
|
1068
1347
|
else
|
|
1069
1348
|
current.removeAttribute(name);
|
|
1070
1349
|
}
|
|
1071
|
-
const
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
if (previousHas) {
|
|
1093
|
-
if (!currentPropertyNames.has(name)
|
|
1094
|
-
|| current.style.getPropertyValue(name) !== previousValue
|
|
1095
|
-
|| current.style.getPropertyPriority(name) !== previousPriority) {
|
|
1350
|
+
const resumeDatePickerPadding = datePickerRowPaddingPatches.get(current)?.();
|
|
1351
|
+
try {
|
|
1352
|
+
const previousPropertyNames = stylePropertyNames(previous.style);
|
|
1353
|
+
const desiredPropertyNames = stylePropertyNames(desired.style);
|
|
1354
|
+
const propertyNames = new Set([
|
|
1355
|
+
...previousPropertyNames,
|
|
1356
|
+
...desiredPropertyNames,
|
|
1357
|
+
]);
|
|
1358
|
+
const currentPropertyNames = stylePropertyNames(current.style);
|
|
1359
|
+
for (const name of propertyNames) {
|
|
1360
|
+
if (layoutStyleProperties.has(name))
|
|
1361
|
+
continue;
|
|
1362
|
+
const previousHas = previousPropertyNames.has(name);
|
|
1363
|
+
const desiredHas = desiredPropertyNames.has(name);
|
|
1364
|
+
const previousValue = previous.style.getPropertyValue(name);
|
|
1365
|
+
const desiredValue = desired.style.getPropertyValue(name);
|
|
1366
|
+
const previousPriority = previous.style.getPropertyPriority(name);
|
|
1367
|
+
const desiredPriority = desired.style.getPropertyPriority(name);
|
|
1368
|
+
if (previousHas === desiredHas
|
|
1369
|
+
&& previousValue === desiredValue
|
|
1370
|
+
&& previousPriority === desiredPriority) {
|
|
1096
1371
|
continue;
|
|
1097
1372
|
}
|
|
1373
|
+
if (previousHas) {
|
|
1374
|
+
if (!currentPropertyNames.has(name)
|
|
1375
|
+
|| current.style.getPropertyValue(name) !== previousValue
|
|
1376
|
+
|| current.style.getPropertyPriority(name) !== previousPriority) {
|
|
1377
|
+
continue;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
else if (currentPropertyNames.has(name)) {
|
|
1381
|
+
continue;
|
|
1382
|
+
}
|
|
1383
|
+
if (desiredHas) {
|
|
1384
|
+
current.style.setProperty(name, desiredValue, desiredPriority);
|
|
1385
|
+
}
|
|
1386
|
+
else {
|
|
1387
|
+
current.style.removeProperty(name);
|
|
1388
|
+
}
|
|
1098
1389
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
if (desiredHas) {
|
|
1103
|
-
current.style.setProperty(name, desiredValue, desiredPriority);
|
|
1104
|
-
}
|
|
1105
|
-
else {
|
|
1106
|
-
current.style.removeProperty(name);
|
|
1107
|
-
}
|
|
1390
|
+
}
|
|
1391
|
+
finally {
|
|
1392
|
+
resumeDatePickerPadding?.();
|
|
1108
1393
|
}
|
|
1109
1394
|
}
|
|
1110
1395
|
/** Release slot-owned item listeners within a disposed subtree. */
|
|
@@ -1391,15 +1676,29 @@ function renderHorizontalScrollSlot(container, children, slotContent, renderChil
|
|
|
1391
1676
|
e.preventDefault();
|
|
1392
1677
|
track.scrollLeft = scrollLeft - (e.pageX - startX);
|
|
1393
1678
|
};
|
|
1394
|
-
const
|
|
1679
|
+
const cancelDrag = () => {
|
|
1395
1680
|
if (!isDragging)
|
|
1396
1681
|
return;
|
|
1397
1682
|
isDragging = false;
|
|
1398
1683
|
track.style.cursor = 'grab';
|
|
1399
1684
|
track.style.removeProperty('user-select');
|
|
1685
|
+
};
|
|
1686
|
+
const stopDrag = () => {
|
|
1687
|
+
if (!isDragging)
|
|
1688
|
+
return;
|
|
1689
|
+
cancelDrag();
|
|
1400
1690
|
if (snap)
|
|
1401
1691
|
track.style.scrollSnapType = 'x mandatory';
|
|
1402
1692
|
};
|
|
1693
|
+
// Leave snap suspended on disable so the viewport does not jump. The next
|
|
1694
|
+
// normal drag/wheel completion restores it.
|
|
1695
|
+
ownerCleanup.add(registerCardDisableCleanup(track, () => {
|
|
1696
|
+
cancelDrag();
|
|
1697
|
+
if (wheelTimer) {
|
|
1698
|
+
window.clearTimeout(wheelTimer);
|
|
1699
|
+
wheelTimer = 0;
|
|
1700
|
+
}
|
|
1701
|
+
}));
|
|
1403
1702
|
addSlotOwnerListener(ownerCleanup, track, 'mousedown', handleMouseDown);
|
|
1404
1703
|
addSlotOwnerListener(ownerCleanup, track, 'mousemove', handleMouseMove);
|
|
1405
1704
|
addSlotOwnerListener(ownerCleanup, track, 'mouseup', stopDrag);
|
|
@@ -1963,6 +2262,7 @@ function renderCarouselSlot(container, children, _slotContent, props, renderChil
|
|
|
1963
2262
|
let isDragging = false;
|
|
1964
2263
|
let startX = 0;
|
|
1965
2264
|
let scrollStart = 0;
|
|
2265
|
+
let wheelTimer = 0;
|
|
1966
2266
|
const handleMouseDown = (event) => {
|
|
1967
2267
|
if (ownerDisposed)
|
|
1968
2268
|
return;
|
|
@@ -1993,12 +2293,46 @@ function renderCarouselSlot(container, children, _slotContent, props, renderChil
|
|
|
1993
2293
|
if (!ownerDisposed)
|
|
1994
2294
|
snapToNearest();
|
|
1995
2295
|
};
|
|
2296
|
+
ownerCleanup.add(registerCardDisableCleanup(container, () => {
|
|
2297
|
+
if (isDragging) {
|
|
2298
|
+
isDragging = false;
|
|
2299
|
+
container.style.cursor = 'grab';
|
|
2300
|
+
}
|
|
2301
|
+
if (wheelTimer) {
|
|
2302
|
+
window.clearTimeout(wheelTimer);
|
|
2303
|
+
wheelTimer = 0;
|
|
2304
|
+
}
|
|
2305
|
+
const wasSnapping = pendingSnapScrollEnd !== null || pendingSnapTimer !== 0;
|
|
2306
|
+
clearPendingSnap();
|
|
2307
|
+
// Cancel the browser's in-flight animation as well as its completion callbacks.
|
|
2308
|
+
// The next normal interaction restores snap through snapToNearest.
|
|
2309
|
+
if (wasSnapping) {
|
|
2310
|
+
const left = container.scrollLeft;
|
|
2311
|
+
const overflowX = container.style.getPropertyValue('overflow-x');
|
|
2312
|
+
const priority = container.style.getPropertyPriority('overflow-x');
|
|
2313
|
+
// Safari can deliver a stale compositor frame after scrollTo('instant').
|
|
2314
|
+
// Flush the scroll-container change synchronously so no delayed correction
|
|
2315
|
+
// can overwrite a fresh gesture or API navigation after re-enabling.
|
|
2316
|
+
container.style.setProperty('overflow-x', 'hidden', 'important');
|
|
2317
|
+
try {
|
|
2318
|
+
void container.offsetWidth;
|
|
2319
|
+
container.scrollTo({ left, behavior: 'instant' });
|
|
2320
|
+
}
|
|
2321
|
+
finally {
|
|
2322
|
+
if (overflowX)
|
|
2323
|
+
container.style.setProperty('overflow-x', overflowX, priority);
|
|
2324
|
+
else
|
|
2325
|
+
container.style.removeProperty('overflow-x');
|
|
2326
|
+
}
|
|
2327
|
+
void container.offsetWidth;
|
|
2328
|
+
container.scrollTo({ left, behavior: 'instant' });
|
|
2329
|
+
}
|
|
2330
|
+
}));
|
|
1996
2331
|
addSlotOwnerListener(ownerCleanup, container, 'mousedown', handleMouseDown);
|
|
1997
2332
|
addSlotOwnerListener(ownerCleanup, document, 'mousemove', handleMouseMove);
|
|
1998
2333
|
addSlotOwnerListener(ownerCleanup, document, 'mouseup', handleMouseUp);
|
|
1999
2334
|
addSlotOwnerListener(ownerCleanup, container, 'touchend', handleTouchEnd, { passive: true });
|
|
2000
2335
|
// Wheel support
|
|
2001
|
-
let wheelTimer = 0;
|
|
2002
2336
|
const handleWheel = (event) => {
|
|
2003
2337
|
if (ownerDisposed)
|
|
2004
2338
|
return;
|
|
@@ -2396,6 +2730,8 @@ class BaseElement extends HTMLElement {
|
|
|
2396
2730
|
this._responsive = createResponsiveContext(this._isMobile, this._responsiveOptions);
|
|
2397
2731
|
this.render();
|
|
2398
2732
|
}
|
|
2733
|
+
/** @internal Close temporary interaction UI without clearing component values. */
|
|
2734
|
+
closeTransientUI() { }
|
|
2399
2735
|
// ─── Helpers ────────────────────────────────────────────────
|
|
2400
2736
|
/** Convert any content value to a safe display string. */
|
|
2401
2737
|
resolveContent(content) {
|
|
@@ -3856,7 +4192,8 @@ class CardInput extends BaseElement {
|
|
|
3856
4192
|
requestAutoFocus() {
|
|
3857
4193
|
if (!this.isConnected
|
|
3858
4194
|
|| !this._props.autoFocus
|
|
3859
|
-
|| this.hasAttribute('data-disabled')
|
|
4195
|
+
|| this.hasAttribute('data-disabled')
|
|
4196
|
+
|| isCardDisabled(this)) {
|
|
3860
4197
|
return false;
|
|
3861
4198
|
}
|
|
3862
4199
|
const control = this.shadowRoot?.querySelector('.card-input');
|
|
@@ -4182,6 +4519,10 @@ class CardImage extends BaseElement {
|
|
|
4182
4519
|
document.body.style.overflow = '';
|
|
4183
4520
|
document.removeEventListener('keydown', this._handleEscape);
|
|
4184
4521
|
}
|
|
4522
|
+
closeTransientUI() {
|
|
4523
|
+
if (this._lightbox?.classList.contains('open'))
|
|
4524
|
+
this.closeLightbox(this._lightbox);
|
|
4525
|
+
}
|
|
4185
4526
|
disconnectedCallback() {
|
|
4186
4527
|
// Ensure body overflow is restored when element is removed
|
|
4187
4528
|
document.body.style.overflow = '';
|
|
@@ -5118,6 +5459,9 @@ class CardSelect extends BaseElement {
|
|
|
5118
5459
|
});
|
|
5119
5460
|
});
|
|
5120
5461
|
}
|
|
5462
|
+
closeTransientUI() {
|
|
5463
|
+
this._setOpen(false);
|
|
5464
|
+
}
|
|
5121
5465
|
disconnectedCallback() {
|
|
5122
5466
|
document.removeEventListener('click', this._onDocClick);
|
|
5123
5467
|
}
|
|
@@ -7222,17 +7566,85 @@ const CHEVRON_ICON = `
|
|
|
7222
7566
|
<svg viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
7223
7567
|
<path d="M2.5 4.5L6 8l3.5-3.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>
|
|
7224
7568
|
</svg>`;
|
|
7569
|
+
// Opening another picker starts before the document click closes the first one.
|
|
7570
|
+
// Share the row reservation so that this overlap cannot accumulate padding.
|
|
7571
|
+
const mobilePanelRows = new WeakMap();
|
|
7572
|
+
function updateRowSpace(row, space) {
|
|
7573
|
+
// Preserve host style changes made while the calendar owns extra padding.
|
|
7574
|
+
const padding = row.style.getPropertyValue('padding-bottom');
|
|
7575
|
+
const priority = row.style.getPropertyPriority('padding-bottom');
|
|
7576
|
+
if (padding !== space.appliedPaddingBottom || priority !== space.priority) {
|
|
7577
|
+
space.paddingBottom = padding;
|
|
7578
|
+
space.priority = priority;
|
|
7579
|
+
space.basePaddingBottom = padding || getComputedStyle(row).paddingBottom;
|
|
7580
|
+
}
|
|
7581
|
+
if (space.panels.size) {
|
|
7582
|
+
const height = Math.max(...space.panels.values());
|
|
7583
|
+
row.style.setProperty('padding-bottom', `calc(${space.basePaddingBottom} + ${height}px)`, space.priority);
|
|
7584
|
+
}
|
|
7585
|
+
else {
|
|
7586
|
+
if (space.paddingBottom)
|
|
7587
|
+
row.style.setProperty('padding-bottom', space.paddingBottom, space.priority);
|
|
7588
|
+
else
|
|
7589
|
+
row.style.removeProperty('padding-bottom');
|
|
7590
|
+
mobilePanelRows.delete(row);
|
|
7591
|
+
space.releasePatch();
|
|
7592
|
+
}
|
|
7593
|
+
// CSSOM can simplify calc(); compare its serialized value on the next write.
|
|
7594
|
+
space.appliedPaddingBottom = row.style.getPropertyValue('padding-bottom');
|
|
7595
|
+
}
|
|
7225
7596
|
class CardDatePicker extends BaseElement {
|
|
7226
7597
|
constructor() {
|
|
7227
7598
|
super(...arguments);
|
|
7228
7599
|
this._open = false;
|
|
7229
7600
|
this._calendar = null;
|
|
7601
|
+
this._panelResizeObserver = null;
|
|
7602
|
+
this._mobilePanelRow = null;
|
|
7230
7603
|
/** Dates picked in the panel; shown until props.value changes externally. */
|
|
7231
7604
|
this._localValue = null;
|
|
7232
7605
|
this._onDocClick = (e) => {
|
|
7233
|
-
if (!
|
|
7606
|
+
if (!e.composedPath().includes(this))
|
|
7234
7607
|
this._setOpen(false);
|
|
7235
7608
|
};
|
|
7609
|
+
this._positionMobilePanel = () => {
|
|
7610
|
+
if (!this._isMobile || !this._open)
|
|
7611
|
+
return;
|
|
7612
|
+
const panel = this.shadowRoot?.querySelector('.panel');
|
|
7613
|
+
const calendar = panel?.querySelector('[data-vc="calendar"]');
|
|
7614
|
+
if (!panel || !calendar)
|
|
7615
|
+
return;
|
|
7616
|
+
this._panelResizeObserver?.observe(calendar);
|
|
7617
|
+
const row = this._mobilePanelRow;
|
|
7618
|
+
if (row) {
|
|
7619
|
+
const style = getComputedStyle(row);
|
|
7620
|
+
const contentBottom = row.getBoundingClientRect().bottom
|
|
7621
|
+
- parseFloat(style.paddingBottom) - parseFloat(style.borderBottomWidth);
|
|
7622
|
+
panel.style.top = `${contentBottom - this.getBoundingClientRect().top}px`;
|
|
7623
|
+
const space = mobilePanelRows.get(row);
|
|
7624
|
+
space.panels.set(this, calendar.getBoundingClientRect().bottom - contentBottom);
|
|
7625
|
+
updateRowSpace(row, space);
|
|
7626
|
+
}
|
|
7627
|
+
panel.style.left = '0px';
|
|
7628
|
+
const bounds = calendar.getBoundingClientRect();
|
|
7629
|
+
let left = 0;
|
|
7630
|
+
let right = document.documentElement.clientWidth;
|
|
7631
|
+
// Intersect clipping ancestors, crossing shadow roots when cards are embedded.
|
|
7632
|
+
let ancestor = this.shadowRoot.host;
|
|
7633
|
+
while (ancestor) {
|
|
7634
|
+
this._panelResizeObserver?.observe(ancestor);
|
|
7635
|
+
if (/^(auto|scroll|hidden|clip)$/.test(getComputedStyle(ancestor).overflowX)) {
|
|
7636
|
+
const rect = ancestor.getBoundingClientRect();
|
|
7637
|
+
const innerLeft = rect.left + ancestor.clientLeft;
|
|
7638
|
+
left = Math.max(left, innerLeft);
|
|
7639
|
+
right = Math.min(right, innerLeft + ancestor.clientWidth);
|
|
7640
|
+
}
|
|
7641
|
+
const root = ancestor.getRootNode();
|
|
7642
|
+
ancestor = ancestor.assignedSlot ?? ancestor.parentElement
|
|
7643
|
+
?? (root instanceof ShadowRoot ? root.host : null);
|
|
7644
|
+
}
|
|
7645
|
+
// Shift the panel without changing the trigger's intrinsic width.
|
|
7646
|
+
panel.style.left = `${Math.max(left, Math.min(bounds.left, right - bounds.width)) - bounds.left}px`;
|
|
7647
|
+
};
|
|
7236
7648
|
}
|
|
7237
7649
|
render() {
|
|
7238
7650
|
if (!this.shadowRoot || !this._node)
|
|
@@ -7333,8 +7745,11 @@ class CardDatePicker extends BaseElement {
|
|
|
7333
7745
|
.trigger-arrow.open { transform: rotate(180deg); }
|
|
7334
7746
|
.panel {
|
|
7335
7747
|
display: none;
|
|
7336
|
-
|
|
7337
|
-
|
|
7748
|
+
/* Column layouts include the calendar in flow. Horizontal flex rows
|
|
7749
|
+
reserve space below the whole row when the panel is mounted. */
|
|
7750
|
+
position: ${this._isMobile ? 'relative' : 'absolute'};
|
|
7751
|
+
${this._isMobile ? 'margin-top: 4px; contain: inline-size;' : ''}
|
|
7752
|
+
top: ${this._isMobile ? '0' : 'calc(100% + 4px)'};
|
|
7338
7753
|
left: 0;
|
|
7339
7754
|
z-index: 1000;
|
|
7340
7755
|
}
|
|
@@ -7386,6 +7801,9 @@ class CardDatePicker extends BaseElement {
|
|
|
7386
7801
|
this._destroyCalendar();
|
|
7387
7802
|
}
|
|
7388
7803
|
// ─── Private ────────────────────────────────────────────────
|
|
7804
|
+
closeTransientUI() {
|
|
7805
|
+
this._setOpen(false);
|
|
7806
|
+
}
|
|
7389
7807
|
_setOpen(open) {
|
|
7390
7808
|
if (this._open === open)
|
|
7391
7809
|
return;
|
|
@@ -7467,8 +7885,59 @@ class CardDatePicker extends BaseElement {
|
|
|
7467
7885
|
},
|
|
7468
7886
|
});
|
|
7469
7887
|
this._calendar.init();
|
|
7888
|
+
if (this._isMobile) {
|
|
7889
|
+
const row = this.parentElement;
|
|
7890
|
+
if (row && /^(inline-)?flex$/.test(getComputedStyle(row).display)
|
|
7891
|
+
&& /^row/.test(getComputedStyle(row).flexDirection)) {
|
|
7892
|
+
const panel = container.parentElement;
|
|
7893
|
+
panel.style.position = 'absolute';
|
|
7894
|
+
this._mobilePanelRow = row;
|
|
7895
|
+
if (!mobilePanelRows.has(row)) {
|
|
7896
|
+
const space = {
|
|
7897
|
+
paddingBottom: row.style.getPropertyValue('padding-bottom'),
|
|
7898
|
+
priority: row.style.getPropertyPriority('padding-bottom'),
|
|
7899
|
+
basePaddingBottom: row.style.paddingBottom || getComputedStyle(row).paddingBottom,
|
|
7900
|
+
appliedPaddingBottom: row.style.getPropertyValue('padding-bottom'),
|
|
7901
|
+
panels: new Map(),
|
|
7902
|
+
releasePatch: () => { },
|
|
7903
|
+
};
|
|
7904
|
+
mobilePanelRows.set(row, space);
|
|
7905
|
+
space.releasePatch = registerDatePickerRowPaddingPatch(row, () => {
|
|
7906
|
+
// Make the schema's baseline visible to the incremental style diff.
|
|
7907
|
+
// If a host already replaced our value, leave that external style.
|
|
7908
|
+
if (row.style.getPropertyValue('padding-bottom') === space.appliedPaddingBottom
|
|
7909
|
+
&& row.style.getPropertyPriority('padding-bottom') === space.priority) {
|
|
7910
|
+
if (space.paddingBottom)
|
|
7911
|
+
row.style.setProperty('padding-bottom', space.paddingBottom, space.priority);
|
|
7912
|
+
else
|
|
7913
|
+
row.style.removeProperty('padding-bottom');
|
|
7914
|
+
space.appliedPaddingBottom = row.style.getPropertyValue('padding-bottom');
|
|
7915
|
+
}
|
|
7916
|
+
return () => updateRowSpace(row, space);
|
|
7917
|
+
});
|
|
7918
|
+
}
|
|
7919
|
+
}
|
|
7920
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
7921
|
+
this._panelResizeObserver = new ResizeObserver(this._positionMobilePanel);
|
|
7922
|
+
}
|
|
7923
|
+
// Calendar navigation changes height synchronously, including browsers
|
|
7924
|
+
// without ResizeObserver. Run after the calendar's own click handler.
|
|
7925
|
+
container.parentElement.addEventListener('click', this._positionMobilePanel);
|
|
7926
|
+
window.addEventListener('resize', this._positionMobilePanel);
|
|
7927
|
+
this._positionMobilePanel();
|
|
7928
|
+
}
|
|
7470
7929
|
}
|
|
7471
7930
|
_destroyCalendar() {
|
|
7931
|
+
window.removeEventListener('resize', this._positionMobilePanel);
|
|
7932
|
+
this.shadowRoot?.querySelector('.panel')?.removeEventListener('click', this._positionMobilePanel);
|
|
7933
|
+
this._panelResizeObserver?.disconnect();
|
|
7934
|
+
this._panelResizeObserver = null;
|
|
7935
|
+
if (this._mobilePanelRow) {
|
|
7936
|
+
const space = mobilePanelRows.get(this._mobilePanelRow);
|
|
7937
|
+
space.panels.delete(this);
|
|
7938
|
+
updateRowSpace(this._mobilePanelRow, space);
|
|
7939
|
+
this._mobilePanelRow = null;
|
|
7940
|
+
}
|
|
7472
7941
|
if (this._calendar) {
|
|
7473
7942
|
this._calendar.destroy();
|
|
7474
7943
|
this._calendar = null;
|
|
@@ -8972,7 +9441,7 @@ function createCardNodeAccess(container) {
|
|
|
8972
9441
|
},
|
|
8973
9442
|
focus(options) {
|
|
8974
9443
|
const element = resolveElement(id);
|
|
8975
|
-
if (!element || element.hasAttribute('data-disabled'))
|
|
9444
|
+
if (!element || element.hasAttribute('data-disabled') || isCardDisabled(element))
|
|
8976
9445
|
return false;
|
|
8977
9446
|
const target = element.shadowRoot
|
|
8978
9447
|
?.querySelector(FOCUS_TARGET_SELECTOR) ?? element;
|
|
@@ -9192,40 +9661,6 @@ function createCardNodeAccess(container) {
|
|
|
9192
9661
|
};
|
|
9193
9662
|
}
|
|
9194
9663
|
|
|
9195
|
-
const DISABLED_MARKER = 'data-copilot-card-disabled';
|
|
9196
|
-
const DISABLED_STYLES_MARKER = 'data-copilot-card-disabled-styles';
|
|
9197
|
-
const DISABLED_PRESENTATION_CSS = `
|
|
9198
|
-
[${DISABLED_MARKER}="true"] {
|
|
9199
|
-
background-color: var(--card-disabled-background, #F5F5F5) !important;
|
|
9200
|
-
color: var(--card-disabled-foreground, #C0C0C0) !important;
|
|
9201
|
-
}
|
|
9202
|
-
`;
|
|
9203
|
-
function ensureDisabledPresentationStyles(ownerDocument) {
|
|
9204
|
-
if (ownerDocument.head.querySelector(`style[${DISABLED_STYLES_MARKER}]`)) {
|
|
9205
|
-
return;
|
|
9206
|
-
}
|
|
9207
|
-
const style = ownerDocument.createElement('style');
|
|
9208
|
-
style.setAttribute(DISABLED_STYLES_MARKER, '');
|
|
9209
|
-
style.textContent = DISABLED_PRESENTATION_CSS;
|
|
9210
|
-
ownerDocument.head.appendChild(style);
|
|
9211
|
-
}
|
|
9212
|
-
function applyDisabledState(element, disabled) {
|
|
9213
|
-
if (!disabled)
|
|
9214
|
-
return;
|
|
9215
|
-
ensureDisabledPresentationStyles(element.ownerDocument);
|
|
9216
|
-
element.setAttribute('data-disabled', 'true');
|
|
9217
|
-
element.setAttribute(DISABLED_MARKER, 'true');
|
|
9218
|
-
element.style.pointerEvents = 'none';
|
|
9219
|
-
element.style.cursor = 'default';
|
|
9220
|
-
}
|
|
9221
|
-
function applyDisabledDescendants(element, disabled) {
|
|
9222
|
-
if (!disabled)
|
|
9223
|
-
return;
|
|
9224
|
-
element.querySelectorAll('*').forEach((child) => {
|
|
9225
|
-
child.setAttribute('data-disabled', 'true');
|
|
9226
|
-
});
|
|
9227
|
-
}
|
|
9228
|
-
|
|
9229
9664
|
const FORCE_REPLACE = Symbol('bound-force-replace');
|
|
9230
9665
|
const REPEAT_APPEND = Symbol('bound-repeat-append');
|
|
9231
9666
|
/**
|
|
@@ -9479,6 +9914,7 @@ function renderBoundCard(container, schema, options) {
|
|
|
9479
9914
|
},
|
|
9480
9915
|
events,
|
|
9481
9916
|
isActive: () => (!disposed
|
|
9917
|
+
&& !cardDisabled.isDisabled
|
|
9482
9918
|
&& !publishing
|
|
9483
9919
|
&& container.contains(element)),
|
|
9484
9920
|
});
|
|
@@ -9982,7 +10418,12 @@ function renderBoundCard(container, schema, options) {
|
|
|
9982
10418
|
try {
|
|
9983
10419
|
for (const [occurrenceKey, plan] of appendPlans) {
|
|
9984
10420
|
const prepared = findPreparedByOccurrenceKey(preparedRoot, occurrenceKey);
|
|
9985
|
-
|
|
10421
|
+
// Hidden or force-replaced ancestors prune their descendants from the
|
|
10422
|
+
// prepared tree. Their normal replacement commits the new variables;
|
|
10423
|
+
// there is no live descendant append to prepare in this transaction.
|
|
10424
|
+
if (!prepared)
|
|
10425
|
+
continue;
|
|
10426
|
+
if (!prepared[REPEAT_APPEND]) {
|
|
9986
10427
|
throw new Error(`[renderCard] Missing prepared repeat append owner "${occurrenceKey}"`);
|
|
9987
10428
|
}
|
|
9988
10429
|
const nextOccurrenceKeys = occurrenceKeysForChildren(plan.current.occurrenceKey, plan.nextNode.children);
|
|
@@ -10463,7 +10904,7 @@ function renderBoundCard(container, schema, options) {
|
|
|
10463
10904
|
error.failures = failures;
|
|
10464
10905
|
return error;
|
|
10465
10906
|
}
|
|
10466
|
-
function
|
|
10907
|
+
function commitIncrementalCandidateContent(candidate, renderVariables) {
|
|
10467
10908
|
const replacements = candidate.replacementRoots;
|
|
10468
10909
|
try {
|
|
10469
10910
|
if (!currentMountedTree) {
|
|
@@ -10655,6 +11096,9 @@ function renderBoundCard(container, schema, options) {
|
|
|
10655
11096
|
disposeCandidate(candidate);
|
|
10656
11097
|
}
|
|
10657
11098
|
}
|
|
11099
|
+
function commitIncrementalCandidate(candidate, renderVariables) {
|
|
11100
|
+
return cardDisabled.update(() => commitIncrementalCandidateContent(candidate, renderVariables));
|
|
11101
|
+
}
|
|
10658
11102
|
function assertCurrentRevision(baseRevision) {
|
|
10659
11103
|
if (disposed || publishing || revision !== baseRevision) {
|
|
10660
11104
|
const error = new Error('[renderCard] BOUND_TRANSACTION_CONFLICT');
|
|
@@ -10662,7 +11106,7 @@ function renderBoundCard(container, schema, options) {
|
|
|
10662
11106
|
throw error;
|
|
10663
11107
|
}
|
|
10664
11108
|
}
|
|
10665
|
-
function
|
|
11109
|
+
function commitDraftContent(before, draft, baseRevision) {
|
|
10666
11110
|
assertCurrentRevision(baseRevision);
|
|
10667
11111
|
const validationRoot = cloneJsonData(variables);
|
|
10668
11112
|
replaceRootContents(validationRoot, draft);
|
|
@@ -10716,6 +11160,9 @@ function renderBoundCard(container, schema, options) {
|
|
|
10716
11160
|
reconcileLifecycles(selectLifecycleNodes(currentMaterialized, collectMountedLifecycleIds(currentMountedTree)));
|
|
10717
11161
|
applyAutoFocus(candidate);
|
|
10718
11162
|
}
|
|
11163
|
+
function commitDraft(before, draft, baseRevision) {
|
|
11164
|
+
return cardDisabled.update(() => commitDraftContent(before, draft, baseRevision));
|
|
11165
|
+
}
|
|
10719
11166
|
function writeDraftVariable(draft, key, value) {
|
|
10720
11167
|
Object.defineProperty(draft, String(key), {
|
|
10721
11168
|
value,
|
|
@@ -10772,7 +11219,7 @@ function renderBoundCard(container, schema, options) {
|
|
|
10772
11219
|
};
|
|
10773
11220
|
}
|
|
10774
11221
|
async function runBoundEvent(runtimeId, eventName, eventDetail, baseRevision, repeatTargetFingerprint) {
|
|
10775
|
-
if (disposed)
|
|
11222
|
+
if (disposed || cardDisabled.isDisabled)
|
|
10776
11223
|
return;
|
|
10777
11224
|
assertCurrentRevision(baseRevision);
|
|
10778
11225
|
const transactionBefore = cloneJsonData(variables);
|
|
@@ -10808,13 +11255,14 @@ function renderBoundCard(container, schema, options) {
|
|
|
10808
11255
|
commitDraft(cloneJsonData(lastPublishedVariables), draft, baseRevision);
|
|
10809
11256
|
}
|
|
10810
11257
|
function enqueueBoundEvent(runtimeId, eventName, eventDetail, repeatTargetFingerprint) {
|
|
10811
|
-
if (disposed)
|
|
11258
|
+
if (disposed || cardDisabled.isDisabled)
|
|
10812
11259
|
return;
|
|
11260
|
+
const interactionEpoch = cardDisabled.epoch;
|
|
10813
11261
|
const enqueueRevision = revision;
|
|
10814
11262
|
const queuedBehindAnotherAction = queuedActionCount > 0;
|
|
10815
11263
|
queuedActionCount += 1;
|
|
10816
11264
|
actionQueue = actionQueue
|
|
10817
|
-
.then(() => runBoundEvent(runtimeId, eventName, eventDetail, queuedBehindAnotherAction ? revision : enqueueRevision, repeatTargetFingerprint))
|
|
11265
|
+
.then(() => interactionEpoch === cardDisabled.epoch ? runBoundEvent(runtimeId, eventName, eventDetail, queuedBehindAnotherAction ? revision : enqueueRevision, repeatTargetFingerprint) : undefined)
|
|
10818
11266
|
.catch((error) => {
|
|
10819
11267
|
if (error
|
|
10820
11268
|
&& typeof error === 'object'
|
|
@@ -10846,6 +11294,7 @@ function renderBoundCard(container, schema, options) {
|
|
|
10846
11294
|
disposed = true;
|
|
10847
11295
|
disposeRequested = false;
|
|
10848
11296
|
nodeAccess.dispose();
|
|
11297
|
+
cardDisabled.dispose();
|
|
10849
11298
|
abortController.abort();
|
|
10850
11299
|
if (currentMountedTree) {
|
|
10851
11300
|
disposeBoundSubtree(currentMountedTree);
|
|
@@ -10883,17 +11332,26 @@ function renderBoundCard(container, schema, options) {
|
|
|
10883
11332
|
console.error('[renderCard] Bound lifecycle dispose failed', error);
|
|
10884
11333
|
});
|
|
10885
11334
|
}
|
|
10886
|
-
const
|
|
10887
|
-
publishing = true;
|
|
11335
|
+
const cardDisabled = createCardDisabledController(container, options.disabled);
|
|
10888
11336
|
try {
|
|
10889
|
-
|
|
10890
|
-
|
|
11337
|
+
const initialCandidate = prepareIncrementalCandidate(variables, variables);
|
|
11338
|
+
publishing = true;
|
|
11339
|
+
try {
|
|
11340
|
+
currentMountedTree = commitIncrementalCandidate(initialCandidate, variables);
|
|
11341
|
+
currentMaterialized = materializeCard(schema, variables);
|
|
11342
|
+
}
|
|
11343
|
+
finally {
|
|
11344
|
+
publishing = false;
|
|
11345
|
+
}
|
|
11346
|
+
reconcileLifecycles(selectLifecycleNodes(currentMaterialized, collectMountedLifecycleIds(currentMountedTree)));
|
|
10891
11347
|
}
|
|
10892
|
-
|
|
10893
|
-
|
|
11348
|
+
catch (error) {
|
|
11349
|
+
nodeAccess.dispose();
|
|
11350
|
+
cardDisabled.dispose();
|
|
11351
|
+
throw error;
|
|
10894
11352
|
}
|
|
10895
|
-
reconcileLifecycles(selectLifecycleNodes(currentMaterialized, collectMountedLifecycleIds(currentMountedTree)));
|
|
10896
11353
|
return {
|
|
11354
|
+
setDisabled: cardDisabled.setDisabled,
|
|
10897
11355
|
getNode: nodeAccess.getNode,
|
|
10898
11356
|
onFocusChange: nodeAccess.onFocusChange,
|
|
10899
11357
|
onScroll: nodeAccess.onScroll,
|
|
@@ -11261,7 +11719,7 @@ function renderStaticCard(container, schema, options) {
|
|
|
11261
11719
|
};
|
|
11262
11720
|
}
|
|
11263
11721
|
function runStaticEventActions(steps, detail) {
|
|
11264
|
-
if (disposed)
|
|
11722
|
+
if (disposed || cardDisabled.isDisabled)
|
|
11265
11723
|
return;
|
|
11266
11724
|
if (detail != null)
|
|
11267
11725
|
variables._event = detail;
|
|
@@ -11400,6 +11858,7 @@ function renderStaticCard(container, schema, options) {
|
|
|
11400
11858
|
},
|
|
11401
11859
|
events: resolvedEventBindings,
|
|
11402
11860
|
isActive: () => (!disposed
|
|
11861
|
+
&& !cardDisabled.isDisabled
|
|
11403
11862
|
&& !publishing
|
|
11404
11863
|
&& container.contains(element)),
|
|
11405
11864
|
});
|
|
@@ -11598,7 +12057,7 @@ function renderStaticCard(container, schema, options) {
|
|
|
11598
12057
|
}
|
|
11599
12058
|
}
|
|
11600
12059
|
}
|
|
11601
|
-
function
|
|
12060
|
+
function renderContent() {
|
|
11602
12061
|
if (disposed)
|
|
11603
12062
|
return;
|
|
11604
12063
|
const generation = ++renderGeneration;
|
|
@@ -11692,6 +12151,9 @@ function renderStaticCard(container, schema, options) {
|
|
|
11692
12151
|
startLifecycleMount(id, lifecycle);
|
|
11693
12152
|
}
|
|
11694
12153
|
}
|
|
12154
|
+
function render() {
|
|
12155
|
+
return cardDisabled.update(() => renderContent());
|
|
12156
|
+
}
|
|
11695
12157
|
function rerender() {
|
|
11696
12158
|
if (disposed)
|
|
11697
12159
|
return;
|
|
@@ -11705,6 +12167,7 @@ function renderStaticCard(container, schema, options) {
|
|
|
11705
12167
|
disposeRequested = false;
|
|
11706
12168
|
hostAuthorityEpoch += 1;
|
|
11707
12169
|
nodeAccess.dispose();
|
|
12170
|
+
cardDisabled.dispose();
|
|
11708
12171
|
abortController.abort();
|
|
11709
12172
|
if (mountedTree) {
|
|
11710
12173
|
disposeStaticSubtree(mountedTree);
|
|
@@ -11718,9 +12181,18 @@ function renderStaticCard(container, schema, options) {
|
|
|
11718
12181
|
destroyLifecycle(record);
|
|
11719
12182
|
}
|
|
11720
12183
|
// 7. Initial render
|
|
11721
|
-
|
|
12184
|
+
const cardDisabled = createCardDisabledController(container, options.disabled);
|
|
12185
|
+
try {
|
|
12186
|
+
render();
|
|
12187
|
+
}
|
|
12188
|
+
catch (error) {
|
|
12189
|
+
nodeAccess.dispose();
|
|
12190
|
+
cardDisabled.dispose();
|
|
12191
|
+
throw error;
|
|
12192
|
+
}
|
|
11722
12193
|
// 8. Return instance handle
|
|
11723
12194
|
return {
|
|
12195
|
+
setDisabled: cardDisabled.setDisabled,
|
|
11724
12196
|
getNode: nodeAccess.getNode,
|
|
11725
12197
|
onFocusChange: nodeAccess.onFocusChange,
|
|
11726
12198
|
onScroll: nodeAccess.onScroll,
|
|
@@ -12101,6 +12573,8 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12101
12573
|
const variableKey = resolvedProps.variableKey;
|
|
12102
12574
|
if (variableKey) {
|
|
12103
12575
|
element.addEventListener('input', ((event) => {
|
|
12576
|
+
if (disposed || cardDisabled.isDisabled || !container.contains(element))
|
|
12577
|
+
return;
|
|
12104
12578
|
if (event.target !== element || !currentMaterialized)
|
|
12105
12579
|
return;
|
|
12106
12580
|
const value = event.detail?.value
|
|
@@ -12116,6 +12590,8 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12116
12590
|
}
|
|
12117
12591
|
const domEvent = eventMap[eventName] ?? eventName;
|
|
12118
12592
|
element.addEventListener(domEvent, ((event) => {
|
|
12593
|
+
if (disposed || cardDisabled.isDisabled || !container.contains(element))
|
|
12594
|
+
return;
|
|
12119
12595
|
const ownsValueEvent = ((domEvent === 'input' || domEvent === 'change')
|
|
12120
12596
|
&& valueControlTypes.has(node.type));
|
|
12121
12597
|
if (ownsValueEvent && event.target !== element)
|
|
@@ -12184,6 +12660,8 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12184
12660
|
const variableKey = resolvedProps.variableKey;
|
|
12185
12661
|
if (variableKey) {
|
|
12186
12662
|
el.addEventListener('input', ((e) => {
|
|
12663
|
+
if (disposed || cardDisabled.isDisabled || !container.contains(el))
|
|
12664
|
+
return;
|
|
12187
12665
|
const value = e.detail?.value
|
|
12188
12666
|
?? e.target?.value;
|
|
12189
12667
|
if (value !== undefined) {
|
|
@@ -12202,6 +12680,8 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12202
12680
|
continue;
|
|
12203
12681
|
const domEvent = eventMap[event] ?? event;
|
|
12204
12682
|
el.addEventListener(domEvent, ((e) => {
|
|
12683
|
+
if (disposed || cardDisabled.isDisabled || !container.contains(el))
|
|
12684
|
+
return;
|
|
12205
12685
|
if (e instanceof CustomEvent && e.detail != null) {
|
|
12206
12686
|
variables._event = e.detail;
|
|
12207
12687
|
}
|
|
@@ -12385,7 +12865,7 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12385
12865
|
* (visibility flips / container shape changes) re-render only their subtree.
|
|
12386
12866
|
* Falls back to a full render solely when a subtree can't be rebuilt.
|
|
12387
12867
|
*/
|
|
12388
|
-
function
|
|
12868
|
+
function diffAllElementsContent(previousVariables) {
|
|
12389
12869
|
actionContext = buildActionContext();
|
|
12390
12870
|
const schema = (currentSurfaceId ? engine.getSchema(currentSurfaceId) : undefined) ?? currentSchema;
|
|
12391
12871
|
if (!schema)
|
|
@@ -12425,6 +12905,8 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12425
12905
|
continue;
|
|
12426
12906
|
if ('updateProps' in el) {
|
|
12427
12907
|
el.updateProps(resolved, isMobile, options.responsive);
|
|
12908
|
+
// Some components replace host cssText while updating their props.
|
|
12909
|
+
applyDisabledState(el, wasDisabled);
|
|
12428
12910
|
propsCache.set(id, key);
|
|
12429
12911
|
}
|
|
12430
12912
|
else if (!replaceSubtree(schema, id, el)) {
|
|
@@ -12435,6 +12917,9 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12435
12917
|
}
|
|
12436
12918
|
applyAutoFocusIds(autoFocusIds);
|
|
12437
12919
|
}
|
|
12920
|
+
function diffAllElements(previousVariables) {
|
|
12921
|
+
return cardDisabled.update(() => diffAllElementsContent(previousVariables));
|
|
12922
|
+
}
|
|
12438
12923
|
function captureBoundScrollPositions(root) {
|
|
12439
12924
|
const positions = new Map();
|
|
12440
12925
|
root.querySelectorAll('[data-scroll-id]').forEach((element) => {
|
|
@@ -12785,7 +13270,7 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12785
13270
|
throw error;
|
|
12786
13271
|
}
|
|
12787
13272
|
}
|
|
12788
|
-
function
|
|
13273
|
+
function commitBoundFullContent(prepared, schema, draft, baseRevision, commitAuthoritativeVariables) {
|
|
12789
13274
|
assertBoundRevision(baseRevision);
|
|
12790
13275
|
commitAuthoritativeVariables?.();
|
|
12791
13276
|
replaceRootContents(variables, draft);
|
|
@@ -12807,6 +13292,9 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12807
13292
|
restoreBoundScrollPositions(container, scrollPositions);
|
|
12808
13293
|
restoreBoundMediaStates(container, mediaStates);
|
|
12809
13294
|
}
|
|
13295
|
+
function commitBoundFull(prepared, schema, draft, baseRevision, commitAuthoritativeVariables) {
|
|
13296
|
+
return cardDisabled.update(() => commitBoundFullContent(prepared, schema, draft, baseRevision, commitAuthoritativeVariables));
|
|
13297
|
+
}
|
|
12810
13298
|
function ownerKeysWithoutNestedDuplicates(materialized, owners) {
|
|
12811
13299
|
const selected = new Set(owners.map(owner => owner.key));
|
|
12812
13300
|
return owners.filter((owner) => {
|
|
@@ -12926,7 +13414,7 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12926
13414
|
replacedLifecycleIds,
|
|
12927
13415
|
};
|
|
12928
13416
|
}
|
|
12929
|
-
function
|
|
13417
|
+
function commitBoundIncrementalContent(prepared, schema, draft, baseRevision, commitAuthoritativeVariables) {
|
|
12930
13418
|
assertBoundRevision(baseRevision);
|
|
12931
13419
|
commitAuthoritativeVariables?.();
|
|
12932
13420
|
replaceRootContents(variables, draft);
|
|
@@ -12957,6 +13445,9 @@ function renderStreamingCard(container, options = {}) {
|
|
|
12957
13445
|
restoreBoundScrollPositions(container, scrollPositions);
|
|
12958
13446
|
restoreBoundMediaStates(container, mediaStates);
|
|
12959
13447
|
}
|
|
13448
|
+
function commitBoundIncremental(prepared, schema, draft, baseRevision, commitAuthoritativeVariables) {
|
|
13449
|
+
return cardDisabled.update(() => commitBoundIncrementalContent(prepared, schema, draft, baseRevision, commitAuthoritativeVariables));
|
|
13450
|
+
}
|
|
12960
13451
|
function prepareAndCommitBoundUpdate(schema, draft, owners, baseRevision, commitAuthoritativeVariables, changedSourceIds = new Set()) {
|
|
12961
13452
|
try {
|
|
12962
13453
|
const prepared = prepareBoundIncremental(schema, draft, owners, changedSourceIds);
|
|
@@ -13136,6 +13627,8 @@ function renderStreamingCard(container, options = {}) {
|
|
|
13136
13627
|
prepareAndCommitBoundUpdate(schema, draft, owners, baseRevision, commitAuthoritative);
|
|
13137
13628
|
}
|
|
13138
13629
|
async function runBoundEvent(runtimeId, eventName, eventDetail) {
|
|
13630
|
+
if (disposed || cardDisabled.isDisabled)
|
|
13631
|
+
return;
|
|
13139
13632
|
if (!currentMaterialized || !currentSchema || !currentSurfaceId)
|
|
13140
13633
|
return;
|
|
13141
13634
|
const baseRevision = boundRevision;
|
|
@@ -13162,8 +13655,12 @@ function renderStreamingCard(container, options = {}) {
|
|
|
13162
13655
|
applyAutoFocusIds(autoFocusIds);
|
|
13163
13656
|
}
|
|
13164
13657
|
function enqueueBoundEvent(runtimeId, eventName, eventDetail) {
|
|
13658
|
+
if (disposed || cardDisabled.isDisabled)
|
|
13659
|
+
return;
|
|
13660
|
+
const interactionEpoch = cardDisabled.epoch;
|
|
13165
13661
|
boundActionQueue = boundActionQueue
|
|
13166
|
-
.then(() =>
|
|
13662
|
+
.then(() => interactionEpoch === cardDisabled.epoch
|
|
13663
|
+
? runBoundEvent(runtimeId, eventName, eventDetail) : undefined)
|
|
13167
13664
|
.catch((error) => {
|
|
13168
13665
|
if (error
|
|
13169
13666
|
&& typeof error === 'object'
|
|
@@ -13338,7 +13835,7 @@ function renderStreamingCard(container, options = {}) {
|
|
|
13338
13835
|
* assigned on createSurface — so newly added components would not render and text
|
|
13339
13836
|
* appended via appendContent would be wiped on the next full re-render.
|
|
13340
13837
|
*/
|
|
13341
|
-
function
|
|
13838
|
+
function renderFullContent() {
|
|
13342
13839
|
const engineSchema = currentSurfaceId ? engine.getSchema(currentSurfaceId) : undefined;
|
|
13343
13840
|
const schema = engineSchema ?? currentSchema;
|
|
13344
13841
|
if (!schema)
|
|
@@ -13365,6 +13862,9 @@ function renderStreamingCard(container, options = {}) {
|
|
|
13365
13862
|
const dom = renderNode(tree);
|
|
13366
13863
|
container.appendChild(dom);
|
|
13367
13864
|
}
|
|
13865
|
+
function renderFull() {
|
|
13866
|
+
return cardDisabled.update(() => renderFullContent());
|
|
13867
|
+
}
|
|
13368
13868
|
/**
|
|
13369
13869
|
* Full render that tolerates mid-stream schemas (e.g. children referencing
|
|
13370
13870
|
* elements that have not arrived yet): keeps the previous DOM on failure so
|
|
@@ -13381,7 +13881,7 @@ function renderStreamingCard(container, options = {}) {
|
|
|
13381
13881
|
}
|
|
13382
13882
|
}
|
|
13383
13883
|
// ─── Engine Event Handlers ──────────────────────────────────────
|
|
13384
|
-
const
|
|
13884
|
+
const engineEvents = {
|
|
13385
13885
|
onSurfaceCreated(surfaceId, schemaInput) {
|
|
13386
13886
|
if (schemaInput) {
|
|
13387
13887
|
const nextSchema = engine.getSchema(surfaceId)
|
|
@@ -13596,6 +14096,7 @@ function renderStreamingCard(container, options = {}) {
|
|
|
13596
14096
|
const typeChanged = el.getAttribute('data-card-type') !== element.type;
|
|
13597
14097
|
if (!typeChanged && 'updateProps' in el) {
|
|
13598
14098
|
el.updateProps(resolved, isMobile, options.responsive);
|
|
14099
|
+
applyDisabledState(el, wasDisabled);
|
|
13599
14100
|
propsCache.set(id, key);
|
|
13600
14101
|
}
|
|
13601
14102
|
else if (!typeChanged && isChildrenOnlyChange(propsCache.get(id), key, element)) {
|
|
@@ -13746,9 +14247,18 @@ function renderStreamingCard(container, options = {}) {
|
|
|
13746
14247
|
boundRevision += 1;
|
|
13747
14248
|
lifecycleManager.dispose(actionContext);
|
|
13748
14249
|
},
|
|
14250
|
+
};
|
|
14251
|
+
const engine = new StreamingEngine({
|
|
14252
|
+
onSurfaceCreated: (...args) => cardDisabled.update(() => engineEvents.onSurfaceCreated?.(...args)),
|
|
14253
|
+
onComponentsUpdated: (...args) => cardDisabled.update(() => engineEvents.onComponentsUpdated?.(...args)),
|
|
14254
|
+
onDataModelUpdated: (...args) => cardDisabled.update(() => engineEvents.onDataModelUpdated?.(...args)),
|
|
14255
|
+
onContentAppended: (...args) => cardDisabled.update(() => engineEvents.onContentAppended?.(...args)),
|
|
14256
|
+
onSurfaceDeleted: (...args) => cardDisabled.update(() => engineEvents.onSurfaceDeleted?.(...args)),
|
|
13749
14257
|
});
|
|
13750
14258
|
// ─── Public API ─────────────────────────────────────────────────
|
|
14259
|
+
const cardDisabled = createCardDisabledController(container, options.disabled);
|
|
13751
14260
|
return {
|
|
14261
|
+
setDisabled: cardDisabled.setDisabled,
|
|
13752
14262
|
getNode: nodeAccess.getNode,
|
|
13753
14263
|
onFocusChange: nodeAccess.onFocusChange,
|
|
13754
14264
|
onScroll: nodeAccess.onScroll,
|
|
@@ -13829,6 +14339,7 @@ function renderStreamingCard(container, options = {}) {
|
|
|
13829
14339
|
return;
|
|
13830
14340
|
disposed = true;
|
|
13831
14341
|
nodeAccess.dispose();
|
|
14342
|
+
cardDisabled.dispose();
|
|
13832
14343
|
boundRevision += 1;
|
|
13833
14344
|
abortController.abort();
|
|
13834
14345
|
teardownBoundLifecycles();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antglobal/copilot-cards-web",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20260915071159-dev.1",
|
|
4
4
|
"description": "Web Component renderer for copilot bot card SDK — PC + Mobile + WebView unified rendering via Custom Elements",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
],
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@antglobal/copilot-cards-core": "0.0.
|
|
31
|
+
"@antglobal/copilot-cards-core": "0.0.20260915071159-dev.1",
|
|
32
32
|
"echarts": "^5.6.0",
|
|
33
33
|
"marked": "^18.0.5",
|
|
34
34
|
"tslib": "^2.8.1",
|