@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.cjs
CHANGED
|
@@ -12156,7 +12156,8 @@ function PromptInput({
|
|
|
12156
12156
|
placeholder = "Ask anything. Type / for commands, @ for mentions. \u2318/Ctrl+Enter to send.",
|
|
12157
12157
|
charsPerToken = 4,
|
|
12158
12158
|
mentionColor,
|
|
12159
|
-
maxHeight = 280
|
|
12159
|
+
maxHeight = 280,
|
|
12160
|
+
aboveInput
|
|
12160
12161
|
}) {
|
|
12161
12162
|
const [text, setText] = react.useState("");
|
|
12162
12163
|
const [attachments, setAttachments] = react.useState([]);
|
|
@@ -12292,6 +12293,7 @@ function PromptInput({
|
|
|
12292
12293
|
onDrop,
|
|
12293
12294
|
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`,
|
|
12294
12295
|
children: [
|
|
12296
|
+
aboveInput && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-zinc-200 dark:border-zinc-800", children: aboveInput }),
|
|
12295
12297
|
attachments.length > 0 && /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs(
|
|
12296
12298
|
"span",
|
|
12297
12299
|
{
|
|
@@ -12432,6 +12434,491 @@ function fmtSize(b) {
|
|
|
12432
12434
|
if (b < 1024 * 1024) return `${(b / 1024).toFixed(0)} KB`;
|
|
12433
12435
|
return `${(b / 1024 / 1024).toFixed(1)} MB`;
|
|
12434
12436
|
}
|
|
12437
|
+
function ChatDrawer({
|
|
12438
|
+
tabs,
|
|
12439
|
+
activeTabId,
|
|
12440
|
+
onTabChange,
|
|
12441
|
+
open = true,
|
|
12442
|
+
onToggle,
|
|
12443
|
+
children,
|
|
12444
|
+
minBodyHeight = 140,
|
|
12445
|
+
className
|
|
12446
|
+
}) {
|
|
12447
|
+
const handleToggle = react.useCallback(() => {
|
|
12448
|
+
onToggle?.(!open);
|
|
12449
|
+
}, [onToggle, open]);
|
|
12450
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
12451
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 px-2.5 py-2", children: [
|
|
12452
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-1.5", children: tabs.map((tab, i) => {
|
|
12453
|
+
const active = tab.id === activeTabId;
|
|
12454
|
+
const number = tab.number === null ? null : tab.number ?? i + 1;
|
|
12455
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
12456
|
+
"button",
|
|
12457
|
+
{
|
|
12458
|
+
type: "button",
|
|
12459
|
+
onClick: () => onTabChange(tab.id),
|
|
12460
|
+
className: [
|
|
12461
|
+
"group inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-[12px] font-medium transition",
|
|
12462
|
+
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"
|
|
12463
|
+
].join(" "),
|
|
12464
|
+
"aria-pressed": active,
|
|
12465
|
+
children: [
|
|
12466
|
+
number !== null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
12467
|
+
"span",
|
|
12468
|
+
{
|
|
12469
|
+
className: [
|
|
12470
|
+
"inline-flex h-4 w-4 items-center justify-center rounded-full text-[10px] font-semibold",
|
|
12471
|
+
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"
|
|
12472
|
+
].join(" "),
|
|
12473
|
+
children: number
|
|
12474
|
+
}
|
|
12475
|
+
),
|
|
12476
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[180px]", children: tab.label })
|
|
12477
|
+
]
|
|
12478
|
+
},
|
|
12479
|
+
tab.id
|
|
12480
|
+
);
|
|
12481
|
+
}) }),
|
|
12482
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12483
|
+
"button",
|
|
12484
|
+
{
|
|
12485
|
+
type: "button",
|
|
12486
|
+
onClick: handleToggle,
|
|
12487
|
+
"aria-label": open ? "Collapse drawer" : "Expand drawer",
|
|
12488
|
+
"aria-expanded": open,
|
|
12489
|
+
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",
|
|
12490
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
12491
|
+
Icon,
|
|
12492
|
+
{
|
|
12493
|
+
name: open ? "chevron-down" : "chevron-up",
|
|
12494
|
+
className: "h-3.5 w-3.5"
|
|
12495
|
+
}
|
|
12496
|
+
)
|
|
12497
|
+
}
|
|
12498
|
+
)
|
|
12499
|
+
] }),
|
|
12500
|
+
open && /* @__PURE__ */ jsxRuntime.jsx(
|
|
12501
|
+
"div",
|
|
12502
|
+
{
|
|
12503
|
+
className: "px-2.5 pb-2.5",
|
|
12504
|
+
style: { minHeight: minBodyHeight },
|
|
12505
|
+
children
|
|
12506
|
+
}
|
|
12507
|
+
)
|
|
12508
|
+
] });
|
|
12509
|
+
}
|
|
12510
|
+
function defaultKeyOf(item) {
|
|
12511
|
+
if (item && typeof item === "object") {
|
|
12512
|
+
const r = item;
|
|
12513
|
+
if (typeof r.name === "string") return r.name;
|
|
12514
|
+
if (typeof r.id === "string") return r.id;
|
|
12515
|
+
}
|
|
12516
|
+
return String(item);
|
|
12517
|
+
}
|
|
12518
|
+
function defaultFilter(item, query) {
|
|
12519
|
+
if (!query) return true;
|
|
12520
|
+
return defaultKeyOf(item).toLowerCase().includes(query.toLowerCase());
|
|
12521
|
+
}
|
|
12522
|
+
function detectTrigger(text, caret, triggerChars) {
|
|
12523
|
+
for (let i = caret - 1; i >= 0; i--) {
|
|
12524
|
+
const ch = text[i];
|
|
12525
|
+
if (ch === void 0) break;
|
|
12526
|
+
if (triggerChars.has(ch)) {
|
|
12527
|
+
if (i === 0 || /\s/.test(text[i - 1])) {
|
|
12528
|
+
return {
|
|
12529
|
+
char: ch,
|
|
12530
|
+
start: i,
|
|
12531
|
+
end: caret,
|
|
12532
|
+
query: text.slice(i + 1, caret)
|
|
12533
|
+
};
|
|
12534
|
+
}
|
|
12535
|
+
return null;
|
|
12536
|
+
}
|
|
12537
|
+
if (/\s/.test(ch)) return null;
|
|
12538
|
+
}
|
|
12539
|
+
return null;
|
|
12540
|
+
}
|
|
12541
|
+
function InputTag({
|
|
12542
|
+
adapter,
|
|
12543
|
+
triggers,
|
|
12544
|
+
maxItems = 8,
|
|
12545
|
+
placement = "bottom-left",
|
|
12546
|
+
className,
|
|
12547
|
+
style,
|
|
12548
|
+
onPick
|
|
12549
|
+
}) {
|
|
12550
|
+
const triggerChars = react.useMemo(() => new Set(Object.keys(triggers)), [triggers]);
|
|
12551
|
+
const [active, setActive] = react.useState(null);
|
|
12552
|
+
const [cursor, setCursor] = react.useState(0);
|
|
12553
|
+
const [anchorRect, setAnchorRect] = react.useState(null);
|
|
12554
|
+
const stateRef = react.useRef({ text: "", caretIndex: 0 });
|
|
12555
|
+
const activeRef = react.useRef(null);
|
|
12556
|
+
const cursorRef = react.useRef(0);
|
|
12557
|
+
activeRef.current = active;
|
|
12558
|
+
cursorRef.current = cursor;
|
|
12559
|
+
const items = react.useMemo(() => {
|
|
12560
|
+
if (!active) return [];
|
|
12561
|
+
const cfg2 = triggers[active.char];
|
|
12562
|
+
if (!cfg2) return [];
|
|
12563
|
+
const filter = cfg2.filter ?? defaultFilter;
|
|
12564
|
+
const out = [];
|
|
12565
|
+
for (const item of cfg2.items) {
|
|
12566
|
+
if (filter(item, active.query)) out.push(item);
|
|
12567
|
+
if (out.length >= maxItems) break;
|
|
12568
|
+
}
|
|
12569
|
+
return out;
|
|
12570
|
+
}, [active, triggers, maxItems]);
|
|
12571
|
+
react.useEffect(() => {
|
|
12572
|
+
return adapter.subscribe((s) => {
|
|
12573
|
+
stateRef.current = s;
|
|
12574
|
+
const next = detectTrigger(s.text, s.caretIndex, triggerChars);
|
|
12575
|
+
setActive((prev) => {
|
|
12576
|
+
if (!prev || !next || prev.char !== next.char || prev.start !== next.start) {
|
|
12577
|
+
setCursor(0);
|
|
12578
|
+
}
|
|
12579
|
+
return next;
|
|
12580
|
+
});
|
|
12581
|
+
if (next) setAnchorRect(adapter.getAnchorRect());
|
|
12582
|
+
});
|
|
12583
|
+
}, [adapter, triggerChars]);
|
|
12584
|
+
react.useLayoutEffect(() => {
|
|
12585
|
+
if (!active) return;
|
|
12586
|
+
const update = () => setAnchorRect(adapter.getAnchorRect());
|
|
12587
|
+
update();
|
|
12588
|
+
window.addEventListener("scroll", update, true);
|
|
12589
|
+
window.addEventListener("resize", update);
|
|
12590
|
+
return () => {
|
|
12591
|
+
window.removeEventListener("scroll", update, true);
|
|
12592
|
+
window.removeEventListener("resize", update);
|
|
12593
|
+
};
|
|
12594
|
+
}, [active, adapter]);
|
|
12595
|
+
react.useEffect(() => {
|
|
12596
|
+
if (cursor >= items.length) setCursor(Math.max(0, items.length - 1));
|
|
12597
|
+
}, [items.length, cursor]);
|
|
12598
|
+
const pickItem = react.useCallback(
|
|
12599
|
+
(item) => {
|
|
12600
|
+
const cur = activeRef.current;
|
|
12601
|
+
if (!cur) return;
|
|
12602
|
+
const cfg2 = triggers[cur.char];
|
|
12603
|
+
if (!cfg2) return;
|
|
12604
|
+
const replacement = cfg2.insert(item, cur.query);
|
|
12605
|
+
adapter.replaceRange(cur.start, cur.end, replacement);
|
|
12606
|
+
onPick?.({ triggerChar: cur.char, query: cur.query, item });
|
|
12607
|
+
setActive(null);
|
|
12608
|
+
},
|
|
12609
|
+
[adapter, triggers, onPick]
|
|
12610
|
+
);
|
|
12611
|
+
react.useEffect(() => {
|
|
12612
|
+
return adapter.onKey((e) => {
|
|
12613
|
+
const cur = activeRef.current;
|
|
12614
|
+
if (!cur) return false;
|
|
12615
|
+
const visible = items;
|
|
12616
|
+
switch (e.key) {
|
|
12617
|
+
case "ArrowDown":
|
|
12618
|
+
if (visible.length === 0) return false;
|
|
12619
|
+
setCursor((c) => (c + 1) % visible.length);
|
|
12620
|
+
return true;
|
|
12621
|
+
case "ArrowUp":
|
|
12622
|
+
if (visible.length === 0) return false;
|
|
12623
|
+
setCursor((c) => (c - 1 + visible.length) % visible.length);
|
|
12624
|
+
return true;
|
|
12625
|
+
case "Enter":
|
|
12626
|
+
case "Tab": {
|
|
12627
|
+
if (visible.length === 0) return false;
|
|
12628
|
+
const idx = Math.min(cursorRef.current, visible.length - 1);
|
|
12629
|
+
pickItem(visible[idx]);
|
|
12630
|
+
return true;
|
|
12631
|
+
}
|
|
12632
|
+
case "Escape":
|
|
12633
|
+
setActive(null);
|
|
12634
|
+
return true;
|
|
12635
|
+
default:
|
|
12636
|
+
return false;
|
|
12637
|
+
}
|
|
12638
|
+
});
|
|
12639
|
+
}, [adapter, items, pickItem]);
|
|
12640
|
+
if (!active || !anchorRect || items.length === 0) return null;
|
|
12641
|
+
const cfg = triggers[active.char];
|
|
12642
|
+
if (!cfg) return null;
|
|
12643
|
+
const popStyle = computePopoverStyle(anchorRect, placement);
|
|
12644
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
12645
|
+
"div",
|
|
12646
|
+
{
|
|
12647
|
+
role: "listbox",
|
|
12648
|
+
"aria-label": cfg.label ?? `Pick a ${active.char === "/" ? "command" : "mention"}`,
|
|
12649
|
+
className: [
|
|
12650
|
+
"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",
|
|
12651
|
+
className ?? ""
|
|
12652
|
+
].filter(Boolean).join(" "),
|
|
12653
|
+
style: { ...popStyle, ...style },
|
|
12654
|
+
children: [
|
|
12655
|
+
(cfg.label || active.query) && /* @__PURE__ */ jsxRuntime.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: [
|
|
12656
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: cfg.label ?? labelForChar(active.char) }),
|
|
12657
|
+
active.query && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-[10px] normal-case tracking-normal text-zinc-400", children: [
|
|
12658
|
+
active.char,
|
|
12659
|
+
active.query
|
|
12660
|
+
] })
|
|
12661
|
+
] }),
|
|
12662
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "max-h-60 overflow-y-auto", children: items.map((item, i) => {
|
|
12663
|
+
const renderer = cfg.render ?? ((it) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: defaultKeyOf(it) }));
|
|
12664
|
+
const active2 = i === cursor;
|
|
12665
|
+
const key = (cfg.keyOf ?? defaultKeyOf)(item);
|
|
12666
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
12667
|
+
"li",
|
|
12668
|
+
{
|
|
12669
|
+
role: "option",
|
|
12670
|
+
"aria-selected": active2,
|
|
12671
|
+
onMouseDown: (e) => {
|
|
12672
|
+
e.preventDefault();
|
|
12673
|
+
pickItem(item);
|
|
12674
|
+
},
|
|
12675
|
+
onMouseEnter: () => setCursor(i),
|
|
12676
|
+
className: [
|
|
12677
|
+
"cursor-pointer px-2 py-1.5 text-[12px]",
|
|
12678
|
+
active2 ? "bg-violet-100 dark:bg-violet-900/30" : "hover:bg-zinc-50 dark:hover:bg-zinc-800"
|
|
12679
|
+
].join(" "),
|
|
12680
|
+
children: renderer(item, active2)
|
|
12681
|
+
},
|
|
12682
|
+
key
|
|
12683
|
+
);
|
|
12684
|
+
}) })
|
|
12685
|
+
]
|
|
12686
|
+
}
|
|
12687
|
+
);
|
|
12688
|
+
}
|
|
12689
|
+
function labelForChar(ch) {
|
|
12690
|
+
if (ch === "/") return "Commands";
|
|
12691
|
+
if (ch === "@") return "Mentions";
|
|
12692
|
+
if (ch === "#") return "Tags";
|
|
12693
|
+
if (ch === ":") return "Emoji";
|
|
12694
|
+
return `Trigger ${ch}`;
|
|
12695
|
+
}
|
|
12696
|
+
function computePopoverStyle(anchor, placement) {
|
|
12697
|
+
const offset = 4;
|
|
12698
|
+
switch (placement) {
|
|
12699
|
+
case "bottom-right":
|
|
12700
|
+
return { top: anchor.bottom + offset, right: window.innerWidth - anchor.right };
|
|
12701
|
+
case "top-left":
|
|
12702
|
+
return { bottom: window.innerHeight - anchor.top + offset, left: anchor.left };
|
|
12703
|
+
case "top-right":
|
|
12704
|
+
return { bottom: window.innerHeight - anchor.top + offset, right: window.innerWidth - anchor.right };
|
|
12705
|
+
case "bottom-left":
|
|
12706
|
+
default:
|
|
12707
|
+
return { top: anchor.bottom + offset, left: anchor.left };
|
|
12708
|
+
}
|
|
12709
|
+
}
|
|
12710
|
+
|
|
12711
|
+
// src/components/InputTag/adapters.ts
|
|
12712
|
+
function nativeValueSetter(el) {
|
|
12713
|
+
const proto = el instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
|
|
12714
|
+
const desc = Object.getOwnPropertyDescriptor(proto, "value");
|
|
12715
|
+
if (!desc?.set) return null;
|
|
12716
|
+
return desc.set.bind(el);
|
|
12717
|
+
}
|
|
12718
|
+
function replaceInValueElement(el, start, end, replacement) {
|
|
12719
|
+
const current = el.value;
|
|
12720
|
+
const next = current.slice(0, start) + replacement + current.slice(end);
|
|
12721
|
+
const setter = nativeValueSetter(el);
|
|
12722
|
+
if (setter) {
|
|
12723
|
+
setter(next);
|
|
12724
|
+
} else {
|
|
12725
|
+
el.value = next;
|
|
12726
|
+
}
|
|
12727
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
12728
|
+
const caret = start + replacement.length;
|
|
12729
|
+
el.setSelectionRange(caret, caret);
|
|
12730
|
+
el.focus();
|
|
12731
|
+
}
|
|
12732
|
+
function valueElementAdapter(ref) {
|
|
12733
|
+
return {
|
|
12734
|
+
subscribe(fn) {
|
|
12735
|
+
const handler = () => {
|
|
12736
|
+
const el2 = ref.current;
|
|
12737
|
+
if (!el2) return;
|
|
12738
|
+
fn({
|
|
12739
|
+
text: el2.value,
|
|
12740
|
+
caretIndex: el2.selectionStart ?? el2.value.length
|
|
12741
|
+
});
|
|
12742
|
+
};
|
|
12743
|
+
const el = ref.current;
|
|
12744
|
+
if (el) {
|
|
12745
|
+
el.addEventListener("input", handler);
|
|
12746
|
+
el.addEventListener("click", handler);
|
|
12747
|
+
el.addEventListener("keyup", handler);
|
|
12748
|
+
el.addEventListener("focus", handler);
|
|
12749
|
+
}
|
|
12750
|
+
return () => {
|
|
12751
|
+
const el2 = ref.current;
|
|
12752
|
+
if (el2) {
|
|
12753
|
+
el2.removeEventListener("input", handler);
|
|
12754
|
+
el2.removeEventListener("click", handler);
|
|
12755
|
+
el2.removeEventListener("keyup", handler);
|
|
12756
|
+
el2.removeEventListener("focus", handler);
|
|
12757
|
+
}
|
|
12758
|
+
};
|
|
12759
|
+
},
|
|
12760
|
+
replaceRange(start, end, replacement) {
|
|
12761
|
+
const el = ref.current;
|
|
12762
|
+
if (!el) return;
|
|
12763
|
+
replaceInValueElement(el, start, end, replacement);
|
|
12764
|
+
},
|
|
12765
|
+
getAnchorRect() {
|
|
12766
|
+
const el = ref.current;
|
|
12767
|
+
return el ? el.getBoundingClientRect() : null;
|
|
12768
|
+
},
|
|
12769
|
+
onKey(handler) {
|
|
12770
|
+
const fn = (e) => {
|
|
12771
|
+
if (handler(e)) {
|
|
12772
|
+
e.preventDefault();
|
|
12773
|
+
e.stopPropagation();
|
|
12774
|
+
}
|
|
12775
|
+
};
|
|
12776
|
+
const el = ref.current;
|
|
12777
|
+
if (el) el.addEventListener("keydown", fn);
|
|
12778
|
+
return () => {
|
|
12779
|
+
const el2 = ref.current;
|
|
12780
|
+
if (el2) el2.removeEventListener("keydown", fn);
|
|
12781
|
+
};
|
|
12782
|
+
}
|
|
12783
|
+
};
|
|
12784
|
+
}
|
|
12785
|
+
function textareaAdapter(ref) {
|
|
12786
|
+
return valueElementAdapter(ref);
|
|
12787
|
+
}
|
|
12788
|
+
function inputAdapter(ref) {
|
|
12789
|
+
return valueElementAdapter(ref);
|
|
12790
|
+
}
|
|
12791
|
+
function contentEditableAdapter(ref) {
|
|
12792
|
+
function caretIndex(el) {
|
|
12793
|
+
const sel = window.getSelection();
|
|
12794
|
+
if (!sel || sel.rangeCount === 0) return 0;
|
|
12795
|
+
const range2 = sel.getRangeAt(0).cloneRange();
|
|
12796
|
+
range2.selectNodeContents(el);
|
|
12797
|
+
range2.setEnd(sel.focusNode, sel.focusOffset);
|
|
12798
|
+
return range2.toString().length;
|
|
12799
|
+
}
|
|
12800
|
+
function setCaret(el, index) {
|
|
12801
|
+
const sel = window.getSelection();
|
|
12802
|
+
if (!sel) return;
|
|
12803
|
+
const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
|
|
12804
|
+
let remaining = index;
|
|
12805
|
+
let node = walker.nextNode();
|
|
12806
|
+
while (node) {
|
|
12807
|
+
const len = (node.textContent ?? "").length;
|
|
12808
|
+
if (remaining <= len) {
|
|
12809
|
+
const range3 = document.createRange();
|
|
12810
|
+
range3.setStart(node, remaining);
|
|
12811
|
+
range3.collapse(true);
|
|
12812
|
+
sel.removeAllRanges();
|
|
12813
|
+
sel.addRange(range3);
|
|
12814
|
+
return;
|
|
12815
|
+
}
|
|
12816
|
+
remaining -= len;
|
|
12817
|
+
node = walker.nextNode();
|
|
12818
|
+
}
|
|
12819
|
+
const range2 = document.createRange();
|
|
12820
|
+
range2.selectNodeContents(el);
|
|
12821
|
+
range2.collapse(false);
|
|
12822
|
+
sel.removeAllRanges();
|
|
12823
|
+
sel.addRange(range2);
|
|
12824
|
+
}
|
|
12825
|
+
return {
|
|
12826
|
+
subscribe(fn) {
|
|
12827
|
+
const handler = () => {
|
|
12828
|
+
const el2 = ref.current;
|
|
12829
|
+
if (!el2) return;
|
|
12830
|
+
fn({ text: el2.textContent ?? "", caretIndex: caretIndex(el2) });
|
|
12831
|
+
};
|
|
12832
|
+
const el = ref.current;
|
|
12833
|
+
if (el) {
|
|
12834
|
+
el.addEventListener("input", handler);
|
|
12835
|
+
el.addEventListener("click", handler);
|
|
12836
|
+
el.addEventListener("keyup", handler);
|
|
12837
|
+
el.addEventListener("focus", handler);
|
|
12838
|
+
}
|
|
12839
|
+
return () => {
|
|
12840
|
+
const el2 = ref.current;
|
|
12841
|
+
if (el2) {
|
|
12842
|
+
el2.removeEventListener("input", handler);
|
|
12843
|
+
el2.removeEventListener("click", handler);
|
|
12844
|
+
el2.removeEventListener("keyup", handler);
|
|
12845
|
+
el2.removeEventListener("focus", handler);
|
|
12846
|
+
}
|
|
12847
|
+
};
|
|
12848
|
+
},
|
|
12849
|
+
replaceRange(start, end, replacement) {
|
|
12850
|
+
const el = ref.current;
|
|
12851
|
+
if (!el) return;
|
|
12852
|
+
const current = el.textContent ?? "";
|
|
12853
|
+
const next = current.slice(0, start) + replacement + current.slice(end);
|
|
12854
|
+
el.textContent = next;
|
|
12855
|
+
setCaret(el, start + replacement.length);
|
|
12856
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
12857
|
+
el.focus();
|
|
12858
|
+
},
|
|
12859
|
+
getAnchorRect() {
|
|
12860
|
+
const el = ref.current;
|
|
12861
|
+
return el ? el.getBoundingClientRect() : null;
|
|
12862
|
+
},
|
|
12863
|
+
onKey(handler) {
|
|
12864
|
+
const fn = (e) => {
|
|
12865
|
+
if (handler(e)) {
|
|
12866
|
+
e.preventDefault();
|
|
12867
|
+
e.stopPropagation();
|
|
12868
|
+
}
|
|
12869
|
+
};
|
|
12870
|
+
const el = ref.current;
|
|
12871
|
+
if (el) el.addEventListener("keydown", fn);
|
|
12872
|
+
return () => {
|
|
12873
|
+
const el2 = ref.current;
|
|
12874
|
+
if (el2) el2.removeEventListener("keydown", fn);
|
|
12875
|
+
};
|
|
12876
|
+
}
|
|
12877
|
+
};
|
|
12878
|
+
}
|
|
12879
|
+
function controlledAdapter(opts) {
|
|
12880
|
+
let listener = null;
|
|
12881
|
+
let keyHandler = null;
|
|
12882
|
+
const installKey = () => {
|
|
12883
|
+
const el = opts.anchorRef.current;
|
|
12884
|
+
if (!el || !keyHandler) return () => {
|
|
12885
|
+
};
|
|
12886
|
+
const fn = (e) => {
|
|
12887
|
+
if (keyHandler && keyHandler(e)) {
|
|
12888
|
+
e.preventDefault();
|
|
12889
|
+
e.stopPropagation();
|
|
12890
|
+
}
|
|
12891
|
+
};
|
|
12892
|
+
el.addEventListener("keydown", fn);
|
|
12893
|
+
return () => el.removeEventListener("keydown", fn);
|
|
12894
|
+
};
|
|
12895
|
+
return {
|
|
12896
|
+
notify(state) {
|
|
12897
|
+
listener?.(state);
|
|
12898
|
+
},
|
|
12899
|
+
subscribe(fn) {
|
|
12900
|
+
listener = fn;
|
|
12901
|
+
return () => {
|
|
12902
|
+
if (listener === fn) listener = null;
|
|
12903
|
+
};
|
|
12904
|
+
},
|
|
12905
|
+
replaceRange(start, end, replacement) {
|
|
12906
|
+
opts.onReplaceRange(start, end, replacement);
|
|
12907
|
+
},
|
|
12908
|
+
getAnchorRect() {
|
|
12909
|
+
const el = opts.anchorRef.current;
|
|
12910
|
+
return el ? el.getBoundingClientRect() : null;
|
|
12911
|
+
},
|
|
12912
|
+
onKey(handler) {
|
|
12913
|
+
keyHandler = handler;
|
|
12914
|
+
const uninstall = installKey();
|
|
12915
|
+
return () => {
|
|
12916
|
+
if (keyHandler === handler) keyHandler = null;
|
|
12917
|
+
uninstall();
|
|
12918
|
+
};
|
|
12919
|
+
}
|
|
12920
|
+
};
|
|
12921
|
+
}
|
|
12435
12922
|
function MagicWand({
|
|
12436
12923
|
value,
|
|
12437
12924
|
onValueChange,
|
|
@@ -12641,6 +13128,7 @@ exports.Callout = Callout;
|
|
|
12641
13128
|
exports.Card = Card;
|
|
12642
13129
|
exports.Carousel = Carousel;
|
|
12643
13130
|
exports.Chart = Chart;
|
|
13131
|
+
exports.ChatDrawer = ChatDrawer;
|
|
12644
13132
|
exports.Checkbox = Checkbox;
|
|
12645
13133
|
exports.CheckboxGroup = CheckboxGroup;
|
|
12646
13134
|
exports.ColorPicker = ColorPicker;
|
|
@@ -12661,6 +13149,7 @@ exports.FileUpload = FileUpload;
|
|
|
12661
13149
|
exports.Heading = Heading;
|
|
12662
13150
|
exports.Icon = Icon;
|
|
12663
13151
|
exports.Input = Input;
|
|
13152
|
+
exports.InputTag = InputTag;
|
|
12664
13153
|
exports.Kanban = Kanban;
|
|
12665
13154
|
exports.MagicWand = MagicWand;
|
|
12666
13155
|
exports.Menu = Menu2;
|
|
@@ -12698,8 +13187,11 @@ exports.TreeNav = TreeNav;
|
|
|
12698
13187
|
exports.applyTone = applyTone;
|
|
12699
13188
|
exports.cn = cn;
|
|
12700
13189
|
exports.configureIcons = configureIcons;
|
|
13190
|
+
exports.contentEditableAdapter = contentEditableAdapter;
|
|
13191
|
+
exports.controlledAdapter = controlledAdapter;
|
|
12701
13192
|
exports.find = find;
|
|
12702
13193
|
exports.hasSkinTones = hasSkinTones;
|
|
13194
|
+
exports.inputAdapter = inputAdapter;
|
|
12703
13195
|
exports.registerExtension = registerExtension;
|
|
12704
13196
|
exports.registerExtensions = registerExtensions;
|
|
12705
13197
|
exports.registerIconSet = registerIconSet;
|
|
@@ -12709,6 +13201,7 @@ exports.sanitizeHref = sanitizeHref;
|
|
|
12709
13201
|
exports.sanitizeHtml = sanitizeHtml;
|
|
12710
13202
|
exports.search = search;
|
|
12711
13203
|
exports.skinTones = skinTones;
|
|
13204
|
+
exports.textareaAdapter = textareaAdapter;
|
|
12712
13205
|
exports.useAccordion = useAccordion;
|
|
12713
13206
|
exports.useAccordionPanel = useAccordionPanel;
|
|
12714
13207
|
exports.useAccordionSection = useAccordionSection;
|