@tutti-os/ui-rich-text 0.0.14 → 0.0.15
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/at-panel/index.d.ts +7 -0
- package/dist/at-panel/index.js +63 -14
- package/dist/at-panel/index.js.map +1 -1
- package/dist/{chunk-QK6NMNYN.js → chunk-YFXORJLD.js} +52 -40
- package/dist/chunk-YFXORJLD.js.map +1 -0
- package/dist/editor/index.d.ts +0 -5
- package/dist/editor/index.js +62 -104
- package/dist/editor/index.js.map +1 -1
- package/dist/plugins/index.js +1 -1
- package/dist/types/index.d.ts +2 -2
- package/package.json +4 -4
- package/dist/chunk-QK6NMNYN.js.map +0 -1
package/README.md
CHANGED
|
@@ -97,7 +97,7 @@ interface RichTextTriggerProvider<TItem = unknown> {
|
|
|
97
97
|
getItemKey: (item: TItem) => string;
|
|
98
98
|
getItemLabel: (item: TItem) => string;
|
|
99
99
|
getItemSubtitle?: (item: TItem) => string | null | undefined;
|
|
100
|
-
|
|
100
|
+
getItemIconUrl?: (
|
|
101
101
|
item: TItem
|
|
102
102
|
) => string | null | undefined | Promise<string | null | undefined>;
|
|
103
103
|
getItemKeywords?: (item: TItem) => readonly string[] | undefined;
|
package/dist/at-panel/index.d.ts
CHANGED
|
@@ -34,6 +34,13 @@ interface MentionRowClassNames {
|
|
|
34
34
|
interface MentionRowRenderOptions {
|
|
35
35
|
classNames?: MentionRowClassNames;
|
|
36
36
|
dataAttributeMode?: MentionRowDataAttributeMode;
|
|
37
|
+
/**
|
|
38
|
+
* 当提供时,issue / app 行末尾渲染一个「查看产物文件」入口图标(独立点击热区,
|
|
39
|
+
* 不触发整行选中)。点击回调由调用方注入(如打开引用文件 picker 并定位到该实体)。
|
|
40
|
+
*/
|
|
41
|
+
onOpenReferences?: () => void;
|
|
42
|
+
/** 入口图标的无障碍标签 / tooltip 文案。 */
|
|
43
|
+
openReferencesLabel?: string;
|
|
37
44
|
}
|
|
38
45
|
/**
|
|
39
46
|
* Render the inner content of a single `@`-mention palette row from a
|
package/dist/at-panel/index.js
CHANGED
|
@@ -690,6 +690,7 @@ import {
|
|
|
690
690
|
FileTextIcon,
|
|
691
691
|
FolderIcon,
|
|
692
692
|
ImageFileIcon,
|
|
693
|
+
LocateFolderIcon,
|
|
693
694
|
ProductIcon,
|
|
694
695
|
StatusDot,
|
|
695
696
|
VideoFileIcon,
|
|
@@ -705,6 +706,7 @@ var MENTION_ROW_DATA_ATTRIBUTES = {
|
|
|
705
706
|
fileThumb: "data-rich-text-at-mention-file-thumb",
|
|
706
707
|
fileVisualKind: "data-rich-text-at-mention-file-visual-kind",
|
|
707
708
|
navigation: "data-rich-text-at-mention-navigation",
|
|
709
|
+
openReferences: "data-rich-text-at-mention-open-references",
|
|
708
710
|
statusTag: "data-rich-text-at-mention-status-tag",
|
|
709
711
|
userAvatar: "data-rich-text-at-mention-user-avatar"
|
|
710
712
|
},
|
|
@@ -715,6 +717,7 @@ var MENTION_ROW_DATA_ATTRIBUTES = {
|
|
|
715
717
|
fileThumb: "data-agent-mention-file-thumb",
|
|
716
718
|
fileVisualKind: "data-agent-file-visual-kind",
|
|
717
719
|
navigation: "data-agent-mention-navigation",
|
|
720
|
+
openReferences: "data-agent-mention-open-references",
|
|
718
721
|
statusTag: "data-agent-mention-status-tag",
|
|
719
722
|
userAvatar: "data-agent-mention-user-avatar"
|
|
720
723
|
}
|
|
@@ -765,7 +768,9 @@ function resolveMentionRowRenderOptions(options) {
|
|
|
765
768
|
if (isMentionRowRenderOptions(options)) {
|
|
766
769
|
return {
|
|
767
770
|
classNames: options.classNames,
|
|
768
|
-
dataAttributeMode: options.dataAttributeMode ?? "shared"
|
|
771
|
+
dataAttributeMode: options.dataAttributeMode ?? "shared",
|
|
772
|
+
onOpenReferences: options.onOpenReferences,
|
|
773
|
+
openReferencesLabel: options.openReferencesLabel
|
|
769
774
|
};
|
|
770
775
|
}
|
|
771
776
|
return {
|
|
@@ -777,8 +782,21 @@ function isMentionRowRenderOptions(options) {
|
|
|
777
782
|
return options !== void 0 && ("classNames" in options || "dataAttributeMode" in options);
|
|
778
783
|
}
|
|
779
784
|
function renderMentionRow(item, options) {
|
|
780
|
-
const {
|
|
785
|
+
const {
|
|
786
|
+
classNames,
|
|
787
|
+
dataAttributeMode,
|
|
788
|
+
onOpenReferences,
|
|
789
|
+
openReferencesLabel
|
|
790
|
+
} = resolveMentionRowRenderOptions(options);
|
|
781
791
|
const resolved = resolveMentionRowClassNames(classNames);
|
|
792
|
+
const referencesButton = onOpenReferences ? /* @__PURE__ */ jsx3(
|
|
793
|
+
MentionOpenReferencesButton,
|
|
794
|
+
{
|
|
795
|
+
label: openReferencesLabel,
|
|
796
|
+
onOpenReferences,
|
|
797
|
+
dataAttributeMode
|
|
798
|
+
}
|
|
799
|
+
) : null;
|
|
782
800
|
if (item.kind === "file") {
|
|
783
801
|
return /* @__PURE__ */ jsx3(
|
|
784
802
|
MentionFileRow,
|
|
@@ -824,26 +842,57 @@ function renderMentionRow(item, options) {
|
|
|
824
842
|
/* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 flex-1 items-baseline gap-1 overflow-hidden", children: [
|
|
825
843
|
/* @__PURE__ */ jsx3("span", { className: "min-w-0 max-w-[40%] shrink-0 truncate text-[13px] font-semibold text-[var(--text-primary)]", children: item.name }),
|
|
826
844
|
item.description ? /* @__PURE__ */ jsx3("span", { className: "min-w-0 flex-1 truncate text-[13px] font-normal text-[var(--text-secondary)]", children: item.description }) : null
|
|
827
|
-
] })
|
|
845
|
+
] }),
|
|
846
|
+
referencesButton
|
|
828
847
|
] });
|
|
829
848
|
}
|
|
830
849
|
if (item.kind === "app-factory") {
|
|
831
850
|
return /* @__PURE__ */ jsx3("span", { className: "grid min-w-0 overflow-hidden gap-1", children: /* @__PURE__ */ jsx3("span", { className: "min-w-0 flex-1 truncate text-[13px] font-semibold text-[var(--text-primary)]", children: item.name }) });
|
|
832
851
|
}
|
|
833
|
-
return /* @__PURE__ */ jsxs2("span", { className: "
|
|
834
|
-
/* @__PURE__ */ jsxs2("span", { className: "
|
|
835
|
-
/* @__PURE__ */
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
852
|
+
return /* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 items-center gap-2 overflow-hidden", children: [
|
|
853
|
+
/* @__PURE__ */ jsxs2("span", { className: "grid min-w-0 flex-1 overflow-hidden gap-1", children: [
|
|
854
|
+
/* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 items-center gap-2 overflow-hidden", children: [
|
|
855
|
+
/* @__PURE__ */ jsx3("span", { className: "min-w-0 truncate text-[13px] font-semibold text-[var(--text-primary)]", children: item.title }),
|
|
856
|
+
item.statusTag ? /* @__PURE__ */ jsx3(
|
|
857
|
+
MentionStatusBadge,
|
|
858
|
+
{
|
|
859
|
+
statusTag: item.statusTag,
|
|
860
|
+
dataAttributeMode
|
|
861
|
+
}
|
|
862
|
+
) : null
|
|
863
|
+
] }),
|
|
864
|
+
item.creatorName ? /* @__PURE__ */ jsx3("span", { className: "truncate text-[13px] font-normal text-[var(--text-secondary)]", children: item.creatorName }) : null
|
|
843
865
|
] }),
|
|
844
|
-
|
|
866
|
+
referencesButton
|
|
845
867
|
] });
|
|
846
868
|
}
|
|
869
|
+
function MentionOpenReferencesButton({
|
|
870
|
+
label,
|
|
871
|
+
onOpenReferences,
|
|
872
|
+
dataAttributeMode
|
|
873
|
+
}) {
|
|
874
|
+
return /* @__PURE__ */ jsx3(
|
|
875
|
+
"span",
|
|
876
|
+
{
|
|
877
|
+
role: "button",
|
|
878
|
+
tabIndex: -1,
|
|
879
|
+
"aria-label": label,
|
|
880
|
+
title: label,
|
|
881
|
+
className: "ml-auto grid h-6 w-6 shrink-0 cursor-pointer place-items-center rounded-[5px] text-[var(--text-tertiary)] transition-colors hover:bg-[var(--transparency-active)] hover:text-[var(--text-secondary)]",
|
|
882
|
+
...mentionRowDataAttribute(dataAttributeMode, "openReferences", "true"),
|
|
883
|
+
onMouseDown: (event) => {
|
|
884
|
+
event.preventDefault();
|
|
885
|
+
event.stopPropagation();
|
|
886
|
+
},
|
|
887
|
+
onClick: (event) => {
|
|
888
|
+
event.preventDefault();
|
|
889
|
+
event.stopPropagation();
|
|
890
|
+
onOpenReferences();
|
|
891
|
+
},
|
|
892
|
+
children: /* @__PURE__ */ jsx3(LocateFolderIcon, { size: 16 })
|
|
893
|
+
}
|
|
894
|
+
);
|
|
895
|
+
}
|
|
847
896
|
function MentionFileRow({
|
|
848
897
|
item,
|
|
849
898
|
classNames,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/at-panel/MentionPalette.tsx","../../src/at-panel/mentionPaletteScrollbar.tsx","../../src/at-panel/MentionRow.tsx","../../src/at-panel/mentionRowDataAttributes.ts","../../src/at-panel/useAtPanelKeyboard.ts"],"sourcesContent":["import {\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type JSX,\n type MutableRefObject,\n type ReactNode\n} from \"react\";\nimport {\n FolderFailedFilledIcon,\n KeyboardFilledIcon\n} from \"@tutti-os/ui-system/icons\";\nimport { Spinner, UnderlineTabs } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport { flattenMentionPaletteEntries } from \"./mentionPaletteEntries.ts\";\nimport { MentionPaletteScrollbar } from \"./mentionPaletteScrollbar.tsx\";\nimport type {\n MentionPaletteGroup,\n MentionPaletteProps,\n MentionPaletteState,\n MentionPaletteTheme\n} from \"./mentionPaletteTypes.ts\";\nimport \"./mentionPalette.css\";\n\nconst DEFAULT_THEME = {\n classNames: {\n palette: \"rich-text-at-mention-palette\",\n header: \"rich-text-at-mention-palette-header\",\n footer: \"rich-text-at-mention-palette-footer\",\n tabs: \"rich-text-at-mention-palette-tabs\",\n scrollRegion: \"rich-text-at-mention-palette-scroll-region\",\n scrollbar: \"rich-text-at-mention-palette-scrollbar\",\n scrollbarThumb: \"rich-text-at-mention-palette-scrollbar-thumb\",\n hint: \"rich-text-at-mention-palette-hint\",\n hintItem: \"rich-text-at-mention-palette-hint-item\",\n hintButton: \"rich-text-at-mention-palette-hint-button\",\n hintSeparator: \"rich-text-at-mention-palette-hint-separator\",\n shortcut: \"rich-text-at-mention-palette-shortcut\",\n shortcutArrow: \"rich-text-at-mention-palette-shortcut--arrow\",\n shortcutButton: \"rich-text-at-mention-palette-shortcut-button\",\n shortcutGroup: \"rich-text-at-mention-palette-shortcut-group\"\n },\n testIds: {\n emptyState: \"rich-text-at-mention-palette-empty-state\",\n hint: \"rich-text-at-mention-palette-hint\",\n scrollbar: \"rich-text-at-mention-palette-scrollbar\",\n loadingSpinner: \"rich-text-at-mention-loading-spinner\"\n },\n groupDividerAttribute: \"data-rich-text-at-mention-group-divider\"\n} as const;\n\ninterface ResolvedMentionPaletteTheme {\n classNames: Required<NonNullable<MentionPaletteTheme[\"classNames\"]>>;\n testIds: Required<NonNullable<MentionPaletteTheme[\"testIds\"]>>;\n groupDividerAttribute: string;\n}\n\nfunction resolveMentionPaletteTheme(\n theme: MentionPaletteTheme | undefined\n): ResolvedMentionPaletteTheme {\n return {\n classNames: { ...DEFAULT_THEME.classNames, ...theme?.classNames },\n testIds: { ...DEFAULT_THEME.testIds, ...theme?.testIds },\n groupDividerAttribute:\n theme?.groupDividerAttribute ?? DEFAULT_THEME.groupDividerAttribute\n };\n}\n\nconst paletteStyles = {\n palette:\n \"nodrag grid h-full max-h-[320px] min-h-0 grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden text-[13px] [-webkit-app-region:no-drag]\",\n header: \"relative z-10 shrink-0\",\n footer: \"shrink-0\",\n scrollShell: \"relative min-h-0 overflow-hidden\",\n scrollBody:\n \"h-full min-h-0 overflow-y-auto overscroll-contain px-1 pb-1 pt-2\",\n rowButton:\n \"nodrag relative flex min-h-9 w-full min-w-0 cursor-pointer select-none items-center gap-1.5 overflow-hidden rounded-[6px] border-0 bg-transparent px-2.5 py-2 text-left text-[13px] text-[var(--text-primary)] outline-hidden transition-colors duration-200 [-webkit-app-region:no-drag] active:bg-[var(--transparency-active)] data-[highlighted]:bg-[var(--transparency-block)] data-[highlighted]:text-[var(--text-primary)] [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:min-w-0 *:[span]:last:flex-1 *:[span]:last:items-center *:[span]:last:gap-2\",\n categoryButton:\n \"nodrag flex min-h-[72px] w-full items-center gap-3.5 rounded-[6px] border-0 bg-transparent px-2.5 py-2.5 text-left text-[var(--text-primary)] transition-[background-color,color] hover:bg-[var(--transparency-block)] focus-visible:bg-[var(--transparency-block)] focus-visible:outline-none active:bg-[var(--transparency-active)]\",\n expandButton:\n \"nodrag flex w-full items-center justify-center rounded-[6px] px-3 py-2 text-[13px] font-medium text-[var(--text-secondary)] transition focus-visible:outline-none active:bg-[var(--transparency-active)] data-[highlighted]:bg-[var(--transparency-block)] data-[highlighted]:text-[var(--text-primary)]\"\n} as const;\n\nconst MENTION_PALETTE_LOADING_MIN_VISIBLE_MS = 320;\n\nexport function MentionPalette<TItem>(\n props: MentionPaletteProps<TItem>\n): JSX.Element {\n \"use memo\";\n const {\n state,\n highlightedKey,\n getItemKey,\n renderItem,\n labels,\n hintLabels,\n maxHeightPx,\n onHighlightChange,\n onSelectItem,\n onSelectCategory,\n onSelectFilter,\n onExpandGroup,\n onCycleFilter,\n onMoveSelection,\n renderListFooter,\n loadingBanner,\n scrollHighlightedIntoViewCentered = false,\n theme: themeProp\n } = props;\n const theme = resolveMentionPaletteTheme(themeProp);\n\n const highlightedOptionRef = useRef<HTMLButtonElement | null>(null);\n const scrollBodyRef = useRef<HTMLDivElement | null>(null);\n const loadingVisibleUntilRef = useRef(0);\n const loadingHideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null\n );\n const [loadingIndicatorVisible, setLoadingIndicatorVisible] = useState(\n state.status === \"loading\"\n );\n\n const interactiveEntries = flattenMentionPaletteEntries(\n state,\n (item, groupId) => getItemKey(item, findGroup(state.groups, groupId))\n );\n const hasInteractiveEntries = interactiveEntries.some(\n (entry) => entry.type === \"item\" || entry.type === \"expand\"\n );\n\n const showLoadingState =\n loadingIndicatorVisible &&\n (!hasInteractiveEntries || state.mode === \"browse\");\n const showLoadingBanner =\n Boolean(loadingBanner) &&\n loadingIndicatorVisible &&\n hasInteractiveEntries &&\n state.mode === \"results\";\n\n useEffect(() => {\n const highlightedElement = highlightedOptionRef.current;\n if (!highlightedElement) {\n return;\n }\n const scrollContainer = scrollBodyRef.current;\n if (!scrollContainer || !scrollContainer.contains(highlightedElement)) {\n highlightedElement.scrollIntoView({ block: \"nearest\" });\n return;\n }\n if (!scrollHighlightedIntoViewCentered) {\n return;\n }\n centerElementInScrollContainer(scrollContainer, highlightedElement);\n }, [highlightedKey, scrollHighlightedIntoViewCentered]);\n\n useEffect(() => {\n if (loadingHideTimerRef.current !== null) {\n clearTimeout(loadingHideTimerRef.current);\n loadingHideTimerRef.current = null;\n }\n\n if (state.status === \"loading\") {\n loadingVisibleUntilRef.current =\n Date.now() + MENTION_PALETTE_LOADING_MIN_VISIBLE_MS;\n setLoadingIndicatorVisible(true);\n return;\n }\n\n const remainingMs = loadingVisibleUntilRef.current - Date.now();\n if (remainingMs <= 0) {\n setLoadingIndicatorVisible(false);\n return;\n }\n\n loadingHideTimerRef.current = setTimeout(() => {\n loadingHideTimerRef.current = null;\n setLoadingIndicatorVisible(false);\n }, remainingMs);\n\n return () => {\n if (loadingHideTimerRef.current !== null) {\n clearTimeout(loadingHideTimerRef.current);\n loadingHideTimerRef.current = null;\n }\n };\n }, [state.status]);\n\n const paletteMaxHeightStyle: CSSProperties | undefined =\n maxHeightPx > 0 ? { maxHeight: `${maxHeightPx}px` } : undefined;\n\n if (state.status === \"error\") {\n return (\n <div\n className={cn(theme.classNames.palette, paletteStyles.palette)}\n style={paletteMaxHeightStyle}\n role=\"listbox\"\n aria-label={labels.listbox ?? labels.tabHint}\n >\n <MentionPaletteEmptyState\n icon=\"folder-failed\"\n label={labels.error}\n testId={theme.testIds.emptyState}\n />\n </div>\n );\n }\n\n const isBrowse = state.mode === \"browse\";\n\n let body: ReactNode;\n if (showLoadingState) {\n body = (\n <MentionPaletteLoading\n label={labels.loading}\n spinnerTestId={theme.testIds.loadingSpinner}\n />\n );\n } else if (state.groups.length === 0) {\n body = (\n <MentionPaletteEmptyState\n icon={isBrowse ? \"keyboard\" : \"folder-failed\"}\n label={labels.empty}\n testId={theme.testIds.emptyState}\n />\n );\n } else {\n body = (\n <MentionPaletteGroups\n state={state}\n highlightedKey={highlightedKey}\n highlightedOptionRef={highlightedOptionRef}\n getItemKey={getItemKey}\n renderItem={renderItem}\n onHighlightChange={onHighlightChange}\n onSelectItem={onSelectItem}\n onExpandGroup={onExpandGroup}\n renderListFooter={renderListFooter}\n groupDividerAttribute={theme.groupDividerAttribute}\n />\n );\n }\n\n return (\n <div\n className={cn(theme.classNames.palette, paletteStyles.palette)}\n style={paletteMaxHeightStyle}\n role=\"listbox\"\n aria-label={labels.listbox ?? labels.tabHint}\n >\n <div className={cn(theme.classNames.header, paletteStyles.header)}>\n <UnderlineTabs\n tabs={state.categories.map((category) => ({\n value: category.id,\n label: category.label\n }))}\n value={state.filter}\n onValueChange={isBrowse ? onSelectCategory : onSelectFilter}\n className={theme.classNames.tabs}\n preventMouseDownDefault\n />\n {showLoadingBanner ? loadingBanner : null}\n </div>\n <div className={paletteStyles.scrollShell}>\n <div\n ref={scrollBodyRef}\n className={cn(\n theme.classNames.scrollRegion,\n paletteStyles.scrollBody\n )}\n >\n {body}\n </div>\n <MentionPaletteScrollbar\n scrollBodyRef={scrollBodyRef}\n className={theme.classNames.scrollbar}\n thumbClassName={theme.classNames.scrollbarThumb}\n testId={theme.testIds.scrollbar}\n />\n </div>\n <div className={cn(theme.classNames.footer, paletteStyles.footer)}>\n <MentionPaletteHint\n ariaLabel={labels.tabHint}\n cycleFilterLabel={hintLabels.cycleFilter}\n moveSelectionLabel={hintLabels.moveSelection}\n onCycleFilter={onCycleFilter}\n onMoveSelection={onMoveSelection}\n classNames={theme.classNames}\n testId={theme.testIds.hint}\n />\n </div>\n </div>\n );\n}\n\nfunction centerElementInScrollContainer(\n container: HTMLElement,\n element: HTMLElement\n): void {\n const containerRect = container.getBoundingClientRect();\n const elementRect = element.getBoundingClientRect();\n const currentScrollTop = container.scrollTop;\n const elementTop = elementRect.top - containerRect.top + currentScrollTop;\n const centeredScrollTop =\n elementTop - (container.clientHeight - elementRect.height) / 2;\n const maxScrollTop = Math.max(\n 0,\n container.scrollHeight - container.clientHeight\n );\n const nextScrollTop = Math.min(Math.max(0, centeredScrollTop), maxScrollTop);\n container.scrollTo({ top: nextScrollTop, behavior: \"auto\" });\n}\n\nfunction findGroup<TItem>(\n groups: MentionPaletteState<TItem>[\"groups\"],\n groupId: string\n): MentionPaletteGroup<TItem> {\n const group = groups.find((candidate) => candidate.id === groupId);\n if (!group) {\n throw new Error(`MentionPalette: unknown group id \"${groupId}\"`);\n }\n return group;\n}\n\nfunction MentionPaletteGroups<TItem>({\n state,\n highlightedKey,\n highlightedOptionRef,\n getItemKey,\n renderItem,\n onHighlightChange,\n onSelectItem,\n onExpandGroup,\n renderListFooter,\n groupDividerAttribute\n}: {\n state: MentionPaletteState<TItem>;\n highlightedKey: string | null;\n highlightedOptionRef: MutableRefObject<HTMLButtonElement | null>;\n getItemKey: (item: TItem, group: MentionPaletteGroup<TItem>) => string;\n renderItem: (item: TItem, ctx: { active: boolean }) => ReactNode;\n onHighlightChange: (key: string) => void;\n onSelectItem: (item: TItem, group: MentionPaletteGroup<TItem>) => void;\n onExpandGroup: (groupId: string) => void;\n renderListFooter?: () => ReactNode;\n groupDividerAttribute: string;\n}): JSX.Element {\n return (\n <div className=\"grid gap-3\">\n {state.groups.map((group, index) => {\n const showGroupDivider = index > 0 && !group.hideTopDivider;\n return (\n <section\n key={group.id}\n className={cn(\"grid gap-1\", group.sectionClassName)}\n >\n {showGroupDivider ? (\n <div\n className=\"mx-3 mb-2 border-t border-[var(--line-1)]\"\n {...{ [groupDividerAttribute]: \"true\" }}\n aria-hidden=\"true\"\n />\n ) : null}\n {group.label ? (\n <div className=\"px-3 text-[13px] font-normal text-[var(--text-secondary)]\">\n {group.label}\n </div>\n ) : null}\n <div className=\"grid gap-1\">\n {group.items.length === 0 && group.emptyLabel ? (\n <div className=\"px-3 py-1 text-[13px] font-normal text-[var(--text-tertiary)]\">\n {group.emptyLabel}\n </div>\n ) : null}\n {group.items.map((item) => {\n const entryKey = `${group.id}:${getItemKey(item, group)}`;\n const isHighlighted = entryKey === highlightedKey;\n return (\n <button\n key={entryKey}\n ref={isHighlighted ? highlightedOptionRef : null}\n type=\"button\"\n className={cn(\n paletteStyles.rowButton,\n isHighlighted && \"bg-[var(--transparency-block)]\"\n )}\n role=\"option\"\n aria-selected={isHighlighted}\n data-highlighted={isHighlighted ? \"\" : undefined}\n onMouseEnter={() => onHighlightChange(entryKey)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onSelectItem(item, group)}\n >\n {renderItem(item, { active: isHighlighted })}\n </button>\n );\n })}\n {group.hasMore ? (\n <button\n key={`expand:${group.id}`}\n ref={\n `expand:${group.id}` === highlightedKey\n ? highlightedOptionRef\n : null\n }\n type=\"button\"\n className={cn(\n paletteStyles.expandButton,\n `expand:${group.id}` === highlightedKey &&\n \"bg-[var(--transparency-block)] text-[var(--text-primary)]\"\n )}\n data-highlighted={\n `expand:${group.id}` === highlightedKey ? \"\" : undefined\n }\n onMouseEnter={() => onHighlightChange(`expand:${group.id}`)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onExpandGroup(group.id)}\n >\n {group.expandLabel ??\n `+${Math.max(0, group.totalCount - group.visibleCount)}`}\n </button>\n ) : null}\n </div>\n </section>\n );\n })}\n {renderListFooter?.()}\n </div>\n );\n}\n\nfunction MentionPaletteEmptyState({\n icon = \"folder-failed\",\n label,\n testId\n}: {\n icon?: \"folder-failed\" | \"keyboard\";\n label: string;\n testId: string;\n}): JSX.Element {\n \"use memo\";\n const EmptyStateIcon =\n icon === \"keyboard\" ? KeyboardFilledIcon : FolderFailedFilledIcon;\n\n return (\n <div\n className=\"flex h-full min-h-0 flex-1 items-center justify-center px-4 py-6 text-center text-[13px] text-[var(--text-tertiary)]\"\n data-empty-state-icon={icon}\n data-testid={testId}\n >\n <div className=\"flex max-w-[28ch] flex-col items-center justify-center gap-3\">\n <EmptyStateIcon\n className=\"h-6 w-6 text-[var(--text-tertiary)]\"\n aria-hidden=\"true\"\n />\n <span className=\"leading-5 text-[var(--text-tertiary)]\">{label}</span>\n </div>\n </div>\n );\n}\n\nfunction MentionPaletteLoading({\n label,\n spinnerTestId\n}: {\n label: string;\n spinnerTestId: string;\n}): JSX.Element {\n \"use memo\";\n return (\n <div className=\"flex min-h-[52px] items-center gap-2 rounded-xl px-3 text-[13px] text-[var(--text-secondary)]\">\n <Spinner\n size={16}\n className=\"text-[var(--text-secondary)]\"\n testId={spinnerTestId}\n />\n <span>{label}</span>\n </div>\n );\n}\n\nfunction MentionPaletteHint({\n ariaLabel,\n cycleFilterLabel,\n moveSelectionLabel,\n onCycleFilter,\n onMoveSelection,\n classNames,\n testId\n}: {\n ariaLabel: string;\n cycleFilterLabel: string;\n moveSelectionLabel: string;\n onCycleFilter: (delta: 1 | -1) => void;\n onMoveSelection: (delta: 1 | -1) => void;\n classNames: ResolvedMentionPaletteTheme[\"classNames\"];\n testId: string;\n}): JSX.Element {\n \"use memo\";\n return (\n <div\n className={classNames.hint}\n aria-label={ariaLabel}\n data-testid={testId}\n >\n <button\n className={cn(classNames.hintItem, classNames.hintButton)}\n type=\"button\"\n aria-label={cycleFilterLabel}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onCycleFilter(1)}\n >\n {/* i18n-check-ignore: Keyboard key label. */}\n <kbd className={classNames.shortcut}>Tab</kbd>\n <span>{cycleFilterLabel}</span>\n </button>\n <span className={classNames.hintSeparator} aria-hidden=\"true\">\n |\n </span>\n <span className={classNames.hintItem}>\n <span className={classNames.shortcutGroup}>\n <button\n className={cn(\n classNames.shortcut,\n classNames.shortcutArrow,\n classNames.shortcutButton\n )}\n type=\"button\"\n aria-label={`↑ ${moveSelectionLabel}`}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onMoveSelection(-1)}\n >\n ↑\n </button>\n <button\n className={cn(\n classNames.shortcut,\n classNames.shortcutArrow,\n classNames.shortcutButton\n )}\n type=\"button\"\n aria-label={`↓ ${moveSelectionLabel}`}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onMoveSelection(1)}\n >\n ↓\n </button>\n </span>\n <span>{moveSelectionLabel}</span>\n </span>\n </div>\n );\n}\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n type JSX,\n type MouseEvent as ReactMouseEvent,\n type RefObject\n} from \"react\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\n\ninterface MentionPaletteScrollbarState {\n scrollable: boolean;\n thumbHeight: number;\n thumbTop: number;\n}\n\ninterface MentionPaletteScrollbarDragState {\n maxScrollTop: number;\n maxThumbTop: number;\n startClientY: number;\n startScrollTop: number;\n}\n\nconst MENTION_PALETTE_SCROLLBAR_MIN_THUMB_HEIGHT = 24;\nconst MENTION_PALETTE_SCROLLBAR_HIDDEN_STATE: MentionPaletteScrollbarState = {\n scrollable: false,\n thumbHeight: 0,\n thumbTop: 0\n};\n\nexport function MentionPaletteScrollbar({\n scrollBodyRef,\n className,\n thumbClassName,\n testId\n}: {\n scrollBodyRef: RefObject<HTMLDivElement | null>;\n className: string;\n thumbClassName: string;\n testId: string;\n}): JSX.Element {\n \"use memo\";\n const trackRef = useRef<HTMLDivElement | null>(null);\n const dragStateRef = useRef<MentionPaletteScrollbarDragState | null>(null);\n const [scrollbarState, setScrollbarState] =\n useState<MentionPaletteScrollbarState>({\n scrollable: false,\n thumbHeight: 0,\n thumbTop: 0\n });\n const [dragging, setDragging] = useState(false);\n\n const hideScrollbar = useCallback((): void => {\n setScrollbarState((previous) =>\n previous.scrollable ||\n previous.thumbHeight !== 0 ||\n previous.thumbTop !== 0\n ? MENTION_PALETTE_SCROLLBAR_HIDDEN_STATE\n : previous\n );\n }, []);\n\n const syncScrollbarState = useCallback((): void => {\n const contentElement = scrollBodyRef.current;\n if (!contentElement) {\n hideScrollbar();\n return;\n }\n\n const { scrollHeight, scrollTop, clientHeight } = contentElement;\n const measuredTrackHeight = trackRef.current?.clientHeight ?? 0;\n const trackHeight =\n measuredTrackHeight > 0 ? measuredTrackHeight : clientHeight;\n const maxScrollTop = Math.max(0, scrollHeight - clientHeight);\n\n if (clientHeight <= 0 || trackHeight <= 0 || maxScrollTop <= 0) {\n hideScrollbar();\n return;\n }\n\n const thumbHeight = Math.max(\n MENTION_PALETTE_SCROLLBAR_MIN_THUMB_HEIGHT,\n Math.round((clientHeight / scrollHeight) * trackHeight)\n );\n const maxThumbTop = Math.max(0, trackHeight - thumbHeight);\n const thumbTop = Math.round((scrollTop / maxScrollTop) * maxThumbTop);\n setScrollbarState((previous) =>\n previous.scrollable &&\n previous.thumbHeight === thumbHeight &&\n previous.thumbTop === thumbTop\n ? previous\n : { scrollable: true, thumbHeight, thumbTop }\n );\n }, [hideScrollbar, scrollBodyRef]);\n\n useEffect(() => {\n const contentElement = scrollBodyRef.current;\n if (!contentElement) {\n hideScrollbar();\n return;\n }\n\n syncScrollbarState();\n contentElement.addEventListener(\"scroll\", syncScrollbarState, {\n passive: true\n });\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(syncScrollbarState)\n : null;\n resizeObserver?.observe(contentElement);\n if (trackRef.current) {\n resizeObserver?.observe(trackRef.current);\n }\n const animationFrameId = window.requestAnimationFrame(syncScrollbarState);\n return () => {\n contentElement.removeEventListener(\"scroll\", syncScrollbarState);\n resizeObserver?.disconnect();\n window.cancelAnimationFrame(animationFrameId);\n };\n }, [hideScrollbar, scrollBodyRef, syncScrollbarState]);\n\n useEffect(() => {\n if (!dragging) {\n return;\n }\n\n const handleMouseMove = (event: MouseEvent): void => {\n const contentElement = scrollBodyRef.current;\n const dragState = dragStateRef.current;\n if (!contentElement || !dragState || dragState.maxThumbTop <= 0) {\n return;\n }\n const delta = event.clientY - dragState.startClientY;\n const nextThumbTop =\n (dragState.startScrollTop / dragState.maxScrollTop) *\n dragState.maxThumbTop +\n delta;\n contentElement.scrollTop =\n (Math.min(Math.max(0, nextThumbTop), dragState.maxThumbTop) /\n dragState.maxThumbTop) *\n dragState.maxScrollTop;\n syncScrollbarState();\n };\n\n const handleMouseUp = (): void => {\n dragStateRef.current = null;\n setDragging(false);\n };\n\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleMouseUp);\n return () => {\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [dragging, scrollBodyRef, syncScrollbarState]);\n\n const scrollContentToThumbTop = (thumbTop: number): void => {\n const contentElement = scrollBodyRef.current;\n const trackElement = trackRef.current;\n if (!contentElement || !trackElement) {\n return;\n }\n const maxScrollTop = Math.max(\n 0,\n contentElement.scrollHeight - contentElement.clientHeight\n );\n const maxThumbTop = Math.max(\n 0,\n trackElement.clientHeight - scrollbarState.thumbHeight\n );\n if (maxScrollTop <= 0 || maxThumbTop <= 0) {\n return;\n }\n contentElement.scrollTop =\n (Math.min(Math.max(0, thumbTop), maxThumbTop) / maxThumbTop) *\n maxScrollTop;\n syncScrollbarState();\n };\n\n const handleTrackMouseDown = (\n event: ReactMouseEvent<HTMLDivElement>\n ): void => {\n if (\n event.button !== 0 ||\n !scrollbarState.scrollable ||\n event.target !== event.currentTarget\n ) {\n return;\n }\n event.preventDefault();\n const trackRect = event.currentTarget.getBoundingClientRect();\n scrollContentToThumbTop(\n event.clientY - trackRect.top - scrollbarState.thumbHeight / 2\n );\n };\n\n const handleThumbMouseDown = (\n event: ReactMouseEvent<HTMLDivElement>\n ): void => {\n if (event.button !== 0 || !scrollbarState.scrollable) {\n return;\n }\n const contentElement = scrollBodyRef.current;\n const trackElement = trackRef.current;\n if (!contentElement || !trackElement) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n dragStateRef.current = {\n maxScrollTop: Math.max(\n 0,\n contentElement.scrollHeight - contentElement.clientHeight\n ),\n maxThumbTop: Math.max(\n 0,\n trackElement.clientHeight - scrollbarState.thumbHeight\n ),\n startClientY: event.clientY,\n startScrollTop: contentElement.scrollTop\n };\n setDragging(true);\n };\n\n if (!scrollbarState.scrollable && !dragging) {\n return <div ref={trackRef} className=\"hidden\" aria-hidden=\"true\" />;\n }\n\n return (\n <div\n ref={trackRef}\n className={cn(\"group/status-scrollbar\", className)}\n data-scrollable={scrollbarState.scrollable ? \"true\" : \"false\"}\n data-dragging={dragging ? \"true\" : \"false\"}\n data-testid={testId}\n aria-hidden=\"true\"\n onMouseDown={handleTrackMouseDown}\n >\n <div\n className={thumbClassName}\n onMouseDown={handleThumbMouseDown}\n style={{\n height: `${scrollbarState.thumbHeight}px`,\n transform: `translateY(${scrollbarState.thumbTop}px)`\n }}\n />\n </div>\n );\n}\n","import {\n ArrowLeftIcon,\n Badge,\n FileCodeIcon,\n FileTextIcon,\n FolderIcon,\n ImageFileIcon,\n ProductIcon,\n StatusDot,\n VideoFileIcon,\n cn,\n type IconProps\n} from \"@tutti-os/ui-system\";\nimport type { MentionFileVisualKind } from \"./mentionFileVisualKind.ts\";\nimport {\n mentionRowDataAttribute,\n mentionRowRootDataAttributes,\n type MentionRowDataAttributeMode\n} from \"./mentionRowDataAttributes.ts\";\nimport type {\n MentionRowFileItem,\n MentionRowItem,\n MentionRowSessionItem,\n MentionRowStatusTag\n} from \"./mentionRowTypes.ts\";\nimport { mentionStatusBadgeClassName } from \"./mentionStatusTone.ts\";\n\n/**\n * Default file kind-icon shapes for surfaces that do NOT ship the agent's\n * CSS-masked glyph stylesheet. These mirror the agent's mask glyph shapes\n * (`agentactivity.css`: folder-filled / doc-filled / code-filled / image-filled\n * / video-filled / arrow-left-filled) using ui-system icon components, so a\n * file row renders a real glyph without `agentactivity.css`. The agent composer\n * passes its own `fileIcon` class and keeps rendering the masked `<span>`.\n */\nconst MENTION_FILE_VISUAL_KIND_ICON: Record<\n MentionFileVisualKind,\n (props: IconProps) => React.JSX.Element\n> = {\n back: ArrowLeftIcon,\n folder: FolderIcon,\n document: FileTextIcon,\n // The agent maps markdown to `product-filled.svg`; ProductIcon is the\n // matching boundary-safe ui-system glyph.\n markdown: ProductIcon,\n code: FileCodeIcon,\n image: ImageFileIcon,\n video: VideoFileIcon\n};\n\n/**\n * Structural class-name hooks for the elements a {@link MentionRow} renders that\n * rely on a stylesheet (file icon/thumb, the app fallback kind-icon, and the\n * session avatar placeholder modifier). Every key is optional and defaults to a\n * PACKAGE-OWNED `rich-text-at-mention-*` class whose CSS ships with\n * `mentionPalette.css`, so any consumer renders styled rows out of the box.\n *\n * Surfaces with their own stylesheet (e.g. the agent composer) pass their exact\n * existing class names here so their rendered DOM stays byte-identical.\n */\nexport interface MentionRowClassNames {\n /** The masked file kind-icon `<span>`. */\n fileIcon?: string;\n /** The image-thumbnail wrapper `<span>` (rendered for image files). */\n fileThumb?: string;\n /** The fallback app icon glyph rendered when no `iconUrl` is present. */\n kindIcon?: string;\n /**\n * Modifier class added to the session user avatar `<img>` when the user has no\n * avatar URL and the placeholder asset is shown.\n */\n avatarImgUserPlaceholder?: string;\n}\n\nexport interface MentionRowRenderOptions {\n classNames?: MentionRowClassNames;\n dataAttributeMode?: MentionRowDataAttributeMode;\n}\n\ninterface ResolvedMentionRowRenderOptions {\n classNames?: MentionRowClassNames;\n dataAttributeMode: MentionRowDataAttributeMode;\n}\n\nconst DEFAULT_MENTION_ROW_CLASS_NAMES = {\n fileIcon: \"rich-text-at-mention-file-icon\",\n fileThumb: \"rich-text-at-mention-file-thumb\",\n kindIcon: \"rich-text-at-mention-kind-icon\",\n avatarImgUserPlaceholder: \"rich-text-at-mention-avatar-img--user-placeholder\"\n} as const satisfies Required<MentionRowClassNames>;\n\nfunction resolveMentionRowClassNames(\n classNames?: MentionRowClassNames\n): Required<MentionRowClassNames> {\n return {\n fileIcon: classNames?.fileIcon ?? DEFAULT_MENTION_ROW_CLASS_NAMES.fileIcon,\n fileThumb:\n classNames?.fileThumb ?? DEFAULT_MENTION_ROW_CLASS_NAMES.fileThumb,\n kindIcon: classNames?.kindIcon ?? DEFAULT_MENTION_ROW_CLASS_NAMES.kindIcon,\n avatarImgUserPlaceholder:\n classNames?.avatarImgUserPlaceholder ??\n DEFAULT_MENTION_ROW_CLASS_NAMES.avatarImgUserPlaceholder\n };\n}\n\nfunction resolveMentionRowRenderOptions(\n options?: MentionRowClassNames | MentionRowRenderOptions\n): ResolvedMentionRowRenderOptions {\n if (isMentionRowRenderOptions(options)) {\n return {\n classNames: options.classNames,\n dataAttributeMode: options.dataAttributeMode ?? \"shared\"\n };\n }\n return {\n classNames: options,\n dataAttributeMode: \"shared\"\n };\n}\n\nfunction isMentionRowRenderOptions(\n options: MentionRowClassNames | MentionRowRenderOptions | undefined\n): options is MentionRowRenderOptions {\n return (\n options !== undefined &&\n (\"classNames\" in options || \"dataAttributeMode\" in options)\n );\n}\n\n/**\n * Render the inner content of a single `@`-mention palette row from a\n * fully-resolved {@link MentionRowItem}. The surrounding option button / active\n * state is provided by the shared `MentionPalette` shell; this renders only the\n * row body.\n *\n * Pass {@link classNames} to override the package-owned structural class hooks\n * (e.g. so the agent composer keeps emitting its own stylesheet's class names).\n */\nexport function renderMentionRow(\n item: MentionRowItem,\n options?: MentionRowClassNames | MentionRowRenderOptions\n): React.ReactNode {\n const { classNames, dataAttributeMode } =\n resolveMentionRowRenderOptions(options);\n const resolved = resolveMentionRowClassNames(classNames);\n if (item.kind === \"file\") {\n return (\n <MentionFileRow\n item={item}\n classNames={resolved}\n dataAttributeMode={dataAttributeMode}\n />\n );\n }\n\n if (item.kind === \"session\") {\n return (\n <span className=\"grid w-full min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-3\">\n <span className=\"flex min-w-0 items-center gap-2 overflow-hidden\">\n <MentionSessionAvatarStack\n item={item}\n classNames={resolved}\n dataAttributeMode={dataAttributeMode}\n />\n <span className=\"min-w-0 truncate text-[13px] font-semibold leading-[16px] text-[var(--text-primary)]\">\n <MentionSessionTitle item={item} />\n </span>\n </span>\n {item.statusTag ? (\n <MentionStatusBadge\n statusTag={item.statusTag}\n dataAttributeMode={dataAttributeMode}\n />\n ) : null}\n </span>\n );\n }\n\n if (item.kind === \"app\") {\n return (\n <span className=\"flex min-w-0 items-center gap-2 overflow-hidden\">\n <MentionWorkspaceAppIcon\n iconUrl={item.iconUrl}\n kindIconClassName={resolved.kindIcon}\n dataAttributeMode={dataAttributeMode}\n />\n <span className=\"flex min-w-0 flex-1 items-baseline gap-1 overflow-hidden\">\n <span className=\"min-w-0 max-w-[40%] shrink-0 truncate text-[13px] font-semibold text-[var(--text-primary)]\">\n {item.name}\n </span>\n {item.description ? (\n <span className=\"min-w-0 flex-1 truncate text-[13px] font-normal text-[var(--text-secondary)]\">\n {item.description}\n </span>\n ) : null}\n </span>\n </span>\n );\n }\n\n if (item.kind === \"app-factory\") {\n return (\n <span className=\"grid min-w-0 overflow-hidden gap-1\">\n <span className=\"min-w-0 flex-1 truncate text-[13px] font-semibold text-[var(--text-primary)]\">\n {item.name}\n </span>\n </span>\n );\n }\n\n return (\n <span className=\"grid min-w-0 overflow-hidden gap-1\">\n <span className=\"flex min-w-0 items-center gap-2 overflow-hidden\">\n <span className=\"min-w-0 truncate text-[13px] font-semibold text-[var(--text-primary)]\">\n {item.title}\n </span>\n {item.statusTag ? (\n <MentionStatusBadge\n statusTag={item.statusTag}\n dataAttributeMode={dataAttributeMode}\n />\n ) : null}\n </span>\n {item.creatorName ? (\n <span className=\"truncate text-[13px] font-normal text-[var(--text-secondary)]\">\n {item.creatorName}\n </span>\n ) : null}\n </span>\n );\n}\n\nfunction MentionFileRow({\n item,\n classNames,\n dataAttributeMode\n}: {\n item: MentionRowFileItem;\n classNames: Required<MentionRowClassNames>;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n return (\n <span\n className=\"flex min-w-0 items-center gap-2\"\n {...mentionRowRootDataAttributes(dataAttributeMode, \"file\")}\n {...(item.entryKind\n ? mentionRowDataAttribute(\n dataAttributeMode,\n \"fileEntryKind\",\n item.entryKind\n )\n : {})}\n {...mentionRowDataAttribute(\n dataAttributeMode,\n \"fileVisualKind\",\n item.visualKind\n )}\n {...(item.mentionNavigation\n ? mentionRowDataAttribute(\n dataAttributeMode,\n \"navigation\",\n item.mentionNavigation\n )\n : {})}\n >\n <MentionFileIcon\n item={item}\n classNames={classNames}\n dataAttributeMode={dataAttributeMode}\n />\n <span className=\"flex min-w-0 items-baseline gap-1 overflow-hidden\">\n <span className=\"min-w-0 truncate text-[13px] font-semibold text-[var(--text-primary)]\">\n {item.name}\n </span>\n {item.childCountLabel ? (\n <span className=\"shrink-0 text-[13px] font-normal text-[var(--text-secondary)]\">\n {item.childCountLabel}\n </span>\n ) : null}\n </span>\n </span>\n );\n}\n\nfunction MentionFileIcon({\n item,\n classNames,\n dataAttributeMode\n}: {\n item: MentionRowFileItem;\n classNames: Required<MentionRowClassNames>;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n const thumbnailUrl =\n item.visualKind === \"image\" ? item.thumbnailUrl?.trim() || \"\" : \"\";\n if (thumbnailUrl) {\n return (\n <span\n className={classNames.fileThumb}\n {...mentionRowDataAttribute(dataAttributeMode, \"fileThumb\", \"true\")}\n aria-hidden=\"true\"\n >\n <img\n src={thumbnailUrl}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n decoding=\"async\"\n loading=\"lazy\"\n draggable={false}\n />\n </span>\n );\n }\n\n // Surfaces that ship a custom file-icon stylesheet (e.g. the agent composer\n // via `agentactivity.css`) render the empty CSS-masked `<span>` so their DOM\n // stays byte-identical. Surfaces using the package default class have no such\n // stylesheet, so render a real ui-system kind glyph instead of an empty box.\n const usesDefaultFileIcon =\n classNames.fileIcon === DEFAULT_MENTION_ROW_CLASS_NAMES.fileIcon;\n if (usesDefaultFileIcon) {\n const Icon = MENTION_FILE_VISUAL_KIND_ICON[item.visualKind];\n return (\n <span\n className={cn(\n classNames.fileIcon,\n \"grid h-4 w-4 shrink-0 place-items-center text-[var(--text-secondary)]\"\n )}\n {...mentionRowDataAttribute(\n dataAttributeMode,\n \"fileVisualKind\",\n item.visualKind\n )}\n aria-hidden=\"true\"\n >\n <Icon size={16} />\n </span>\n );\n }\n\n return (\n <span\n className={classNames.fileIcon}\n {...mentionRowDataAttribute(\n dataAttributeMode,\n \"fileVisualKind\",\n item.visualKind\n )}\n aria-hidden=\"true\"\n />\n );\n}\n\nfunction MentionWorkspaceAppIcon({\n iconUrl,\n kindIconClassName,\n dataAttributeMode\n}: {\n iconUrl?: string | null;\n kindIconClassName: string;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n const normalizedIconUrl = iconUrl?.trim() ?? \"\";\n return (\n <span\n className=\"grid h-5 w-5 shrink-0 place-items-center overflow-hidden rounded-[5px] bg-block text-[var(--text-secondary)]\"\n {...mentionRowDataAttribute(dataAttributeMode, \"appIcon\", \"true\")}\n data-workspace-app-icon=\"true\"\n aria-hidden=\"true\"\n >\n {normalizedIconUrl ? (\n <img\n src={normalizedIconUrl}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n decoding=\"async\"\n loading=\"lazy\"\n draggable={false}\n />\n ) : (\n <span className={cn(kindIconClassName, \"h-4 w-4\")} />\n )}\n </span>\n );\n}\n\nfunction MentionSessionAvatarStack({\n item,\n classNames,\n dataAttributeMode\n}: {\n item: MentionRowSessionItem;\n classNames: Required<MentionRowClassNames>;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n const userAvatarUrl = item.userAvatarUrl?.trim() ?? \"\";\n const placeholderUrl = item.userAvatarPlaceholderUrl;\n const userImageUrl = userAvatarUrl || placeholderUrl;\n return (\n <span\n className=\"relative isolate block h-5 w-9 shrink-0\"\n aria-hidden=\"true\"\n >\n <span\n className=\"absolute left-0 top-0 z-0 grid h-5 w-5 overflow-hidden rounded-full bg-block\"\n {...mentionRowDataAttribute(dataAttributeMode, \"userAvatar\", \"true\")}\n >\n <img\n src={userImageUrl}\n alt=\"\"\n className={cn(\n \"h-full w-full object-cover\",\n !userAvatarUrl && classNames.avatarImgUserPlaceholder\n )}\n decoding=\"async\"\n loading=\"lazy\"\n referrerPolicy=\"no-referrer\"\n draggable={false}\n onError={(event) => {\n if (event.currentTarget.dataset.fallbackAvatarApplied === \"true\") {\n return;\n }\n event.currentTarget.dataset.fallbackAvatarApplied = \"true\";\n event.currentTarget.src = placeholderUrl;\n event.currentTarget.classList.add(\n classNames.avatarImgUserPlaceholder\n );\n }}\n />\n </span>\n <span\n className=\"absolute left-4 top-0 z-10 grid h-5 w-5 overflow-hidden rounded-full bg-block\"\n {...mentionRowDataAttribute(dataAttributeMode, \"agentAvatar\", \"true\")}\n >\n <img\n src={item.agentIconUrl}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n decoding=\"async\"\n loading=\"lazy\"\n draggable={false}\n />\n </span>\n </span>\n );\n}\n\nfunction MentionSessionTitle({\n item\n}: {\n item: MentionRowSessionItem;\n}): React.JSX.Element {\n return (\n <>\n <span className=\"text-[13px] leading-[16px]\">{item.participant}</span>\n <span className=\"text-[13px] font-normal leading-[16px] text-[var(--text-secondary)]\">\n {\" \"}\n {item.summary ?? \"\"}\n </span>\n </>\n );\n}\n\nfunction MentionStatusBadge({\n statusTag,\n dataAttributeMode\n}: {\n statusTag: MentionRowStatusTag;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n if (statusTag.variant === \"issue\") {\n return (\n <Badge\n variant=\"secondary\"\n className={cn(\n \"shrink-0 text-[13px]\",\n mentionStatusBadgeClassName({\n tone: statusTag.tone,\n variant: \"issue\"\n })\n )}\n {...mentionRowDataAttribute(dataAttributeMode, \"statusTag\", \"true\")}\n {...(statusTag.dataStatus\n ? { \"data-status\": statusTag.dataStatus }\n : {})}\n >\n {statusTag.label}\n </Badge>\n );\n }\n\n return (\n <Badge\n variant=\"secondary\"\n className={cn(\n \"inline-flex h-5 shrink-0 items-center gap-1.5 rounded-[4px] px-2 text-[11px] font-semibold leading-none\",\n mentionStatusBadgeClassName({\n tone: statusTag.tone,\n variant: \"activity\"\n })\n )}\n {...mentionRowDataAttribute(dataAttributeMode, \"statusTag\", \"true\")}\n {...(statusTag.dataStatus ? { \"data-status\": statusTag.dataStatus } : {})}\n data-tone={statusTag.tone}\n title={statusTag.label}\n >\n <StatusDot\n tone={statusTag.tone}\n pulse={statusTag.pulse ?? false}\n size=\"xs\"\n title={statusTag.label}\n />\n <span>{statusTag.label}</span>\n </Badge>\n );\n}\n","import type { MentionRowItem } from \"./mentionRowTypes.ts\";\n\nexport type MentionRowDataAttributeMode = \"shared\" | \"agent\";\n\nexport type MentionRowDataAttributeKey =\n | \"agentAvatar\"\n | \"appIcon\"\n | \"fileEntryKind\"\n | \"fileThumb\"\n | \"fileVisualKind\"\n | \"navigation\"\n | \"statusTag\"\n | \"userAvatar\";\n\nconst MENTION_ROW_DATA_ATTRIBUTES: Record<\n MentionRowDataAttributeMode,\n Record<MentionRowDataAttributeKey, string>\n> = {\n shared: {\n agentAvatar: \"data-rich-text-at-mention-agent-avatar\",\n appIcon: \"data-rich-text-at-mention-app-icon\",\n fileEntryKind: \"data-rich-text-at-mention-file-entry-kind\",\n fileThumb: \"data-rich-text-at-mention-file-thumb\",\n fileVisualKind: \"data-rich-text-at-mention-file-visual-kind\",\n navigation: \"data-rich-text-at-mention-navigation\",\n statusTag: \"data-rich-text-at-mention-status-tag\",\n userAvatar: \"data-rich-text-at-mention-user-avatar\"\n },\n agent: {\n agentAvatar: \"data-agent-mention-agent-avatar\",\n appIcon: \"data-agent-mention-app-icon\",\n fileEntryKind: \"data-agent-file-entry-kind\",\n fileThumb: \"data-agent-mention-file-thumb\",\n fileVisualKind: \"data-agent-file-visual-kind\",\n navigation: \"data-agent-mention-navigation\",\n statusTag: \"data-agent-mention-status-tag\",\n userAvatar: \"data-agent-mention-user-avatar\"\n }\n};\n\nexport function mentionRowRootDataAttributes(\n mode: MentionRowDataAttributeMode,\n kind: MentionRowItem[\"kind\"]\n): Record<string, string> {\n return mode === \"agent\"\n ? {\n \"data-agent-file-mention\": \"true\",\n \"data-agent-mention-kind\": kind\n }\n : {\n \"data-rich-text-at-mention-row\": \"true\",\n \"data-rich-text-at-mention-kind\": kind\n };\n}\n\nexport function mentionRowDataAttribute(\n mode: MentionRowDataAttributeMode,\n key: MentionRowDataAttributeKey,\n value: string\n): Record<string, string> {\n return {\n [MENTION_ROW_DATA_ATTRIBUTES[mode][key]]: value\n };\n}\n","export interface AtPanelKeyboardActions {\n moveSelection: (delta: 1 | -1) => void;\n commitSelection: () => void;\n close: () => void;\n cycleFilter?: (delta: 1 | -1) => void;\n}\n\nexport interface AtPanelKeyboardEventLike {\n key: string;\n shiftKey?: boolean;\n preventDefault: () => void;\n}\n\nexport function makeAtPanelKeyDown(actions: AtPanelKeyboardActions) {\n return (event: AtPanelKeyboardEventLike): boolean => {\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n actions.moveSelection(1);\n return true;\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n actions.moveSelection(-1);\n return true;\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n actions.close();\n return true;\n }\n if (event.key === \"Tab\" && actions.cycleFilter) {\n event.preventDefault();\n actions.cycleFilter(event.shiftKey ? -1 : 1);\n return true;\n }\n if (event.key === \"Enter\") {\n event.preventDefault();\n actions.commitSelection();\n return true;\n }\n return false;\n };\n}\n\nexport function useAtPanelKeyboard(actions: AtPanelKeyboardActions) {\n return makeAtPanelKeyDown(actions);\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","cn","jsx","useRef","useState","useEffect","cn","cn","jsx","jsxs","cn"]}
|
|
1
|
+
{"version":3,"sources":["../../src/at-panel/MentionPalette.tsx","../../src/at-panel/mentionPaletteScrollbar.tsx","../../src/at-panel/MentionRow.tsx","../../src/at-panel/mentionRowDataAttributes.ts","../../src/at-panel/useAtPanelKeyboard.ts"],"sourcesContent":["import {\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type JSX,\n type MutableRefObject,\n type ReactNode\n} from \"react\";\nimport {\n FolderFailedFilledIcon,\n KeyboardFilledIcon\n} from \"@tutti-os/ui-system/icons\";\nimport { Spinner, UnderlineTabs } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport { flattenMentionPaletteEntries } from \"./mentionPaletteEntries.ts\";\nimport { MentionPaletteScrollbar } from \"./mentionPaletteScrollbar.tsx\";\nimport type {\n MentionPaletteGroup,\n MentionPaletteProps,\n MentionPaletteState,\n MentionPaletteTheme\n} from \"./mentionPaletteTypes.ts\";\nimport \"./mentionPalette.css\";\n\nconst DEFAULT_THEME = {\n classNames: {\n palette: \"rich-text-at-mention-palette\",\n header: \"rich-text-at-mention-palette-header\",\n footer: \"rich-text-at-mention-palette-footer\",\n tabs: \"rich-text-at-mention-palette-tabs\",\n scrollRegion: \"rich-text-at-mention-palette-scroll-region\",\n scrollbar: \"rich-text-at-mention-palette-scrollbar\",\n scrollbarThumb: \"rich-text-at-mention-palette-scrollbar-thumb\",\n hint: \"rich-text-at-mention-palette-hint\",\n hintItem: \"rich-text-at-mention-palette-hint-item\",\n hintButton: \"rich-text-at-mention-palette-hint-button\",\n hintSeparator: \"rich-text-at-mention-palette-hint-separator\",\n shortcut: \"rich-text-at-mention-palette-shortcut\",\n shortcutArrow: \"rich-text-at-mention-palette-shortcut--arrow\",\n shortcutButton: \"rich-text-at-mention-palette-shortcut-button\",\n shortcutGroup: \"rich-text-at-mention-palette-shortcut-group\"\n },\n testIds: {\n emptyState: \"rich-text-at-mention-palette-empty-state\",\n hint: \"rich-text-at-mention-palette-hint\",\n scrollbar: \"rich-text-at-mention-palette-scrollbar\",\n loadingSpinner: \"rich-text-at-mention-loading-spinner\"\n },\n groupDividerAttribute: \"data-rich-text-at-mention-group-divider\"\n} as const;\n\ninterface ResolvedMentionPaletteTheme {\n classNames: Required<NonNullable<MentionPaletteTheme[\"classNames\"]>>;\n testIds: Required<NonNullable<MentionPaletteTheme[\"testIds\"]>>;\n groupDividerAttribute: string;\n}\n\nfunction resolveMentionPaletteTheme(\n theme: MentionPaletteTheme | undefined\n): ResolvedMentionPaletteTheme {\n return {\n classNames: { ...DEFAULT_THEME.classNames, ...theme?.classNames },\n testIds: { ...DEFAULT_THEME.testIds, ...theme?.testIds },\n groupDividerAttribute:\n theme?.groupDividerAttribute ?? DEFAULT_THEME.groupDividerAttribute\n };\n}\n\nconst paletteStyles = {\n palette:\n \"nodrag grid h-full max-h-[320px] min-h-0 grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden text-[13px] [-webkit-app-region:no-drag]\",\n header: \"relative z-10 shrink-0\",\n footer: \"shrink-0\",\n scrollShell: \"relative min-h-0 overflow-hidden\",\n scrollBody:\n \"h-full min-h-0 overflow-y-auto overscroll-contain px-1 pb-1 pt-2\",\n rowButton:\n \"nodrag relative flex min-h-9 w-full min-w-0 cursor-pointer select-none items-center gap-1.5 overflow-hidden rounded-[6px] border-0 bg-transparent px-2.5 py-2 text-left text-[13px] text-[var(--text-primary)] outline-hidden transition-colors duration-200 [-webkit-app-region:no-drag] active:bg-[var(--transparency-active)] data-[highlighted]:bg-[var(--transparency-block)] data-[highlighted]:text-[var(--text-primary)] [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:min-w-0 *:[span]:last:flex-1 *:[span]:last:items-center *:[span]:last:gap-2\",\n categoryButton:\n \"nodrag flex min-h-[72px] w-full items-center gap-3.5 rounded-[6px] border-0 bg-transparent px-2.5 py-2.5 text-left text-[var(--text-primary)] transition-[background-color,color] hover:bg-[var(--transparency-block)] focus-visible:bg-[var(--transparency-block)] focus-visible:outline-none active:bg-[var(--transparency-active)]\",\n expandButton:\n \"nodrag flex w-full items-center justify-center rounded-[6px] px-3 py-2 text-[13px] font-medium text-[var(--text-secondary)] transition focus-visible:outline-none active:bg-[var(--transparency-active)] data-[highlighted]:bg-[var(--transparency-block)] data-[highlighted]:text-[var(--text-primary)]\"\n} as const;\n\nconst MENTION_PALETTE_LOADING_MIN_VISIBLE_MS = 320;\n\nexport function MentionPalette<TItem>(\n props: MentionPaletteProps<TItem>\n): JSX.Element {\n \"use memo\";\n const {\n state,\n highlightedKey,\n getItemKey,\n renderItem,\n labels,\n hintLabels,\n maxHeightPx,\n onHighlightChange,\n onSelectItem,\n onSelectCategory,\n onSelectFilter,\n onExpandGroup,\n onCycleFilter,\n onMoveSelection,\n renderListFooter,\n loadingBanner,\n scrollHighlightedIntoViewCentered = false,\n theme: themeProp\n } = props;\n const theme = resolveMentionPaletteTheme(themeProp);\n\n const highlightedOptionRef = useRef<HTMLButtonElement | null>(null);\n const scrollBodyRef = useRef<HTMLDivElement | null>(null);\n const loadingVisibleUntilRef = useRef(0);\n const loadingHideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null\n );\n const [loadingIndicatorVisible, setLoadingIndicatorVisible] = useState(\n state.status === \"loading\"\n );\n\n const interactiveEntries = flattenMentionPaletteEntries(\n state,\n (item, groupId) => getItemKey(item, findGroup(state.groups, groupId))\n );\n const hasInteractiveEntries = interactiveEntries.some(\n (entry) => entry.type === \"item\" || entry.type === \"expand\"\n );\n\n const showLoadingState =\n loadingIndicatorVisible &&\n (!hasInteractiveEntries || state.mode === \"browse\");\n const showLoadingBanner =\n Boolean(loadingBanner) &&\n loadingIndicatorVisible &&\n hasInteractiveEntries &&\n state.mode === \"results\";\n\n useEffect(() => {\n const highlightedElement = highlightedOptionRef.current;\n if (!highlightedElement) {\n return;\n }\n const scrollContainer = scrollBodyRef.current;\n if (!scrollContainer || !scrollContainer.contains(highlightedElement)) {\n highlightedElement.scrollIntoView({ block: \"nearest\" });\n return;\n }\n if (!scrollHighlightedIntoViewCentered) {\n return;\n }\n centerElementInScrollContainer(scrollContainer, highlightedElement);\n }, [highlightedKey, scrollHighlightedIntoViewCentered]);\n\n useEffect(() => {\n if (loadingHideTimerRef.current !== null) {\n clearTimeout(loadingHideTimerRef.current);\n loadingHideTimerRef.current = null;\n }\n\n if (state.status === \"loading\") {\n loadingVisibleUntilRef.current =\n Date.now() + MENTION_PALETTE_LOADING_MIN_VISIBLE_MS;\n setLoadingIndicatorVisible(true);\n return;\n }\n\n const remainingMs = loadingVisibleUntilRef.current - Date.now();\n if (remainingMs <= 0) {\n setLoadingIndicatorVisible(false);\n return;\n }\n\n loadingHideTimerRef.current = setTimeout(() => {\n loadingHideTimerRef.current = null;\n setLoadingIndicatorVisible(false);\n }, remainingMs);\n\n return () => {\n if (loadingHideTimerRef.current !== null) {\n clearTimeout(loadingHideTimerRef.current);\n loadingHideTimerRef.current = null;\n }\n };\n }, [state.status]);\n\n const paletteMaxHeightStyle: CSSProperties | undefined =\n maxHeightPx > 0 ? { maxHeight: `${maxHeightPx}px` } : undefined;\n\n if (state.status === \"error\") {\n return (\n <div\n className={cn(theme.classNames.palette, paletteStyles.palette)}\n style={paletteMaxHeightStyle}\n role=\"listbox\"\n aria-label={labels.listbox ?? labels.tabHint}\n >\n <MentionPaletteEmptyState\n icon=\"folder-failed\"\n label={labels.error}\n testId={theme.testIds.emptyState}\n />\n </div>\n );\n }\n\n const isBrowse = state.mode === \"browse\";\n\n let body: ReactNode;\n if (showLoadingState) {\n body = (\n <MentionPaletteLoading\n label={labels.loading}\n spinnerTestId={theme.testIds.loadingSpinner}\n />\n );\n } else if (state.groups.length === 0) {\n body = (\n <MentionPaletteEmptyState\n icon={isBrowse ? \"keyboard\" : \"folder-failed\"}\n label={labels.empty}\n testId={theme.testIds.emptyState}\n />\n );\n } else {\n body = (\n <MentionPaletteGroups\n state={state}\n highlightedKey={highlightedKey}\n highlightedOptionRef={highlightedOptionRef}\n getItemKey={getItemKey}\n renderItem={renderItem}\n onHighlightChange={onHighlightChange}\n onSelectItem={onSelectItem}\n onExpandGroup={onExpandGroup}\n renderListFooter={renderListFooter}\n groupDividerAttribute={theme.groupDividerAttribute}\n />\n );\n }\n\n return (\n <div\n className={cn(theme.classNames.palette, paletteStyles.palette)}\n style={paletteMaxHeightStyle}\n role=\"listbox\"\n aria-label={labels.listbox ?? labels.tabHint}\n >\n <div className={cn(theme.classNames.header, paletteStyles.header)}>\n <UnderlineTabs\n tabs={state.categories.map((category) => ({\n value: category.id,\n label: category.label\n }))}\n value={state.filter}\n onValueChange={isBrowse ? onSelectCategory : onSelectFilter}\n className={theme.classNames.tabs}\n preventMouseDownDefault\n />\n {showLoadingBanner ? loadingBanner : null}\n </div>\n <div className={paletteStyles.scrollShell}>\n <div\n ref={scrollBodyRef}\n className={cn(\n theme.classNames.scrollRegion,\n paletteStyles.scrollBody\n )}\n >\n {body}\n </div>\n <MentionPaletteScrollbar\n scrollBodyRef={scrollBodyRef}\n className={theme.classNames.scrollbar}\n thumbClassName={theme.classNames.scrollbarThumb}\n testId={theme.testIds.scrollbar}\n />\n </div>\n <div className={cn(theme.classNames.footer, paletteStyles.footer)}>\n <MentionPaletteHint\n ariaLabel={labels.tabHint}\n cycleFilterLabel={hintLabels.cycleFilter}\n moveSelectionLabel={hintLabels.moveSelection}\n onCycleFilter={onCycleFilter}\n onMoveSelection={onMoveSelection}\n classNames={theme.classNames}\n testId={theme.testIds.hint}\n />\n </div>\n </div>\n );\n}\n\nfunction centerElementInScrollContainer(\n container: HTMLElement,\n element: HTMLElement\n): void {\n const containerRect = container.getBoundingClientRect();\n const elementRect = element.getBoundingClientRect();\n const currentScrollTop = container.scrollTop;\n const elementTop = elementRect.top - containerRect.top + currentScrollTop;\n const centeredScrollTop =\n elementTop - (container.clientHeight - elementRect.height) / 2;\n const maxScrollTop = Math.max(\n 0,\n container.scrollHeight - container.clientHeight\n );\n const nextScrollTop = Math.min(Math.max(0, centeredScrollTop), maxScrollTop);\n container.scrollTo({ top: nextScrollTop, behavior: \"auto\" });\n}\n\nfunction findGroup<TItem>(\n groups: MentionPaletteState<TItem>[\"groups\"],\n groupId: string\n): MentionPaletteGroup<TItem> {\n const group = groups.find((candidate) => candidate.id === groupId);\n if (!group) {\n throw new Error(`MentionPalette: unknown group id \"${groupId}\"`);\n }\n return group;\n}\n\nfunction MentionPaletteGroups<TItem>({\n state,\n highlightedKey,\n highlightedOptionRef,\n getItemKey,\n renderItem,\n onHighlightChange,\n onSelectItem,\n onExpandGroup,\n renderListFooter,\n groupDividerAttribute\n}: {\n state: MentionPaletteState<TItem>;\n highlightedKey: string | null;\n highlightedOptionRef: MutableRefObject<HTMLButtonElement | null>;\n getItemKey: (item: TItem, group: MentionPaletteGroup<TItem>) => string;\n renderItem: (item: TItem, ctx: { active: boolean }) => ReactNode;\n onHighlightChange: (key: string) => void;\n onSelectItem: (item: TItem, group: MentionPaletteGroup<TItem>) => void;\n onExpandGroup: (groupId: string) => void;\n renderListFooter?: () => ReactNode;\n groupDividerAttribute: string;\n}): JSX.Element {\n return (\n <div className=\"grid gap-3\">\n {state.groups.map((group, index) => {\n const showGroupDivider = index > 0 && !group.hideTopDivider;\n return (\n <section\n key={group.id}\n className={cn(\"grid gap-1\", group.sectionClassName)}\n >\n {showGroupDivider ? (\n <div\n className=\"mx-3 mb-2 border-t border-[var(--line-1)]\"\n {...{ [groupDividerAttribute]: \"true\" }}\n aria-hidden=\"true\"\n />\n ) : null}\n {group.label ? (\n <div className=\"px-3 text-[13px] font-normal text-[var(--text-secondary)]\">\n {group.label}\n </div>\n ) : null}\n <div className=\"grid gap-1\">\n {group.items.length === 0 && group.emptyLabel ? (\n <div className=\"px-3 py-1 text-[13px] font-normal text-[var(--text-tertiary)]\">\n {group.emptyLabel}\n </div>\n ) : null}\n {group.items.map((item) => {\n const entryKey = `${group.id}:${getItemKey(item, group)}`;\n const isHighlighted = entryKey === highlightedKey;\n return (\n <button\n key={entryKey}\n ref={isHighlighted ? highlightedOptionRef : null}\n type=\"button\"\n className={cn(\n paletteStyles.rowButton,\n isHighlighted && \"bg-[var(--transparency-block)]\"\n )}\n role=\"option\"\n aria-selected={isHighlighted}\n data-highlighted={isHighlighted ? \"\" : undefined}\n onMouseEnter={() => onHighlightChange(entryKey)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onSelectItem(item, group)}\n >\n {renderItem(item, { active: isHighlighted })}\n </button>\n );\n })}\n {group.hasMore ? (\n <button\n key={`expand:${group.id}`}\n ref={\n `expand:${group.id}` === highlightedKey\n ? highlightedOptionRef\n : null\n }\n type=\"button\"\n className={cn(\n paletteStyles.expandButton,\n `expand:${group.id}` === highlightedKey &&\n \"bg-[var(--transparency-block)] text-[var(--text-primary)]\"\n )}\n data-highlighted={\n `expand:${group.id}` === highlightedKey ? \"\" : undefined\n }\n onMouseEnter={() => onHighlightChange(`expand:${group.id}`)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onExpandGroup(group.id)}\n >\n {group.expandLabel ??\n `+${Math.max(0, group.totalCount - group.visibleCount)}`}\n </button>\n ) : null}\n </div>\n </section>\n );\n })}\n {renderListFooter?.()}\n </div>\n );\n}\n\nfunction MentionPaletteEmptyState({\n icon = \"folder-failed\",\n label,\n testId\n}: {\n icon?: \"folder-failed\" | \"keyboard\";\n label: string;\n testId: string;\n}): JSX.Element {\n \"use memo\";\n const EmptyStateIcon =\n icon === \"keyboard\" ? KeyboardFilledIcon : FolderFailedFilledIcon;\n\n return (\n <div\n className=\"flex h-full min-h-0 flex-1 items-center justify-center px-4 py-6 text-center text-[13px] text-[var(--text-tertiary)]\"\n data-empty-state-icon={icon}\n data-testid={testId}\n >\n <div className=\"flex max-w-[28ch] flex-col items-center justify-center gap-3\">\n <EmptyStateIcon\n className=\"h-6 w-6 text-[var(--text-tertiary)]\"\n aria-hidden=\"true\"\n />\n <span className=\"leading-5 text-[var(--text-tertiary)]\">{label}</span>\n </div>\n </div>\n );\n}\n\nfunction MentionPaletteLoading({\n label,\n spinnerTestId\n}: {\n label: string;\n spinnerTestId: string;\n}): JSX.Element {\n \"use memo\";\n return (\n <div className=\"flex min-h-[52px] items-center gap-2 rounded-xl px-3 text-[13px] text-[var(--text-secondary)]\">\n <Spinner\n size={16}\n className=\"text-[var(--text-secondary)]\"\n testId={spinnerTestId}\n />\n <span>{label}</span>\n </div>\n );\n}\n\nfunction MentionPaletteHint({\n ariaLabel,\n cycleFilterLabel,\n moveSelectionLabel,\n onCycleFilter,\n onMoveSelection,\n classNames,\n testId\n}: {\n ariaLabel: string;\n cycleFilterLabel: string;\n moveSelectionLabel: string;\n onCycleFilter: (delta: 1 | -1) => void;\n onMoveSelection: (delta: 1 | -1) => void;\n classNames: ResolvedMentionPaletteTheme[\"classNames\"];\n testId: string;\n}): JSX.Element {\n \"use memo\";\n return (\n <div\n className={classNames.hint}\n aria-label={ariaLabel}\n data-testid={testId}\n >\n <button\n className={cn(classNames.hintItem, classNames.hintButton)}\n type=\"button\"\n aria-label={cycleFilterLabel}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onCycleFilter(1)}\n >\n {/* i18n-check-ignore: Keyboard key label. */}\n <kbd className={classNames.shortcut}>Tab</kbd>\n <span>{cycleFilterLabel}</span>\n </button>\n <span className={classNames.hintSeparator} aria-hidden=\"true\">\n |\n </span>\n <span className={classNames.hintItem}>\n <span className={classNames.shortcutGroup}>\n <button\n className={cn(\n classNames.shortcut,\n classNames.shortcutArrow,\n classNames.shortcutButton\n )}\n type=\"button\"\n aria-label={`↑ ${moveSelectionLabel}`}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onMoveSelection(-1)}\n >\n ↑\n </button>\n <button\n className={cn(\n classNames.shortcut,\n classNames.shortcutArrow,\n classNames.shortcutButton\n )}\n type=\"button\"\n aria-label={`↓ ${moveSelectionLabel}`}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => onMoveSelection(1)}\n >\n ↓\n </button>\n </span>\n <span>{moveSelectionLabel}</span>\n </span>\n </div>\n );\n}\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n type JSX,\n type MouseEvent as ReactMouseEvent,\n type RefObject\n} from \"react\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\n\ninterface MentionPaletteScrollbarState {\n scrollable: boolean;\n thumbHeight: number;\n thumbTop: number;\n}\n\ninterface MentionPaletteScrollbarDragState {\n maxScrollTop: number;\n maxThumbTop: number;\n startClientY: number;\n startScrollTop: number;\n}\n\nconst MENTION_PALETTE_SCROLLBAR_MIN_THUMB_HEIGHT = 24;\nconst MENTION_PALETTE_SCROLLBAR_HIDDEN_STATE: MentionPaletteScrollbarState = {\n scrollable: false,\n thumbHeight: 0,\n thumbTop: 0\n};\n\nexport function MentionPaletteScrollbar({\n scrollBodyRef,\n className,\n thumbClassName,\n testId\n}: {\n scrollBodyRef: RefObject<HTMLDivElement | null>;\n className: string;\n thumbClassName: string;\n testId: string;\n}): JSX.Element {\n \"use memo\";\n const trackRef = useRef<HTMLDivElement | null>(null);\n const dragStateRef = useRef<MentionPaletteScrollbarDragState | null>(null);\n const [scrollbarState, setScrollbarState] =\n useState<MentionPaletteScrollbarState>({\n scrollable: false,\n thumbHeight: 0,\n thumbTop: 0\n });\n const [dragging, setDragging] = useState(false);\n\n const hideScrollbar = useCallback((): void => {\n setScrollbarState((previous) =>\n previous.scrollable ||\n previous.thumbHeight !== 0 ||\n previous.thumbTop !== 0\n ? MENTION_PALETTE_SCROLLBAR_HIDDEN_STATE\n : previous\n );\n }, []);\n\n const syncScrollbarState = useCallback((): void => {\n const contentElement = scrollBodyRef.current;\n if (!contentElement) {\n hideScrollbar();\n return;\n }\n\n const { scrollHeight, scrollTop, clientHeight } = contentElement;\n const measuredTrackHeight = trackRef.current?.clientHeight ?? 0;\n const trackHeight =\n measuredTrackHeight > 0 ? measuredTrackHeight : clientHeight;\n const maxScrollTop = Math.max(0, scrollHeight - clientHeight);\n\n if (clientHeight <= 0 || trackHeight <= 0 || maxScrollTop <= 0) {\n hideScrollbar();\n return;\n }\n\n const thumbHeight = Math.max(\n MENTION_PALETTE_SCROLLBAR_MIN_THUMB_HEIGHT,\n Math.round((clientHeight / scrollHeight) * trackHeight)\n );\n const maxThumbTop = Math.max(0, trackHeight - thumbHeight);\n const thumbTop = Math.round((scrollTop / maxScrollTop) * maxThumbTop);\n setScrollbarState((previous) =>\n previous.scrollable &&\n previous.thumbHeight === thumbHeight &&\n previous.thumbTop === thumbTop\n ? previous\n : { scrollable: true, thumbHeight, thumbTop }\n );\n }, [hideScrollbar, scrollBodyRef]);\n\n useEffect(() => {\n const contentElement = scrollBodyRef.current;\n if (!contentElement) {\n hideScrollbar();\n return;\n }\n\n syncScrollbarState();\n contentElement.addEventListener(\"scroll\", syncScrollbarState, {\n passive: true\n });\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(syncScrollbarState)\n : null;\n resizeObserver?.observe(contentElement);\n if (trackRef.current) {\n resizeObserver?.observe(trackRef.current);\n }\n const animationFrameId = window.requestAnimationFrame(syncScrollbarState);\n return () => {\n contentElement.removeEventListener(\"scroll\", syncScrollbarState);\n resizeObserver?.disconnect();\n window.cancelAnimationFrame(animationFrameId);\n };\n }, [hideScrollbar, scrollBodyRef, syncScrollbarState]);\n\n useEffect(() => {\n if (!dragging) {\n return;\n }\n\n const handleMouseMove = (event: MouseEvent): void => {\n const contentElement = scrollBodyRef.current;\n const dragState = dragStateRef.current;\n if (!contentElement || !dragState || dragState.maxThumbTop <= 0) {\n return;\n }\n const delta = event.clientY - dragState.startClientY;\n const nextThumbTop =\n (dragState.startScrollTop / dragState.maxScrollTop) *\n dragState.maxThumbTop +\n delta;\n contentElement.scrollTop =\n (Math.min(Math.max(0, nextThumbTop), dragState.maxThumbTop) /\n dragState.maxThumbTop) *\n dragState.maxScrollTop;\n syncScrollbarState();\n };\n\n const handleMouseUp = (): void => {\n dragStateRef.current = null;\n setDragging(false);\n };\n\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleMouseUp);\n return () => {\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [dragging, scrollBodyRef, syncScrollbarState]);\n\n const scrollContentToThumbTop = (thumbTop: number): void => {\n const contentElement = scrollBodyRef.current;\n const trackElement = trackRef.current;\n if (!contentElement || !trackElement) {\n return;\n }\n const maxScrollTop = Math.max(\n 0,\n contentElement.scrollHeight - contentElement.clientHeight\n );\n const maxThumbTop = Math.max(\n 0,\n trackElement.clientHeight - scrollbarState.thumbHeight\n );\n if (maxScrollTop <= 0 || maxThumbTop <= 0) {\n return;\n }\n contentElement.scrollTop =\n (Math.min(Math.max(0, thumbTop), maxThumbTop) / maxThumbTop) *\n maxScrollTop;\n syncScrollbarState();\n };\n\n const handleTrackMouseDown = (\n event: ReactMouseEvent<HTMLDivElement>\n ): void => {\n if (\n event.button !== 0 ||\n !scrollbarState.scrollable ||\n event.target !== event.currentTarget\n ) {\n return;\n }\n event.preventDefault();\n const trackRect = event.currentTarget.getBoundingClientRect();\n scrollContentToThumbTop(\n event.clientY - trackRect.top - scrollbarState.thumbHeight / 2\n );\n };\n\n const handleThumbMouseDown = (\n event: ReactMouseEvent<HTMLDivElement>\n ): void => {\n if (event.button !== 0 || !scrollbarState.scrollable) {\n return;\n }\n const contentElement = scrollBodyRef.current;\n const trackElement = trackRef.current;\n if (!contentElement || !trackElement) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n dragStateRef.current = {\n maxScrollTop: Math.max(\n 0,\n contentElement.scrollHeight - contentElement.clientHeight\n ),\n maxThumbTop: Math.max(\n 0,\n trackElement.clientHeight - scrollbarState.thumbHeight\n ),\n startClientY: event.clientY,\n startScrollTop: contentElement.scrollTop\n };\n setDragging(true);\n };\n\n if (!scrollbarState.scrollable && !dragging) {\n return <div ref={trackRef} className=\"hidden\" aria-hidden=\"true\" />;\n }\n\n return (\n <div\n ref={trackRef}\n className={cn(\"group/status-scrollbar\", className)}\n data-scrollable={scrollbarState.scrollable ? \"true\" : \"false\"}\n data-dragging={dragging ? \"true\" : \"false\"}\n data-testid={testId}\n aria-hidden=\"true\"\n onMouseDown={handleTrackMouseDown}\n >\n <div\n className={thumbClassName}\n onMouseDown={handleThumbMouseDown}\n style={{\n height: `${scrollbarState.thumbHeight}px`,\n transform: `translateY(${scrollbarState.thumbTop}px)`\n }}\n />\n </div>\n );\n}\n","import {\n ArrowLeftIcon,\n Badge,\n FileCodeIcon,\n FileTextIcon,\n FolderIcon,\n ImageFileIcon,\n LocateFolderIcon,\n ProductIcon,\n StatusDot,\n VideoFileIcon,\n cn,\n type IconProps\n} from \"@tutti-os/ui-system\";\nimport type { MentionFileVisualKind } from \"./mentionFileVisualKind.ts\";\nimport {\n mentionRowDataAttribute,\n mentionRowRootDataAttributes,\n type MentionRowDataAttributeMode\n} from \"./mentionRowDataAttributes.ts\";\nimport type {\n MentionRowFileItem,\n MentionRowItem,\n MentionRowSessionItem,\n MentionRowStatusTag\n} from \"./mentionRowTypes.ts\";\nimport { mentionStatusBadgeClassName } from \"./mentionStatusTone.ts\";\n\n/**\n * Default file kind-icon shapes for surfaces that do NOT ship the agent's\n * CSS-masked glyph stylesheet. These mirror the agent's mask glyph shapes\n * (`agentactivity.css`: folder-filled / doc-filled / code-filled / image-filled\n * / video-filled / arrow-left-filled) using ui-system icon components, so a\n * file row renders a real glyph without `agentactivity.css`. The agent composer\n * passes its own `fileIcon` class and keeps rendering the masked `<span>`.\n */\nconst MENTION_FILE_VISUAL_KIND_ICON: Record<\n MentionFileVisualKind,\n (props: IconProps) => React.JSX.Element\n> = {\n back: ArrowLeftIcon,\n folder: FolderIcon,\n document: FileTextIcon,\n // The agent maps markdown to `product-filled.svg`; ProductIcon is the\n // matching boundary-safe ui-system glyph.\n markdown: ProductIcon,\n code: FileCodeIcon,\n image: ImageFileIcon,\n video: VideoFileIcon\n};\n\n/**\n * Structural class-name hooks for the elements a {@link MentionRow} renders that\n * rely on a stylesheet (file icon/thumb, the app fallback kind-icon, and the\n * session avatar placeholder modifier). Every key is optional and defaults to a\n * PACKAGE-OWNED `rich-text-at-mention-*` class whose CSS ships with\n * `mentionPalette.css`, so any consumer renders styled rows out of the box.\n *\n * Surfaces with their own stylesheet (e.g. the agent composer) pass their exact\n * existing class names here so their rendered DOM stays byte-identical.\n */\nexport interface MentionRowClassNames {\n /** The masked file kind-icon `<span>`. */\n fileIcon?: string;\n /** The image-thumbnail wrapper `<span>` (rendered for image files). */\n fileThumb?: string;\n /** The fallback app icon glyph rendered when no `iconUrl` is present. */\n kindIcon?: string;\n /**\n * Modifier class added to the session user avatar `<img>` when the user has no\n * avatar URL and the placeholder asset is shown.\n */\n avatarImgUserPlaceholder?: string;\n}\n\nexport interface MentionRowRenderOptions {\n classNames?: MentionRowClassNames;\n dataAttributeMode?: MentionRowDataAttributeMode;\n /**\n * 当提供时,issue / app 行末尾渲染一个「查看产物文件」入口图标(独立点击热区,\n * 不触发整行选中)。点击回调由调用方注入(如打开引用文件 picker 并定位到该实体)。\n */\n onOpenReferences?: () => void;\n /** 入口图标的无障碍标签 / tooltip 文案。 */\n openReferencesLabel?: string;\n}\n\ninterface ResolvedMentionRowRenderOptions {\n classNames?: MentionRowClassNames;\n dataAttributeMode: MentionRowDataAttributeMode;\n onOpenReferences?: () => void;\n openReferencesLabel?: string;\n}\n\nconst DEFAULT_MENTION_ROW_CLASS_NAMES = {\n fileIcon: \"rich-text-at-mention-file-icon\",\n fileThumb: \"rich-text-at-mention-file-thumb\",\n kindIcon: \"rich-text-at-mention-kind-icon\",\n avatarImgUserPlaceholder: \"rich-text-at-mention-avatar-img--user-placeholder\"\n} as const satisfies Required<MentionRowClassNames>;\n\nfunction resolveMentionRowClassNames(\n classNames?: MentionRowClassNames\n): Required<MentionRowClassNames> {\n return {\n fileIcon: classNames?.fileIcon ?? DEFAULT_MENTION_ROW_CLASS_NAMES.fileIcon,\n fileThumb:\n classNames?.fileThumb ?? DEFAULT_MENTION_ROW_CLASS_NAMES.fileThumb,\n kindIcon: classNames?.kindIcon ?? DEFAULT_MENTION_ROW_CLASS_NAMES.kindIcon,\n avatarImgUserPlaceholder:\n classNames?.avatarImgUserPlaceholder ??\n DEFAULT_MENTION_ROW_CLASS_NAMES.avatarImgUserPlaceholder\n };\n}\n\nfunction resolveMentionRowRenderOptions(\n options?: MentionRowClassNames | MentionRowRenderOptions\n): ResolvedMentionRowRenderOptions {\n if (isMentionRowRenderOptions(options)) {\n return {\n classNames: options.classNames,\n dataAttributeMode: options.dataAttributeMode ?? \"shared\",\n onOpenReferences: options.onOpenReferences,\n openReferencesLabel: options.openReferencesLabel\n };\n }\n return {\n classNames: options,\n dataAttributeMode: \"shared\"\n };\n}\n\nfunction isMentionRowRenderOptions(\n options: MentionRowClassNames | MentionRowRenderOptions | undefined\n): options is MentionRowRenderOptions {\n return (\n options !== undefined &&\n (\"classNames\" in options || \"dataAttributeMode\" in options)\n );\n}\n\n/**\n * Render the inner content of a single `@`-mention palette row from a\n * fully-resolved {@link MentionRowItem}. The surrounding option button / active\n * state is provided by the shared `MentionPalette` shell; this renders only the\n * row body.\n *\n * Pass {@link classNames} to override the package-owned structural class hooks\n * (e.g. so the agent composer keeps emitting its own stylesheet's class names).\n */\nexport function renderMentionRow(\n item: MentionRowItem,\n options?: MentionRowClassNames | MentionRowRenderOptions\n): React.ReactNode {\n const {\n classNames,\n dataAttributeMode,\n onOpenReferences,\n openReferencesLabel\n } = resolveMentionRowRenderOptions(options);\n const resolved = resolveMentionRowClassNames(classNames);\n const referencesButton = onOpenReferences ? (\n <MentionOpenReferencesButton\n label={openReferencesLabel}\n onOpenReferences={onOpenReferences}\n dataAttributeMode={dataAttributeMode}\n />\n ) : null;\n if (item.kind === \"file\") {\n return (\n <MentionFileRow\n item={item}\n classNames={resolved}\n dataAttributeMode={dataAttributeMode}\n />\n );\n }\n\n if (item.kind === \"session\") {\n return (\n <span className=\"grid w-full min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-3\">\n <span className=\"flex min-w-0 items-center gap-2 overflow-hidden\">\n <MentionSessionAvatarStack\n item={item}\n classNames={resolved}\n dataAttributeMode={dataAttributeMode}\n />\n <span className=\"min-w-0 truncate text-[13px] font-semibold leading-[16px] text-[var(--text-primary)]\">\n <MentionSessionTitle item={item} />\n </span>\n </span>\n {item.statusTag ? (\n <MentionStatusBadge\n statusTag={item.statusTag}\n dataAttributeMode={dataAttributeMode}\n />\n ) : null}\n </span>\n );\n }\n\n if (item.kind === \"app\") {\n return (\n <span className=\"flex min-w-0 items-center gap-2 overflow-hidden\">\n <MentionWorkspaceAppIcon\n iconUrl={item.iconUrl}\n kindIconClassName={resolved.kindIcon}\n dataAttributeMode={dataAttributeMode}\n />\n <span className=\"flex min-w-0 flex-1 items-baseline gap-1 overflow-hidden\">\n <span className=\"min-w-0 max-w-[40%] shrink-0 truncate text-[13px] font-semibold text-[var(--text-primary)]\">\n {item.name}\n </span>\n {item.description ? (\n <span className=\"min-w-0 flex-1 truncate text-[13px] font-normal text-[var(--text-secondary)]\">\n {item.description}\n </span>\n ) : null}\n </span>\n {referencesButton}\n </span>\n );\n }\n\n if (item.kind === \"app-factory\") {\n return (\n <span className=\"grid min-w-0 overflow-hidden gap-1\">\n <span className=\"min-w-0 flex-1 truncate text-[13px] font-semibold text-[var(--text-primary)]\">\n {item.name}\n </span>\n </span>\n );\n }\n\n return (\n <span className=\"flex min-w-0 items-center gap-2 overflow-hidden\">\n <span className=\"grid min-w-0 flex-1 overflow-hidden gap-1\">\n <span className=\"flex min-w-0 items-center gap-2 overflow-hidden\">\n <span className=\"min-w-0 truncate text-[13px] font-semibold text-[var(--text-primary)]\">\n {item.title}\n </span>\n {item.statusTag ? (\n <MentionStatusBadge\n statusTag={item.statusTag}\n dataAttributeMode={dataAttributeMode}\n />\n ) : null}\n </span>\n {item.creatorName ? (\n <span className=\"truncate text-[13px] font-normal text-[var(--text-secondary)]\">\n {item.creatorName}\n </span>\n ) : null}\n </span>\n {referencesButton}\n </span>\n );\n}\n\n/**\n * 「查看产物文件」入口图标。issue / app 行末尾的独立点击热区:点击只触发\n * {@link onOpenReferences}(如打开引用文件 picker 并定位),阻断冒泡以免触发整行选中。\n * 行外层按钮的 `[&_svg]:pointer-events-none` 使图标本身不吃事件,点击落在此 `<span>` 上。\n */\nfunction MentionOpenReferencesButton({\n label,\n onOpenReferences,\n dataAttributeMode\n}: {\n label?: string;\n onOpenReferences: () => void;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n return (\n <span\n role=\"button\"\n tabIndex={-1}\n aria-label={label}\n title={label}\n className=\"ml-auto grid h-6 w-6 shrink-0 cursor-pointer place-items-center rounded-[5px] text-[var(--text-tertiary)] transition-colors hover:bg-[var(--transparency-active)] hover:text-[var(--text-secondary)]\"\n {...mentionRowDataAttribute(dataAttributeMode, \"openReferences\", \"true\")}\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onOpenReferences();\n }}\n >\n <LocateFolderIcon size={16} />\n </span>\n );\n}\n\nfunction MentionFileRow({\n item,\n classNames,\n dataAttributeMode\n}: {\n item: MentionRowFileItem;\n classNames: Required<MentionRowClassNames>;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n return (\n <span\n className=\"flex min-w-0 items-center gap-2\"\n {...mentionRowRootDataAttributes(dataAttributeMode, \"file\")}\n {...(item.entryKind\n ? mentionRowDataAttribute(\n dataAttributeMode,\n \"fileEntryKind\",\n item.entryKind\n )\n : {})}\n {...mentionRowDataAttribute(\n dataAttributeMode,\n \"fileVisualKind\",\n item.visualKind\n )}\n {...(item.mentionNavigation\n ? mentionRowDataAttribute(\n dataAttributeMode,\n \"navigation\",\n item.mentionNavigation\n )\n : {})}\n >\n <MentionFileIcon\n item={item}\n classNames={classNames}\n dataAttributeMode={dataAttributeMode}\n />\n <span className=\"flex min-w-0 items-baseline gap-1 overflow-hidden\">\n <span className=\"min-w-0 truncate text-[13px] font-semibold text-[var(--text-primary)]\">\n {item.name}\n </span>\n {item.childCountLabel ? (\n <span className=\"shrink-0 text-[13px] font-normal text-[var(--text-secondary)]\">\n {item.childCountLabel}\n </span>\n ) : null}\n </span>\n </span>\n );\n}\n\nfunction MentionFileIcon({\n item,\n classNames,\n dataAttributeMode\n}: {\n item: MentionRowFileItem;\n classNames: Required<MentionRowClassNames>;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n const thumbnailUrl =\n item.visualKind === \"image\" ? item.thumbnailUrl?.trim() || \"\" : \"\";\n if (thumbnailUrl) {\n return (\n <span\n className={classNames.fileThumb}\n {...mentionRowDataAttribute(dataAttributeMode, \"fileThumb\", \"true\")}\n aria-hidden=\"true\"\n >\n <img\n src={thumbnailUrl}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n decoding=\"async\"\n loading=\"lazy\"\n draggable={false}\n />\n </span>\n );\n }\n\n // Surfaces that ship a custom file-icon stylesheet (e.g. the agent composer\n // via `agentactivity.css`) render the empty CSS-masked `<span>` so their DOM\n // stays byte-identical. Surfaces using the package default class have no such\n // stylesheet, so render a real ui-system kind glyph instead of an empty box.\n const usesDefaultFileIcon =\n classNames.fileIcon === DEFAULT_MENTION_ROW_CLASS_NAMES.fileIcon;\n if (usesDefaultFileIcon) {\n const Icon = MENTION_FILE_VISUAL_KIND_ICON[item.visualKind];\n return (\n <span\n className={cn(\n classNames.fileIcon,\n \"grid h-4 w-4 shrink-0 place-items-center text-[var(--text-secondary)]\"\n )}\n {...mentionRowDataAttribute(\n dataAttributeMode,\n \"fileVisualKind\",\n item.visualKind\n )}\n aria-hidden=\"true\"\n >\n <Icon size={16} />\n </span>\n );\n }\n\n return (\n <span\n className={classNames.fileIcon}\n {...mentionRowDataAttribute(\n dataAttributeMode,\n \"fileVisualKind\",\n item.visualKind\n )}\n aria-hidden=\"true\"\n />\n );\n}\n\nfunction MentionWorkspaceAppIcon({\n iconUrl,\n kindIconClassName,\n dataAttributeMode\n}: {\n iconUrl?: string | null;\n kindIconClassName: string;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n const normalizedIconUrl = iconUrl?.trim() ?? \"\";\n return (\n <span\n className=\"grid h-5 w-5 shrink-0 place-items-center overflow-hidden rounded-[5px] bg-block text-[var(--text-secondary)]\"\n {...mentionRowDataAttribute(dataAttributeMode, \"appIcon\", \"true\")}\n data-workspace-app-icon=\"true\"\n aria-hidden=\"true\"\n >\n {normalizedIconUrl ? (\n <img\n src={normalizedIconUrl}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n decoding=\"async\"\n loading=\"lazy\"\n draggable={false}\n />\n ) : (\n <span className={cn(kindIconClassName, \"h-4 w-4\")} />\n )}\n </span>\n );\n}\n\nfunction MentionSessionAvatarStack({\n item,\n classNames,\n dataAttributeMode\n}: {\n item: MentionRowSessionItem;\n classNames: Required<MentionRowClassNames>;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n const userAvatarUrl = item.userAvatarUrl?.trim() ?? \"\";\n const placeholderUrl = item.userAvatarPlaceholderUrl;\n const userImageUrl = userAvatarUrl || placeholderUrl;\n return (\n <span\n className=\"relative isolate block h-5 w-9 shrink-0\"\n aria-hidden=\"true\"\n >\n <span\n className=\"absolute left-0 top-0 z-0 grid h-5 w-5 overflow-hidden rounded-full bg-block\"\n {...mentionRowDataAttribute(dataAttributeMode, \"userAvatar\", \"true\")}\n >\n <img\n src={userImageUrl}\n alt=\"\"\n className={cn(\n \"h-full w-full object-cover\",\n !userAvatarUrl && classNames.avatarImgUserPlaceholder\n )}\n decoding=\"async\"\n loading=\"lazy\"\n referrerPolicy=\"no-referrer\"\n draggable={false}\n onError={(event) => {\n if (event.currentTarget.dataset.fallbackAvatarApplied === \"true\") {\n return;\n }\n event.currentTarget.dataset.fallbackAvatarApplied = \"true\";\n event.currentTarget.src = placeholderUrl;\n event.currentTarget.classList.add(\n classNames.avatarImgUserPlaceholder\n );\n }}\n />\n </span>\n <span\n className=\"absolute left-4 top-0 z-10 grid h-5 w-5 overflow-hidden rounded-full bg-block\"\n {...mentionRowDataAttribute(dataAttributeMode, \"agentAvatar\", \"true\")}\n >\n <img\n src={item.agentIconUrl}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n decoding=\"async\"\n loading=\"lazy\"\n draggable={false}\n />\n </span>\n </span>\n );\n}\n\nfunction MentionSessionTitle({\n item\n}: {\n item: MentionRowSessionItem;\n}): React.JSX.Element {\n return (\n <>\n <span className=\"text-[13px] leading-[16px]\">{item.participant}</span>\n <span className=\"text-[13px] font-normal leading-[16px] text-[var(--text-secondary)]\">\n {\" \"}\n {item.summary ?? \"\"}\n </span>\n </>\n );\n}\n\nfunction MentionStatusBadge({\n statusTag,\n dataAttributeMode\n}: {\n statusTag: MentionRowStatusTag;\n dataAttributeMode: MentionRowDataAttributeMode;\n}): React.JSX.Element {\n if (statusTag.variant === \"issue\") {\n return (\n <Badge\n variant=\"secondary\"\n className={cn(\n \"shrink-0 text-[13px]\",\n mentionStatusBadgeClassName({\n tone: statusTag.tone,\n variant: \"issue\"\n })\n )}\n {...mentionRowDataAttribute(dataAttributeMode, \"statusTag\", \"true\")}\n {...(statusTag.dataStatus\n ? { \"data-status\": statusTag.dataStatus }\n : {})}\n >\n {statusTag.label}\n </Badge>\n );\n }\n\n return (\n <Badge\n variant=\"secondary\"\n className={cn(\n \"inline-flex h-5 shrink-0 items-center gap-1.5 rounded-[4px] px-2 text-[11px] font-semibold leading-none\",\n mentionStatusBadgeClassName({\n tone: statusTag.tone,\n variant: \"activity\"\n })\n )}\n {...mentionRowDataAttribute(dataAttributeMode, \"statusTag\", \"true\")}\n {...(statusTag.dataStatus ? { \"data-status\": statusTag.dataStatus } : {})}\n data-tone={statusTag.tone}\n title={statusTag.label}\n >\n <StatusDot\n tone={statusTag.tone}\n pulse={statusTag.pulse ?? false}\n size=\"xs\"\n title={statusTag.label}\n />\n <span>{statusTag.label}</span>\n </Badge>\n );\n}\n","import type { MentionRowItem } from \"./mentionRowTypes.ts\";\n\nexport type MentionRowDataAttributeMode = \"shared\" | \"agent\";\n\nexport type MentionRowDataAttributeKey =\n | \"agentAvatar\"\n | \"appIcon\"\n | \"fileEntryKind\"\n | \"fileThumb\"\n | \"fileVisualKind\"\n | \"navigation\"\n | \"openReferences\"\n | \"statusTag\"\n | \"userAvatar\";\n\nconst MENTION_ROW_DATA_ATTRIBUTES: Record<\n MentionRowDataAttributeMode,\n Record<MentionRowDataAttributeKey, string>\n> = {\n shared: {\n agentAvatar: \"data-rich-text-at-mention-agent-avatar\",\n appIcon: \"data-rich-text-at-mention-app-icon\",\n fileEntryKind: \"data-rich-text-at-mention-file-entry-kind\",\n fileThumb: \"data-rich-text-at-mention-file-thumb\",\n fileVisualKind: \"data-rich-text-at-mention-file-visual-kind\",\n navigation: \"data-rich-text-at-mention-navigation\",\n openReferences: \"data-rich-text-at-mention-open-references\",\n statusTag: \"data-rich-text-at-mention-status-tag\",\n userAvatar: \"data-rich-text-at-mention-user-avatar\"\n },\n agent: {\n agentAvatar: \"data-agent-mention-agent-avatar\",\n appIcon: \"data-agent-mention-app-icon\",\n fileEntryKind: \"data-agent-file-entry-kind\",\n fileThumb: \"data-agent-mention-file-thumb\",\n fileVisualKind: \"data-agent-file-visual-kind\",\n navigation: \"data-agent-mention-navigation\",\n openReferences: \"data-agent-mention-open-references\",\n statusTag: \"data-agent-mention-status-tag\",\n userAvatar: \"data-agent-mention-user-avatar\"\n }\n};\n\nexport function mentionRowRootDataAttributes(\n mode: MentionRowDataAttributeMode,\n kind: MentionRowItem[\"kind\"]\n): Record<string, string> {\n return mode === \"agent\"\n ? {\n \"data-agent-file-mention\": \"true\",\n \"data-agent-mention-kind\": kind\n }\n : {\n \"data-rich-text-at-mention-row\": \"true\",\n \"data-rich-text-at-mention-kind\": kind\n };\n}\n\nexport function mentionRowDataAttribute(\n mode: MentionRowDataAttributeMode,\n key: MentionRowDataAttributeKey,\n value: string\n): Record<string, string> {\n return {\n [MENTION_ROW_DATA_ATTRIBUTES[mode][key]]: value\n };\n}\n","export interface AtPanelKeyboardActions {\n moveSelection: (delta: 1 | -1) => void;\n commitSelection: () => void;\n close: () => void;\n cycleFilter?: (delta: 1 | -1) => void;\n}\n\nexport interface AtPanelKeyboardEventLike {\n key: string;\n shiftKey?: boolean;\n preventDefault: () => void;\n}\n\nexport function makeAtPanelKeyDown(actions: AtPanelKeyboardActions) {\n return (event: AtPanelKeyboardEventLike): boolean => {\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n actions.moveSelection(1);\n return true;\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n actions.moveSelection(-1);\n return true;\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n actions.close();\n return true;\n }\n if (event.key === \"Tab\" && actions.cycleFilter) {\n event.preventDefault();\n actions.cycleFilter(event.shiftKey ? -1 : 1);\n return true;\n }\n if (event.key === \"Enter\") {\n event.preventDefault();\n actions.commitSelection();\n return true;\n }\n return false;\n };\n}\n\nexport function useAtPanelKeyboard(actions: AtPanelKeyboardActions) {\n return makeAtPanelKeyDown(actions);\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","cn","jsx","useRef","useState","useEffect","cn","cn","jsx","jsxs","cn"]}
|
|
@@ -27,28 +27,28 @@ function normalizeMentionPresentation(presentation) {
|
|
|
27
27
|
return void 0;
|
|
28
28
|
}
|
|
29
29
|
const normalized = {};
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (iconUrl) {
|
|
36
|
-
normalized.iconUrl = iconUrl;
|
|
37
|
-
}
|
|
38
|
-
if (thumbnailUrl) {
|
|
39
|
-
normalized.thumbnailUrl = thumbnailUrl;
|
|
40
|
-
}
|
|
41
|
-
if (subtitle) {
|
|
42
|
-
normalized.subtitle = subtitle;
|
|
43
|
-
}
|
|
44
|
-
if (description) {
|
|
45
|
-
normalized.description = description;
|
|
46
|
-
}
|
|
47
|
-
if (status) {
|
|
48
|
-
normalized.status = status;
|
|
30
|
+
for (const key of richTextMentionPresentationKeys) {
|
|
31
|
+
const value = normalizeOptionalString(presentation[key]);
|
|
32
|
+
if (value) {
|
|
33
|
+
normalized[key] = value;
|
|
34
|
+
}
|
|
49
35
|
}
|
|
50
36
|
return Object.keys(normalized).length > 0 ? Object.freeze(normalized) : void 0;
|
|
51
37
|
}
|
|
38
|
+
var richTextMentionPresentationKeys = [
|
|
39
|
+
"agentProviderId",
|
|
40
|
+
"agentIconUrl",
|
|
41
|
+
"iconUrl",
|
|
42
|
+
"thumbnailUrl",
|
|
43
|
+
"subtitle",
|
|
44
|
+
"description",
|
|
45
|
+
"participant",
|
|
46
|
+
"status",
|
|
47
|
+
"statusDataStatus",
|
|
48
|
+
"statusLabel",
|
|
49
|
+
"statusPulse",
|
|
50
|
+
"userAvatarPlaceholderUrl"
|
|
51
|
+
];
|
|
52
52
|
function createRichTextMentionAttrs(providerId, mention) {
|
|
53
53
|
const normalizedProviderId = providerId.trim();
|
|
54
54
|
const entityId = mention.entityId.trim();
|
|
@@ -185,21 +185,30 @@ function normalizeProviderTriggerConfig(provider) {
|
|
|
185
185
|
boundary: normalizeProviderBoundary(provider)
|
|
186
186
|
};
|
|
187
187
|
}
|
|
188
|
-
function
|
|
188
|
+
function normalizeOptionalIconUrl(value) {
|
|
189
189
|
const trimmed = value?.trim();
|
|
190
190
|
return trimmed ? trimmed : void 0;
|
|
191
191
|
}
|
|
192
|
-
|
|
193
|
-
if (
|
|
192
|
+
function resolveInsertResultIconUrl(insertResult) {
|
|
193
|
+
if (insertResult.kind !== "mention") {
|
|
194
194
|
return void 0;
|
|
195
195
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
196
|
+
return normalizeOptionalIconUrl(insertResult.mention.presentation?.iconUrl);
|
|
197
|
+
}
|
|
198
|
+
async function resolveItemIconUrl(provider, item, insertResult) {
|
|
199
|
+
if (provider.getItemIconUrl) {
|
|
200
|
+
try {
|
|
201
|
+
const iconUrl = normalizeOptionalIconUrl(
|
|
202
|
+
await Promise.resolve(provider.getItemIconUrl(item))
|
|
203
|
+
);
|
|
204
|
+
if (iconUrl) {
|
|
205
|
+
return iconUrl;
|
|
206
|
+
}
|
|
207
|
+
} catch {
|
|
208
|
+
return resolveInsertResultIconUrl(insertResult);
|
|
209
|
+
}
|
|
202
210
|
}
|
|
211
|
+
return resolveInsertResultIconUrl(insertResult);
|
|
203
212
|
}
|
|
204
213
|
function createRichTextTriggerRegistry(providers) {
|
|
205
214
|
const providerMap = /* @__PURE__ */ new Map();
|
|
@@ -237,17 +246,20 @@ function createRichTextTriggerRegistry(providers) {
|
|
|
237
246
|
return [];
|
|
238
247
|
}
|
|
239
248
|
return Promise.all(
|
|
240
|
-
items.map(async (item) =>
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
249
|
+
items.map(async (item) => {
|
|
250
|
+
const insertResult = provider.toInsertResult(item);
|
|
251
|
+
return {
|
|
252
|
+
providerId: provider.id,
|
|
253
|
+
trigger: input.trigger,
|
|
254
|
+
key: provider.getItemKey(item),
|
|
255
|
+
label: provider.getItemLabel(item),
|
|
256
|
+
subtitle: provider.getItemSubtitle?.(item) || void 0,
|
|
257
|
+
iconUrl: await resolveItemIconUrl(provider, item, insertResult),
|
|
258
|
+
keywords: provider.getItemKeywords?.(item),
|
|
259
|
+
item,
|
|
260
|
+
insertResult
|
|
261
|
+
};
|
|
262
|
+
})
|
|
251
263
|
);
|
|
252
264
|
})
|
|
253
265
|
);
|
|
@@ -343,4 +355,4 @@ export {
|
|
|
343
355
|
createRichTextTriggerRegistry,
|
|
344
356
|
createRichTextMentionRegistry
|
|
345
357
|
};
|
|
346
|
-
//# sourceMappingURL=chunk-
|
|
358
|
+
//# sourceMappingURL=chunk-YFXORJLD.js.map
|