@particle-academy/react-fancy 4.12.1 → 4.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { clsx } from 'clsx';
3
3
  import { twMerge } from 'tailwind-merge';
4
4
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
5
5
  import { createPortal } from 'react-dom';
6
- import { X, ChevronUp, ChevronDown, ChevronLeft, ChevronRight, Search, Menu, File, Upload, PanelLeftOpen, PanelLeftClose, Check, XCircle, AlertTriangle, Info } from 'lucide-react';
6
+ import { X, ChevronUp, ChevronDown, ChevronLeft, ChevronRight, Search, Menu, File, Upload, PanelLeftOpen, PanelLeftClose, Loader2, ArrowUp, ArrowDown, Pencil, CircleAlert, RotateCw, Check, XCircle, AlertTriangle, Info } from 'lucide-react';
7
7
  import { marked } from 'marked';
8
8
 
9
9
  // src/components/Button/Button.tsx
@@ -7882,11 +7882,12 @@ function usePopover() {
7882
7882
  }
7883
7883
  return ctx;
7884
7884
  }
7885
- function PopoverTrigger({ children, className }) {
7885
+ function PopoverTrigger({ children, className, ...rest }) {
7886
7886
  const { setOpen, open, anchorRef, hover, onHoverEnter, onHoverLeave } = usePopover();
7887
7887
  return /* @__PURE__ */ jsx(
7888
7888
  "span",
7889
7889
  {
7890
+ ...rest,
7890
7891
  ref: anchorRef,
7891
7892
  "data-react-fancy-popover-trigger": "",
7892
7893
  className: cn("inline-flex", className),
@@ -7900,7 +7901,7 @@ function PopoverTrigger({ children, className }) {
7900
7901
  );
7901
7902
  }
7902
7903
  PopoverTrigger.displayName = "PopoverTrigger";
7903
- function PopoverContent({ children, className }) {
7904
+ function PopoverContent({ children, className, style, ...rest }) {
7904
7905
  const { open, setOpen, anchorRef, floatingRef, placement, offset, hover, onHoverEnter, onHoverLeave } = usePopover();
7905
7906
  const outsideRef = useRef(null);
7906
7907
  const position = useFloatingPosition(anchorRef, floatingRef, {
@@ -7916,6 +7917,7 @@ function PopoverContent({ children, className }) {
7916
7917
  return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(
7917
7918
  "div",
7918
7919
  {
7920
+ ...rest,
7919
7921
  ref: (node) => {
7920
7922
  outsideRef.current = node;
7921
7923
  floatingRef.current = node;
@@ -7926,7 +7928,7 @@ function PopoverContent({ children, className }) {
7926
7928
  positioned ? "fancy-scale-in" : "invisible",
7927
7929
  className
7928
7930
  ),
7929
- style: { left: position.x, top: position.y },
7931
+ style: { ...style, left: position.x, top: position.y },
7930
7932
  onMouseEnter: hover ? onHoverEnter : void 0,
7931
7933
  onMouseLeave: hover ? onHoverLeave : void 0,
7932
7934
  children
@@ -13140,6 +13142,923 @@ TreeNavRoot.displayName = "TreeNav";
13140
13142
  var TreeNav = Object.assign(TreeNavRoot, {
13141
13143
  Node: TreeNode
13142
13144
  });
13145
+ var FileBrowserContext = createContext(null);
13146
+ function useFileBrowser() {
13147
+ const ctx = useContext(FileBrowserContext);
13148
+ if (!ctx) {
13149
+ throw new Error("useFileBrowser must be used within a <FileBrowser> component");
13150
+ }
13151
+ return ctx;
13152
+ }
13153
+
13154
+ // src/components/FileBrowser/FileBrowser.utils.ts
13155
+ function normalizePath(input) {
13156
+ const raw = input.trim().replace(/\\/g, "/");
13157
+ if (raw === "") return "/";
13158
+ const absolute = raw.startsWith("/");
13159
+ const out = [];
13160
+ for (const segment of raw.split("/")) {
13161
+ if (segment === "" || segment === ".") continue;
13162
+ if (segment === "..") {
13163
+ out.pop();
13164
+ continue;
13165
+ }
13166
+ out.push(segment);
13167
+ }
13168
+ if (out.length === 0) return "/";
13169
+ return (absolute ? "/" : "") + out.join("/");
13170
+ }
13171
+ function parentPath(path) {
13172
+ const i = path.lastIndexOf("/");
13173
+ if (i === -1) return "/";
13174
+ if (i === 0) return "/";
13175
+ return path.slice(0, i);
13176
+ }
13177
+ function pathSegments(path) {
13178
+ const absolute = path.startsWith("/");
13179
+ const parts = path.split("/").filter(Boolean);
13180
+ const segments = [];
13181
+ let acc = "";
13182
+ parts.forEach((part, i) => {
13183
+ acc = i === 0 && !absolute ? part : `${acc}/${part}`;
13184
+ segments.push({ label: part, path: acc });
13185
+ });
13186
+ return segments;
13187
+ }
13188
+ function compareNames(a, b) {
13189
+ const cmp = a.localeCompare(b, "en", { numeric: true, sensitivity: "base" });
13190
+ if (cmp !== 0) return cmp;
13191
+ return a < b ? -1 : a > b ? 1 : 0;
13192
+ }
13193
+ function compareFileEntries(a, b, sort) {
13194
+ if (a.kind !== b.kind) return a.kind === "dir" ? -1 : 1;
13195
+ const direction = sort.direction === "desc" ? -1 : 1;
13196
+ let cmp;
13197
+ switch (sort.by) {
13198
+ case "size":
13199
+ cmp = (a.size ?? -1) - (b.size ?? -1);
13200
+ break;
13201
+ case "mtime": {
13202
+ const am = a.mtime ?? "";
13203
+ const bm = b.mtime ?? "";
13204
+ cmp = am < bm ? -1 : am > bm ? 1 : 0;
13205
+ break;
13206
+ }
13207
+ default:
13208
+ cmp = compareNames(a.name, b.name);
13209
+ }
13210
+ if (cmp !== 0) return direction * cmp;
13211
+ return compareNames(a.name, b.name);
13212
+ }
13213
+ function isEntryExpandable(entry, children, hasProvider) {
13214
+ if (entry.kind !== "dir" || entry.hasChildren === false) return false;
13215
+ if (children !== void 0) return children.length > 0;
13216
+ return hasProvider;
13217
+ }
13218
+ function entryMatchesFilter(entry, query, entriesFor, visited = /* @__PURE__ */ new Set()) {
13219
+ if (entry.name.toLowerCase().includes(query)) return true;
13220
+ if (entry.kind !== "dir" || visited.has(entry.path)) return false;
13221
+ visited.add(entry.path);
13222
+ const children = entriesFor(entry.path);
13223
+ return children?.some((child) => entryMatchesFilter(child, query, entriesFor, visited)) ?? false;
13224
+ }
13225
+ function formatFileSize(bytes) {
13226
+ if (!Number.isFinite(bytes) || bytes < 0) return "";
13227
+ if (bytes < 1024) return `${bytes} B`;
13228
+ const units = ["KB", "MB", "GB", "TB"];
13229
+ let value = bytes;
13230
+ let unit = -1;
13231
+ do {
13232
+ value /= 1024;
13233
+ unit++;
13234
+ } while (value >= 1024 && unit < units.length - 1);
13235
+ const rounded = value >= 100 ? Math.round(value) : Math.round(value * 10) / 10;
13236
+ return `${rounded} ${units[unit]}`;
13237
+ }
13238
+ var SEGMENT_CLASS = "shrink-0 rounded text-[13px] text-zinc-500 transition-colors hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-300";
13239
+ var ACTIVE_SEGMENT_CLASS = "shrink-0 truncate text-[13px] font-medium text-zinc-900 dark:text-white";
13240
+ function FileBrowserPathBar({
13241
+ editable = true,
13242
+ placeholder = "/path/to/folder",
13243
+ className
13244
+ }) {
13245
+ const { path, navigate } = useFileBrowser();
13246
+ const [editing, setEditing] = useState(false);
13247
+ const [draft, setDraft] = useState("");
13248
+ const startEdit = () => {
13249
+ setDraft(path);
13250
+ setEditing(true);
13251
+ };
13252
+ const commit = () => {
13253
+ navigate(normalizePath(draft));
13254
+ setEditing(false);
13255
+ };
13256
+ const segments = pathSegments(path);
13257
+ const atRoot = segments.length === 0;
13258
+ return /* @__PURE__ */ jsxs(
13259
+ "div",
13260
+ {
13261
+ "data-react-fancy-file-browser-path": "",
13262
+ className: cn(
13263
+ "flex items-center gap-1 border-b border-zinc-200 px-2 py-1.5 dark:border-zinc-700",
13264
+ className
13265
+ ),
13266
+ children: [
13267
+ editing ? /* @__PURE__ */ jsx(
13268
+ "input",
13269
+ {
13270
+ "data-react-fancy-file-browser-path-input": "",
13271
+ type: "text",
13272
+ value: draft,
13273
+ onChange: (e) => setDraft(e.target.value),
13274
+ onKeyDown: (e) => {
13275
+ if (e.key === "Enter") {
13276
+ e.preventDefault();
13277
+ commit();
13278
+ } else if (e.key === "Escape") {
13279
+ e.preventDefault();
13280
+ setEditing(false);
13281
+ }
13282
+ },
13283
+ onBlur: () => setEditing(false),
13284
+ autoFocus: true,
13285
+ spellCheck: false,
13286
+ placeholder,
13287
+ "aria-label": "Path",
13288
+ className: "min-w-0 flex-1 rounded-md border border-zinc-300 bg-transparent px-2 py-0.5 font-mono text-xs text-zinc-700 outline-none placeholder:text-zinc-400 focus:border-blue-400 dark:border-zinc-600 dark:text-zinc-300"
13289
+ }
13290
+ ) : /* @__PURE__ */ jsxs(
13291
+ "nav",
13292
+ {
13293
+ "aria-label": "Path",
13294
+ onDoubleClick: editable ? startEdit : void 0,
13295
+ className: "flex min-w-0 flex-1 items-center gap-1 overflow-x-auto",
13296
+ children: [
13297
+ atRoot ? /* @__PURE__ */ jsx("span", { "data-react-fancy-file-browser-path-segment": "", "aria-current": "location", className: ACTIVE_SEGMENT_CLASS, children: "/" }) : /* @__PURE__ */ jsx(
13298
+ "button",
13299
+ {
13300
+ type: "button",
13301
+ "data-react-fancy-file-browser-path-segment": "",
13302
+ onClick: () => navigate("/"),
13303
+ className: SEGMENT_CLASS,
13304
+ children: "/"
13305
+ }
13306
+ ),
13307
+ segments.map((segment, i) => {
13308
+ const last = i === segments.length - 1;
13309
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
13310
+ i > 0 && /* @__PURE__ */ jsx(ChevronRight, { size: 12, "aria-hidden": "true", className: "shrink-0 text-zinc-400" }),
13311
+ last ? /* @__PURE__ */ jsx(
13312
+ "span",
13313
+ {
13314
+ "data-react-fancy-file-browser-path-segment": "",
13315
+ "aria-current": "location",
13316
+ className: ACTIVE_SEGMENT_CLASS,
13317
+ children: segment.label
13318
+ }
13319
+ ) : /* @__PURE__ */ jsx(
13320
+ "button",
13321
+ {
13322
+ type: "button",
13323
+ "data-react-fancy-file-browser-path-segment": "",
13324
+ onClick: () => navigate(segment.path),
13325
+ className: SEGMENT_CLASS,
13326
+ children: segment.label
13327
+ }
13328
+ )
13329
+ ] }, segment.path);
13330
+ })
13331
+ ]
13332
+ }
13333
+ ),
13334
+ editable && !editing && /* @__PURE__ */ jsx(
13335
+ "button",
13336
+ {
13337
+ type: "button",
13338
+ "aria-label": "Edit path",
13339
+ onClick: startEdit,
13340
+ className: "shrink-0 rounded-md p-1 text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300",
13341
+ children: /* @__PURE__ */ jsx(Pencil, { size: 13 })
13342
+ }
13343
+ )
13344
+ ]
13345
+ }
13346
+ );
13347
+ }
13348
+ FileBrowserPathBar.displayName = "FileBrowserPathBar";
13349
+ var SORT_FIELDS = [
13350
+ { field: "name", label: "Name" },
13351
+ { field: "size", label: "Size" },
13352
+ { field: "mtime", label: "Modified" }
13353
+ ];
13354
+ function FileBrowserToolbar({ filterPlaceholder = "Filter", className }) {
13355
+ const { filter, setFilter, sort, setSort } = useFileBrowser();
13356
+ return /* @__PURE__ */ jsxs(
13357
+ "div",
13358
+ {
13359
+ "data-react-fancy-file-browser-toolbar": "",
13360
+ className: cn(
13361
+ "flex items-center gap-2 border-b border-zinc-200 px-2 py-1.5 dark:border-zinc-700",
13362
+ className
13363
+ ),
13364
+ children: [
13365
+ /* @__PURE__ */ jsxs(
13366
+ "div",
13367
+ {
13368
+ "data-react-fancy-file-browser-filter": "",
13369
+ className: "flex min-w-0 flex-1 items-center gap-1.5 rounded-md border border-zinc-200 px-2 dark:border-zinc-700",
13370
+ children: [
13371
+ /* @__PURE__ */ jsx(Search, { size: 13, "aria-hidden": "true", className: "shrink-0 text-zinc-400" }),
13372
+ /* @__PURE__ */ jsx(
13373
+ "input",
13374
+ {
13375
+ type: "text",
13376
+ value: filter,
13377
+ onChange: (e) => setFilter(e.target.value),
13378
+ placeholder: filterPlaceholder,
13379
+ "aria-label": "Filter by name",
13380
+ spellCheck: false,
13381
+ className: "min-w-0 flex-1 bg-transparent py-1 text-xs text-zinc-700 outline-none placeholder:text-zinc-400 dark:text-zinc-300"
13382
+ }
13383
+ ),
13384
+ filter !== "" && /* @__PURE__ */ jsx(
13385
+ "button",
13386
+ {
13387
+ type: "button",
13388
+ "aria-label": "Clear filter",
13389
+ onClick: () => setFilter(""),
13390
+ className: "shrink-0 text-zinc-400 transition-colors hover:text-zinc-600 dark:hover:text-zinc-300",
13391
+ children: /* @__PURE__ */ jsx(X, { size: 12 })
13392
+ }
13393
+ )
13394
+ ]
13395
+ }
13396
+ ),
13397
+ /* @__PURE__ */ jsx(
13398
+ "div",
13399
+ {
13400
+ "data-react-fancy-file-browser-sort": "",
13401
+ role: "group",
13402
+ "aria-label": "Sort",
13403
+ className: "flex shrink-0 items-center gap-0.5",
13404
+ children: SORT_FIELDS.map(({ field, label }) => {
13405
+ const active = sort.by === field;
13406
+ return /* @__PURE__ */ jsxs(
13407
+ "button",
13408
+ {
13409
+ type: "button",
13410
+ "data-sort-field": field,
13411
+ "aria-pressed": active,
13412
+ onClick: () => setSort(
13413
+ active ? { by: field, direction: sort.direction === "asc" ? "desc" : "asc" } : { by: field, direction: "asc" }
13414
+ ),
13415
+ className: cn(
13416
+ "flex items-center gap-0.5 rounded-md px-1.5 py-0.5 text-xs transition-colors",
13417
+ active ? "bg-zinc-100 font-medium text-zinc-900 dark:bg-zinc-800 dark:text-white" : "text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-300"
13418
+ ),
13419
+ children: [
13420
+ label,
13421
+ active && (sort.direction === "asc" ? /* @__PURE__ */ jsx(ArrowUp, { size: 11, "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ArrowDown, { size: 11, "aria-hidden": "true" }))
13422
+ ]
13423
+ },
13424
+ field
13425
+ );
13426
+ })
13427
+ }
13428
+ )
13429
+ ]
13430
+ }
13431
+ );
13432
+ }
13433
+ FileBrowserToolbar.displayName = "FileBrowserToolbar";
13434
+ var EXT_COLORS2 = {
13435
+ ts: "#3178c6",
13436
+ tsx: "#3178c6",
13437
+ js: "#f7df1e",
13438
+ jsx: "#f7df1e",
13439
+ php: "#777bb4",
13440
+ html: "#e34c26",
13441
+ htm: "#e34c26",
13442
+ css: "#264de4",
13443
+ json: "#a1a1aa",
13444
+ md: "#71717a",
13445
+ yaml: "#cb171e",
13446
+ yml: "#cb171e"
13447
+ };
13448
+ function FileIcon2({ ext }) {
13449
+ const color = ext && EXT_COLORS2[ext.toLowerCase()] || "#71717a";
13450
+ return /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "shrink-0", children: [
13451
+ /* @__PURE__ */ jsx("path", { d: "M4 1h5.5L13 4.5V14a1 1 0 01-1 1H4a1 1 0 01-1-1V2a1 1 0 011-1z", stroke: color, strokeWidth: "1.2" }),
13452
+ /* @__PURE__ */ jsx("path", { d: "M9 1v4h4", stroke: color, strokeWidth: "1.2" })
13453
+ ] });
13454
+ }
13455
+ function FolderIcon2({ open }) {
13456
+ if (open) {
13457
+ return /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "shrink-0", children: [
13458
+ /* @__PURE__ */ jsx("path", { d: "M1.5 3.5a1 1 0 011-1h3l1.5 1.5H13a1 1 0 011 1V5H2.5V3.5z", fill: "#fbbf24" }),
13459
+ /* @__PURE__ */ jsx("path", { d: "M1 6h13l-1.5 7.5H2.5L1 6z", fill: "#fbbf24", opacity: "0.7" })
13460
+ ] });
13461
+ }
13462
+ return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "shrink-0", children: /* @__PURE__ */ jsx("path", { d: "M1.5 3a1 1 0 011-1h3l1.5 1.5H13a1 1 0 011 1v8a1 1 0 01-1 1H2.5a1 1 0 01-1-1V3z", fill: "#fbbf24" }) });
13463
+ }
13464
+ function FileBrowserStatusRow({ depth, kind, message, onRetry }) {
13465
+ const { indentSize } = useFileBrowser();
13466
+ const paddingLeft = depth * indentSize + 4 + 18;
13467
+ if (kind === "error") {
13468
+ return /* @__PURE__ */ jsxs(
13469
+ "div",
13470
+ {
13471
+ role: "none",
13472
+ "data-react-fancy-file-browser-status": "error",
13473
+ className: "flex items-center gap-1.5 py-0.5 pr-2 text-xs text-red-600 dark:text-red-400",
13474
+ style: { paddingLeft },
13475
+ children: [
13476
+ /* @__PURE__ */ jsx(CircleAlert, { size: 12, className: "shrink-0" }),
13477
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: message || "Failed to load" }),
13478
+ onRetry && /* @__PURE__ */ jsxs(
13479
+ "button",
13480
+ {
13481
+ type: "button",
13482
+ onClick: onRetry,
13483
+ className: "flex shrink-0 items-center gap-1 rounded-md px-1.5 py-0.5 text-[11px] text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-200",
13484
+ children: [
13485
+ /* @__PURE__ */ jsx(RotateCw, { size: 11 }),
13486
+ "Retry"
13487
+ ]
13488
+ }
13489
+ )
13490
+ ]
13491
+ }
13492
+ );
13493
+ }
13494
+ return /* @__PURE__ */ jsxs(
13495
+ "div",
13496
+ {
13497
+ role: "none",
13498
+ "data-react-fancy-file-browser-status": kind,
13499
+ className: "flex items-center gap-1.5 py-0.5 text-xs text-zinc-400 italic dark:text-zinc-500",
13500
+ style: { paddingLeft },
13501
+ children: [
13502
+ kind === "loading" && /* @__PURE__ */ jsx(Loader2, { size: 12, className: "shrink-0 animate-spin", "aria-hidden": "true" }),
13503
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: kind === "loading" ? "Loading\u2026" : kind === "empty" ? "Empty" : kind === "no-matches" ? "No matches" : "No entries" })
13504
+ ]
13505
+ }
13506
+ );
13507
+ }
13508
+ FileBrowserStatusRow.displayName = "FileBrowserStatusRow";
13509
+ function FileBrowserNode({ entry, depth }) {
13510
+ const {
13511
+ entriesFor,
13512
+ visibleChildrenFor,
13513
+ statusFor,
13514
+ errorFor,
13515
+ loadPath,
13516
+ hasProvider,
13517
+ expandedPaths,
13518
+ toggleExpanded,
13519
+ navigate,
13520
+ isSelected,
13521
+ isSelectable,
13522
+ selectEntry,
13523
+ tabFocusPath,
13524
+ setFocusedPath,
13525
+ focusRow,
13526
+ registerRow,
13527
+ indentSize,
13528
+ showIcons
13529
+ } = useFileBrowser();
13530
+ const rawChildren = entriesFor(entry.path);
13531
+ const childrenKnown = rawChildren !== void 0;
13532
+ const expandable = isEntryExpandable(entry, rawChildren, hasProvider);
13533
+ const expanded = expandable && expandedPaths.includes(entry.path);
13534
+ const status = statusFor(entry.path);
13535
+ const selectable = isSelectable(entry);
13536
+ const selected = isSelected(entry.path);
13537
+ const loading = expanded && !childrenKnown && status === "loading";
13538
+ const paddingLeft = depth * indentSize + 4;
13539
+ const ext = entry.name.includes(".") ? entry.name.split(".").pop() : void 0;
13540
+ const handleClick = () => {
13541
+ if (entry.disabled) return;
13542
+ setFocusedPath(entry.path);
13543
+ focusRow(entry.path);
13544
+ if (selectable) selectEntry(entry);
13545
+ if (expandable) toggleExpanded(entry.path);
13546
+ };
13547
+ const handleDoubleClick = () => {
13548
+ if (entry.disabled || entry.kind !== "dir") return;
13549
+ navigate(entry.path);
13550
+ };
13551
+ const handleChevronClick = (e) => {
13552
+ e.stopPropagation();
13553
+ if (!entry.disabled && expandable) toggleExpanded(entry.path);
13554
+ };
13555
+ const visibleChildren = expanded && childrenKnown ? visibleChildrenFor(entry.path) : [];
13556
+ return /* @__PURE__ */ jsxs(
13557
+ "div",
13558
+ {
13559
+ role: "treeitem",
13560
+ "data-react-fancy-file-browser-node": "",
13561
+ "data-path": entry.path,
13562
+ "data-kind": entry.kind,
13563
+ "aria-level": depth + 1,
13564
+ "aria-expanded": expandable ? expanded : void 0,
13565
+ "aria-selected": selectable ? selected : void 0,
13566
+ "aria-disabled": entry.disabled || void 0,
13567
+ "aria-busy": loading || void 0,
13568
+ tabIndex: tabFocusPath === entry.path ? 0 : -1,
13569
+ ref: (el) => registerRow(entry.path, el),
13570
+ onFocus: (e) => {
13571
+ if (e.target === e.currentTarget) setFocusedPath(entry.path);
13572
+ },
13573
+ className: "group outline-none",
13574
+ children: [
13575
+ /* @__PURE__ */ jsxs(
13576
+ "div",
13577
+ {
13578
+ "data-react-fancy-file-browser-row": "",
13579
+ onClick: handleClick,
13580
+ onDoubleClick: handleDoubleClick,
13581
+ className: cn(
13582
+ "flex w-full cursor-pointer items-center gap-1 rounded-md py-0.5 pr-2 text-left text-[13px] transition-colors select-none",
13583
+ selected ? "bg-blue-500/15 text-blue-600 dark:text-blue-400" : "text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800",
13584
+ entry.disabled && "pointer-events-none opacity-40",
13585
+ "group-focus-visible:ring-2 group-focus-visible:ring-blue-500/40 group-focus-visible:ring-inset"
13586
+ ),
13587
+ style: { paddingLeft },
13588
+ children: [
13589
+ expandable ? loading ? /* @__PURE__ */ jsx(Loader2, { size: 14, className: "shrink-0 animate-spin text-zinc-400", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(
13590
+ "button",
13591
+ {
13592
+ type: "button",
13593
+ tabIndex: -1,
13594
+ "aria-hidden": "true",
13595
+ onClick: handleChevronClick,
13596
+ className: "flex shrink-0 items-center justify-center text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300",
13597
+ children: /* @__PURE__ */ jsx(
13598
+ ChevronRight,
13599
+ {
13600
+ size: 14,
13601
+ className: cn("transition-transform duration-150", expanded && "rotate-90")
13602
+ }
13603
+ )
13604
+ }
13605
+ ) : /* @__PURE__ */ jsx("span", { className: "w-3.5 shrink-0" }),
13606
+ showIcons && (entry.kind === "dir" ? /* @__PURE__ */ jsx(FolderIcon2, { open: expanded }) : /* @__PURE__ */ jsx(FileIcon2, { ext })),
13607
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: entry.name }),
13608
+ entry.kind === "file" && entry.size !== void 0 && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[11px] text-zinc-400 tabular-nums dark:text-zinc-500", children: formatFileSize(entry.size) })
13609
+ ]
13610
+ }
13611
+ ),
13612
+ expanded && /* @__PURE__ */ jsxs("div", { role: "group", "data-react-fancy-file-browser-node-children": "", children: [
13613
+ !childrenKnown && (status === "loading" || status === "idle") && /* @__PURE__ */ jsx(FileBrowserStatusRow, { depth: depth + 1, kind: "loading" }),
13614
+ !childrenKnown && status === "error" && /* @__PURE__ */ jsx(
13615
+ FileBrowserStatusRow,
13616
+ {
13617
+ depth: depth + 1,
13618
+ kind: "error",
13619
+ message: errorFor(entry.path),
13620
+ onRetry: () => loadPath(entry.path, { reload: true })
13621
+ }
13622
+ ),
13623
+ childrenKnown && (visibleChildren.length > 0 ? visibleChildren.map((child) => /* @__PURE__ */ jsx(FileBrowserNode, { entry: child, depth: depth + 1 }, child.path)) : /* @__PURE__ */ jsx(
13624
+ FileBrowserStatusRow,
13625
+ {
13626
+ depth: depth + 1,
13627
+ kind: rawChildren.length === 0 ? "empty" : "no-matches"
13628
+ }
13629
+ ))
13630
+ ] })
13631
+ ]
13632
+ }
13633
+ );
13634
+ }
13635
+ FileBrowserNode.displayName = "FileBrowserNode";
13636
+ function FileBrowserTree({ ariaLabel = "Files", className }) {
13637
+ const ctx = useFileBrowser();
13638
+ const {
13639
+ path,
13640
+ entriesFor,
13641
+ visibleChildrenFor,
13642
+ statusFor,
13643
+ errorFor,
13644
+ loadPath,
13645
+ hasProvider,
13646
+ visibleRows,
13647
+ tabFocusPath,
13648
+ setFocusedPath,
13649
+ focusRow,
13650
+ toggleExpanded,
13651
+ isSelectable,
13652
+ selectEntry,
13653
+ navigate,
13654
+ multiple
13655
+ } = ctx;
13656
+ const rootEntries = entriesFor(path);
13657
+ const rootStatus = statusFor(path);
13658
+ const rootChildren = rootEntries !== void 0 ? visibleChildrenFor(path) : [];
13659
+ const moveTo = (row) => {
13660
+ setFocusedPath(row.entry.path);
13661
+ focusRow(row.entry.path);
13662
+ };
13663
+ const activate = (row) => {
13664
+ if (row.entry.disabled) return;
13665
+ if (isSelectable(row.entry)) selectEntry(row.entry);
13666
+ if (row.expandable) toggleExpanded(row.entry.path);
13667
+ else if (row.entry.kind === "dir" && !isSelectable(row.entry)) navigate(row.entry.path);
13668
+ };
13669
+ const handleKeyDown = (e) => {
13670
+ const rows = visibleRows;
13671
+ if (rows.length === 0) return;
13672
+ const index = rows.findIndex((row) => row.entry.path === tabFocusPath);
13673
+ const current = index >= 0 ? rows[index] : rows[0];
13674
+ switch (e.key) {
13675
+ case "ArrowDown":
13676
+ e.preventDefault();
13677
+ if (index < rows.length - 1) moveTo(rows[index + 1]);
13678
+ break;
13679
+ case "ArrowUp":
13680
+ e.preventDefault();
13681
+ if (index > 0) moveTo(rows[index - 1]);
13682
+ break;
13683
+ case "Home":
13684
+ e.preventDefault();
13685
+ moveTo(rows[0]);
13686
+ break;
13687
+ case "End":
13688
+ e.preventDefault();
13689
+ moveTo(rows[rows.length - 1]);
13690
+ break;
13691
+ case "ArrowRight":
13692
+ e.preventDefault();
13693
+ if (current.entry.disabled) break;
13694
+ if (current.expandable && !current.expanded) {
13695
+ toggleExpanded(current.entry.path);
13696
+ } else if (current.expanded) {
13697
+ const firstChild = rows[index + 1];
13698
+ if (firstChild && firstChild.parentPath === current.entry.path) moveTo(firstChild);
13699
+ }
13700
+ break;
13701
+ case "ArrowLeft":
13702
+ e.preventDefault();
13703
+ if (current.expanded && !current.entry.disabled) {
13704
+ toggleExpanded(current.entry.path);
13705
+ } else if (current.parentPath) {
13706
+ const parent = rows.find((row) => row.entry.path === current.parentPath);
13707
+ if (parent) moveTo(parent);
13708
+ }
13709
+ break;
13710
+ case "Enter":
13711
+ e.preventDefault();
13712
+ activate(current);
13713
+ break;
13714
+ case " ":
13715
+ e.preventDefault();
13716
+ if (!current.entry.disabled) selectEntry(current.entry);
13717
+ break;
13718
+ }
13719
+ };
13720
+ return /* @__PURE__ */ jsxs(
13721
+ "div",
13722
+ {
13723
+ role: "tree",
13724
+ "aria-label": ariaLabel,
13725
+ "aria-multiselectable": multiple || void 0,
13726
+ "data-react-fancy-file-browser-tree": "",
13727
+ className: cn("min-h-0 flex-1 overflow-auto p-1", className),
13728
+ onKeyDown: handleKeyDown,
13729
+ children: [
13730
+ rootEntries === void 0 && hasProvider && (rootStatus === "loading" || rootStatus === "idle") && /* @__PURE__ */ jsx(FileBrowserStatusRow, { depth: 0, kind: "loading" }),
13731
+ rootEntries === void 0 && rootStatus === "error" && /* @__PURE__ */ jsx(
13732
+ FileBrowserStatusRow,
13733
+ {
13734
+ depth: 0,
13735
+ kind: "error",
13736
+ message: errorFor(path),
13737
+ onRetry: () => loadPath(path, { reload: true })
13738
+ }
13739
+ ),
13740
+ rootEntries === void 0 && rootStatus === "idle" && !hasProvider && /* @__PURE__ */ jsx(FileBrowserStatusRow, { depth: 0, kind: "unknown" }),
13741
+ rootEntries !== void 0 && (rootChildren.length > 0 ? rootChildren.map((entry) => /* @__PURE__ */ jsx(FileBrowserNode, { entry, depth: 0 }, entry.path)) : /* @__PURE__ */ jsx(FileBrowserStatusRow, { depth: 0, kind: rootEntries.length === 0 ? "empty" : "no-matches" }))
13742
+ ]
13743
+ }
13744
+ );
13745
+ }
13746
+ FileBrowserTree.displayName = "FileBrowserTree";
13747
+ var DEFAULT_SORT2 = { by: "name", direction: "asc" };
13748
+ function snapshotNodeToEntry(node) {
13749
+ const { children: _children, ...entry } = node;
13750
+ return entry;
13751
+ }
13752
+ function buildSnapshotMap(snapshot) {
13753
+ const map = /* @__PURE__ */ new Map();
13754
+ if (!snapshot || snapshot.length === 0) return map;
13755
+ for (const root of snapshot) {
13756
+ const parent = parentPath(root.path);
13757
+ const list = map.get(parent);
13758
+ if (list) list.push(snapshotNodeToEntry(root));
13759
+ else map.set(parent, [snapshotNodeToEntry(root)]);
13760
+ }
13761
+ const walk2 = (nodes) => {
13762
+ for (const node of nodes) {
13763
+ if (node.children) {
13764
+ map.set(node.path, node.children.map(snapshotNodeToEntry));
13765
+ walk2(node.children);
13766
+ }
13767
+ }
13768
+ };
13769
+ walk2(snapshot);
13770
+ return map;
13771
+ }
13772
+ function FileBrowserRoot({
13773
+ provider,
13774
+ snapshot,
13775
+ select = "file",
13776
+ multiple = false,
13777
+ value,
13778
+ defaultValue,
13779
+ onChange,
13780
+ path,
13781
+ defaultPath = "/",
13782
+ onPathChange,
13783
+ expandedPaths,
13784
+ defaultExpandedPaths,
13785
+ onExpandedChange,
13786
+ sort,
13787
+ defaultSort,
13788
+ onSortChange,
13789
+ filter,
13790
+ defaultFilter: defaultFilter2,
13791
+ onFilterChange,
13792
+ onError,
13793
+ indentSize = 16,
13794
+ showIcons = true,
13795
+ className,
13796
+ children
13797
+ }) {
13798
+ const [currentPath, setCurrentPath] = useControllableState(path, defaultPath, onPathChange);
13799
+ const [expanded, setExpanded] = useControllableState(
13800
+ expandedPaths,
13801
+ defaultExpandedPaths ?? [],
13802
+ onExpandedChange
13803
+ );
13804
+ const [sortState, setSortState] = useControllableState(sort, defaultSort ?? DEFAULT_SORT2, onSortChange);
13805
+ const [filterState, setFilterState] = useControllableState(filter, defaultFilter2 ?? "", onFilterChange);
13806
+ const [internalValue, setInternalValue] = useState(
13807
+ () => defaultValue ?? (multiple ? [] : null)
13808
+ );
13809
+ const selection = value !== void 0 ? value : internalValue;
13810
+ const selectedPaths = useMemo(
13811
+ () => selection == null ? [] : Array.isArray(selection) ? selection : [selection],
13812
+ [selection]
13813
+ );
13814
+ const snapshotMap = useMemo(() => buildSnapshotMap(snapshot), [snapshot]);
13815
+ const [loadedChildren, setLoadedChildren] = useState({});
13816
+ const [loadStatus, setLoadStatus] = useState({});
13817
+ const [loadErrors, setLoadErrors] = useState({});
13818
+ const seqCounter = useRef(0);
13819
+ const requestSeq = useRef({});
13820
+ const stateRef = useRef({ snapshotMap, loadedChildren, loadStatus });
13821
+ stateRef.current = { snapshotMap, loadedChildren, loadStatus };
13822
+ const providerRef = useRef(provider);
13823
+ providerRef.current = provider;
13824
+ const onErrorRef = useRef(onError);
13825
+ onErrorRef.current = onError;
13826
+ const onChangeRef = useRef(onChange);
13827
+ onChangeRef.current = onChange;
13828
+ const loadPath = useCallback((targetPath, options) => {
13829
+ const prov = providerRef.current;
13830
+ if (!prov) return;
13831
+ const { snapshotMap: snap, loadedChildren: loaded, loadStatus: statuses } = stateRef.current;
13832
+ const status = statuses[targetPath] ?? "idle";
13833
+ if (status === "loading") return;
13834
+ const known = snap.get(targetPath) ?? loaded[targetPath];
13835
+ if (!options?.reload && (known !== void 0 || status === "error")) return;
13836
+ const requestId = ++seqCounter.current;
13837
+ requestSeq.current[targetPath] = requestId;
13838
+ setLoadStatus((prev) => ({ ...prev, [targetPath]: "loading" }));
13839
+ prov.loadChildren(targetPath).then(
13840
+ (entries) => {
13841
+ if (requestSeq.current[targetPath] !== requestId) return;
13842
+ setLoadedChildren((prev) => ({ ...prev, [targetPath]: entries }));
13843
+ setLoadStatus((prev) => ({ ...prev, [targetPath]: "loaded" }));
13844
+ setLoadErrors((prev) => {
13845
+ if (!(targetPath in prev)) return prev;
13846
+ const next = { ...prev };
13847
+ delete next[targetPath];
13848
+ return next;
13849
+ });
13850
+ },
13851
+ (error) => {
13852
+ if (requestSeq.current[targetPath] !== requestId) return;
13853
+ setLoadStatus((prev) => ({ ...prev, [targetPath]: "error" }));
13854
+ setLoadErrors((prev) => ({
13855
+ ...prev,
13856
+ [targetPath]: error instanceof Error ? error.message : String(error)
13857
+ }));
13858
+ onErrorRef.current?.(targetPath, error);
13859
+ }
13860
+ );
13861
+ }, []);
13862
+ const entriesFor = useCallback(
13863
+ (p) => snapshotMap.get(p) ?? loadedChildren[p],
13864
+ [snapshotMap, loadedChildren]
13865
+ );
13866
+ const statusFor = useCallback(
13867
+ (p) => {
13868
+ if (snapshotMap.has(p)) return "loaded";
13869
+ const status = loadStatus[p];
13870
+ if (status) return status;
13871
+ return loadedChildren[p] !== void 0 ? "loaded" : "idle";
13872
+ },
13873
+ [snapshotMap, loadStatus, loadedChildren]
13874
+ );
13875
+ const errorFor = useCallback((p) => loadErrors[p], [loadErrors]);
13876
+ useEffect(() => {
13877
+ if (!provider) return;
13878
+ loadPath(currentPath);
13879
+ for (const p of expanded) loadPath(p);
13880
+ }, [provider, currentPath, expanded, snapshotMap, loadPath]);
13881
+ const filterLower = filterState.trim().toLowerCase();
13882
+ const visibleChildrenFor = useCallback(
13883
+ (p) => {
13884
+ const entries = entriesFor(p);
13885
+ if (!entries) return [];
13886
+ const filtered = filterLower ? entries.filter((entry) => entryMatchesFilter(entry, filterLower, entriesFor)) : entries.slice();
13887
+ return filtered.sort((a, b) => compareFileEntries(a, b, sortState));
13888
+ },
13889
+ [entriesFor, filterLower, sortState]
13890
+ );
13891
+ const visibleRows = useMemo(() => {
13892
+ const rows = [];
13893
+ const visited = /* @__PURE__ */ new Set([currentPath]);
13894
+ const walk2 = (p, depth, parent) => {
13895
+ for (const entry of visibleChildrenFor(p)) {
13896
+ const expandable = isEntryExpandable(entry, entriesFor(entry.path), !!provider);
13897
+ const isOpen = expandable && expanded.includes(entry.path);
13898
+ rows.push({ entry, depth, expandable, expanded: isOpen, parentPath: parent });
13899
+ if (isOpen && !visited.has(entry.path)) {
13900
+ visited.add(entry.path);
13901
+ walk2(entry.path, depth + 1, entry.path);
13902
+ }
13903
+ }
13904
+ };
13905
+ walk2(currentPath, 0, null);
13906
+ return rows;
13907
+ }, [visibleChildrenFor, entriesFor, provider, expanded, currentPath]);
13908
+ const entryIndex = useMemo(() => {
13909
+ const map = /* @__PURE__ */ new Map();
13910
+ for (const list of snapshotMap.values()) {
13911
+ for (const entry of list) map.set(entry.path, entry);
13912
+ }
13913
+ for (const list of Object.values(loadedChildren)) {
13914
+ for (const entry of list) {
13915
+ if (!map.has(entry.path)) map.set(entry.path, entry);
13916
+ }
13917
+ }
13918
+ return map;
13919
+ }, [snapshotMap, loadedChildren]);
13920
+ const isSelectable = useCallback(
13921
+ (entry) => !entry.disabled && (select === "both" || (select === "file" ? entry.kind === "file" : entry.kind === "dir")),
13922
+ [select]
13923
+ );
13924
+ const isSelected = useCallback((p) => selectedPaths.includes(p), [selectedPaths]);
13925
+ const commitSelection = useCallback(
13926
+ (paths) => {
13927
+ const nextValue = multiple ? paths : paths[0] ?? null;
13928
+ if (value === void 0) setInternalValue(nextValue);
13929
+ onChangeRef.current?.(
13930
+ nextValue,
13931
+ paths.map((p) => entryIndex.get(p)).filter((entry) => entry !== void 0)
13932
+ );
13933
+ },
13934
+ [multiple, value, entryIndex]
13935
+ );
13936
+ const selectEntry = useCallback(
13937
+ (entry) => {
13938
+ if (!isSelectable(entry)) return;
13939
+ if (multiple) {
13940
+ commitSelection(
13941
+ selectedPaths.includes(entry.path) ? selectedPaths.filter((p) => p !== entry.path) : [...selectedPaths, entry.path]
13942
+ );
13943
+ } else {
13944
+ commitSelection([entry.path]);
13945
+ }
13946
+ },
13947
+ [isSelectable, multiple, selectedPaths, commitSelection]
13948
+ );
13949
+ const toggleExpanded = useCallback(
13950
+ (p) => {
13951
+ setExpanded((prev) => prev.includes(p) ? prev.filter((x) => x !== p) : [...prev, p]);
13952
+ },
13953
+ [setExpanded]
13954
+ );
13955
+ const [focusedPath, setFocusedPath] = useState(null);
13956
+ const navigate = useCallback(
13957
+ (p) => {
13958
+ setCurrentPath(p);
13959
+ setFilterState("");
13960
+ setFocusedPath(null);
13961
+ },
13962
+ [setCurrentPath, setFilterState]
13963
+ );
13964
+ const rowRefs = useRef(/* @__PURE__ */ new Map());
13965
+ const registerRow = useCallback((p, el) => {
13966
+ if (el) rowRefs.current.set(p, el);
13967
+ else rowRefs.current.delete(p);
13968
+ }, []);
13969
+ const focusRow = useCallback((p) => {
13970
+ rowRefs.current.get(p)?.focus();
13971
+ }, []);
13972
+ const tabFocusPath = useMemo(() => {
13973
+ if (focusedPath && visibleRows.some((row) => row.entry.path === focusedPath)) {
13974
+ return focusedPath;
13975
+ }
13976
+ return visibleRows[0]?.entry.path ?? null;
13977
+ }, [focusedPath, visibleRows]);
13978
+ const ctx = useMemo(
13979
+ () => ({
13980
+ entriesFor,
13981
+ visibleChildrenFor,
13982
+ statusFor,
13983
+ errorFor,
13984
+ loadPath,
13985
+ hasProvider: !!provider,
13986
+ path: currentPath,
13987
+ navigate,
13988
+ expandedPaths: expanded,
13989
+ toggleExpanded,
13990
+ select,
13991
+ multiple,
13992
+ selectedPaths,
13993
+ isSelected,
13994
+ isSelectable,
13995
+ selectEntry,
13996
+ sort: sortState,
13997
+ setSort: setSortState,
13998
+ filter: filterState,
13999
+ setFilter: setFilterState,
14000
+ visibleRows,
14001
+ focusedPath,
14002
+ setFocusedPath,
14003
+ tabFocusPath,
14004
+ focusRow,
14005
+ registerRow,
14006
+ indentSize,
14007
+ showIcons
14008
+ }),
14009
+ [
14010
+ entriesFor,
14011
+ visibleChildrenFor,
14012
+ statusFor,
14013
+ errorFor,
14014
+ loadPath,
14015
+ provider,
14016
+ currentPath,
14017
+ navigate,
14018
+ expanded,
14019
+ toggleExpanded,
14020
+ select,
14021
+ multiple,
14022
+ selectedPaths,
14023
+ isSelected,
14024
+ isSelectable,
14025
+ selectEntry,
14026
+ sortState,
14027
+ setSortState,
14028
+ filterState,
14029
+ setFilterState,
14030
+ visibleRows,
14031
+ focusedPath,
14032
+ tabFocusPath,
14033
+ focusRow,
14034
+ registerRow,
14035
+ indentSize,
14036
+ showIcons
14037
+ ]
14038
+ );
14039
+ return /* @__PURE__ */ jsx(FileBrowserContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
14040
+ "div",
14041
+ {
14042
+ "data-react-fancy-file-browser": "",
14043
+ className: cn(
14044
+ "flex flex-col overflow-hidden rounded-lg border border-zinc-200 bg-white text-sm dark:border-zinc-700 dark:bg-zinc-900",
14045
+ className
14046
+ ),
14047
+ children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
14048
+ /* @__PURE__ */ jsx(FileBrowserPathBar, {}),
14049
+ /* @__PURE__ */ jsx(FileBrowserToolbar, {}),
14050
+ /* @__PURE__ */ jsx(FileBrowserTree, {})
14051
+ ] })
14052
+ }
14053
+ ) });
14054
+ }
14055
+ FileBrowserRoot.displayName = "FileBrowser";
14056
+ var FileBrowser = Object.assign(FileBrowserRoot, {
14057
+ PathBar: FileBrowserPathBar,
14058
+ Toolbar: FileBrowserToolbar,
14059
+ Tree: FileBrowserTree,
14060
+ Node: FileBrowserNode
14061
+ });
13143
14062
 
13144
14063
  // src/utils/media-type.ts
13145
14064
  var IMAGE_EXTS = /* @__PURE__ */ new Set([
@@ -14955,6 +15874,6 @@ var MediaViewer = forwardRef(
14955
15874
  );
14956
15875
  MediaViewer.displayName = "MediaViewer";
14957
15876
 
14958
- export { Accordion, AccordionPanel, AccordionPanelContent, AccordionPanelSection, AccordionPanelTrigger, Action, AudioViewer, Autocomplete, Avatar, Badge, Brand, Breadcrumbs, Button, Calendar, Callout, Card, Carousel, Chart, ChatDrawer, Checkbox, CheckboxGroup, ColorPicker, Command, Composer, ContentRenderer, ContextMenu, DatePicker, DisplayValue, Dropdown, EMOJI_CATEGORY_ORDER, EMOJI_DATA, EMOJI_ENTRIES, Editor, Emoji, EmojiSelect, FauxClient, Field, FieldModeContext, FileUpload, Form, FormProvider, Heading, Icon, ImageViewer, Input, InputTag, Kanban, MagicWand, Marquee, MediaViewer, Menu2 as Menu, MobileMenu, Modal, MoodMeter, MultiSwitch, Navbar, OtpInput, Pagination, PdfViewer, Pillbox, Popover, Portal, Profile, Progress, PromptInput, RadioGroup, ReasonTag, SKIN_TONES, Select, Separator, Sidebar, Skeleton, Slider, StickyNote, Switch, Table, Tabs, Text, Textarea, TimeGrid, TimePicker, Timeline, Toast, Tooltip, TreeNav, VideoViewer, applyTone, cn, configureIcons, contentEditableAdapter, controlledAdapter, find, hasSkinTones, inputAdapter, registerExtension, registerExtensions, registerIconAddendum, registerIconSet, registerIcons, resolve, resolveMediaType, sanitizeHref, sanitizeHtml, search, skinTones, textareaAdapter, useAccordion, useAccordionPanel, useAccordionSection, useAnimation, useCarousel, useCommand, useContextMenu, useControllableState, useDropdown, useEditor, useEscapeKey, useFieldMode, useFileUpload, useFloatingPosition, useFocusTrap, useId12 as useId, useKanban, useMenu, useMobileMenu, useModal, useNavbar, useNodeRegistry, useOutsideClick, usePanZoom, usePopover, useSidebar, useTabs, useToast, useTreeNav };
15877
+ export { Accordion, AccordionPanel, AccordionPanelContent, AccordionPanelSection, AccordionPanelTrigger, Action, AudioViewer, Autocomplete, Avatar, Badge, Brand, Breadcrumbs, Button, Calendar, Callout, Card, Carousel, Chart, ChatDrawer, Checkbox, CheckboxGroup, ColorPicker, Command, Composer, ContentRenderer, ContextMenu, DatePicker, DisplayValue, Dropdown, EMOJI_CATEGORY_ORDER, EMOJI_DATA, EMOJI_ENTRIES, Editor, Emoji, EmojiSelect, FauxClient, Field, FieldModeContext, FileBrowser, FileUpload, Form, FormProvider, Heading, Icon, ImageViewer, Input, InputTag, Kanban, MagicWand, Marquee, MediaViewer, Menu2 as Menu, MobileMenu, Modal, MoodMeter, MultiSwitch, Navbar, OtpInput, Pagination, PdfViewer, Pillbox, Popover, Portal, Profile, Progress, PromptInput, RadioGroup, ReasonTag, SKIN_TONES, Select, Separator, Sidebar, Skeleton, Slider, StickyNote, Switch, Table, Tabs, Text, Textarea, TimeGrid, TimePicker, Timeline, Toast, Tooltip, TreeNav, VideoViewer, applyTone, cn, configureIcons, contentEditableAdapter, controlledAdapter, find, hasSkinTones, inputAdapter, registerExtension, registerExtensions, registerIconAddendum, registerIconSet, registerIcons, resolve, resolveMediaType, sanitizeHref, sanitizeHtml, search, skinTones, textareaAdapter, useAccordion, useAccordionPanel, useAccordionSection, useAnimation, useCarousel, useCommand, useContextMenu, useControllableState, useDropdown, useEditor, useEscapeKey, useFieldMode, useFileBrowser, useFileUpload, useFloatingPosition, useFocusTrap, useId12 as useId, useKanban, useMenu, useMobileMenu, useModal, useNavbar, useNodeRegistry, useOutsideClick, usePanZoom, usePopover, useSidebar, useTabs, useToast, useTreeNav };
14959
15878
  //# sourceMappingURL=index.js.map
14960
15879
  //# sourceMappingURL=index.js.map