@particle-academy/react-fancy 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +494 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +198 -3
- package/dist/index.d.ts +198 -3
- package/dist/index.js +489 -2
- package/dist/index.js.map +1 -1
- package/docs/ChatDrawer.md +75 -0
- package/docs/InputTag.md +155 -0
- package/docs/PromptInput.md +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12135,7 +12135,8 @@ function PromptInput({
|
|
|
12135
12135
|
placeholder = "Ask anything. Type / for commands, @ for mentions. \u2318/Ctrl+Enter to send.",
|
|
12136
12136
|
charsPerToken = 4,
|
|
12137
12137
|
mentionColor,
|
|
12138
|
-
maxHeight = 280
|
|
12138
|
+
maxHeight = 280,
|
|
12139
|
+
aboveInput
|
|
12139
12140
|
}) {
|
|
12140
12141
|
const [text, setText] = useState("");
|
|
12141
12142
|
const [attachments, setAttachments] = useState([]);
|
|
@@ -12271,6 +12272,7 @@ function PromptInput({
|
|
|
12271
12272
|
onDrop,
|
|
12272
12273
|
className: `relative rounded-md border transition ${dragOver ? "border-violet-400 bg-violet-50/50 dark:border-violet-600 dark:bg-violet-950/30" : "border-zinc-200 dark:border-zinc-800"} bg-white dark:bg-zinc-900`,
|
|
12273
12274
|
children: [
|
|
12275
|
+
aboveInput && /* @__PURE__ */ jsx("div", { className: "border-b border-zinc-200 dark:border-zinc-800", children: aboveInput }),
|
|
12274
12276
|
attachments.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5 border-b border-zinc-200 px-3 py-2 dark:border-zinc-800", children: attachments.map((a) => /* @__PURE__ */ jsxs(
|
|
12275
12277
|
"span",
|
|
12276
12278
|
{
|
|
@@ -12411,6 +12413,491 @@ function fmtSize(b) {
|
|
|
12411
12413
|
if (b < 1024 * 1024) return `${(b / 1024).toFixed(0)} KB`;
|
|
12412
12414
|
return `${(b / 1024 / 1024).toFixed(1)} MB`;
|
|
12413
12415
|
}
|
|
12416
|
+
function ChatDrawer({
|
|
12417
|
+
tabs,
|
|
12418
|
+
activeTabId,
|
|
12419
|
+
onTabChange,
|
|
12420
|
+
open = true,
|
|
12421
|
+
onToggle,
|
|
12422
|
+
children,
|
|
12423
|
+
minBodyHeight = 140,
|
|
12424
|
+
className
|
|
12425
|
+
}) {
|
|
12426
|
+
const handleToggle = useCallback(() => {
|
|
12427
|
+
onToggle?.(!open);
|
|
12428
|
+
}, [onToggle, open]);
|
|
12429
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
12430
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 px-2.5 py-2", children: [
|
|
12431
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-1.5", children: tabs.map((tab, i) => {
|
|
12432
|
+
const active = tab.id === activeTabId;
|
|
12433
|
+
const number = tab.number === null ? null : tab.number ?? i + 1;
|
|
12434
|
+
return /* @__PURE__ */ jsxs(
|
|
12435
|
+
"button",
|
|
12436
|
+
{
|
|
12437
|
+
type: "button",
|
|
12438
|
+
onClick: () => onTabChange(tab.id),
|
|
12439
|
+
className: [
|
|
12440
|
+
"group inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-[12px] font-medium transition",
|
|
12441
|
+
active ? "border-violet-500 bg-violet-500 text-white" : "border-zinc-200 bg-transparent text-zinc-700 hover:border-zinc-300 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:bg-zinc-800"
|
|
12442
|
+
].join(" "),
|
|
12443
|
+
"aria-pressed": active,
|
|
12444
|
+
children: [
|
|
12445
|
+
number !== null && /* @__PURE__ */ jsx(
|
|
12446
|
+
"span",
|
|
12447
|
+
{
|
|
12448
|
+
className: [
|
|
12449
|
+
"inline-flex h-4 w-4 items-center justify-center rounded-full text-[10px] font-semibold",
|
|
12450
|
+
active ? "bg-white/20 text-white" : "bg-zinc-200 text-zinc-600 group-hover:bg-zinc-300 dark:bg-zinc-700 dark:text-zinc-300"
|
|
12451
|
+
].join(" "),
|
|
12452
|
+
children: number
|
|
12453
|
+
}
|
|
12454
|
+
),
|
|
12455
|
+
/* @__PURE__ */ jsx("span", { className: "truncate max-w-[180px]", children: tab.label })
|
|
12456
|
+
]
|
|
12457
|
+
},
|
|
12458
|
+
tab.id
|
|
12459
|
+
);
|
|
12460
|
+
}) }),
|
|
12461
|
+
/* @__PURE__ */ jsx(
|
|
12462
|
+
"button",
|
|
12463
|
+
{
|
|
12464
|
+
type: "button",
|
|
12465
|
+
onClick: handleToggle,
|
|
12466
|
+
"aria-label": open ? "Collapse drawer" : "Expand drawer",
|
|
12467
|
+
"aria-expanded": open,
|
|
12468
|
+
className: "ml-auto inline-flex h-6 w-6 items-center justify-center rounded-full text-zinc-400 transition hover:bg-zinc-100 hover:text-zinc-700 dark:hover:bg-zinc-800 dark:hover:text-zinc-200",
|
|
12469
|
+
children: /* @__PURE__ */ jsx(
|
|
12470
|
+
Icon,
|
|
12471
|
+
{
|
|
12472
|
+
name: open ? "chevron-down" : "chevron-up",
|
|
12473
|
+
className: "h-3.5 w-3.5"
|
|
12474
|
+
}
|
|
12475
|
+
)
|
|
12476
|
+
}
|
|
12477
|
+
)
|
|
12478
|
+
] }),
|
|
12479
|
+
open && /* @__PURE__ */ jsx(
|
|
12480
|
+
"div",
|
|
12481
|
+
{
|
|
12482
|
+
className: "px-2.5 pb-2.5",
|
|
12483
|
+
style: { minHeight: minBodyHeight },
|
|
12484
|
+
children
|
|
12485
|
+
}
|
|
12486
|
+
)
|
|
12487
|
+
] });
|
|
12488
|
+
}
|
|
12489
|
+
function defaultKeyOf(item) {
|
|
12490
|
+
if (item && typeof item === "object") {
|
|
12491
|
+
const r = item;
|
|
12492
|
+
if (typeof r.name === "string") return r.name;
|
|
12493
|
+
if (typeof r.id === "string") return r.id;
|
|
12494
|
+
}
|
|
12495
|
+
return String(item);
|
|
12496
|
+
}
|
|
12497
|
+
function defaultFilter(item, query) {
|
|
12498
|
+
if (!query) return true;
|
|
12499
|
+
return defaultKeyOf(item).toLowerCase().includes(query.toLowerCase());
|
|
12500
|
+
}
|
|
12501
|
+
function detectTrigger(text, caret, triggerChars) {
|
|
12502
|
+
for (let i = caret - 1; i >= 0; i--) {
|
|
12503
|
+
const ch = text[i];
|
|
12504
|
+
if (ch === void 0) break;
|
|
12505
|
+
if (triggerChars.has(ch)) {
|
|
12506
|
+
if (i === 0 || /\s/.test(text[i - 1])) {
|
|
12507
|
+
return {
|
|
12508
|
+
char: ch,
|
|
12509
|
+
start: i,
|
|
12510
|
+
end: caret,
|
|
12511
|
+
query: text.slice(i + 1, caret)
|
|
12512
|
+
};
|
|
12513
|
+
}
|
|
12514
|
+
return null;
|
|
12515
|
+
}
|
|
12516
|
+
if (/\s/.test(ch)) return null;
|
|
12517
|
+
}
|
|
12518
|
+
return null;
|
|
12519
|
+
}
|
|
12520
|
+
function InputTag({
|
|
12521
|
+
adapter,
|
|
12522
|
+
triggers,
|
|
12523
|
+
maxItems = 8,
|
|
12524
|
+
placement = "bottom-left",
|
|
12525
|
+
className,
|
|
12526
|
+
style,
|
|
12527
|
+
onPick
|
|
12528
|
+
}) {
|
|
12529
|
+
const triggerChars = useMemo(() => new Set(Object.keys(triggers)), [triggers]);
|
|
12530
|
+
const [active, setActive] = useState(null);
|
|
12531
|
+
const [cursor, setCursor] = useState(0);
|
|
12532
|
+
const [anchorRect, setAnchorRect] = useState(null);
|
|
12533
|
+
const stateRef = useRef({ text: "", caretIndex: 0 });
|
|
12534
|
+
const activeRef = useRef(null);
|
|
12535
|
+
const cursorRef = useRef(0);
|
|
12536
|
+
activeRef.current = active;
|
|
12537
|
+
cursorRef.current = cursor;
|
|
12538
|
+
const items = useMemo(() => {
|
|
12539
|
+
if (!active) return [];
|
|
12540
|
+
const cfg2 = triggers[active.char];
|
|
12541
|
+
if (!cfg2) return [];
|
|
12542
|
+
const filter = cfg2.filter ?? defaultFilter;
|
|
12543
|
+
const out = [];
|
|
12544
|
+
for (const item of cfg2.items) {
|
|
12545
|
+
if (filter(item, active.query)) out.push(item);
|
|
12546
|
+
if (out.length >= maxItems) break;
|
|
12547
|
+
}
|
|
12548
|
+
return out;
|
|
12549
|
+
}, [active, triggers, maxItems]);
|
|
12550
|
+
useEffect(() => {
|
|
12551
|
+
return adapter.subscribe((s) => {
|
|
12552
|
+
stateRef.current = s;
|
|
12553
|
+
const next = detectTrigger(s.text, s.caretIndex, triggerChars);
|
|
12554
|
+
setActive((prev) => {
|
|
12555
|
+
if (!prev || !next || prev.char !== next.char || prev.start !== next.start) {
|
|
12556
|
+
setCursor(0);
|
|
12557
|
+
}
|
|
12558
|
+
return next;
|
|
12559
|
+
});
|
|
12560
|
+
if (next) setAnchorRect(adapter.getAnchorRect());
|
|
12561
|
+
});
|
|
12562
|
+
}, [adapter, triggerChars]);
|
|
12563
|
+
useLayoutEffect(() => {
|
|
12564
|
+
if (!active) return;
|
|
12565
|
+
const update = () => setAnchorRect(adapter.getAnchorRect());
|
|
12566
|
+
update();
|
|
12567
|
+
window.addEventListener("scroll", update, true);
|
|
12568
|
+
window.addEventListener("resize", update);
|
|
12569
|
+
return () => {
|
|
12570
|
+
window.removeEventListener("scroll", update, true);
|
|
12571
|
+
window.removeEventListener("resize", update);
|
|
12572
|
+
};
|
|
12573
|
+
}, [active, adapter]);
|
|
12574
|
+
useEffect(() => {
|
|
12575
|
+
if (cursor >= items.length) setCursor(Math.max(0, items.length - 1));
|
|
12576
|
+
}, [items.length, cursor]);
|
|
12577
|
+
const pickItem = useCallback(
|
|
12578
|
+
(item) => {
|
|
12579
|
+
const cur = activeRef.current;
|
|
12580
|
+
if (!cur) return;
|
|
12581
|
+
const cfg2 = triggers[cur.char];
|
|
12582
|
+
if (!cfg2) return;
|
|
12583
|
+
const replacement = cfg2.insert(item, cur.query);
|
|
12584
|
+
adapter.replaceRange(cur.start, cur.end, replacement);
|
|
12585
|
+
onPick?.({ triggerChar: cur.char, query: cur.query, item });
|
|
12586
|
+
setActive(null);
|
|
12587
|
+
},
|
|
12588
|
+
[adapter, triggers, onPick]
|
|
12589
|
+
);
|
|
12590
|
+
useEffect(() => {
|
|
12591
|
+
return adapter.onKey((e) => {
|
|
12592
|
+
const cur = activeRef.current;
|
|
12593
|
+
if (!cur) return false;
|
|
12594
|
+
const visible = items;
|
|
12595
|
+
switch (e.key) {
|
|
12596
|
+
case "ArrowDown":
|
|
12597
|
+
if (visible.length === 0) return false;
|
|
12598
|
+
setCursor((c) => (c + 1) % visible.length);
|
|
12599
|
+
return true;
|
|
12600
|
+
case "ArrowUp":
|
|
12601
|
+
if (visible.length === 0) return false;
|
|
12602
|
+
setCursor((c) => (c - 1 + visible.length) % visible.length);
|
|
12603
|
+
return true;
|
|
12604
|
+
case "Enter":
|
|
12605
|
+
case "Tab": {
|
|
12606
|
+
if (visible.length === 0) return false;
|
|
12607
|
+
const idx = Math.min(cursorRef.current, visible.length - 1);
|
|
12608
|
+
pickItem(visible[idx]);
|
|
12609
|
+
return true;
|
|
12610
|
+
}
|
|
12611
|
+
case "Escape":
|
|
12612
|
+
setActive(null);
|
|
12613
|
+
return true;
|
|
12614
|
+
default:
|
|
12615
|
+
return false;
|
|
12616
|
+
}
|
|
12617
|
+
});
|
|
12618
|
+
}, [adapter, items, pickItem]);
|
|
12619
|
+
if (!active || !anchorRect || items.length === 0) return null;
|
|
12620
|
+
const cfg = triggers[active.char];
|
|
12621
|
+
if (!cfg) return null;
|
|
12622
|
+
const popStyle = computePopoverStyle(anchorRect, placement);
|
|
12623
|
+
return /* @__PURE__ */ jsxs(
|
|
12624
|
+
"div",
|
|
12625
|
+
{
|
|
12626
|
+
role: "listbox",
|
|
12627
|
+
"aria-label": cfg.label ?? `Pick a ${active.char === "/" ? "command" : "mention"}`,
|
|
12628
|
+
className: [
|
|
12629
|
+
"fixed z-50 w-72 overflow-hidden rounded-md border border-zinc-200 bg-white shadow-lg dark:border-zinc-700 dark:bg-zinc-900",
|
|
12630
|
+
className ?? ""
|
|
12631
|
+
].filter(Boolean).join(" "),
|
|
12632
|
+
style: { ...popStyle, ...style },
|
|
12633
|
+
children: [
|
|
12634
|
+
(cfg.label || active.query) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b border-zinc-100 bg-zinc-50 px-2 py-1 text-[10px] font-semibold uppercase tracking-wider text-zinc-500 dark:border-zinc-800 dark:bg-zinc-950", children: [
|
|
12635
|
+
/* @__PURE__ */ jsx("span", { children: cfg.label ?? labelForChar(active.char) }),
|
|
12636
|
+
active.query && /* @__PURE__ */ jsxs("span", { className: "font-mono text-[10px] normal-case tracking-normal text-zinc-400", children: [
|
|
12637
|
+
active.char,
|
|
12638
|
+
active.query
|
|
12639
|
+
] })
|
|
12640
|
+
] }),
|
|
12641
|
+
/* @__PURE__ */ jsx("ul", { className: "max-h-60 overflow-y-auto", children: items.map((item, i) => {
|
|
12642
|
+
const renderer = cfg.render ?? ((it) => /* @__PURE__ */ jsx("span", { children: defaultKeyOf(it) }));
|
|
12643
|
+
const active2 = i === cursor;
|
|
12644
|
+
const key = (cfg.keyOf ?? defaultKeyOf)(item);
|
|
12645
|
+
return /* @__PURE__ */ jsx(
|
|
12646
|
+
"li",
|
|
12647
|
+
{
|
|
12648
|
+
role: "option",
|
|
12649
|
+
"aria-selected": active2,
|
|
12650
|
+
onMouseDown: (e) => {
|
|
12651
|
+
e.preventDefault();
|
|
12652
|
+
pickItem(item);
|
|
12653
|
+
},
|
|
12654
|
+
onMouseEnter: () => setCursor(i),
|
|
12655
|
+
className: [
|
|
12656
|
+
"cursor-pointer px-2 py-1.5 text-[12px]",
|
|
12657
|
+
active2 ? "bg-violet-100 dark:bg-violet-900/30" : "hover:bg-zinc-50 dark:hover:bg-zinc-800"
|
|
12658
|
+
].join(" "),
|
|
12659
|
+
children: renderer(item, active2)
|
|
12660
|
+
},
|
|
12661
|
+
key
|
|
12662
|
+
);
|
|
12663
|
+
}) })
|
|
12664
|
+
]
|
|
12665
|
+
}
|
|
12666
|
+
);
|
|
12667
|
+
}
|
|
12668
|
+
function labelForChar(ch) {
|
|
12669
|
+
if (ch === "/") return "Commands";
|
|
12670
|
+
if (ch === "@") return "Mentions";
|
|
12671
|
+
if (ch === "#") return "Tags";
|
|
12672
|
+
if (ch === ":") return "Emoji";
|
|
12673
|
+
return `Trigger ${ch}`;
|
|
12674
|
+
}
|
|
12675
|
+
function computePopoverStyle(anchor, placement) {
|
|
12676
|
+
const offset = 4;
|
|
12677
|
+
switch (placement) {
|
|
12678
|
+
case "bottom-right":
|
|
12679
|
+
return { top: anchor.bottom + offset, right: window.innerWidth - anchor.right };
|
|
12680
|
+
case "top-left":
|
|
12681
|
+
return { bottom: window.innerHeight - anchor.top + offset, left: anchor.left };
|
|
12682
|
+
case "top-right":
|
|
12683
|
+
return { bottom: window.innerHeight - anchor.top + offset, right: window.innerWidth - anchor.right };
|
|
12684
|
+
case "bottom-left":
|
|
12685
|
+
default:
|
|
12686
|
+
return { top: anchor.bottom + offset, left: anchor.left };
|
|
12687
|
+
}
|
|
12688
|
+
}
|
|
12689
|
+
|
|
12690
|
+
// src/components/InputTag/adapters.ts
|
|
12691
|
+
function nativeValueSetter(el) {
|
|
12692
|
+
const proto = el instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
|
|
12693
|
+
const desc = Object.getOwnPropertyDescriptor(proto, "value");
|
|
12694
|
+
if (!desc?.set) return null;
|
|
12695
|
+
return desc.set.bind(el);
|
|
12696
|
+
}
|
|
12697
|
+
function replaceInValueElement(el, start, end, replacement) {
|
|
12698
|
+
const current = el.value;
|
|
12699
|
+
const next = current.slice(0, start) + replacement + current.slice(end);
|
|
12700
|
+
const setter = nativeValueSetter(el);
|
|
12701
|
+
if (setter) {
|
|
12702
|
+
setter(next);
|
|
12703
|
+
} else {
|
|
12704
|
+
el.value = next;
|
|
12705
|
+
}
|
|
12706
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
12707
|
+
const caret = start + replacement.length;
|
|
12708
|
+
el.setSelectionRange(caret, caret);
|
|
12709
|
+
el.focus();
|
|
12710
|
+
}
|
|
12711
|
+
function valueElementAdapter(ref) {
|
|
12712
|
+
return {
|
|
12713
|
+
subscribe(fn) {
|
|
12714
|
+
const handler = () => {
|
|
12715
|
+
const el2 = ref.current;
|
|
12716
|
+
if (!el2) return;
|
|
12717
|
+
fn({
|
|
12718
|
+
text: el2.value,
|
|
12719
|
+
caretIndex: el2.selectionStart ?? el2.value.length
|
|
12720
|
+
});
|
|
12721
|
+
};
|
|
12722
|
+
const el = ref.current;
|
|
12723
|
+
if (el) {
|
|
12724
|
+
el.addEventListener("input", handler);
|
|
12725
|
+
el.addEventListener("click", handler);
|
|
12726
|
+
el.addEventListener("keyup", handler);
|
|
12727
|
+
el.addEventListener("focus", handler);
|
|
12728
|
+
}
|
|
12729
|
+
return () => {
|
|
12730
|
+
const el2 = ref.current;
|
|
12731
|
+
if (el2) {
|
|
12732
|
+
el2.removeEventListener("input", handler);
|
|
12733
|
+
el2.removeEventListener("click", handler);
|
|
12734
|
+
el2.removeEventListener("keyup", handler);
|
|
12735
|
+
el2.removeEventListener("focus", handler);
|
|
12736
|
+
}
|
|
12737
|
+
};
|
|
12738
|
+
},
|
|
12739
|
+
replaceRange(start, end, replacement) {
|
|
12740
|
+
const el = ref.current;
|
|
12741
|
+
if (!el) return;
|
|
12742
|
+
replaceInValueElement(el, start, end, replacement);
|
|
12743
|
+
},
|
|
12744
|
+
getAnchorRect() {
|
|
12745
|
+
const el = ref.current;
|
|
12746
|
+
return el ? el.getBoundingClientRect() : null;
|
|
12747
|
+
},
|
|
12748
|
+
onKey(handler) {
|
|
12749
|
+
const fn = (e) => {
|
|
12750
|
+
if (handler(e)) {
|
|
12751
|
+
e.preventDefault();
|
|
12752
|
+
e.stopPropagation();
|
|
12753
|
+
}
|
|
12754
|
+
};
|
|
12755
|
+
const el = ref.current;
|
|
12756
|
+
if (el) el.addEventListener("keydown", fn);
|
|
12757
|
+
return () => {
|
|
12758
|
+
const el2 = ref.current;
|
|
12759
|
+
if (el2) el2.removeEventListener("keydown", fn);
|
|
12760
|
+
};
|
|
12761
|
+
}
|
|
12762
|
+
};
|
|
12763
|
+
}
|
|
12764
|
+
function textareaAdapter(ref) {
|
|
12765
|
+
return valueElementAdapter(ref);
|
|
12766
|
+
}
|
|
12767
|
+
function inputAdapter(ref) {
|
|
12768
|
+
return valueElementAdapter(ref);
|
|
12769
|
+
}
|
|
12770
|
+
function contentEditableAdapter(ref) {
|
|
12771
|
+
function caretIndex(el) {
|
|
12772
|
+
const sel = window.getSelection();
|
|
12773
|
+
if (!sel || sel.rangeCount === 0) return 0;
|
|
12774
|
+
const range2 = sel.getRangeAt(0).cloneRange();
|
|
12775
|
+
range2.selectNodeContents(el);
|
|
12776
|
+
range2.setEnd(sel.focusNode, sel.focusOffset);
|
|
12777
|
+
return range2.toString().length;
|
|
12778
|
+
}
|
|
12779
|
+
function setCaret(el, index) {
|
|
12780
|
+
const sel = window.getSelection();
|
|
12781
|
+
if (!sel) return;
|
|
12782
|
+
const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
|
|
12783
|
+
let remaining = index;
|
|
12784
|
+
let node = walker.nextNode();
|
|
12785
|
+
while (node) {
|
|
12786
|
+
const len = (node.textContent ?? "").length;
|
|
12787
|
+
if (remaining <= len) {
|
|
12788
|
+
const range3 = document.createRange();
|
|
12789
|
+
range3.setStart(node, remaining);
|
|
12790
|
+
range3.collapse(true);
|
|
12791
|
+
sel.removeAllRanges();
|
|
12792
|
+
sel.addRange(range3);
|
|
12793
|
+
return;
|
|
12794
|
+
}
|
|
12795
|
+
remaining -= len;
|
|
12796
|
+
node = walker.nextNode();
|
|
12797
|
+
}
|
|
12798
|
+
const range2 = document.createRange();
|
|
12799
|
+
range2.selectNodeContents(el);
|
|
12800
|
+
range2.collapse(false);
|
|
12801
|
+
sel.removeAllRanges();
|
|
12802
|
+
sel.addRange(range2);
|
|
12803
|
+
}
|
|
12804
|
+
return {
|
|
12805
|
+
subscribe(fn) {
|
|
12806
|
+
const handler = () => {
|
|
12807
|
+
const el2 = ref.current;
|
|
12808
|
+
if (!el2) return;
|
|
12809
|
+
fn({ text: el2.textContent ?? "", caretIndex: caretIndex(el2) });
|
|
12810
|
+
};
|
|
12811
|
+
const el = ref.current;
|
|
12812
|
+
if (el) {
|
|
12813
|
+
el.addEventListener("input", handler);
|
|
12814
|
+
el.addEventListener("click", handler);
|
|
12815
|
+
el.addEventListener("keyup", handler);
|
|
12816
|
+
el.addEventListener("focus", handler);
|
|
12817
|
+
}
|
|
12818
|
+
return () => {
|
|
12819
|
+
const el2 = ref.current;
|
|
12820
|
+
if (el2) {
|
|
12821
|
+
el2.removeEventListener("input", handler);
|
|
12822
|
+
el2.removeEventListener("click", handler);
|
|
12823
|
+
el2.removeEventListener("keyup", handler);
|
|
12824
|
+
el2.removeEventListener("focus", handler);
|
|
12825
|
+
}
|
|
12826
|
+
};
|
|
12827
|
+
},
|
|
12828
|
+
replaceRange(start, end, replacement) {
|
|
12829
|
+
const el = ref.current;
|
|
12830
|
+
if (!el) return;
|
|
12831
|
+
const current = el.textContent ?? "";
|
|
12832
|
+
const next = current.slice(0, start) + replacement + current.slice(end);
|
|
12833
|
+
el.textContent = next;
|
|
12834
|
+
setCaret(el, start + replacement.length);
|
|
12835
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
12836
|
+
el.focus();
|
|
12837
|
+
},
|
|
12838
|
+
getAnchorRect() {
|
|
12839
|
+
const el = ref.current;
|
|
12840
|
+
return el ? el.getBoundingClientRect() : null;
|
|
12841
|
+
},
|
|
12842
|
+
onKey(handler) {
|
|
12843
|
+
const fn = (e) => {
|
|
12844
|
+
if (handler(e)) {
|
|
12845
|
+
e.preventDefault();
|
|
12846
|
+
e.stopPropagation();
|
|
12847
|
+
}
|
|
12848
|
+
};
|
|
12849
|
+
const el = ref.current;
|
|
12850
|
+
if (el) el.addEventListener("keydown", fn);
|
|
12851
|
+
return () => {
|
|
12852
|
+
const el2 = ref.current;
|
|
12853
|
+
if (el2) el2.removeEventListener("keydown", fn);
|
|
12854
|
+
};
|
|
12855
|
+
}
|
|
12856
|
+
};
|
|
12857
|
+
}
|
|
12858
|
+
function controlledAdapter(opts) {
|
|
12859
|
+
let listener = null;
|
|
12860
|
+
let keyHandler = null;
|
|
12861
|
+
const installKey = () => {
|
|
12862
|
+
const el = opts.anchorRef.current;
|
|
12863
|
+
if (!el || !keyHandler) return () => {
|
|
12864
|
+
};
|
|
12865
|
+
const fn = (e) => {
|
|
12866
|
+
if (keyHandler && keyHandler(e)) {
|
|
12867
|
+
e.preventDefault();
|
|
12868
|
+
e.stopPropagation();
|
|
12869
|
+
}
|
|
12870
|
+
};
|
|
12871
|
+
el.addEventListener("keydown", fn);
|
|
12872
|
+
return () => el.removeEventListener("keydown", fn);
|
|
12873
|
+
};
|
|
12874
|
+
return {
|
|
12875
|
+
notify(state) {
|
|
12876
|
+
listener?.(state);
|
|
12877
|
+
},
|
|
12878
|
+
subscribe(fn) {
|
|
12879
|
+
listener = fn;
|
|
12880
|
+
return () => {
|
|
12881
|
+
if (listener === fn) listener = null;
|
|
12882
|
+
};
|
|
12883
|
+
},
|
|
12884
|
+
replaceRange(start, end, replacement) {
|
|
12885
|
+
opts.onReplaceRange(start, end, replacement);
|
|
12886
|
+
},
|
|
12887
|
+
getAnchorRect() {
|
|
12888
|
+
const el = opts.anchorRef.current;
|
|
12889
|
+
return el ? el.getBoundingClientRect() : null;
|
|
12890
|
+
},
|
|
12891
|
+
onKey(handler) {
|
|
12892
|
+
keyHandler = handler;
|
|
12893
|
+
const uninstall = installKey();
|
|
12894
|
+
return () => {
|
|
12895
|
+
if (keyHandler === handler) keyHandler = null;
|
|
12896
|
+
uninstall();
|
|
12897
|
+
};
|
|
12898
|
+
}
|
|
12899
|
+
};
|
|
12900
|
+
}
|
|
12414
12901
|
function MagicWand({
|
|
12415
12902
|
value,
|
|
12416
12903
|
onValueChange,
|
|
@@ -12604,6 +13091,6 @@ function caretRect(ta, start, end) {
|
|
|
12604
13091
|
return { x, y };
|
|
12605
13092
|
}
|
|
12606
13093
|
|
|
12607
|
-
export { Accordion, AccordionPanel, AccordionPanelContent, AccordionPanelSection, AccordionPanelTrigger, Action, Autocomplete, Avatar, Badge, Brand, Breadcrumbs, Calendar, Callout, Card, Carousel, Chart, Checkbox, CheckboxGroup, ColorPicker, Command, Composer, ContentRenderer, ContextMenu, DatePicker, Dropdown, EMOJI_CATEGORY_ORDER, EMOJI_DATA, EMOJI_ENTRIES, Editor, Emoji, EmojiSelect, Field, FileUpload, Heading, Icon, Input, Kanban, MagicWand, Menu2 as Menu, MobileMenu, Modal, MoodMeter, MultiSwitch, Navbar, OtpInput, Pagination, Pillbox, Popover, Portal, Profile, Progress, PromptInput, RadioGroup, ReasonTag, SKIN_TONES, Select, Separator, Sidebar, Skeleton, Slider, Switch, Table, Tabs, Text, Textarea, TimePicker, Timeline, Toast, Tooltip, TreeNav, applyTone, cn, configureIcons, find, hasSkinTones, registerExtension, registerExtensions, registerIconSet, registerIcons, resolve, sanitizeHref, sanitizeHtml, search, skinTones, useAccordion, useAccordionPanel, useAccordionSection, useAnimation, useCarousel, useCommand, useContextMenu, useControllableState, useDropdown, useEditor, useEscapeKey, useFileUpload, useFloatingPosition, useFocusTrap, useId12 as useId, useKanban, useMenu, useMobileMenu, useModal, useNavbar, useNodeRegistry, useOutsideClick, usePanZoom, usePopover, useSidebar, useTabs, useToast, useTreeNav };
|
|
13094
|
+
export { Accordion, AccordionPanel, AccordionPanelContent, AccordionPanelSection, AccordionPanelTrigger, Action, Autocomplete, Avatar, Badge, Brand, Breadcrumbs, Calendar, Callout, Card, Carousel, Chart, ChatDrawer, Checkbox, CheckboxGroup, ColorPicker, Command, Composer, ContentRenderer, ContextMenu, DatePicker, Dropdown, EMOJI_CATEGORY_ORDER, EMOJI_DATA, EMOJI_ENTRIES, Editor, Emoji, EmojiSelect, Field, FileUpload, Heading, Icon, Input, InputTag, Kanban, MagicWand, Menu2 as Menu, MobileMenu, Modal, MoodMeter, MultiSwitch, Navbar, OtpInput, Pagination, Pillbox, Popover, Portal, Profile, Progress, PromptInput, RadioGroup, ReasonTag, SKIN_TONES, Select, Separator, Sidebar, Skeleton, Slider, Switch, Table, Tabs, Text, Textarea, TimePicker, Timeline, Toast, Tooltip, TreeNav, applyTone, cn, configureIcons, contentEditableAdapter, controlledAdapter, find, hasSkinTones, inputAdapter, registerExtension, registerExtensions, registerIconSet, registerIcons, resolve, sanitizeHref, sanitizeHtml, search, skinTones, textareaAdapter, useAccordion, useAccordionPanel, useAccordionSection, useAnimation, useCarousel, useCommand, useContextMenu, useControllableState, useDropdown, useEditor, useEscapeKey, useFileUpload, useFloatingPosition, useFocusTrap, useId12 as useId, useKanban, useMenu, useMobileMenu, useModal, useNavbar, useNodeRegistry, useOutsideClick, usePanZoom, usePopover, useSidebar, useTabs, useToast, useTreeNav };
|
|
12608
13095
|
//# sourceMappingURL=index.js.map
|
|
12609
13096
|
//# sourceMappingURL=index.js.map
|