@k2b/ui 0.35.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/actions/Dropdown.js +132 -116
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/Tabs.js +18 -15
- package/dist/browser/actions/Tabs.js.map +1 -1
- package/dist/browser/chat/ChatComposer.js +58 -25
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/content/MapView.js +128 -13
- package/dist/browser/content/MapView.js.map +1 -1
- package/dist/browser/content/MapViewFrame.js +1 -1
- package/dist/browser/content/MapViewFrame.js.map +1 -1
- package/dist/browser/content/MessageRow.js +164 -152
- package/dist/browser/content/MessageRow.js.map +1 -1
- package/dist/browser/content/index.js +1 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/map-view-glyphs.js +23 -0
- package/dist/browser/content/map-view-glyphs.js.map +1 -0
- package/dist/browser/content/map-view-live.js +45 -22
- package/dist/browser/content/map-view-live.js.map +1 -1
- package/dist/browser/content/map-view-snapshot.js +191 -0
- package/dist/browser/content/map-view-snapshot.js.map +1 -0
- package/dist/browser/content/map-view-types.js.map +1 -1
- package/dist/browser/feedback/prompts.js +23 -9
- package/dist/browser/feedback/prompts.js.map +1 -1
- package/dist/browser/inputs/Combobox.js +164 -82
- package/dist/browser/inputs/Combobox.js.map +1 -1
- package/dist/browser/inputs/RichSelect.js +86 -67
- package/dist/browser/inputs/RichSelect.js.map +1 -1
- package/dist/browser/inputs/TextInput.js +1 -1
- package/dist/browser/inputs/TextInput.js.map +1 -1
- package/dist/browser/internal/keyed-for.js +47 -0
- package/dist/browser/internal/keyed-for.js.map +1 -0
- package/dist/browser/layout/AppWorkspace.js +73 -70
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/ScrollArea.js +4 -1
- package/dist/browser/layout/ScrollArea.js.map +1 -1
- package/dist/browser/text-editor/engine.js +13 -10
- package/dist/browser/text-editor/engine.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +101 -85
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/Tabs.js +12 -9
- package/dist/ssr/actions/Tabs.js.map +1 -1
- package/dist/ssr/chat/ChatComposer.js +41 -15
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/content/MapView.js +128 -13
- package/dist/ssr/content/MapView.js.map +1 -1
- package/dist/ssr/content/MapViewFrame.js +1 -1
- package/dist/ssr/content/MapViewFrame.js.map +1 -1
- package/dist/ssr/content/MessageRow.js +9 -2
- package/dist/ssr/content/MessageRow.js.map +1 -1
- package/dist/ssr/content/index.js +1 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/map-view-glyphs.js +23 -0
- package/dist/ssr/content/map-view-glyphs.js.map +1 -0
- package/dist/ssr/content/map-view-snapshot.js +191 -0
- package/dist/ssr/content/map-view-snapshot.js.map +1 -0
- package/dist/ssr/content/map-view-types.js.map +1 -1
- package/dist/ssr/feedback/prompts.js +22 -8
- package/dist/ssr/feedback/prompts.js.map +1 -1
- package/dist/ssr/inputs/Combobox.js +79 -28
- package/dist/ssr/inputs/Combobox.js.map +1 -1
- package/dist/ssr/inputs/RichSelect.js +47 -28
- package/dist/ssr/inputs/RichSelect.js.map +1 -1
- package/dist/ssr/inputs/TextInput.js.map +1 -1
- package/dist/ssr/internal/keyed-for.js +47 -0
- package/dist/ssr/internal/keyed-for.js.map +1 -0
- package/dist/ssr/layout/AppWorkspace.js +1 -1
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/ScrollArea.js +4 -1
- package/dist/ssr/layout/ScrollArea.js.map +1 -1
- package/dist/ssr/text-editor/engine.js +13 -10
- package/dist/ssr/text-editor/engine.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/content/MapViewFrame.d.ts +1 -1
- package/dist/types/content/MessageRow.d.ts +1 -1
- package/dist/types/content/index.d.ts +2 -1
- package/dist/types/content/map-view-glyphs.d.ts +5 -0
- package/dist/types/content/map-view-live.d.ts +1 -1
- package/dist/types/content/map-view-snapshot.d.ts +13 -0
- package/dist/types/content/map-view-types.d.ts +15 -0
- package/dist/types/feedback/prompts.d.ts +5 -0
- package/dist/types/inputs/Combobox.d.ts +12 -0
- package/dist/types/inputs/TextInput.d.ts +2 -1
- package/dist/types/internal/keyed-for.d.ts +13 -0
- package/dist/types/layout/AppWorkspace.d.ts +4 -1
- package/dist/types/layout/ScrollArea.d.ts +2 -0
- package/dist/types/text-editor/engine.d.ts +1 -1
- package/package.json +4 -2
package/dist/ssr/actions/Tabs.js
CHANGED
|
@@ -8,8 +8,10 @@ var _tmpl$ = ["<div class=\"k2b-tabs__trailing\">", "</div>"],
|
|
|
8
8
|
_tmpl$4 = ["<button type=\"button\" class=\"k2b-tabs__close\"", "", "><i class=\"ti ti-x\" aria-hidden=\"true\"></i></button>"],
|
|
9
9
|
_tmpl$5 = ["<div class=\"k2b-tabs__item\" role=\"presentation\"><button", " type=\"button\" role=\"tab\"", "", ">", "<span", ">", "</span></button>", "</div>"],
|
|
10
10
|
_tmpl$6 = ["<i", " aria-hidden=\"true\"></i>"];
|
|
11
|
-
import { children, createEffect, createMemo, createUniqueId,
|
|
11
|
+
import { children, createEffect, createMemo, createUniqueId, Show } from "solid-js";
|
|
12
12
|
import { resolveMaybeAccessor } from "../inputs/field-contract";
|
|
13
|
+
import { KeyedFor } from "../internal/keyed-for";
|
|
14
|
+
const tabName = label => typeof label === "string" ? label : undefined;
|
|
13
15
|
import { useUiMessages } from "../intl/messages";
|
|
14
16
|
import { createScrollFade } from "../layout/scroll-fade";
|
|
15
17
|
const TABS_ITEM = Symbol("Tabs.Item");
|
|
@@ -93,26 +95,27 @@ function TabsRoot(props) {
|
|
|
93
95
|
const next = available[(currentIndex + delta + available.length) % available.length] ?? available[0];
|
|
94
96
|
if (next) select(next.index);
|
|
95
97
|
};
|
|
96
|
-
return _$ssr(_tmpl$3, `k2b-tabs ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-orientation", _$escape(props.orientation ?? "horizontal", true), false) + _$ssrAttribute("data-variant", _$escape(props.variant ?? "line", true), false), _$ssrAttribute("data-scroll-fade-mode", props.orientation !== "vertical" ? "both" : _$escape(undefined, true), false), _$ssrAttribute("aria-label", _$escape(props.ariaLabel, true), false) + _$ssrAttribute("aria-orientation", _$escape(props.orientation ?? "horizontal", true), false), _$escape(_$createComponent(
|
|
98
|
+
return _$ssr(_tmpl$3, `k2b-tabs ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-orientation", _$escape(props.orientation ?? "horizontal", true), false) + _$ssrAttribute("data-variant", _$escape(props.variant ?? "line", true), false), _$ssrAttribute("data-scroll-fade-mode", props.orientation !== "vertical" ? "both" : _$escape(undefined, true), false), _$ssrAttribute("aria-label", _$escape(props.ariaLabel, true), false) + _$ssrAttribute("aria-orientation", _$escape(props.orientation ?? "horizontal", true), false), _$escape(_$createComponent(KeyedFor, {
|
|
97
99
|
get each() {
|
|
98
100
|
return items();
|
|
99
101
|
},
|
|
102
|
+
by: option => option.value,
|
|
100
103
|
children: (option, index) => {
|
|
101
104
|
const id = () => `${instanceId}-tab-${index()}`;
|
|
102
105
|
const panelId = () => `${instanceId}-panel-${index()}`;
|
|
103
|
-
return _$ssr(_tmpl$5, _$ssrAttribute("id", _$escape(id(), true), false), _$ssrAttribute("aria-selected", _$escape(current(), true) === _$escape(option.value, true), false) + _$ssrAttribute("aria-controls", option.panel !== undefined ? _$escape(panelId(), true) : _$escape(undefined, true), false) + _$ssrAttribute("tabindex", tabStopIndex() === index() ? 0 : -1, false), _$ssrAttribute("disabled", option.disabled, true), _$escape(_$createComponent(Show, {
|
|
106
|
+
return _$ssr(_tmpl$5, _$ssrAttribute("id", _$escape(id(), true), false), _$ssrAttribute("aria-selected", _$escape(current(), true) === _$escape(option().value, true), false) + _$ssrAttribute("aria-controls", option().panel !== undefined ? _$escape(panelId(), true) : _$escape(undefined, true), false) + _$ssrAttribute("tabindex", tabStopIndex() === index() ? 0 : -1, false), _$ssrAttribute("disabled", option().disabled, true), _$escape(_$createComponent(Show, {
|
|
104
107
|
get when() {
|
|
105
|
-
return option.icon;
|
|
108
|
+
return option().icon;
|
|
106
109
|
},
|
|
107
110
|
children: icon => _$ssr(_tmpl$6, _$ssrAttribute("class", _$escape(icon(), true), false))
|
|
108
|
-
})), _$ssrAttribute("class", props.variant === "pill" ? "k2b-truncate-fade" : _$escape(undefined, true), false), _$escape(option.label), _$escape(_$createComponent(Show, {
|
|
111
|
+
})), _$ssrAttribute("class", props.variant === "pill" ? "k2b-truncate-fade" : _$escape(undefined, true), false), _$escape(option().label), _$escape(_$createComponent(Show, {
|
|
109
112
|
get when() {
|
|
110
|
-
return option.onClose;
|
|
113
|
+
return option().onClose;
|
|
111
114
|
},
|
|
112
115
|
get children() {
|
|
113
|
-
return _$ssr(_tmpl$4, _$ssrAttribute("aria-label", _$escape(option.closeLabel ?? messages().closeNamed({
|
|
114
|
-
name:
|
|
115
|
-
}), true), false), _$ssrAttribute("disabled", option.disabled, true));
|
|
116
|
+
return _$ssr(_tmpl$4, _$ssrAttribute("aria-label", _$escape(option().closeLabel ?? messages().closeNamed({
|
|
117
|
+
name: tabName(option().label) ?? props.ariaLabel
|
|
118
|
+
}), true), false), _$ssrAttribute("disabled", option().disabled, true));
|
|
116
119
|
}
|
|
117
120
|
})));
|
|
118
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["actions/Tabs.tsx"],"sourcesContent":["import { children, createEffect, createMemo, createUniqueId, For, type JSX, Show } from \"solid-js\";\nimport type { MaybeAccessor } from \"../inputs/field-contract\";\nimport { resolveMaybeAccessor } from \"../inputs/field-contract\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { createScrollFade } from \"../layout/scroll-fade\";\n\nexport type TabOption<T extends string = string> = {\n value: T;\n label: JSX.Element;\n icon?: string;\n disabled?: boolean;\n panel?: JSX.Element;\n onClose?: () => void;\n closeLabel?: string;\n};\n\nexport type TabsItemProps<T extends string = string> = Omit<TabOption<T>, \"panel\"> & {\n children?: JSX.Element;\n};\n\ntype TabsItemSlot<T extends string = string> = {\n readonly kind: typeof TABS_ITEM;\n readonly props: TabsItemProps<T>;\n};\n\nexport type TabsProps<T extends string = string> = {\n value: MaybeAccessor<T>;\n onValueChange: (value: T) => void;\n ariaLabel: string;\n orientation?: \"horizontal\" | \"vertical\";\n class?: string;\n variant?: \"line\" | \"pill\";\n trailing?: JSX.Element;\n /** Data-driven alternative to colocated `Tabs.Item` children. */\n options?: readonly TabOption<T>[];\n children?: JSX.Element;\n};\n\ntype TabsComponent = (<T extends string = string>(props: TabsProps<T>) => JSX.Element) & {\n Item: <T extends string = string>(props: TabsItemProps<T>) => JSX.Element;\n};\n\nconst TABS_ITEM = Symbol(\"Tabs.Item\");\n\nconst isTabsItem = <T extends string>(value: unknown): value is TabsItemSlot<T> =>\n !!value && typeof value === \"object\" && \"kind\" in value && value.kind === TABS_ITEM;\n\nconst collectTabsItems = <T extends string>(value: unknown): TabsItemSlot<T>[] => {\n if (Array.isArray(value)) return value.flatMap(collectTabsItems<T>);\n return isTabsItem<T>(value) ? [value] : [];\n};\n\nfunction TabsItem<T extends string = string>(props: TabsItemProps<T>): JSX.Element {\n return { kind: TABS_ITEM, props } satisfies TabsItemSlot<T> as unknown as JSX.Element;\n}\n\n/** Controlled, keyboard-accessible tabs with compositional or data-driven items. */\nfunction TabsRoot<T extends string = string>(props: TabsProps<T>): JSX.Element {\n const messages = useUiMessages();\n let root: HTMLDivElement | undefined;\n let list: HTMLDivElement | undefined;\n createScrollFade(\n () => list,\n () => props.orientation !== \"vertical\",\n );\n const instanceId = `k2b-tabs-${createUniqueId()}`;\n const resolvedChildren = children(() => props.children);\n const trailing = children(() => props.trailing);\n const items = createMemo<readonly TabOption<T>[]>(() => {\n if (props.options) return props.options;\n return collectTabsItems<T>(resolvedChildren.toArray()).map((item) => ({\n value: item.props.value,\n label: item.props.label,\n icon: item.props.icon,\n disabled: item.props.disabled,\n panel: item.props.children,\n onClose: item.props.onClose,\n closeLabel: item.props.closeLabel,\n }));\n });\n const buttons: HTMLButtonElement[] = [];\n let closing: T | undefined;\n const requestClose = (option: TabOption<T>) => {\n closing = option.value;\n option.onClose?.();\n };\n const current = () => resolveMaybeAccessor(props.value);\n const active = createMemo(() => items().find((option) => option.value === current()));\n const activeIndex = createMemo(() =>\n Math.max(\n 0,\n items().findIndex((option) => option.value === current()),\n ),\n );\n const enabled = () =>\n items()\n .map((option, index) => ({ option, index }))\n .filter(({ option }) => !option.disabled);\n const tabStopIndex = createMemo(() => {\n const selected = items().findIndex((option) => option.value === current() && !option.disabled);\n return selected >= 0 ? selected : (enabled()[0]?.index ?? -1);\n });\n createEffect(() => {\n const index = activeIndex();\n const removed = closing !== undefined && !items().some((item) => item.value === closing);\n if (removed) closing = undefined;\n queueMicrotask(() => {\n buttons[index]?.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\" });\n if (removed) {\n const target = items().length ? buttons[index] : root?.querySelector<HTMLElement>(\".k2b-tabs__trailing button\");\n target?.focus();\n }\n });\n });\n const select = (index: number) => {\n const option = items()[index];\n if (!option || option.disabled) return;\n props.onValueChange(option.value);\n queueMicrotask(() => buttons[index]?.focus());\n };\n const move = (index: number, delta: 1 | -1) => {\n const available = enabled();\n if (available.length === 0) return;\n const currentIndex = available.findIndex((item) => item.index === index);\n const next = available[(currentIndex + delta + available.length) % available.length] ?? available[0];\n if (next) select(next.index);\n };\n\n return (\n <div\n ref={root}\n class={`k2b-tabs ${props.class ?? \"\"}`}\n data-orientation={props.orientation ?? \"horizontal\"}\n data-variant={props.variant ?? \"line\"}\n >\n <div class=\"k2b-tabs__bar\">\n <div\n ref={list}\n data-scroll-fade-mode={props.orientation !== \"vertical\" ? \"both\" : undefined}\n data-scroll-fade-axis=\"horizontal\"\n class=\"k2b-tabs__list\"\n role=\"tablist\"\n aria-label={props.ariaLabel}\n aria-orientation={props.orientation ?? \"horizontal\"}\n >\n <For each={items()}>\n {(option, index) => {\n const id = () => `${instanceId}-tab-${index()}`;\n const panelId = () => `${instanceId}-panel-${index()}`;\n return (\n <div class=\"k2b-tabs__item\" role=\"presentation\">\n <button\n ref={(element) => {\n buttons[index()] = element;\n }}\n id={id()}\n type=\"button\"\n role=\"tab\"\n aria-selected={current() === option.value}\n aria-controls={option.panel !== undefined ? panelId() : undefined}\n tabIndex={tabStopIndex() === index() ? 0 : -1}\n disabled={option.disabled}\n onClick={() => props.onValueChange(option.value)}\n onKeyDown={(event) => {\n if ((event.key === \"Delete\" || event.key === \"Backspace\") && option.onClose) {\n event.preventDefault();\n requestClose(option);\n return;\n }\n const previous = props.orientation === \"vertical\" ? \"ArrowUp\" : \"ArrowLeft\";\n const next = props.orientation === \"vertical\" ? \"ArrowDown\" : \"ArrowRight\";\n if (event.key === previous || event.key === next) {\n event.preventDefault();\n move(index(), event.key === next ? 1 : -1);\n } else if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n const available = enabled();\n const target = event.key === \"End\" ? available.at(-1) : available[0];\n if (target) select(target.index);\n }\n }}\n >\n <Show when={option.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <span class={props.variant === \"pill\" ? \"k2b-truncate-fade\" : undefined}>{option.label}</span>\n </button>\n <Show when={option.onClose}>\n <button\n type=\"button\"\n class=\"k2b-tabs__close\"\n aria-label={\n option.closeLabel ??\n messages().closeNamed({ name: typeof option.label === \"string\" ? option.label : props.ariaLabel })\n }\n disabled={option.disabled}\n onClick={() => requestClose(option)}\n >\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </button>\n </Show>\n </div>\n );\n }}\n </For>\n </div>\n <Show when={trailing()}>\n <div class=\"k2b-tabs__trailing\">{trailing()}</div>\n </Show>\n </div>\n <Show when={active()?.panel !== undefined}>\n <div\n id={`${instanceId}-panel-${activeIndex()}`}\n class=\"k2b-tabs__panel\"\n role=\"tabpanel\"\n aria-labelledby={`${instanceId}-tab-${activeIndex()}`}\n tabIndex={0}\n >\n {active()?.panel}\n </div>\n </Show>\n </div>\n );\n}\n\nexport const Tabs = TabsRoot as TabsComponent;\nTabs.Item = TabsItem;\n\nexport default Tabs;\n"],"mappings":";;;;;;;;;;AAAA,SAAS,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,EAAY,IAAI,QAAQ,UAAU;AAElG,SAAS,oBAAoB,QAAQ,0BAA0B;AAC/D,SAAS,aAAa,QAAQ,kBAAkB;AAChD,SAAS,gBAAgB,QAAQ,uBAAuB;AAsCxD,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC;AAErC,MAAM,UAAU,GAAsB,KAAc,IAClD,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;AAErF,MAAM,gBAAgB,GAAsB,KAAc,IAAwB;EAChF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC,OAAO,CAAC,gBAAmB,CAAC;EACnE,OAAO,UAAU,CAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE;AAC5C,CAAC;AAED,SAAS,QAAQ,CAA4B,KAAuB,EAAe;EACjF,OAAO;IAAE,IAAI,EAAE,SAAS;IAAE;EAAM,CAAC;AACnC;;AAEA;AACA,SAAS,QAAQ,CAA4B,KAAmB,EAAe;EAC7E,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC,IAAI,IAAgC;EACpC,IAAI,IAAgC;EACpC,gBAAgB,CACd,MAAM,IAAI,EACV,MAAM,KAAK,CAAC,WAAW,KAAK,UAC9B,CAAC;EACD,MAAM,UAAU,GAAG,YAAY,cAAc,CAAC,CAAC,EAAE;EACjD,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC;EACvD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC;EAC/C,MAAM,KAAK,GAAG,UAAU,CAA0B,MAAM;IACtD,IAAI,KAAK,CAAC,OAAO,EAAE,OAAO,KAAK,CAAC,OAAO;IACvC,OAAO,gBAAgB,CAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAE,IAAI,KAAM;MACpE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK;MACvB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK;MACvB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;MACrB,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ;MAC7B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ;MAC1B,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;MAC3B,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC;IACzB,CAAC,CAAC,CAAC;EACL,CAAC,CAAC;EACF,MAAM,OAA4B,GAAG,EAAE;EACvC,IAAI,OAAsB;EAC1B,MAAM,YAAY,GAAI,MAAoB,IAAK;IAC7C,OAAO,GAAG,MAAM,CAAC,KAAK;IACtB,MAAM,CAAC,OAAO,GAAG,CAAC;EACpB,CAAC;EACD,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC;EACvD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,IAAI,CAAE,MAAM,IAAK,MAAM,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;EACrF,MAAM,WAAW,GAAG,UAAU,CAAC,MAC7B,IAAI,CAAC,GAAG,CACN,CAAC,EACD,KAAK,CAAC,CAAC,CAAC,SAAS,CAAE,MAAM,IAAK,MAAM,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAC1D,CACF,CAAC;EACD,MAAM,OAAO,GAAG,MACd,KAAK,CAAC,CAAC,CACJ,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,MAAM;IAAE,MAAM;IAAE;EAAM,CAAC,CAAC,CAAC,CAC3C,MAAM,CAAC,CAAC;IAAE;EAAO,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;EAC7C,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM;IACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAE,MAAM,IAAK,MAAM,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;IAC9F,OAAO,QAAQ,IAAI,CAAC,GAAG,QAAQ,GAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAE;EAC/D,CAAC,CAAC;EACF,YAAY,CAAC,MAAM;IACjB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC;IAC3B,MAAM,OAAO,GAAG,OAAO,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAE,IAAI,IAAK,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC;IACxF,IAAI,OAAO,EAAE,OAAO,GAAG,SAAS;IAChC,cAAc,CAAC,MAAM;MACnB,OAAO,CAAC,KAAK,CAAC,EAAE,cAAc,GAAG;QAAE,KAAK,EAAE,SAAS;QAAE,MAAM,EAAE;MAAU,CAAC,CAAC;MACzE,IAAI,OAAO,EAAE;QACX,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,aAAa,CAAc,4BAA4B,CAAC;QAC/G,MAAM,EAAE,KAAK,CAAC,CAAC;MACjB;IACF,CAAC,CAAC;EACJ,CAAC,CAAC;EACF,MAAM,MAAM,GAAI,KAAa,IAAK;IAChC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7B,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE;IAChC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC;IACjC,cAAc,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;EAC/C,CAAC;EACD,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,KAAa,KAAK;IAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC;IAC3B,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;IAC5B,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAE,IAAI,IAAK,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;IACxE,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,YAAY,GAAG,KAAK,GAAG,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC;IACpG,IAAI,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;EAC9B,CAAC;EAED,sBAGW,qBAAY,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,8CACpB,KAAK,CAAC,WAAW,IAAI,YAAY,0DACrC,KAAK,CAAC,OAAO,IAAI,MAAM,yDAKV,KAAK,CAAC,WAAW,KAAK,UAAU,GAAG,MAAM,YAAG,SAAS,uDAIhE,KAAK,CAAC,SAAS,8DACT,KAAK,CAAC,WAAW,IAAI,YAAY,4CAElD,GAAG;IAAA,IAAC,IAAI;MAAA,OAAE,KAAK,CAAC,CAAC;IAAA;IAAA,UACf,CAAC,MAAM,EAAE,KAAK,KAAK;MAClB,MAAM,EAAE,GAAG,MAAM,GAAG,UAAU,QAAQ,KAAK,CAAC,CAAC,EAAE;MAC/C,MAAM,OAAO,GAAG,MAAM,GAAG,UAAU,UAAU,KAAK,CAAC,CAAC,EAAE;MACtD,oDAMU,EAAE,CAAC,CAAC,iDAGO,gBAAO,CAAC,CAAC,qBAAK,MAAM,CAAC,KAAK,kDAC1B,MAAM,CAAC,KAAK,KAAK,SAAS,YAAG,OAAO,CAAC,CAAC,mBAAG,SAAS,6CACvD,YAAY,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,qCACnC,MAAM,CAAC,QAAQ,oCAqBxB,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,MAAM,CAAC,IAAI;QAAA;QAAA,UAAI,IAAI,oDAAe,IAAI,CAAC,CAAC;MAAuB,6BAC9D,KAAK,CAAC,OAAO,KAAK,MAAM,GAAG,mBAAmB,YAAG,SAAS,0BAAG,MAAM,CAAC,KAAK,8BAEvF,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,MAAM,CAAC,OAAO;QAAA;QAAA;UAAA,4DAKpB,MAAM,CAAC,UAAU,IACjB,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;YAAE,IAAI,EAAE,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,GAAG,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;UAAU,CAAC,CAAC,4CAE1F,MAAM,CAAC,QAAQ;QAAA;MAAA;IAQnC;EAAC,gCAGJ,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,QAAQ,CAAC,CAAC;IAAA;IAAA;MAAA,8BACa,QAAQ,CAAC,CAAC;IAAA;EAAA,gCAG9C,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,MAAM,CAAC,CAAC,EAAE,KAAK,KAAK,SAAS;IAAA;IAAA;MAAA,sBAEjC,YAAG,UAAU,0BAAU,WAAW,CAAC,CAAC,SAAE,EAGzB,YAAG,UAAU,wBAAQ,WAAW,CAAC,CAAC,SAAE,WAGpD,MAAM,CAAC,CAAC,EAAE,KAAK;IAAA;EAAA;AAK1B;AAEA,OAAO,MAAM,IAAI,GAAG,QAAyB;AAC7C,IAAI,CAAC,IAAI,GAAG,QAAQ;AAEpB,eAAe,IAAI","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["actions/Tabs.tsx"],"sourcesContent":["import { children, createEffect, createMemo, createUniqueId, type JSX, Show } from \"solid-js\";\nimport type { MaybeAccessor } from \"../inputs/field-contract\";\nimport { resolveMaybeAccessor } from \"../inputs/field-contract\";\nimport { KeyedFor } from \"../internal/keyed-for\";\n\nconst tabName = (label: JSX.Element) => (typeof label === \"string\" ? label : undefined);\n\nimport { useUiMessages } from \"../intl/messages\";\nimport { createScrollFade } from \"../layout/scroll-fade\";\n\nexport type TabOption<T extends string = string> = {\n value: T;\n label: JSX.Element;\n icon?: string;\n disabled?: boolean;\n panel?: JSX.Element;\n onClose?: () => void;\n closeLabel?: string;\n};\n\nexport type TabsItemProps<T extends string = string> = Omit<TabOption<T>, \"panel\"> & {\n children?: JSX.Element;\n};\n\ntype TabsItemSlot<T extends string = string> = {\n readonly kind: typeof TABS_ITEM;\n readonly props: TabsItemProps<T>;\n};\n\nexport type TabsProps<T extends string = string> = {\n value: MaybeAccessor<T>;\n onValueChange: (value: T) => void;\n ariaLabel: string;\n orientation?: \"horizontal\" | \"vertical\";\n class?: string;\n variant?: \"line\" | \"pill\";\n trailing?: JSX.Element;\n /** Data-driven alternative to colocated `Tabs.Item` children. */\n options?: readonly TabOption<T>[];\n children?: JSX.Element;\n};\n\ntype TabsComponent = (<T extends string = string>(props: TabsProps<T>) => JSX.Element) & {\n Item: <T extends string = string>(props: TabsItemProps<T>) => JSX.Element;\n};\n\nconst TABS_ITEM = Symbol(\"Tabs.Item\");\n\nconst isTabsItem = <T extends string>(value: unknown): value is TabsItemSlot<T> =>\n !!value && typeof value === \"object\" && \"kind\" in value && value.kind === TABS_ITEM;\n\nconst collectTabsItems = <T extends string>(value: unknown): TabsItemSlot<T>[] => {\n if (Array.isArray(value)) return value.flatMap(collectTabsItems<T>);\n return isTabsItem<T>(value) ? [value] : [];\n};\n\nfunction TabsItem<T extends string = string>(props: TabsItemProps<T>): JSX.Element {\n return { kind: TABS_ITEM, props } satisfies TabsItemSlot<T> as unknown as JSX.Element;\n}\n\n/** Controlled, keyboard-accessible tabs with compositional or data-driven items. */\nfunction TabsRoot<T extends string = string>(props: TabsProps<T>): JSX.Element {\n const messages = useUiMessages();\n let root: HTMLDivElement | undefined;\n let list: HTMLDivElement | undefined;\n createScrollFade(\n () => list,\n () => props.orientation !== \"vertical\",\n );\n const instanceId = `k2b-tabs-${createUniqueId()}`;\n const resolvedChildren = children(() => props.children);\n const trailing = children(() => props.trailing);\n const items = createMemo<readonly TabOption<T>[]>(() => {\n if (props.options) return props.options;\n return collectTabsItems<T>(resolvedChildren.toArray()).map((item) => ({\n value: item.props.value,\n label: item.props.label,\n icon: item.props.icon,\n disabled: item.props.disabled,\n panel: item.props.children,\n onClose: item.props.onClose,\n closeLabel: item.props.closeLabel,\n }));\n });\n const buttons: HTMLButtonElement[] = [];\n let closing: T | undefined;\n const requestClose = (option: TabOption<T>) => {\n closing = option.value;\n option.onClose?.();\n };\n const current = () => resolveMaybeAccessor(props.value);\n const active = createMemo(() => items().find((option) => option.value === current()));\n const activeIndex = createMemo(() =>\n Math.max(\n 0,\n items().findIndex((option) => option.value === current()),\n ),\n );\n const enabled = () =>\n items()\n .map((option, index) => ({ option, index }))\n .filter(({ option }) => !option.disabled);\n const tabStopIndex = createMemo(() => {\n const selected = items().findIndex((option) => option.value === current() && !option.disabled);\n return selected >= 0 ? selected : (enabled()[0]?.index ?? -1);\n });\n createEffect(() => {\n const index = activeIndex();\n const removed = closing !== undefined && !items().some((item) => item.value === closing);\n if (removed) closing = undefined;\n queueMicrotask(() => {\n buttons[index]?.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\" });\n if (removed) {\n const target = items().length ? buttons[index] : root?.querySelector<HTMLElement>(\".k2b-tabs__trailing button\");\n target?.focus();\n }\n });\n });\n const select = (index: number) => {\n const option = items()[index];\n if (!option || option.disabled) return;\n props.onValueChange(option.value);\n queueMicrotask(() => buttons[index]?.focus());\n };\n const move = (index: number, delta: 1 | -1) => {\n const available = enabled();\n if (available.length === 0) return;\n const currentIndex = available.findIndex((item) => item.index === index);\n const next = available[(currentIndex + delta + available.length) % available.length] ?? available[0];\n if (next) select(next.index);\n };\n\n return (\n <div\n ref={root}\n class={`k2b-tabs ${props.class ?? \"\"}`}\n data-orientation={props.orientation ?? \"horizontal\"}\n data-variant={props.variant ?? \"line\"}\n >\n <div class=\"k2b-tabs__bar\">\n <div\n ref={list}\n data-scroll-fade-mode={props.orientation !== \"vertical\" ? \"both\" : undefined}\n data-scroll-fade-axis=\"horizontal\"\n class=\"k2b-tabs__list\"\n role=\"tablist\"\n aria-label={props.ariaLabel}\n aria-orientation={props.orientation ?? \"horizontal\"}\n >\n {/* Keyed by value: tab objects are rebuilt whenever a tab's props change, and a tab replaced between press and\n release would swallow the click (#2140). */}\n <KeyedFor each={items()} by={(option) => option.value}>\n {(option, index) => {\n const id = () => `${instanceId}-tab-${index()}`;\n const panelId = () => `${instanceId}-panel-${index()}`;\n return (\n <div class=\"k2b-tabs__item\" role=\"presentation\">\n <button\n ref={(element) => {\n buttons[index()] = element;\n }}\n id={id()}\n type=\"button\"\n role=\"tab\"\n aria-selected={current() === option().value}\n aria-controls={option().panel !== undefined ? panelId() : undefined}\n tabIndex={tabStopIndex() === index() ? 0 : -1}\n disabled={option().disabled}\n onClick={() => props.onValueChange(option().value)}\n onKeyDown={(event) => {\n if ((event.key === \"Delete\" || event.key === \"Backspace\") && option().onClose) {\n event.preventDefault();\n requestClose(option());\n return;\n }\n const previous = props.orientation === \"vertical\" ? \"ArrowUp\" : \"ArrowLeft\";\n const next = props.orientation === \"vertical\" ? \"ArrowDown\" : \"ArrowRight\";\n if (event.key === previous || event.key === next) {\n event.preventDefault();\n move(index(), event.key === next ? 1 : -1);\n } else if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n const available = enabled();\n const target = event.key === \"End\" ? available.at(-1) : available[0];\n if (target) select(target.index);\n }\n }}\n >\n <Show when={option().icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <span class={props.variant === \"pill\" ? \"k2b-truncate-fade\" : undefined}>{option().label}</span>\n </button>\n <Show when={option().onClose}>\n <button\n type=\"button\"\n class=\"k2b-tabs__close\"\n aria-label={option().closeLabel ?? messages().closeNamed({ name: tabName(option().label) ?? props.ariaLabel })}\n disabled={option().disabled}\n onClick={() => requestClose(option())}\n >\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </button>\n </Show>\n </div>\n );\n }}\n </KeyedFor>\n </div>\n <Show when={trailing()}>\n <div class=\"k2b-tabs__trailing\">{trailing()}</div>\n </Show>\n </div>\n <Show when={active()?.panel !== undefined}>\n <div\n id={`${instanceId}-panel-${activeIndex()}`}\n class=\"k2b-tabs__panel\"\n role=\"tabpanel\"\n aria-labelledby={`${instanceId}-tab-${activeIndex()}`}\n tabIndex={0}\n >\n {active()?.panel}\n </div>\n </Show>\n </div>\n );\n}\n\nexport const Tabs = TabsRoot as TabsComponent;\nTabs.Item = TabsItem;\n\nexport default Tabs;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1936,14 +1936,39 @@ export function ChatComposer(props) {
|
|
|
1936
1936
|
return _$ssr(_tmpl$0);
|
|
1937
1937
|
}
|
|
1938
1938
|
})));
|
|
1939
|
-
|
|
1939
|
+
|
|
1940
|
+
// A press on a row remembers its command. The host can rebuild the list, or the whole menu, between press and release;
|
|
1941
|
+
// the browser then sends the click to a common ancestor (#2140). A release on the same command's new row runs it.
|
|
1942
|
+
let pressedCommand;
|
|
1943
|
+
onMount(() => {
|
|
1944
|
+
const release = event => {
|
|
1945
|
+
const pressed = pressedCommand;
|
|
1946
|
+
pressedCommand = undefined;
|
|
1947
|
+
if (!pressed || pressed.row.isConnected || event.type !== "pointerup") return;
|
|
1948
|
+
const under = document.elementFromPoint(event.clientX, event.clientY)?.closest("[data-command-key]");
|
|
1949
|
+
if (!under || under.dataset.commandKey !== pressed.key || !shellRef?.contains(under)) return;
|
|
1950
|
+
const command = commandRowMap().get(pressed.key)?.command;
|
|
1951
|
+
if (command) void executeCommand(command);
|
|
1952
|
+
};
|
|
1953
|
+
window.addEventListener("pointerup", release, true);
|
|
1954
|
+
window.addEventListener("pointercancel", release, true);
|
|
1955
|
+
onCleanup(() => {
|
|
1956
|
+
window.removeEventListener("pointerup", release, true);
|
|
1957
|
+
window.removeEventListener("pointercancel", release, true);
|
|
1958
|
+
});
|
|
1959
|
+
});
|
|
1960
|
+
// Rows are keyed by the command's key, not its object: hosts rebuild their command objects whenever their inputs change,
|
|
1961
|
+
// and a row replaced between the press and the release would swallow the click (#2140).
|
|
1962
|
+
const commandRowMap = createMemo(() => new Map(commandModel().rows.map(row => [chatCommandKey(row.command), row])));
|
|
1940
1963
|
const commandGroupKey = group => group.scopeTitle ? "scope" : group.section ? `section:${group.section.id}` : "flat";
|
|
1941
|
-
const renderCommandRow =
|
|
1942
|
-
const
|
|
1943
|
-
const
|
|
1944
|
-
const
|
|
1945
|
-
const
|
|
1946
|
-
|
|
1964
|
+
const renderCommandRow = initial => {
|
|
1965
|
+
const key = chatCommandKey(initial);
|
|
1966
|
+
const command = () => commandRowMap().get(key)?.command ?? initial;
|
|
1967
|
+
const highlight = () => commandRowMap().get(key)?.highlight;
|
|
1968
|
+
const title = () => command().label ?? command().name;
|
|
1969
|
+
const opening = () => openingRow() === key;
|
|
1970
|
+
const failure = () => openFailures()[key];
|
|
1971
|
+
return _$ssr(_tmpl$13, _$ssrAttribute("id", _$escape(commandOptionId(command()), true), false), _$ssrAttribute("aria-selected", _$escape(selectedCommandKey(), true) === _$escape(key, true), false) + _$ssrAttribute("aria-disabled", _$escape(Boolean(command().disabled || command().reason), true), false) + _$ssrAttribute("aria-busy", opening() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("aria-describedby", command().reason ? `${_$escape(commandOptionId(command()), true)}-reason` : _$escape(undefined, true), false) + _$ssrAttribute("data-reason", command().reason ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-active", selectedCommandKey() === key ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-command-key", _$escape(key, true), false), _$ssrAttribute("class", _$escape(command().icon ?? "ti ti-slash", true), false), _$escape(_$createComponent(Show, {
|
|
1947
1972
|
get when() {
|
|
1948
1973
|
return highlight();
|
|
1949
1974
|
},
|
|
@@ -1953,24 +1978,24 @@ export function ChatComposer(props) {
|
|
|
1953
1978
|
children: range => [title().slice(0, range()[0]), _$ssr(_tmpl$14, _$escape(title().slice(range()[0], range()[1]))), title().slice(range()[1])]
|
|
1954
1979
|
})), _$escape(_$createComponent(Show, {
|
|
1955
1980
|
get when() {
|
|
1956
|
-
return _$memo(() => !!command.open)() && !command.reason;
|
|
1981
|
+
return _$memo(() => !!command().open)() && !command().reason;
|
|
1957
1982
|
},
|
|
1958
1983
|
get fallback() {
|
|
1959
1984
|
return _$createComponent(Show, {
|
|
1960
1985
|
get when() {
|
|
1961
|
-
return command.reason ?? command.description;
|
|
1986
|
+
return command().reason ?? command().description;
|
|
1962
1987
|
},
|
|
1963
1988
|
get children() {
|
|
1964
|
-
return _$ssr(_tmpl$15, _$ssrAttribute("id", command.reason ? `${_$escape(commandOptionId(command), true)}-reason` : _$escape(undefined, true), false), _$escape(command.reason ?? command.description));
|
|
1989
|
+
return _$ssr(_tmpl$15, _$ssrAttribute("id", command().reason ? `${_$escape(commandOptionId(command()), true)}-reason` : _$escape(undefined, true), false), _$escape(command().reason ?? command().description));
|
|
1965
1990
|
}
|
|
1966
1991
|
});
|
|
1967
1992
|
},
|
|
1968
1993
|
get children() {
|
|
1969
|
-
return _$ssr(_tmpl$11, _$ssrAttribute("data-state", opening() ? "busy" : failure() ? "failed" : _$escape(undefined, true), false), _$ssrAttribute("aria-hidden", opening() ? "true" : _$escape(undefined, true), false), _$escape(failure() ?? command.description), _$ssrAttribute("aria-hidden", opening() ? _$escape(undefined, true) : "true", false), _$escape(command.busyLabel ?? chatMessages().commandOpening));
|
|
1994
|
+
return _$ssr(_tmpl$11, _$ssrAttribute("data-state", opening() ? "busy" : failure() ? "failed" : _$escape(undefined, true), false), _$ssrAttribute("aria-hidden", opening() ? "true" : _$escape(undefined, true), false), _$escape(failure() ?? command().description), _$ssrAttribute("aria-hidden", opening() ? _$escape(undefined, true) : "true", false), _$escape(command().busyLabel ?? chatMessages().commandOpening));
|
|
1970
1995
|
}
|
|
1971
1996
|
})), _$escape(_$createComponent(Show, {
|
|
1972
1997
|
get when() {
|
|
1973
|
-
return command.selected;
|
|
1998
|
+
return command().selected;
|
|
1974
1999
|
},
|
|
1975
2000
|
get children() {
|
|
1976
2001
|
return _$ssr(_tmpl$12, _$escape(chatMessages().commandSelected));
|
|
@@ -2038,7 +2063,8 @@ export function ChatComposer(props) {
|
|
|
2038
2063
|
children: key => {
|
|
2039
2064
|
const group = createMemo(() => commandModel().groups.find(group => commandGroupKey(group) === key));
|
|
2040
2065
|
const headingId = () => `${commandListId}-g-${key === "scope" ? "scope" : props.commandSections?.findIndex(section => section.id === group()?.section?.id)}`;
|
|
2041
|
-
const rows = () => group()?.rows.map(row => row.command) ?? [];
|
|
2066
|
+
const rows = () => group()?.rows.map(row => chatCommandKey(row.command)) ?? [];
|
|
2067
|
+
const row = key => commandRowMap().get(key).command;
|
|
2042
2068
|
return _$createComponent(Show, {
|
|
2043
2069
|
when: key !== "flat",
|
|
2044
2070
|
get fallback() {
|
|
@@ -2046,7 +2072,7 @@ export function ChatComposer(props) {
|
|
|
2046
2072
|
get each() {
|
|
2047
2073
|
return rows();
|
|
2048
2074
|
},
|
|
2049
|
-
children: renderCommandRow
|
|
2075
|
+
children: key => renderCommandRow(row(key))
|
|
2050
2076
|
});
|
|
2051
2077
|
},
|
|
2052
2078
|
get children() {
|
|
@@ -2061,7 +2087,7 @@ export function ChatComposer(props) {
|
|
|
2061
2087
|
get each() {
|
|
2062
2088
|
return rows();
|
|
2063
2089
|
},
|
|
2064
|
-
children: renderCommandRow
|
|
2090
|
+
children: key => renderCommandRow(row(key))
|
|
2065
2091
|
})), _$escape(_$createComponent(Index, {
|
|
2066
2092
|
get each() {
|
|
2067
2093
|
return Array.from({
|