@longd/layout-ui 0.1.1 → 0.1.2

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.
Files changed (37) hide show
  1. package/README.md +257 -6
  2. package/dist/CATEditor-C-b6vybW.d.cts +381 -0
  3. package/dist/CATEditor-CLp6jZAf.d.ts +381 -0
  4. package/dist/chunk-BLJWR4ZV.js +11 -0
  5. package/dist/chunk-BLJWR4ZV.js.map +1 -0
  6. package/dist/{chunk-CZ3IMHZ6.js → chunk-H7SY4VJU.js} +7 -11
  7. package/dist/chunk-H7SY4VJU.js.map +1 -0
  8. package/dist/chunk-YXQGAND3.js +137 -0
  9. package/dist/chunk-YXQGAND3.js.map +1 -0
  10. package/dist/chunk-ZME2TTK5.js +2527 -0
  11. package/dist/chunk-ZME2TTK5.js.map +1 -0
  12. package/dist/index.cjs +2612 -3
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.css +504 -0
  15. package/dist/index.css.map +1 -0
  16. package/dist/index.d.cts +3 -0
  17. package/dist/index.d.ts +3 -0
  18. package/dist/index.js +13 -2
  19. package/dist/layout/cat-editor.cjs +2669 -0
  20. package/dist/layout/cat-editor.cjs.map +1 -0
  21. package/dist/layout/cat-editor.css +504 -0
  22. package/dist/layout/cat-editor.css.map +1 -0
  23. package/dist/layout/cat-editor.d.cts +28 -0
  24. package/dist/layout/cat-editor.d.ts +28 -0
  25. package/dist/layout/cat-editor.js +29 -0
  26. package/dist/layout/cat-editor.js.map +1 -0
  27. package/dist/layout/select.cjs +2 -1
  28. package/dist/layout/select.cjs.map +1 -1
  29. package/dist/layout/select.js +2 -1
  30. package/dist/utils/detect-quotes.cjs +162 -0
  31. package/dist/utils/detect-quotes.cjs.map +1 -0
  32. package/dist/utils/detect-quotes.d.cts +88 -0
  33. package/dist/utils/detect-quotes.d.ts +88 -0
  34. package/dist/utils/detect-quotes.js +9 -0
  35. package/dist/utils/detect-quotes.js.map +1 -0
  36. package/package.json +39 -3
  37. package/dist/chunk-CZ3IMHZ6.js.map +0 -1
@@ -0,0 +1,381 @@
1
+ import * as React from 'react';
2
+ import React__default from 'react';
3
+ import { DetectQuotesOptions } from './utils/detect-quotes.js';
4
+ import { TextNode, Spread, SerializedTextNode, NodeKey, EditorConfig, DOMExportOutput, DOMConversionMap, LexicalNode } from 'lexical';
5
+
6
+ interface ISuggestion {
7
+ value: string;
8
+ }
9
+ interface ISpellCheckValidation {
10
+ categoryId: string;
11
+ start: number;
12
+ end: number;
13
+ content: string;
14
+ message: string;
15
+ shortMessage: string;
16
+ suggestions: Array<ISuggestion>;
17
+ dictionaries?: Array<string>;
18
+ }
19
+ interface ISpellCheckRule {
20
+ type: 'spellcheck';
21
+ validations: Array<ISpellCheckValidation>;
22
+ }
23
+ interface IKeywordsEntry {
24
+ /** The term text used for exact string matching and display. */
25
+ term: string;
26
+ /** Optional description shown in the popover. */
27
+ description?: string;
28
+ /** Optional regex source string. When provided, it is used for matching
29
+ * instead of an exact `term` lookup. The `g` flag is added automatically.
30
+ * Example: `'hello|hi'` matches both "hello" and "hi". */
31
+ pattern?: string;
32
+ }
33
+ /** Generic term-highlighting rule.
34
+ * `label` controls CSS class (`cat-highlight-glossary-{label}`) and badge text.
35
+ * Examples: label='lexiqa', label='tb-target', label='search' */
36
+ interface IKeywordsRule {
37
+ type: 'glossary';
38
+ label: string;
39
+ entries: Array<IKeywordsEntry>;
40
+ }
41
+ /** @deprecated Use `IKeywordsEntry` instead. */
42
+ type IGlossaryEntry = IKeywordsEntry;
43
+ /** @deprecated Use `IKeywordsRule` instead. */
44
+ type IGlossaryRule = IKeywordsRule;
45
+ interface ISpecialCharEntry {
46
+ /** Human-readable name shown in the popover, e.g. "Non-Breaking Space" */
47
+ name: string;
48
+ /** Regex that matches one occurrence of this character */
49
+ pattern: RegExp;
50
+ }
51
+ interface ISpecialCharRule {
52
+ type: 'special-char';
53
+ entries: Array<ISpecialCharEntry>;
54
+ }
55
+ interface ITagRule {
56
+ type: 'tag';
57
+ /** When true (default), innermost tag pairs are matched first. */
58
+ detectInner?: boolean;
59
+ /** When true, tags become atomic (other highlights inside them are
60
+ * suppressed) and the CSS collapsed rendering kicks in.
61
+ * When false/undefined, tags can be split by search/glossary highlights. */
62
+ collapsed?: boolean;
63
+ /** Which tags should be collapsed when `collapsed` is true.
64
+ * - `'all'` (default): collapse every matched tag/placeholder.
65
+ * - `'html-only'`: only collapse HTML-like tags (`<tag>`, `</tag>`, `<br/>`);
66
+ * non-HTML placeholders (e.g. `{{var}}`, `$amount`) stay expanded. */
67
+ collapseScope?: 'all' | 'html-only';
68
+ /** Custom regex pattern (source string) for matching tags / placeholders.
69
+ * When provided, every match is treated as a standalone tag token
70
+ * numbered sequentially (`<1>`, `<2>`, …).
71
+ * When omitted, the built-in HTML tag detection with open/close pairing is used.
72
+ * @example '<[^>]+>|(\\{\\{[^{}]*\\}\\})|(\\{[^{}]*\\})' */
73
+ pattern?: string;
74
+ }
75
+ interface IQuoteRuleMapping {
76
+ opening: string;
77
+ closing: string;
78
+ }
79
+ interface IQuoteRule {
80
+ type: 'quote';
81
+ singleQuote: IQuoteRuleMapping;
82
+ doubleQuote: IQuoteRuleMapping;
83
+ /** When `true`, quote replacement is also applied inside HTML tags
84
+ * (e.g. attribute values like `href="…"`). When `false` (the default),
85
+ * quotes that fall inside a tag range are suppressed. */
86
+ detectInTags?: boolean;
87
+ /** Options forwarded to the `detectQuotes()` utility.
88
+ * Allows customising contraction escaping, nesting behaviour, etc. */
89
+ detectOptions?: DetectQuotesOptions;
90
+ }
91
+ interface ILinkRule {
92
+ type: 'link';
93
+ /** Custom regex pattern (source string) for matching URLs.
94
+ * When omitted, a built-in pattern matching http/https URLs and
95
+ * www-prefixed domains is used. */
96
+ pattern?: string;
97
+ }
98
+ /** A user that can be mentioned via the @ trigger. */
99
+ interface IMentionUser {
100
+ id: string;
101
+ name: string;
102
+ /** Optional avatar render function. When omitted an initials fallback is shown. */
103
+ avatar?: () => React__default.ReactNode;
104
+ }
105
+ interface IMentionRule {
106
+ type: 'mention';
107
+ /** List of users available for the mention typeahead. */
108
+ users: Array<IMentionUser>;
109
+ /** Trigger character, default `@`. */
110
+ trigger?: string;
111
+ }
112
+ type MooRule = ISpellCheckRule | IKeywordsRule | ISpecialCharRule | ITagRule | IQuoteRule | ILinkRule | IMentionRule;
113
+ interface SpellCheckAnnotation {
114
+ type: 'spellcheck';
115
+ id: string;
116
+ data: ISpellCheckValidation;
117
+ }
118
+ interface KeywordsAnnotation {
119
+ type: 'glossary';
120
+ id: string;
121
+ data: {
122
+ label: string;
123
+ term: string;
124
+ description?: string;
125
+ };
126
+ }
127
+ /** @deprecated Use `KeywordsAnnotation` instead. */
128
+ type GlossaryAnnotation = KeywordsAnnotation;
129
+ interface SpecialCharAnnotation {
130
+ type: 'special-char';
131
+ id: string;
132
+ data: {
133
+ name: string;
134
+ char: string;
135
+ codePoint: string;
136
+ };
137
+ }
138
+ interface TagAnnotation {
139
+ type: 'tag';
140
+ id: string;
141
+ data: {
142
+ tagNumber: number;
143
+ tagName: string;
144
+ isClosing: boolean;
145
+ isSelfClosing: boolean;
146
+ originalText: string;
147
+ displayText: string;
148
+ /** `true` when the tag was classified as HTML (`<tag>`, `</tag>`, `<br/>`). */
149
+ isHtml: boolean;
150
+ };
151
+ }
152
+ interface QuoteAnnotation {
153
+ type: 'quote';
154
+ id: string;
155
+ data: {
156
+ quoteType: 'single' | 'double';
157
+ position: 'opening' | 'closing';
158
+ originalChar: string;
159
+ replacementChar: string;
160
+ };
161
+ }
162
+ interface LinkAnnotation {
163
+ type: 'link';
164
+ id: string;
165
+ data: {
166
+ url: string;
167
+ displayText: string;
168
+ };
169
+ }
170
+ type RuleAnnotation = SpellCheckAnnotation | KeywordsAnnotation | SpecialCharAnnotation | TagAnnotation | QuoteAnnotation | LinkAnnotation;
171
+ interface RawRange {
172
+ start: number;
173
+ end: number;
174
+ annotation: RuleAnnotation;
175
+ }
176
+ interface HighlightSegment {
177
+ start: number;
178
+ end: number;
179
+ annotations: Array<RuleAnnotation>;
180
+ }
181
+ interface PopoverState {
182
+ visible: boolean;
183
+ x: number;
184
+ y: number;
185
+ /** Full bounding rect of the hovered highlight element.
186
+ * Used by Popper so that flip/shift avoid overlapping the target. */
187
+ anchorRect?: {
188
+ top: number;
189
+ left: number;
190
+ bottom: number;
191
+ right: number;
192
+ width: number;
193
+ height: number;
194
+ };
195
+ ruleIds: Array<string>;
196
+ }
197
+ /** Props passed to the custom popover content renderer.
198
+ * Use this to fully replace the built-in popover UI for any annotation. */
199
+ interface PopoverContentRendererProps {
200
+ annotation: RuleAnnotation;
201
+ /** Call with a suggestion string to apply it (only relevant for spellcheck) */
202
+ onSuggestionClick: (suggestion: string) => void;
203
+ }
204
+ /** Render function for custom popover content.
205
+ * Return `undefined` / `null` to fall back to the default built-in renderer. */
206
+ type PopoverContentRenderer = (props: PopoverContentRendererProps) => React__default.ReactNode;
207
+ /** Imperative API exposed via `ref` on `<CATEditor>`. */
208
+ interface CATEditorRef {
209
+ /** Insert text at the current (or last saved) cursor position. */
210
+ insertText: (text: string) => void;
211
+ /** Focus the editor. */
212
+ focus: () => void;
213
+ /** Get the full plain-text content. */
214
+ getText: () => string;
215
+ /** Replace all occurrences of `search` with `replacement` in the editor
216
+ * content. Returns the number of replacements made. */
217
+ replaceAll: (search: string, replacement: string) => number;
218
+ /** Temporarily highlight editor elements matching `annotationId` with a
219
+ * pink "flash" overlay. The highlight is automatically removed after
220
+ * `durationMs` (default 5 000 ms), when the user edits the text, or
221
+ * when `clearFlash` / another `flashHighlight` call is made. */
222
+ flashHighlight: (annotationId: string, durationMs?: number) => void;
223
+ /** Remove any active flash highlight immediately. */
224
+ clearFlash: () => void;
225
+ }
226
+
227
+ type SerializedMentionNode = Spread<{
228
+ mentionId: string;
229
+ mentionName: string;
230
+ }, SerializedTextNode>;
231
+ /** Render function that fills the DOM of a mention node.
232
+ * Receives the host `<span>` element, the mentionId, and the display name.
233
+ * Return `true` to signal that you handled the rendering;
234
+ * return `false` / `undefined` to fall back to the built-in renderer. */
235
+ type MentionDOMRenderer = (element: HTMLSpanElement, mentionId: string, mentionName: string) => boolean | void;
236
+ interface MentionNodeConfig {
237
+ /** Custom renderer for the mention node DOM content.
238
+ * When provided, this function is called every time the mention DOM
239
+ * is created or updated. Return `true` to take over rendering. */
240
+ renderDOM?: MentionDOMRenderer;
241
+ /** Converts a mention ID to the model text stored in the editor.
242
+ * Default: `` id => `@{${id}}` `` — produces `@{5}`, `@{user_abc}`, etc. */
243
+ serialize?: (id: string) => string;
244
+ /** RegExp used to detect mention patterns in pasted / imported text.
245
+ * Must contain exactly one capture group that extracts the mention ID.
246
+ * The `g` flag is required.
247
+ * Default: `/@\{([^}]+)\}/g` — matches `@{5}`, `@{user_abc}`, etc. */
248
+ pattern?: RegExp;
249
+ }
250
+ /** Configure the global MentionNode behaviour.
251
+ * Call this from CATEditor whenever props change. */
252
+ declare function setMentionNodeConfig(config: MentionNodeConfig): void;
253
+ /** Get the model text for a mention with the given ID,
254
+ * using the configured `serialize` function (or the default `@{id}`). */
255
+ declare function getMentionModelText(id: string): string;
256
+ /** Get a fresh copy of the mention detection RegExp.
257
+ * A new RegExp is returned every time so that `lastIndex` is always 0. */
258
+ declare function getMentionPattern(): RegExp;
259
+ /**
260
+ * A custom Lexical TextNode that represents a mention.
261
+ *
262
+ * **Model text** (what Lexical stores, what `getTextContent()` returns):
263
+ * `@{mentionId}` — e.g. `@1`, `@user_abc`.
264
+ *
265
+ * **Visible DOM**: `@DisplayName` (+ optional avatar). The display is
266
+ * controlled by a configurable renderer — see `setMentionNodeConfig`.
267
+ *
268
+ * The node uses "segmented" mode so it behaves as an atomic unit:
269
+ * backspace removes the whole mention, typing at boundaries creates a
270
+ * sibling TextNode instead of editing the mention text.
271
+ */
272
+ declare class MentionNode extends TextNode {
273
+ __mentionId: string;
274
+ __mentionName: string;
275
+ static getType(): string;
276
+ static clone(node: MentionNode): MentionNode;
277
+ static importJSON(serializedNode: SerializedMentionNode): MentionNode;
278
+ constructor(mentionId: string, mentionName: string, text?: string, key?: NodeKey);
279
+ exportJSON(): SerializedMentionNode;
280
+ createDOM(config: EditorConfig): HTMLElement;
281
+ updateDOM(prevNode: MentionNode, dom: HTMLElement, _config: EditorConfig): boolean;
282
+ /** Fill the span with visible content (default: @label, or custom). */
283
+ private _renderInnerDOM;
284
+ exportDOM(): DOMExportOutput;
285
+ static importDOM(): DOMConversionMap | null;
286
+ isTextEntity(): true;
287
+ canInsertTextBefore(): boolean;
288
+ canInsertTextAfter(): boolean;
289
+ }
290
+ declare function $createMentionNode(mentionId: string, mentionName: string, textContent?: string): MentionNode;
291
+ declare function $isMentionNode(node: LexicalNode | null | undefined): node is MentionNode;
292
+
293
+ interface CATEditorProps {
294
+ /** Initial text content for the editor */
295
+ initialText?: string;
296
+ /** Rules to apply for highlighting */
297
+ rules?: Array<MooRule>;
298
+ /** Called when editor content changes */
299
+ onChange?: (text: string) => void;
300
+ /** Called when a suggestion is applied.
301
+ * Provides the ruleId, the replacement text, the original text
302
+ * span (start / end / content), and the ruleType so consumers
303
+ * can identify which rule triggered the replacement. */
304
+ onSuggestionApply?: (ruleId: string, suggestion: string, range: {
305
+ start: number;
306
+ end: number;
307
+ content: string;
308
+ }, ruleType: RuleAnnotation['type']) => void;
309
+ /** Custom code-point → display symbol map. Merged on top of the
310
+ * built-in `CODEPOINT_DISPLAY_MAP`. Pass `{ 0x00a0: '⍽' }` to
311
+ * override the symbol shown for non-breaking spaces, etc. */
312
+ codepointDisplayMap?: Record<number, string>;
313
+ /** Custom renderer for popover content per annotation.
314
+ * Return `null`/`undefined` to use the built-in default. */
315
+ renderPopoverContent?: PopoverContentRenderer;
316
+ /** Called when a link highlight is clicked. If not provided, links
317
+ * open in a new browser tab via `window.open`. */
318
+ onLinkClick?: (url: string) => void;
319
+ /** Whether clicking a link highlight should open the URL.
320
+ * When `false`, link clicks are ignored (the click positions the
321
+ * cursor in the editor text instead). Default: `true`. */
322
+ openLinksOnClick?: boolean;
323
+ /** Called when a mention node is clicked. */
324
+ onMentionClick?: (userId: string, userName: string) => void;
325
+ /** Called when a mention is inserted via the typeahead. */
326
+ onMentionInsert?: (user: IMentionUser) => void;
327
+ /** Converts a mention ID to model text.
328
+ * Default: `` id => `@{${id}}` `` producing `@{5}`, `@{user_abc}`, etc. */
329
+ mentionSerialize?: (id: string) => string;
330
+ /** RegExp to detect mention patterns in pasted / imported text.
331
+ * Must have one capture group for the ID and use the `g` flag.
332
+ * Default: `/@\{([^}]+)\}/g` */
333
+ mentionPattern?: RegExp;
334
+ /** Custom DOM renderer for mention nodes.
335
+ * Receives the `<span>` host element, the mentionId and the
336
+ * display name. Return `true` to take over rendering;
337
+ * return `false`/`undefined` to use the default `@name` label. */
338
+ renderMentionDOM?: MentionDOMRenderer;
339
+ /** Placeholder text */
340
+ placeholder?: string;
341
+ /** Additional class name for the editor container */
342
+ className?: string;
343
+ /** Text direction. `'ltr'` (default), `'rtl'`, or `'auto'`. */
344
+ dir?: 'ltr' | 'rtl' | 'auto';
345
+ /** Text direction for the highlight popover. Defaults to `'ltr'` so
346
+ * that popover content stays left-to-right even when the editor is
347
+ * RTL. Set to `'rtl'` or `'auto'` if your popover content should
348
+ * follow the editor direction, or pass `'inherit'` to use the same
349
+ * direction as the editor (`dir` prop). */
350
+ popoverDir?: 'ltr' | 'rtl' | 'auto' | 'inherit';
351
+ /** When `true`, applies a Japanese-optimised font stack to the editor. */
352
+ jpFont?: boolean;
353
+ /** Whether the editor content is editable. Default: `true`.
354
+ * When `false`, all text mutations are blocked.
355
+ * @see readOnlySelectable */
356
+ editable?: boolean;
357
+ /** When `editable` is `false` and this is `true`, the editor still
358
+ * allows caret placement, range selection and copy — but rejects
359
+ * any content changes. Default: `false`. */
360
+ readOnlySelectable?: boolean;
361
+ /** Custom keydown handler. Called before Lexical processes the event.
362
+ * Return `true` to prevent Lexical (and the browser) from handling
363
+ * the key. Useful for intercepting Enter, Tab, Escape, etc.
364
+ * @example
365
+ * ```tsx
366
+ * onKeyDown={(e) => {
367
+ * if (e.key === 'Enter' && !e.shiftKey) {
368
+ * e.preventDefault()
369
+ * handleSubmit()
370
+ * return true
371
+ * }
372
+ * return false
373
+ * }}
374
+ * ``` */
375
+ onKeyDown?: (event: KeyboardEvent) => boolean;
376
+ /** @deprecated Use `editable` instead. */
377
+ readOnly?: boolean;
378
+ }
379
+ declare const CATEditor: React.ForwardRefExoticComponent<CATEditorProps & React.RefAttributes<CATEditorRef>>;
380
+
381
+ export { $createMentionNode as $, getMentionPattern as A, setMentionNodeConfig as B, CATEditor as C, type GlossaryAnnotation as G, type HighlightSegment as H, type IKeywordsRule as I, type KeywordsAnnotation as K, type LinkAnnotation as L, type MooRule as M, type PopoverContentRenderer as P, type QuoteAnnotation as Q, type RuleAnnotation as R, type SerializedMentionNode as S, type TagAnnotation as T, type CATEditorProps as a, type CATEditorRef as b, type ILinkRule as c, type IMentionRule as d, type IMentionUser as e, type IQuoteRule as f, type ISpecialCharRule as g, type ISpellCheckRule as h, type ITagRule as i, type PopoverContentRendererProps as j, $isMentionNode as k, type IGlossaryEntry as l, type IGlossaryRule as m, type IKeywordsEntry as n, type IQuoteRuleMapping as o, type ISpecialCharEntry as p, type ISpellCheckValidation as q, type ISuggestion as r, type MentionDOMRenderer as s, MentionNode as t, type MentionNodeConfig as u, type PopoverState as v, type RawRange as w, type SpecialCharAnnotation as x, type SpellCheckAnnotation as y, getMentionModelText as z };
@@ -0,0 +1,11 @@
1
+ // src/lib/utils.ts
2
+ import { clsx } from "clsx";
3
+ import { twMerge } from "tailwind-merge";
4
+ function cn(...inputs) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+
8
+ export {
9
+ cn
10
+ };
11
+ //# sourceMappingURL=chunk-BLJWR4ZV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/utils.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":";AAAA,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
@@ -1,3 +1,7 @@
1
+ import {
2
+ cn
3
+ } from "./chunk-BLJWR4ZV.js";
4
+
1
5
  // src/layout/select.tsx
2
6
  import * as React from "react";
3
7
  import {
@@ -31,15 +35,6 @@ import {
31
35
  } from "@dnd-kit/modifiers";
32
36
  import { defaultRangeExtractor, useVirtualizer } from "@tanstack/react-virtual";
33
37
  import { Check, ChevronDown, GripVertical, X } from "lucide-react";
34
-
35
- // src/lib/utils.ts
36
- import { clsx } from "clsx";
37
- import { twMerge } from "tailwind-merge";
38
- function cn(...inputs) {
39
- return twMerge(clsx(inputs));
40
- }
41
-
42
- // src/layout/select.tsx
43
38
  import { jsx, jsxs } from "react/jsx-runtime";
44
39
  function resolveIcon(icon) {
45
40
  if (icon === void 0 || icon === null) return null;
@@ -337,8 +332,9 @@ function MultipleTriggerContent({
337
332
  let maxVisible = collapsed ? value.length : visibleCount;
338
333
  const hasExplicitLimit = !collapsed && showItemsLength !== void 0;
339
334
  if (hasExplicitLimit) {
340
- maxVisible = showItemsLength;
335
+ maxVisible = Math.min(visibleCount, showItemsLength);
341
336
  }
337
+ maxVisible = Math.max(1, maxVisible);
342
338
  const hasOverflow = maxVisible < value.length;
343
339
  const displayed = value.slice(0, maxVisible);
344
340
  const overflowItems = value.slice(maxVisible);
@@ -1080,4 +1076,4 @@ export {
1080
1076
  LayoutSelect,
1081
1077
  select_default
1082
1078
  };
1083
- //# sourceMappingURL=chunk-CZ3IMHZ6.js.map
1079
+ //# sourceMappingURL=chunk-H7SY4VJU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/layout/select.tsx"],"sourcesContent":["import * as React from 'react'\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { Popover } from '@base-ui/react/popover'\nimport { Tooltip } from '@base-ui/react/tooltip'\nimport { Command } from 'cmdk'\nimport {\n DndContext,\n KeyboardSensor,\n PointerSensor,\n closestCenter,\n useSensor,\n useSensors,\n} from '@dnd-kit/core'\nimport {\n SortableContext,\n arrayMove,\n useSortable,\n verticalListSortingStrategy,\n} from '@dnd-kit/sortable'\nimport {\n restrictToFirstScrollableAncestor,\n restrictToVerticalAxis,\n} from '@dnd-kit/modifiers'\nimport { defaultRangeExtractor, useVirtualizer } from '@tanstack/react-virtual'\nimport { Check, ChevronDown, GripVertical, X } from 'lucide-react'\n\nimport type { Range } from '@tanstack/react-virtual'\nimport type {\n CollisionDetection,\n DragEndEvent,\n DragOverEvent,\n} from '@dnd-kit/core'\n\nimport { cn } from '@/lib/utils'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * For `icon` we accept either a ReactNode (already rendered) or a **render\n * function** `() => ReactNode`. The render‑function form lets consumers pass\n * lazy/memoised icons so the component only mounts them when visible (better\n * perf for large lists with heavy SVG icons).\n */\nexport type IconProp = React.ReactNode | (() => React.ReactNode)\n\nexport interface IOption {\n label: string\n value: string | number\n icon?: IconProp\n disabled?: boolean\n disabledTooltip?: string\n /** Nested children – rendered as a visual group. */\n children?: Array<IOption>\n}\n\n// ---- Conditional selection types ----\n\ninterface SingleSelectProps {\n type: 'single'\n selectValue?: IOption | null\n onChange?: (value: IOption | null, selectedOption: IOption) => void\n collapsed?: never\n showItemsLength?: never\n}\n\ninterface MultipleSelectProps {\n type: 'multiple'\n selectValue?: Array<IOption>\n onChange?: (value: Array<IOption>, selectedOption: IOption) => void\n /** When `true` the trigger will expand to show all chips instead of\n * collapsing them into a \"+N\" overflow badge. */\n collapsed?: boolean\n /** Force a maximum number of visible chip items. Lower priority than the\n * automatic overflow detection when `collapsed` is not set. */\n showItemsLength?: number\n}\n\n// ---- Shared props ----\n\ninterface SharedSelectProps {\n /** All available options (may contain nested `children`). */\n options: Array<IOption>\n /** Placeholder shown when nothing is selected. */\n placeholder?: string\n /** Whether the entire select is disabled. */\n disabled?: boolean\n /** Whether the select is in read‑only mode (looks interactive but cannot\n * be changed). */\n readOnly?: boolean\n /** Marks the select as having a validation error. */\n error?: boolean\n /** Allow the user to clear the selection. */\n clearable?: boolean\n /** Custom class for the root wrapper. */\n className?: string\n /** Custom class for the trigger. */\n triggerClassName?: string\n /** Custom class for the popup. */\n popupClassName?: string\n\n // ---- Render overrides ----\n\n /** Replace the entire trigger UI. Receives the current value(s) and a\n * boolean indicating whether the popup is open. */\n renderTrigger?: (props: {\n value: IOption | Array<IOption> | null\n open: boolean\n disabled: boolean\n readOnly: boolean\n error: boolean\n placeholder: string\n }) => React.ReactNode\n\n /** Replace the default option row renderer inside the list. */\n renderItem?: (\n option: IOption,\n state: { selected: boolean; highlighted: boolean; disabled: boolean },\n ) => React.ReactNode\n\n // ---- List chrome ----\n\n /** Component(s) rendered *before* the option list inside the popup. */\n listPrefix?: React.ReactNode\n /** Component(s) rendered *after* the option list inside the popup. */\n listSuffix?: React.ReactNode\n\n // ---- Async / lazy ----\n\n /** Called when the popup opens. Return a list of options to *replace* the\n * current `options` prop (useful for lazy fetching). */\n queryFn?: () => Promise<Array<IOption>>\n\n /** Label rendered above the select (optional). */\n label?: string\n}\n\n// ---- Sortable types ----\n\ninterface SortableEnabledProps {\n /** Enable drag‑and‑drop reordering of options in the list. */\n sortable: true\n /** Called after the user finishes reordering. Receives the new sorted\n * array of options. Required when `sortable` is `true`. */\n onSortEnd: (sortedOptions: Array<IOption>) => void\n /** When `true` and options are grouped (have `children`), items can be\n * dragged across groups. By default sorting is scoped within each group. */\n sortableAcrossGroups?: boolean\n}\n\ninterface SortableDisabledProps {\n sortable?: false\n onSortEnd?: never\n sortableAcrossGroups?: never\n}\n\nexport type LayoutSelectProps = SharedSelectProps &\n (SingleSelectProps | MultipleSelectProps) &\n (SortableEnabledProps | SortableDisabledProps)\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Resolve an `IconProp` to a ReactNode – cheap for already‑rendered nodes,\n * and defers the call for function icons. */\nfunction resolveIcon(icon: IconProp | undefined): React.ReactNode {\n if (icon === undefined || icon === null) return null\n if (typeof icon === 'function') return (icon as () => React.ReactNode)()\n return icon\n}\n\n/** Flatten a potentially nested option tree into a flat list (depth‑first).\n * Group parents (options with `children`) are **excluded** – only leaves. */\nfunction flattenOptions(options: Array<IOption>): Array<IOption> {\n const result: Array<IOption> = []\n for (const opt of options) {\n if (opt.children && opt.children.length > 0) {\n result.push(...flattenOptions(opt.children))\n } else {\n result.push(opt)\n }\n }\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Display row types for virtualised list (group headers + leaf options)\n// ---------------------------------------------------------------------------\n\ntype DisplayRow =\n | { kind: 'group-header'; label: string; groupValue: string | number }\n | { kind: 'option'; option: IOption; groupValue?: string | number }\n\n/** Build a display-row list from potentially grouped options.\n * If an option has `children`, emit a group-header row followed by child\n * option rows. Options without `children` are emitted as top-level\n * option rows (groupValue = undefined). */\nfunction buildDisplayRows(options: Array<IOption>): Array<DisplayRow> {\n const rows: Array<DisplayRow> = []\n for (const opt of options) {\n if (opt.children && opt.children.length > 0) {\n rows.push({\n kind: 'group-header',\n label: opt.label,\n groupValue: opt.value,\n })\n for (const child of opt.children) {\n rows.push({ kind: 'option', option: child, groupValue: opt.value })\n }\n } else {\n rows.push({ kind: 'option', option: opt })\n }\n }\n return rows\n}\n\n/** Check whether the options list contains any grouped entries. */\nfunction hasGroups(options: Array<IOption>): boolean {\n return options.some((o) => o.children && o.children.length > 0)\n}\n\n/** Simple value equality check for options. */\nfunction optionEq(a: IOption, b: IOption) {\n return a.value === b.value\n}\n\nfunction isSelected(option: IOption, value: IOption | Array<IOption> | null) {\n if (!value) return false\n if (Array.isArray(value)) return value.some((v) => optionEq(v, option))\n return optionEq(value, option)\n}\n\n// ---------------------------------------------------------------------------\n// Sortable item wrapper (for dnd‑kit inside virtual list)\n// ---------------------------------------------------------------------------\n\ninterface SortableItemProps {\n id: string\n children: React.ReactNode\n disabled?: boolean\n}\n\nfunction SortableItem({ id, children, disabled }: SortableItemProps) {\n const {\n setNodeRef,\n attributes,\n listeners,\n transform,\n transition,\n isDragging,\n } = useSortable({ id, disabled })\n\n const style: React.CSSProperties = {\n transform: transform\n ? `translate3d(${transform.x}px, ${transform.y}px, 0)`\n : undefined,\n transition,\n opacity: isDragging ? 0.5 : 1,\n position: 'relative',\n zIndex: isDragging ? 50 : undefined,\n }\n\n return (\n <div ref={setNodeRef} style={style} className=\"flex items-center\">\n {!disabled && (\n <button\n type=\"button\"\n className=\"flex shrink-0 cursor-grab items-center px-1 text-muted-foreground hover:text-foreground active:cursor-grabbing\"\n {...attributes}\n {...listeners}\n >\n <GripVertical className=\"size-3.5\" />\n </button>\n )}\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// DisabledTooltip wrapper\n// ---------------------------------------------------------------------------\n\nfunction MaybeTooltip({\n tooltip,\n children,\n}: {\n tooltip?: string\n children: React.ReactElement\n}) {\n if (!tooltip) return children\n return (\n <Tooltip.Root>\n <Tooltip.Trigger render={children} />\n <Tooltip.Portal>\n <Tooltip.Positioner sideOffset={6}>\n <Tooltip.Popup className=\"rounded-md bg-foreground px-2.5 py-1 text-xs text-background shadow-md\">\n {tooltip}\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Chip (for multiple‑select trigger)\n// ---------------------------------------------------------------------------\n\ninterface ChipProps {\n option: IOption\n onRemove?: () => void\n readOnly?: boolean\n disabled?: boolean\n className?: string\n /** Mark as the \"partial\" chip that may be squeezed to truncate. */\n partial?: boolean\n}\n\nfunction Chip({\n option,\n onRemove,\n readOnly,\n disabled,\n className,\n partial,\n}: ChipProps) {\n return (\n <span\n data-partial-chip={partial || undefined}\n className={cn(\n 'inline-flex max-w-35 items-center gap-1 rounded-md border border-border bg-secondary px-2 py-0.5 text-xs leading-5 text-secondary-foreground',\n disabled && 'opacity-50',\n className,\n )}\n >\n {option.icon && (\n <span className=\"flex shrink-0 items-center [&_svg]:size-3\">\n {resolveIcon(option.icon)}\n </span>\n )}\n <span className=\"truncate\">{option.label}</span>\n {!readOnly && !disabled && onRemove && (\n <button\n type=\"button\"\n className=\"ml-0.5 flex shrink-0 items-center rounded-sm text-muted-foreground hover:text-foreground\"\n onClick={(e) => {\n e.stopPropagation()\n onRemove()\n }}\n tabIndex={-1}\n aria-label={`Remove ${option.label}`}\n >\n <X className=\"size-3\" />\n </button>\n )}\n </span>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Overflow chip badge\n// ---------------------------------------------------------------------------\n\nfunction OverflowBadge({\n items,\n onRemove,\n}: {\n items: Array<IOption>\n onRemove?: (option: IOption) => void\n}) {\n if (items.length === 0) return null\n return (\n <Tooltip.Root>\n <Tooltip.Trigger\n render={\n <span className=\"inline-flex shrink-0 items-center rounded-md border border-border bg-muted px-1.5 py-0.5 text-xs font-medium text-muted-foreground\">\n +{items.length}\n </span>\n }\n />\n <Tooltip.Portal>\n <Tooltip.Positioner sideOffset={6}>\n <Tooltip.Popup className=\"max-w-xs rounded-md bg-foreground px-3 py-2 text-xs text-background shadow-md\">\n <div className=\"flex flex-wrap gap-1\">\n {items.map((item) => (\n <span\n key={item.value}\n className=\"inline-flex items-center gap-1 rounded-md border border-background/20 bg-background/10 px-1.5 py-0.5 text-xs leading-4 text-background\"\n >\n {item.icon && (\n <span className=\"flex shrink-0 items-center [&_svg]:size-3\">\n {resolveIcon(item.icon)}\n </span>\n )}\n <span className=\"truncate\">{item.label}</span>\n {onRemove && (\n <button\n type=\"button\"\n className=\"ml-0.5 flex shrink-0 items-center rounded-sm text-background/60 hover:text-background\"\n onClick={(e) => {\n e.stopPropagation()\n onRemove(item)\n }}\n tabIndex={-1}\n aria-label={`Remove ${item.label}`}\n >\n <X className=\"size-3\" />\n </button>\n )}\n </span>\n ))}\n </div>\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Default trigger renderers\n// ---------------------------------------------------------------------------\n\nfunction SingleTriggerContent({\n value,\n placeholder,\n}: {\n value: IOption | null\n placeholder: string\n}) {\n if (!value) {\n return <span className=\"truncate text-muted-foreground\">{placeholder}</span>\n }\n return (\n <span className=\"flex items-center gap-2 truncate\">\n {value.icon && (\n <span className=\"flex shrink-0 items-center [&_svg]:size-4\">\n {resolveIcon(value.icon)}\n </span>\n )}\n <span className=\"truncate\">{value.label}</span>\n </span>\n )\n}\n\nfunction MultipleTriggerContent({\n value,\n placeholder,\n collapsed,\n showItemsLength,\n onRemove,\n readOnly,\n disabled,\n}: {\n value: Array<IOption>\n placeholder: string\n collapsed?: boolean\n showItemsLength?: number\n onRemove?: (option: IOption) => void\n readOnly?: boolean\n disabled?: boolean\n}) {\n // Shared layout classes so measure layer, display div, and wrappers\n // always use the same gap / alignment. Change once, applied everywhere.\n const chipRowClass = 'flex items-center gap-1'\n\n const wrapperRef = useRef<HTMLDivElement>(null)\n const measureRef = useRef<HTMLDivElement>(null)\n const [visibleCount, setVisibleCount] = useState(value.length)\n const [lastIsPartial, setLastIsPartial] = useState(false)\n const [measured, setMeasured] = useState(false)\n\n // Cap invisible measurement chips – no single-row trigger needs more than\n // ~20 chips, so we avoid creating thousands of DOM nodes for large lists.\n const measureCount = Math.min(value.length, 20)\n\n const calculate = React.useEffectEvent(() => {\n const measureContainer = measureRef.current\n if (!measureContainer) return\n\n const children = Array.from(measureContainer.children) as Array<HTMLElement>\n const containerRight = measureContainer.getBoundingClientRect().right\n const gap = parseFloat(getComputedStyle(measureContainer).columnGap) || 0\n // The invisible layer has no badge sibling, so always reserve space\n // for the badge that will appear in the visible layer.\n // Estimate badge width based on overflow digit count:\n // \"+N\" at text-xs with px-1.5 + border ≈ 14px + 8px per character.\n const estimateBadgeWidth = (overflowCount: number) =>\n overflowCount > 0 ? 14 + 8 * String(overflowCount).length : 0\n let count = 0\n let partial = false\n\n for (const child of children) {\n const childRight = child.getBoundingClientRect().right\n const overflow = value.length - (count + 1)\n const reserve =\n overflow > 0 ? Math.max(40, estimateBadgeWidth(overflow)) : 0\n if (childRight + reserve <= containerRight) {\n count++\n } else {\n break\n }\n }\n // Show at least 1 chip when there are items\n count = Math.max(1, count)\n\n // If there are overflow items, check whether an extra \"partial\"\n // (squeezed) chip can fit. Chips with icons need more space.\n if (count < value.length && children.length >= count) {\n const lastRight = children[count - 1].getBoundingClientRect().right\n // If the partial chip would be the LAST item, no badge is needed.\n const needsBadge = count + 1 < value.length\n const badgeReserve = needsBadge\n ? Math.max(40, estimateBadgeWidth(value.length - count - 1))\n : 0\n const spaceForPartial = containerRight - badgeReserve - lastRight - gap\n const nextChip = value[count]\n // Base minimum: 50px (covers label truncation + remove button).\n // If the chip has an icon, add the icon's actual rendered width + gap.\n let minPartialWidth = 50\n if (nextChip.icon && children.length > count) {\n const iconWrapper = children[count].firstElementChild\n if (iconWrapper) {\n minPartialWidth += iconWrapper.getBoundingClientRect().width + gap\n }\n }\n if (spaceForPartial >= minPartialWidth) {\n count++ // include partial chip in the count\n partial = true\n }\n }\n\n setVisibleCount(count)\n setLastIsPartial(partial)\n setMeasured(true)\n })\n\n useLayoutEffect(() => {\n if (collapsed || value.length === 0) {\n setVisibleCount(value.length)\n setLastIsPartial(false)\n setMeasured(true)\n return\n }\n\n const wrapper = wrapperRef.current\n const container = measureRef.current\n if (!wrapper || !container) return\n\n // Measure immediately (synchronous, before browser paint)\n calculate()\n\n // Re-measure whenever the wrapper resizes (window resize, container\n // layout change). Because we always measure the invisible layer\n // (which has ALL chips as shrink-0), this correctly handles both\n // resize-smaller AND resize-larger.\n const observer = new ResizeObserver(calculate)\n observer.observe(wrapper)\n return () => observer.disconnect()\n }, [collapsed, value])\n\n if (value.length === 0) {\n return <span className=\"truncate text-muted-foreground\">{placeholder}</span>\n }\n\n // Invisible measurement layer – always present, always has ALL chips\n // rendered at natural (shrink-0) size for stable measurement.\n const measureLayer = !collapsed && (\n <div\n ref={measureRef}\n className={cn(\n 'pointer-events-none absolute inset-0 overflow-hidden opacity-0',\n chipRowClass,\n )}\n aria-hidden\n >\n {value.slice(0, measureCount).map((opt) => (\n <Chip\n key={opt.value}\n option={opt}\n onRemove={onRemove ? () => {} : undefined}\n readOnly={readOnly}\n disabled={disabled}\n className=\"shrink-0\"\n />\n ))}\n </div>\n )\n\n // Wait for first measurement before showing real chips (SSR safety).\n const showContent = collapsed || measured\n if (!showContent) {\n return (\n <div\n ref={wrapperRef}\n className={cn('relative min-w-0 flex-1 overflow-hidden', chipRowClass)}\n >\n {measureLayer}\n <span className=\"truncate text-muted-foreground\">\n {value.length} selected\n </span>\n </div>\n )\n }\n\n // Determine maximum fully-visible chips.\n let maxVisible = collapsed ? value.length : visibleCount\n const hasExplicitLimit = !collapsed && showItemsLength !== undefined\n if (hasExplicitLimit) {\n maxVisible = Math.min(visibleCount, showItemsLength)\n }\n maxVisible = Math.max(1, maxVisible)\n\n const hasOverflow = maxVisible < value.length\n const displayed = value.slice(0, maxVisible)\n const overflowItems = value.slice(maxVisible)\n\n return (\n <div\n ref={wrapperRef}\n className={cn('relative min-w-0 flex-1', chipRowClass)}\n >\n {measureLayer}\n <div\n className={cn(\n 'min-w-0 flex-1',\n chipRowClass,\n collapsed ? 'flex-wrap' : 'overflow-hidden',\n )}\n >\n {displayed.map((opt, i) => {\n const isPartial =\n (hasOverflow || lastIsPartial) &&\n !hasExplicitLimit &&\n i === displayed.length - 1\n const shouldShrink = isPartial || hasExplicitLimit\n return (\n <Chip\n key={opt.value}\n option={opt}\n onRemove={onRemove ? () => onRemove(opt) : undefined}\n readOnly={readOnly}\n disabled={disabled}\n partial={isPartial}\n className={shouldShrink ? 'min-w-0 shrink' : 'shrink-0'}\n />\n )\n })}\n </div>\n {overflowItems.length > 0 && (\n <span className=\"shrink-0\">\n <OverflowBadge items={overflowItems} onRemove={onRemove} />\n </span>\n )}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Option item (rendered inside Command.Item + virtual list)\n// ---------------------------------------------------------------------------\n\ninterface OptionRowProps {\n option: IOption\n selected: boolean\n renderItem?: LayoutSelectProps['renderItem']\n onSelect: (option: IOption) => void\n highlighted?: boolean\n}\n\nfunction OptionRow({\n option,\n selected,\n renderItem,\n onSelect,\n highlighted = false,\n}: OptionRowProps) {\n const content = renderItem ? (\n renderItem(option, {\n selected,\n highlighted,\n disabled: !!option.disabled,\n })\n ) : (\n <div className=\"flex w-full items-center gap-2\">\n {option.icon && (\n <span className=\"flex shrink-0 items-center [&_svg]:size-4\">\n {resolveIcon(option.icon)}\n </span>\n )}\n <span className=\"flex-1 truncate\">{option.label}</span>\n {selected && (\n <span className=\"ml-auto flex shrink-0 items-center text-primary\">\n <Check className=\"size-4\" />\n </span>\n )}\n </div>\n )\n\n const row = (\n <Command.Item\n value={`${option.value}`}\n disabled={option.disabled}\n onSelect={() => {\n if (!option.disabled) onSelect(option)\n }}\n className={cn(\n 'relative flex w-full cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none',\n 'data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground',\n option.disabled && 'pointer-events-none opacity-50',\n )}\n data-highlighted={highlighted || undefined}\n >\n {content}\n </Command.Item>\n )\n\n if (option.disabled && option.disabledTooltip) {\n return (\n <MaybeTooltip tooltip={option.disabledTooltip}>\n <div>{row}</div>\n </MaybeTooltip>\n )\n }\n\n return row\n}\n\n// ---------------------------------------------------------------------------\n// Virtual + Sortable list\n// ---------------------------------------------------------------------------\n\ninterface VirtualListProps {\n /** Raw (potentially grouped) options – used to build display rows. */\n options: Array<IOption>\n /** Flat leaf items for backward-compat (used when there are no groups). */\n items: Array<IOption>\n selectedValue: IOption | Array<IOption> | null\n renderItem?: LayoutSelectProps['renderItem']\n onSelect: (option: IOption) => void\n sortable?: boolean\n sortableAcrossGroups?: boolean\n onSortEnd?: (items: Array<IOption>) => void\n /** Called when items within a group are reordered (grouped mode). Receives\n * the group parent value and the new ordered children. */\n onGroupSortEnd?: (\n groupValue: string | number,\n children: Array<IOption>,\n ) => void\n /** Called when a cross-group drag produces a new grouped tree. */\n onTreeSort?: (tree: Array<IOption>) => void\n}\n\nfunction VirtualList({\n options,\n items,\n selectedValue,\n renderItem,\n onSelect,\n sortable,\n sortableAcrossGroups,\n onSortEnd,\n onGroupSortEnd,\n onTreeSort,\n}: VirtualListProps) {\n const parentRef = useRef<HTMLDivElement>(null)\n const [activeId, setActiveId] = useState<string | null>(null)\n\n // During a cross-group drag, holds the intermediate tree with the dragged\n // item moved to the destination group. When null, `options` prop is used.\n const [dragTree, setDragTree] = useState<Array<IOption> | null>(null)\n\n const effectiveOptions = dragTree ?? options\n\n const grouped = useMemo(() => hasGroups(effectiveOptions), [effectiveOptions])\n const displayRows = useMemo(\n () => (grouped ? buildDisplayRows(effectiveOptions) : undefined),\n [grouped, effectiveOptions],\n )\n\n // The flat list used by the virtualizer – either from display rows or the\n // legacy flat items.\n const flatDisplayRows = useMemo(\n () => items.map<DisplayRow>((o) => ({ kind: 'option', option: o })),\n [items],\n )\n const virtualItems = displayRows ?? flatDisplayRows\n\n // Derive activeIndex from activeId so it stays correct after cross-group\n // moves update the tree mid-drag.\n const activeIndex = useMemo(() => {\n if (!activeId) return null\n const idx = virtualItems.findIndex(\n (r) => r.kind === 'option' && `${r.option.value}` === activeId,\n )\n return idx !== -1 ? idx : null\n }, [activeId, virtualItems])\n\n // Custom range extractor: always include the actively-dragged item so the\n // virtualizer never unmounts it (dnd-kit needs the DOM node to stay alive).\n const rangeExtractor = useCallback(\n (range: Range) => {\n const result = defaultRangeExtractor(range)\n if (activeIndex !== null && !result.includes(activeIndex)) {\n result.push(activeIndex)\n result.sort((a, b) => a - b)\n }\n return result\n },\n [activeIndex],\n )\n\n const virtualizer = useVirtualizer({\n count: virtualItems.length,\n getScrollElement: () => parentRef.current,\n estimateSize: (index) =>\n virtualItems[index].kind === 'group-header' ? 28 : 36,\n overscan: 8,\n rangeExtractor,\n })\n\n // After a cross-group drop the tree rebuilds and displayRows changes.\n // Force the virtualizer to discard stale position caches BEFORE paint\n // so every row gets the correct translateY immediately.\n useLayoutEffect(() => {\n virtualizer.measure()\n }, [virtualizer, displayRows])\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),\n useSensor(KeyboardSensor),\n )\n\n // Flat sortable IDs for the single SortableContext wrapping all items.\n const flatSortableIds = useMemo(\n () =>\n virtualItems\n .filter(\n (r): r is DisplayRow & { kind: 'option' } => r.kind === 'option',\n )\n .map((r) => `${r.option.value}`),\n [virtualItems],\n )\n\n // Custom collision detection: restrict collisions to same-group items\n // when sortableAcrossGroups is disabled.\n const sameGroupCollision: CollisionDetection = useCallback(\n (args) => {\n if (!displayRows) return closestCenter(args)\n const draggedId = args.active.id\n const activeRow = displayRows.find(\n (r) => r.kind === 'option' && `${r.option.value}` === `${draggedId}`,\n )\n if (!activeRow || activeRow.kind !== 'option') return closestCenter(args)\n const activeGroup = activeRow.groupValue\n const filtered = args.droppableContainers.filter((container) => {\n const row = displayRows.find(\n (r) =>\n r.kind === 'option' && `${r.option.value}` === `${container.id}`,\n )\n return row && row.kind === 'option' && row.groupValue === activeGroup\n })\n return closestCenter({ ...args, droppableContainers: filtered })\n },\n [displayRows],\n )\n\n // Custom sorting strategy for grouped options.\n // Only displace items that are in the same group as the active (dragged)\n // item. Cross-group items are never displaced — group headers are at\n // fixed virtualizer positions and can't participate in dnd-kit transforms,\n // so shifting items across groups would cause overlaps.\n const sortingStrategy = useMemo(() => {\n if (!grouped || !displayRows) return verticalListSortingStrategy\n const idToGroup = new Map<string, string | number | undefined>()\n for (const row of displayRows) {\n if (row.kind === 'option') {\n idToGroup.set(`${row.option.value}`, row.groupValue)\n }\n }\n const noMove = { x: 0, y: 0, scaleX: 1, scaleY: 1 }\n return (\n args: Parameters<typeof verticalListSortingStrategy>[0],\n ): ReturnType<typeof verticalListSortingStrategy> => {\n const draggedId = flatSortableIds[args.activeIndex]\n const currentId = flatSortableIds[args.index]\n if (\n draggedId &&\n currentId &&\n idToGroup.get(draggedId) !== idToGroup.get(currentId)\n ) {\n return noMove\n }\n return verticalListSortingStrategy(args)\n }\n }, [grouped, displayRows, flatSortableIds])\n\n // ---- onDragOver: move item between groups during drag ----\n const handleDragOver = useCallback(\n (event: DragOverEvent) => {\n if (!sortableAcrossGroups || !grouped) return\n const { active, over } = event\n if (!over || active.id === over.id) return\n\n const currentTree = dragTree ?? options\n const currentRows = buildDisplayRows(currentTree)\n\n const activeRow = currentRows.find(\n (r) => r.kind === 'option' && `${r.option.value}` === `${active.id}`,\n )\n const overRow = currentRows.find(\n (r) => r.kind === 'option' && `${r.option.value}` === `${over.id}`,\n )\n\n if (\n !activeRow ||\n activeRow.kind !== 'option' ||\n !overRow ||\n overRow.kind !== 'option'\n )\n return\n\n // Same group — let dnd-kit's sorting strategy handle displacement\n if (activeRow.groupValue === overRow.groupValue) return\n\n // Cross-group: move item from source group to destination group\n const newTree = currentTree.map((opt) => {\n if (!opt.children) return opt\n if (opt.value === activeRow.groupValue) {\n return {\n ...opt,\n children: opt.children.filter(\n (c) => `${c.value}` !== `${active.id}`,\n ),\n }\n }\n if (opt.value === overRow.groupValue) {\n // Remove first in case of duplicate, then insert at over position\n const destChildren = opt.children.filter(\n (c) => `${c.value}` !== `${active.id}`,\n )\n const overIdx = destChildren.findIndex(\n (c) => `${c.value}` === `${over.id}`,\n )\n destChildren.splice(\n overIdx !== -1 ? overIdx : destChildren.length,\n 0,\n activeRow.option,\n )\n return { ...opt, children: destChildren }\n }\n return opt\n })\n\n setDragTree(newTree)\n },\n [sortableAcrossGroups, grouped, dragTree, options],\n )\n\n // ---- Drag end handlers ----\n const handleDragEndFlat = useCallback(\n (event: DragEndEvent) => {\n setActiveId(null)\n setDragTree(null)\n const { active, over } = event\n if (!over || active.id === over.id || !onSortEnd) return\n const oldIndex = items.findIndex((i) => `${i.value}` === `${active.id}`)\n const newIndex = items.findIndex((i) => `${i.value}` === `${over.id}`)\n if (oldIndex !== -1 && newIndex !== -1) {\n onSortEnd(arrayMove(items, oldIndex, newIndex))\n }\n },\n [items, onSortEnd],\n )\n\n const handleDragEndGrouped = useCallback(\n (event: DragEndEvent) => {\n setActiveId(null)\n const { active, over } = event\n\n if (!over || active.id === over.id) {\n // No move — revert intermediate drag tree\n if (dragTree) onTreeSort?.(dragTree)\n setDragTree(null)\n return\n }\n\n if (!displayRows) {\n setDragTree(null)\n return\n }\n\n const activeRow = displayRows.find(\n (r) => r.kind === 'option' && `${r.option.value}` === `${active.id}`,\n )\n const overRow = displayRows.find(\n (r) => r.kind === 'option' && `${r.option.value}` === `${over.id}`,\n )\n\n if (\n !activeRow ||\n activeRow.kind !== 'option' ||\n !overRow ||\n overRow.kind !== 'option'\n ) {\n setDragTree(null)\n return\n }\n\n const activeGroup = activeRow.groupValue\n const overGroup = overRow.groupValue\n const baseTree = dragTree ?? options\n\n if (activeGroup === overGroup) {\n // Same-group reorder (applies on top of any earlier cross-group move)\n const groupChildren = displayRows\n .filter(\n (r): r is DisplayRow & { kind: 'option' } =>\n r.kind === 'option' && r.groupValue === activeGroup,\n )\n .map((r) => r.option)\n\n const oldIdx = groupChildren.findIndex(\n (i) => `${i.value}` === `${active.id}`,\n )\n const newIdx = groupChildren.findIndex(\n (i) => `${i.value}` === `${over.id}`,\n )\n\n if (oldIdx !== -1 && newIdx !== -1 && oldIdx !== newIdx) {\n const reordered = arrayMove(groupChildren, oldIdx, newIdx)\n if (dragTree) {\n // Cross-group move happened earlier — commit full tree\n const finalTree = baseTree.map((opt) => {\n if (opt.value === activeGroup && opt.children) {\n return { ...opt, children: reordered }\n }\n return opt\n })\n onTreeSort?.(finalTree)\n } else {\n // Pure within-group reorder\n onGroupSortEnd?.(activeGroup!, reordered)\n }\n } else if (dragTree) {\n // Cross-group happened but no final reorder within group\n onTreeSort?.(baseTree)\n }\n } else {\n // Fallback: active and over still in different groups at drop time\n const finalTree = baseTree.map((opt) => {\n if (!opt.children) return opt\n if (opt.value === activeGroup) {\n return {\n ...opt,\n children: opt.children.filter(\n (c) => `${c.value}` !== `${active.id}`,\n ),\n }\n }\n if (opt.value === overGroup) {\n const destChildren = [...opt.children]\n const overIdx = destChildren.findIndex(\n (c) => `${c.value}` === `${over.id}`,\n )\n destChildren.splice(\n overIdx !== -1 ? overIdx + 1 : destChildren.length,\n 0,\n activeRow.option,\n )\n return { ...opt, children: destChildren }\n }\n return opt\n })\n onTreeSort?.(finalTree)\n }\n\n setDragTree(null)\n },\n [dragTree, options, displayRows, onTreeSort, onGroupSortEnd],\n )\n\n // ---- Render the scrollable virtualised content ----\n const listContent = (\n <div\n ref={parentRef}\n className={cn(\n 'max-h-75 overflow-x-hidden',\n activeIndex !== null ? 'overflow-y-visible' : 'overflow-y-auto',\n )}\n >\n <div\n style={{\n height: `${virtualizer.getTotalSize()}px`,\n position: 'relative',\n width: '100%',\n }}\n >\n {virtualizer.getVirtualItems().map((vItem) => {\n const displayRow = virtualItems[vItem.index]\n\n // ----- Group header row -----\n if (displayRow.kind === 'group-header') {\n return (\n <div\n key={`gh-${displayRow.groupValue}`}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n transform: `translateY(${vItem.start}px)`,\n }}\n data-index={vItem.index}\n ref={virtualizer.measureElement}\n >\n <div className=\"px-2 py-1 text-xs font-semibold text-muted-foreground\">\n {displayRow.label}\n </div>\n </div>\n )\n }\n\n // ----- Leaf option row -----\n const option = displayRow.option\n\n const row = (\n <OptionRow\n key={option.value}\n option={option}\n selected={isSelected(option, selectedValue)}\n renderItem={renderItem}\n onSelect={onSelect}\n />\n )\n\n const wrappedRow = sortable ? (\n <SortableItem\n key={option.value}\n id={`${option.value}`}\n disabled={option.disabled}\n >\n {row}\n </SortableItem>\n ) : (\n row\n )\n\n return (\n <div\n key={option.value}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n transform: `translateY(${vItem.start}px)`,\n }}\n data-index={vItem.index}\n ref={virtualizer.measureElement}\n >\n {wrappedRow}\n </div>\n )\n })}\n </div>\n </div>\n )\n\n if (sortable) {\n const handleDragStart = (event: { active: { id: string | number } }) => {\n setActiveId(`${event.active.id}`)\n }\n const handleCancel = () => {\n setActiveId(null)\n setDragTree(null)\n }\n\n // Single SortableContext wrapping everything.\n // Custom sortingStrategy handles per-group displacement.\n return (\n <DndContext\n modifiers={[restrictToVerticalAxis, restrictToFirstScrollableAncestor]}\n sensors={sensors}\n collisionDetection={\n grouped && !sortableAcrossGroups ? sameGroupCollision : closestCenter\n }\n onDragStart={handleDragStart}\n onDragOver={handleDragOver}\n onDragEnd={grouped ? handleDragEndGrouped : handleDragEndFlat}\n onDragCancel={handleCancel}\n >\n <SortableContext items={flatSortableIds} strategy={sortingStrategy}>\n {listContent}\n </SortableContext>\n </DndContext>\n )\n }\n\n return listContent\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\nexport function LayoutSelect(props: LayoutSelectProps) {\n const {\n type,\n options,\n placeholder = 'Select item',\n disabled = false,\n readOnly = false,\n error = false,\n clearable = false,\n className,\n triggerClassName,\n popupClassName,\n renderTrigger,\n renderItem,\n listPrefix,\n listSuffix,\n queryFn,\n label,\n } = props\n\n const [open, setOpen] = useState(false)\n const [search, setSearch] = useState('')\n const [asyncOptions, setAsyncOptions] = useState<Array<IOption> | null>(null)\n const [loading, setLoading] = useState(false)\n const [internalSortedOptions, setInternalSortedOptions] =\n useState<Array<IOption> | null>(null)\n\n // ---- Resolve current value ----\n const currentValue = useMemo(() => {\n if (type === 'single') {\n return (props as SingleSelectProps).selectValue ?? null\n }\n return (props as MultipleSelectProps).selectValue ?? []\n }, [type, props])\n\n // ---- Resolve display options ----\n const resolvedOptions = useMemo(() => {\n const base = asyncOptions ?? options\n return internalSortedOptions ?? base\n }, [asyncOptions, options, internalSortedOptions])\n\n const flatOptions = useMemo(\n () => flattenOptions(resolvedOptions),\n [resolvedOptions],\n )\n\n // ---- Filtered options (search) ----\n // For virtualisation we need a flat list of leaf options, and when options\n // are grouped we also keep a filtered version of the grouped tree so that\n // VirtualList can render group headers correctly.\n const filteredOptions = useMemo(() => {\n if (!search) return flatOptions\n const q = search.toLowerCase()\n return flatOptions.filter((o) => o.label.toLowerCase().includes(q))\n }, [flatOptions, search])\n\n /** Resolved options filtered by search, preserving group structure. */\n const filteredGroupedOptions = useMemo(() => {\n if (!search) return resolvedOptions\n const q = search.toLowerCase()\n return resolvedOptions\n .map((opt) => {\n if (opt.children && opt.children.length > 0) {\n const matched = opt.children.filter((c) =>\n c.label.toLowerCase().includes(q),\n )\n if (matched.length === 0) return null\n return { ...opt, children: matched }\n }\n return opt.label.toLowerCase().includes(q) ? opt : null\n })\n .filter(Boolean) as Array<IOption>\n }, [resolvedOptions, search])\n\n // ---- Async loading ----\n useEffect(() => {\n if (open && queryFn) {\n let cancelled = false\n setLoading(true)\n queryFn()\n .then((data) => {\n if (!cancelled) {\n setAsyncOptions(data)\n }\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }\n }, [open, queryFn])\n\n // Reset search when closed\n useEffect(() => {\n if (!open) {\n setSearch('')\n }\n }, [open])\n\n // ---- Selection handler ----\n const handleSelect = useCallback(\n (option: IOption) => {\n if (readOnly) return\n\n if (type === 'single') {\n const onChange = (props as SingleSelectProps).onChange\n const current = currentValue as IOption | null\n if (clearable && current && optionEq(current, option)) {\n onChange?.(null, option)\n } else {\n onChange?.(option, option)\n }\n setOpen(false)\n } else {\n const onChange = (props as MultipleSelectProps).onChange\n const current = currentValue as Array<IOption>\n const exists = current.some((v) => optionEq(v, option))\n if (exists) {\n onChange?.(\n current.filter((v) => !optionEq(v, option)),\n option,\n )\n } else {\n onChange?.([...current, option], option)\n }\n }\n },\n [type, currentValue, clearable, readOnly, props],\n )\n\n // ---- Remove chip (multiple) ----\n const handleRemoveChip = useCallback(\n (option: IOption) => {\n if (type !== 'multiple' || readOnly || disabled) return\n const onChange = (props as MultipleSelectProps).onChange\n const current = currentValue as Array<IOption>\n onChange?.(\n current.filter((v) => !optionEq(v, option)),\n option,\n )\n },\n [type, currentValue, readOnly, disabled, props],\n )\n\n // ---- Select all / unselect all (multiple only) ----\n const handleToggleAll = useCallback(() => {\n if (type !== 'multiple' || readOnly || disabled) return\n const onChange = (props as MultipleSelectProps).onChange\n const current = currentValue as Array<IOption>\n const selectableOptions = flatOptions.filter((o) => !o.disabled)\n const allSelected =\n selectableOptions.length > 0 &&\n selectableOptions.every((o) => current.some((v) => optionEq(v, o)))\n\n if (allSelected) {\n // Keep only disabled options that were somehow selected\n const kept = current.filter((v) =>\n selectableOptions.every((o) => !optionEq(o, v)),\n )\n onChange?.(kept, selectableOptions[0])\n } else {\n // Merge: keep existing + add missing selectable options\n const missing = selectableOptions.filter(\n (o) => !current.some((v) => optionEq(v, o)),\n )\n onChange?.([...current, ...missing], selectableOptions[0])\n }\n }, [type, currentValue, flatOptions, readOnly, disabled, props])\n\n const allSelected = useMemo(() => {\n if (type !== 'multiple') return false\n const current = currentValue as Array<IOption>\n const selectableOptions = flatOptions.filter((o) => !o.disabled)\n return (\n selectableOptions.length > 0 &&\n selectableOptions.every((o) => current.some((v) => optionEq(v, o)))\n )\n }, [type, currentValue, flatOptions])\n\n const sortable = props.sortable ?? false\n const sortableAcrossGroups = props.sortable\n ? ((props as SortableEnabledProps).sortableAcrossGroups ?? false)\n : false\n const consumerOnSortEnd = props.sortable\n ? (props as SortableEnabledProps).onSortEnd\n : undefined\n\n // ---- Sort handler (flat) ----\n const handleSortEnd = useCallback(\n (sorted: Array<IOption>) => {\n setInternalSortedOptions(sorted)\n consumerOnSortEnd?.(sorted)\n },\n [consumerOnSortEnd],\n )\n\n // ---- Sort handler (within a group) ----\n const handleGroupSortEnd = useCallback(\n (groupValue: string | number, reorderedChildren: Array<IOption>) => {\n // Rebuild the full options tree with the updated group\n const updated = resolvedOptions.map((opt) => {\n if (opt.value === groupValue && opt.children) {\n return { ...opt, children: reorderedChildren }\n }\n return opt\n })\n setInternalSortedOptions(updated)\n consumerOnSortEnd?.(flattenOptions(updated))\n },\n [resolvedOptions, consumerOnSortEnd],\n )\n\n // ---- Sort handler (cross-group tree rebuild) ----\n const handleTreeSort = useCallback(\n (newTree: Array<IOption>) => {\n setInternalSortedOptions(newTree)\n consumerOnSortEnd?.(flattenOptions(newTree))\n },\n [consumerOnSortEnd],\n )\n\n // ---- Open handler ----\n const handleOpenChange = useCallback(\n (nextOpen: boolean) => {\n if (disabled || readOnly) return\n setOpen(nextOpen)\n },\n [disabled, readOnly],\n )\n\n // ---- Trigger content ----\n const triggerContent = useMemo(() => {\n if (renderTrigger) {\n return renderTrigger({\n value: currentValue,\n open,\n disabled,\n readOnly,\n error,\n placeholder,\n })\n }\n\n if (type === 'single') {\n return (\n <SingleTriggerContent\n value={currentValue as IOption | null}\n placeholder={placeholder}\n />\n )\n }\n\n return (\n <MultipleTriggerContent\n value={currentValue as Array<IOption>}\n placeholder={placeholder}\n collapsed={(props as MultipleSelectProps).collapsed}\n showItemsLength={(props as MultipleSelectProps).showItemsLength}\n onRemove={handleRemoveChip}\n readOnly={readOnly}\n disabled={disabled}\n />\n )\n }, [\n renderTrigger,\n type,\n currentValue,\n open,\n disabled,\n readOnly,\n error,\n placeholder,\n props,\n handleRemoveChip,\n ])\n\n return (\n <Tooltip.Provider>\n <div className={cn('relative inline-flex flex-col', className)}>\n {label && (\n <label className=\"mb-1 text-sm font-medium text-foreground\">\n {label}\n </label>\n )}\n <Popover.Root open={open} onOpenChange={handleOpenChange}>\n <Popover.Trigger\n disabled={disabled}\n render={\n <button\n type=\"button\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-invalid={error || undefined}\n data-readonly={readOnly || undefined}\n className={cn(\n 'border-input flex min-h-9 w-full min-w-45 items-center gap-2 rounded-md border bg-transparent px-3 py-1.5 text-sm shadow-xs transition-[color,box-shadow,border-color] outline-none',\n 'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',\n 'aria-invalid:border-destructive aria-invalid:ring-destructive/20',\n 'data-readonly:pointer-events-none data-readonly:opacity-70',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n \"[&_svg:not([class*='text-'])]:text-muted-foreground\",\n triggerClassName,\n )}\n />\n }\n >\n <div className=\"flex min-w-0 flex-1 items-center\">\n {triggerContent}\n </div>\n <ChevronDown className=\"size-4 shrink-0 opacity-50\" />\n </Popover.Trigger>\n\n <Popover.Portal>\n <Popover.Positioner sideOffset={4}>\n <Popover.Popup\n className={cn(\n 'z-50 min-w-(--anchor-width) rounded-md border bg-popover text-popover-foreground shadow-md outline-none',\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-ending-style:scale-95 data-ending-style:opacity-0',\n 'origin-(--transform-origin) transition-[transform,scale,opacity] duration-150',\n popupClassName,\n )}\n >\n <Command shouldFilter={false} loop>\n {/* Search input */}\n <div className=\"border-b p-1\">\n <Command.Input\n value={search}\n onValueChange={setSearch}\n placeholder=\"Search...\"\n className=\"h-8 w-full rounded-sm bg-transparent px-2 text-sm outline-none placeholder:text-muted-foreground\"\n />\n </div>\n\n {/* List prefix */}\n {listPrefix && (\n <div className=\"border-b px-2 py-1.5\">{listPrefix}</div>\n )}\n\n {/* Select all / Unselect all */}\n {type === 'multiple' && !readOnly && (\n <div className=\"border-b px-1 py-1\">\n <button\n type=\"button\"\n onClick={handleToggleAll}\n className=\"w-full rounded-sm px-2 py-1 text-left text-sm text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n >\n {allSelected ? 'Unselect all' : 'Select all'}\n </button>\n </div>\n )}\n\n <Command.List className=\"p-1\">\n {loading && (\n <Command.Loading>\n <div className=\"flex items-center justify-center py-4 text-sm text-muted-foreground\">\n Loading…\n </div>\n </Command.Loading>\n )}\n\n {!loading && filteredOptions.length === 0 && (\n <Command.Empty className=\"py-4 text-center text-sm text-muted-foreground\">\n No results found.\n </Command.Empty>\n )}\n\n {!loading && filteredOptions.length > 0 && (\n <VirtualList\n options={filteredGroupedOptions}\n items={filteredOptions}\n selectedValue={currentValue}\n renderItem={renderItem}\n onSelect={handleSelect}\n sortable={sortable}\n sortableAcrossGroups={sortableAcrossGroups}\n onSortEnd={handleSortEnd}\n onGroupSortEnd={handleGroupSortEnd}\n onTreeSort={handleTreeSort}\n />\n )}\n </Command.List>\n\n {/* List suffix */}\n {listSuffix && (\n <div className=\"border-t px-2 py-1.5\">{listSuffix}</div>\n )}\n </Command>\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n </div>\n </Tooltip.Provider>\n )\n}\n\nexport default LayoutSelect\n"],"mappings":"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","names":["allSelected"]}