@tutti-os/ui-rich-text 0.0.13 → 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 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
- getItemThumbnailUrl?: (
100
+ getItemIconUrl?: (
101
101
  item: TItem
102
102
  ) => string | null | undefined | Promise<string | null | undefined>;
103
103
  getItemKeywords?: (item: TItem) => readonly string[] | undefined;
@@ -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
@@ -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 { classNames, dataAttributeMode } = resolveMentionRowRenderOptions(options);
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: "grid min-w-0 overflow-hidden gap-1", children: [
834
- /* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 items-center gap-2 overflow-hidden", children: [
835
- /* @__PURE__ */ jsx3("span", { className: "min-w-0 truncate text-[13px] font-semibold text-[var(--text-primary)]", children: item.title }),
836
- item.statusTag ? /* @__PURE__ */ jsx3(
837
- MentionStatusBadge,
838
- {
839
- statusTag: item.statusTag,
840
- dataAttributeMode
841
- }
842
- ) : null
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
- item.creatorName ? /* @__PURE__ */ jsx3("span", { className: "truncate text-[13px] font-normal text-[var(--text-secondary)]", children: item.creatorName }) : null
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 iconUrl = normalizeOptionalString(presentation.iconUrl);
31
- const thumbnailUrl = normalizeOptionalString(presentation.thumbnailUrl);
32
- const subtitle = normalizeOptionalString(presentation.subtitle);
33
- const description = normalizeOptionalString(presentation.description);
34
- const status = normalizeOptionalString(presentation.status);
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 normalizeOptionalThumbnailUrl(value) {
188
+ function normalizeOptionalIconUrl(value) {
189
189
  const trimmed = value?.trim();
190
190
  return trimmed ? trimmed : void 0;
191
191
  }
192
- async function resolveItemThumbnailUrl(provider, item) {
193
- if (!provider.getItemThumbnailUrl) {
192
+ function resolveInsertResultIconUrl(insertResult) {
193
+ if (insertResult.kind !== "mention") {
194
194
  return void 0;
195
195
  }
196
- try {
197
- return normalizeOptionalThumbnailUrl(
198
- await Promise.resolve(provider.getItemThumbnailUrl(item))
199
- );
200
- } catch {
201
- return void 0;
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
- providerId: provider.id,
242
- trigger: input.trigger,
243
- key: provider.getItemKey(item),
244
- label: provider.getItemLabel(item),
245
- subtitle: provider.getItemSubtitle?.(item) || void 0,
246
- thumbnailUrl: await resolveItemThumbnailUrl(provider, item),
247
- keywords: provider.getItemKeywords?.(item),
248
- item,
249
- insertResult: provider.toInsertResult(item)
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-QK6NMNYN.js.map
358
+ //# sourceMappingURL=chunk-YFXORJLD.js.map