@deepseek-ai/dsh-client-ui-primitives 0.2.1-alpha.2 → 0.2.1-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +8 -8
- package/README.md +8 -5
- package/README.zh.md +8 -5
- package/lib/TerminalBlock.module.css +2 -2
- package/lib/index.js +608 -535
- package/lib/types/HoverCard.d.ts +5 -2
- package/lib/types/HoverCardGroup.d.ts +23 -0
- package/lib/types/PermissionIcon.d.ts +12 -0
- package/lib/types/TerminalBlock.d.ts +7 -1
- package/lib/types/Tooltip.d.ts +2 -2
- package/lib/types/index.d.ts +3 -2
- package/lib/types/user-text.d.ts +23 -31
- package/package.json +6 -8
package/lib/index.js
CHANGED
|
@@ -20,15 +20,15 @@ import css$13 from "./ShortcutKeys.module.css";
|
|
|
20
20
|
import css$14 from "./MenuSurface.module.css";
|
|
21
21
|
import css$15 from "./Menu.module.css";
|
|
22
22
|
import css$16 from "./MenuGroup.module.css";
|
|
23
|
-
import css$17 from "./
|
|
24
|
-
import css$18 from "./
|
|
25
|
-
import css$19 from "./
|
|
26
|
-
import css$20 from "./
|
|
27
|
-
import css$21 from "./
|
|
28
|
-
import css$22 from "./FileTypeIcon.module.css";
|
|
23
|
+
import css$17 from "./HoverCard.module.css";
|
|
24
|
+
import css$18 from "./Modal.module.css";
|
|
25
|
+
import css$19 from "./RiskConfirmation.module.css";
|
|
26
|
+
import css$20 from "./ConnectionIndicator.module.css";
|
|
27
|
+
import css$21 from "./FileTypeIcon.module.css";
|
|
29
28
|
import { siAliexpress, siApple, siBaidu, siBilibili, siCsdn, siDuckduckgo, siEbay, siFacebook, siGithub, siGitlab, siGoogle, siInstagram, siJuejin, siMdnwebdocs, siNetflix, siNpm, siPypi, siQq, siQuora, siReddit, siSinaweibo, siSpotify, siStackoverflow, siTaobao, siTelegram, siTiktok, siV2ex, siWechat, siWhatsapp, siWikipedia, siX, siYcombinator, siYoutube, siZhihu } from "simple-icons";
|
|
30
|
-
import css$
|
|
29
|
+
import css$22 from "./user-text.module.css";
|
|
31
30
|
import markdownCss from "./markdown/MarkdownText.module.css";
|
|
31
|
+
import css$23 from "./Tooltip.module.css";
|
|
32
32
|
import css$24 from "./Toast.module.css";
|
|
33
33
|
import css$25 from "./settings-form/SettingsForm.module.css";
|
|
34
34
|
import css$26 from "./settings-form/fields.module.css";
|
|
@@ -4646,396 +4646,176 @@ async function writeClipboard(text) {
|
|
|
4646
4646
|
}
|
|
4647
4647
|
}
|
|
4648
4648
|
//#endregion
|
|
4649
|
-
//#region lib/types/
|
|
4650
|
-
/**
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
*
|
|
4654
|
-
*
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4649
|
+
//#region lib/types/HoverCardGroup.js
|
|
4650
|
+
/** Private coordination shared only by opted-in HoverCards inside one mounted group. */
|
|
4651
|
+
const HoverCardGroupContext = createContext(null);
|
|
4652
|
+
/**
|
|
4653
|
+
* Share first-display dwell across a list and its active portal, including the card's existing pointer grace.
|
|
4654
|
+
* @param props.children - list contents, including opted-in HoverCards.
|
|
4655
|
+
* @param props.className - classes for the physical list container.
|
|
4656
|
+
* @returns the list container and its private hover coordinator.
|
|
4657
|
+
*/
|
|
4658
|
+
function HoverCardGroup({ children, className }) {
|
|
4659
|
+
const [group] = useState(() => {
|
|
4660
|
+
let pointer = "outside";
|
|
4661
|
+
let warm = false;
|
|
4662
|
+
let active = null;
|
|
4663
|
+
return {
|
|
4664
|
+
isWarm: () => warm,
|
|
4665
|
+
enter: (overCard) => {
|
|
4666
|
+
pointer = overCard ? "card" : "list";
|
|
4667
|
+
if (overCard) warm = true;
|
|
4668
|
+
},
|
|
4669
|
+
leave: () => {
|
|
4670
|
+
pointer = "outside";
|
|
4671
|
+
if (active === null) warm = false;
|
|
4672
|
+
},
|
|
4673
|
+
containsCard: (target) => target instanceof Node && active !== null && active.element.contains(target),
|
|
4674
|
+
shown: (owner, dismiss, element) => {
|
|
4675
|
+
if (pointer === "card") {
|
|
4676
|
+
pointer = "outside";
|
|
4677
|
+
warm = false;
|
|
4678
|
+
}
|
|
4679
|
+
if (pointer === "list") warm = true;
|
|
4680
|
+
const previous = active;
|
|
4681
|
+
active = {
|
|
4682
|
+
owner,
|
|
4683
|
+
dismiss,
|
|
4684
|
+
element
|
|
4685
|
+
};
|
|
4686
|
+
if (previous !== null && previous.owner !== owner) previous.dismiss();
|
|
4687
|
+
},
|
|
4688
|
+
release: (owner) => {
|
|
4689
|
+
if (active?.owner !== owner) return;
|
|
4690
|
+
active = null;
|
|
4691
|
+
if (pointer !== "list") {
|
|
4692
|
+
pointer = "outside";
|
|
4693
|
+
warm = false;
|
|
4694
|
+
}
|
|
4695
|
+
}
|
|
4696
|
+
};
|
|
4697
|
+
});
|
|
4698
|
+
return jsx(HoverCardGroupContext.Provider, {
|
|
4699
|
+
value: group,
|
|
4700
|
+
children: jsx("div", {
|
|
4701
|
+
className,
|
|
4702
|
+
onPointerOverCapture: (event) => {
|
|
4703
|
+
const overCard = group.containsCard(event.target);
|
|
4704
|
+
if (event.currentTarget.contains(event.target) || overCard) group.enter(overCard);
|
|
4705
|
+
},
|
|
4706
|
+
onPointerOutCapture: (event) => {
|
|
4707
|
+
const fromGroup = event.currentTarget.contains(event.target) || group.containsCard(event.target);
|
|
4708
|
+
const intoGroup = event.relatedTarget instanceof Node && event.currentTarget.contains(event.relatedTarget) || group.containsCard(event.relatedTarget);
|
|
4709
|
+
if (fromGroup && !intoGroup) group.leave();
|
|
4710
|
+
},
|
|
4711
|
+
children
|
|
4712
|
+
})
|
|
4710
4713
|
});
|
|
4711
4714
|
}
|
|
4712
4715
|
//#endregion
|
|
4713
|
-
//#region lib/types/
|
|
4714
|
-
/**
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
const
|
|
4716
|
+
//#region lib/types/HoverCard.js
|
|
4717
|
+
/** Preview opacity transition and retained lifetime during dismissal. */
|
|
4718
|
+
const PREVIEW_FADE_MS = 100;
|
|
4719
|
+
const PREVIEW_MAX_HEIGHT = 420;
|
|
4720
|
+
const PREVIEW_INSET = 24;
|
|
4721
|
+
const INLINE_PREVIEW_WIDTH = 300;
|
|
4722
|
+
const ANCHOR_GAP = 8;
|
|
4723
|
+
const VIEWPORT_MARGIN = 8;
|
|
4720
4724
|
/**
|
|
4721
|
-
*
|
|
4722
|
-
* @param props.
|
|
4723
|
-
* @param props.
|
|
4724
|
-
*
|
|
4725
|
-
* @param props.
|
|
4726
|
-
*
|
|
4727
|
-
*
|
|
4728
|
-
* @param props.
|
|
4729
|
-
*
|
|
4730
|
-
* @param props.
|
|
4731
|
-
* @param props.
|
|
4732
|
-
*
|
|
4733
|
-
* @param props.
|
|
4734
|
-
*
|
|
4735
|
-
* @param props.
|
|
4736
|
-
*
|
|
4737
|
-
* @
|
|
4738
|
-
* half-viewport cap would render a slab wider than the surface the anchor sits on.
|
|
4739
|
-
* @param props.openOnClick - clicking also pins the bubble for reading; another click, Escape,
|
|
4740
|
-
* Tab, or an outside pointerdown dismisses it. Defaults to false for ordinary action tooltips.
|
|
4741
|
-
* @param props.children - a single anchor element; its own ref (callback or object) is forwarded alongside the tooltip's.
|
|
4742
|
-
* @returns the cloned anchor plus a fixed-position bubble, optionally portaled to the body.
|
|
4743
|
-
* The bubble stays hidden until ResizeObserver supplies its size for viewport fitting; clicking the
|
|
4744
|
-
* anchor dismisses the bubble unless openOnClick is enabled, and focus arriving after a pointer
|
|
4745
|
-
* interaction (a closing menu refocusing its trigger) never raises it.
|
|
4725
|
+
* Render an anchor with a hover-triggered preview card independently of nested tooltips.
|
|
4726
|
+
* @param props.anchor - the hover target (rendered in place inside a wrapper span).
|
|
4727
|
+
* @param props.content - card content; the pointer may rest on it, so it is
|
|
4728
|
+
* readable and selectable, but it carries no dismissal affordance of its own.
|
|
4729
|
+
* @param props.openDelayMs - hover dwell before the card shows (default 500).
|
|
4730
|
+
* @param props.variant - compact card beside the anchor, or a preview above/below it
|
|
4731
|
+
* with 24px side insets, a 420px height cap, frame-top clearance, and 100ms opacity transitions.
|
|
4732
|
+
* @param props.widthAnchorRef - optional element whose width and horizontal position size the preview.
|
|
4733
|
+
* @param props.inline - keep the anchor in prose; show a contained preview on hover or keyboard focus.
|
|
4734
|
+
* @param props.disabled - suppress opening; turning true dismisses an open card.
|
|
4735
|
+
* @param props.grouped - share first-display dwell across the surrounding list and active portal.
|
|
4736
|
+
* Group replacement removes the previous card immediately, including a fading preview.
|
|
4737
|
+
* @param props.copyText - optional primary value copied by activation and
|
|
4738
|
+
* included in the card's accessible name.
|
|
4739
|
+
* @param props.copyLabel - localized accessible activation-label prefix.
|
|
4740
|
+
* @param props.copiedLabel - localized visible success label.
|
|
4741
|
+
* @returns anchor wrapper with the conditional portaled card.
|
|
4746
4742
|
*/
|
|
4747
|
-
function
|
|
4748
|
-
const
|
|
4749
|
-
const
|
|
4750
|
-
const
|
|
4751
|
-
const
|
|
4752
|
-
const
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4743
|
+
function HoverCard({ anchor, content, openDelayMs = 500, disabled = false, grouped = false, copyText, copyLabel, copiedLabel, variant = "compact", widthAnchorRef, inline = false }) {
|
|
4744
|
+
const rootRef = useRef(null);
|
|
4745
|
+
const cardRef = useRef(null);
|
|
4746
|
+
const timerRef = useRef(null);
|
|
4747
|
+
const copyTimerRef = useRef(null);
|
|
4748
|
+
const copyHeightRef = useRef(null);
|
|
4749
|
+
const copyEpochRef = useRef(0);
|
|
4750
|
+
const copyingRef = useRef(false);
|
|
4751
|
+
const mountedRef = useRef(true);
|
|
4752
|
+
const [phase, setPhase] = useState("closed");
|
|
4753
|
+
const open = phase !== "closed";
|
|
4754
|
+
const closing = phase === "closing";
|
|
4757
4755
|
const [pos, setPos] = useState(null);
|
|
4758
|
-
const
|
|
4759
|
-
const
|
|
4760
|
-
const
|
|
4761
|
-
const
|
|
4762
|
-
const
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
}, [
|
|
4771
|
-
const
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4756
|
+
const positioned = pos !== null;
|
|
4757
|
+
const [copied, setCopied] = useState(false);
|
|
4758
|
+
const parentGroup = useContext(HoverCardGroupContext);
|
|
4759
|
+
const group = grouped ? parentGroup : null;
|
|
4760
|
+
const [groupOwner] = useState(() => Symbol("hover-card"));
|
|
4761
|
+
const clearCopied = useCallback(() => {
|
|
4762
|
+
if (copyTimerRef.current !== null) {
|
|
4763
|
+
clearTimeout(copyTimerRef.current);
|
|
4764
|
+
copyTimerRef.current = null;
|
|
4765
|
+
}
|
|
4766
|
+
copyHeightRef.current = null;
|
|
4767
|
+
setCopied(false);
|
|
4768
|
+
}, []);
|
|
4769
|
+
const close = useCallback(() => {
|
|
4770
|
+
copyEpochRef.current += 1;
|
|
4771
|
+
clearCopied();
|
|
4772
|
+
setPhase((current) => variant === "preview" && current !== "closed" ? "closing" : "closed");
|
|
4773
|
+
}, [clearCopied, variant]);
|
|
4774
|
+
const { arm: armClose, cancel: cancelClose } = usePointerGrace(close);
|
|
4775
|
+
const clearTimer = useCallback(() => {
|
|
4776
|
+
if (timerRef.current !== null) {
|
|
4777
|
+
clearTimeout(timerRef.current);
|
|
4778
|
+
timerRef.current = null;
|
|
4779
|
+
}
|
|
4780
|
+
}, []);
|
|
4781
|
+
const dismissImmediately = useCallback(() => {
|
|
4782
|
+
clearTimer();
|
|
4783
|
+
cancelClose();
|
|
4784
|
+
copyEpochRef.current += 1;
|
|
4785
|
+
clearCopied();
|
|
4786
|
+
setPhase("closed");
|
|
4787
|
+
}, [
|
|
4788
|
+
clearTimer,
|
|
4789
|
+
cancelClose,
|
|
4790
|
+
clearCopied
|
|
4791
|
+
]);
|
|
4792
|
+
const groupVisible = open && positioned;
|
|
4793
|
+
useLayoutEffect(() => {
|
|
4794
|
+
if (!groupVisible || group === null) return;
|
|
4795
|
+
group.shown(groupOwner, dismissImmediately, cardRef.current);
|
|
4798
4796
|
return () => {
|
|
4799
|
-
|
|
4800
|
-
window.removeEventListener("resize", fit);
|
|
4797
|
+
group.release(groupOwner);
|
|
4801
4798
|
};
|
|
4802
4799
|
}, [
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
suppressed,
|
|
4808
|
-
visible
|
|
4800
|
+
group,
|
|
4801
|
+
groupOwner,
|
|
4802
|
+
groupVisible,
|
|
4803
|
+
dismissImmediately
|
|
4809
4804
|
]);
|
|
4810
4805
|
useEffect(() => {
|
|
4811
|
-
|
|
4806
|
+
if (!closing) return;
|
|
4807
|
+
const timer = setTimeout(() => {
|
|
4808
|
+
setPhase("closed");
|
|
4809
|
+
}, PREVIEW_FADE_MS);
|
|
4812
4810
|
return () => {
|
|
4813
|
-
|
|
4811
|
+
clearTimeout(timer);
|
|
4814
4812
|
};
|
|
4815
|
-
}, [
|
|
4816
|
-
const cancelShow = useCallback(() => {
|
|
4817
|
-
if (showTimer.current === null) return;
|
|
4818
|
-
clearTimeout(showTimer.current);
|
|
4819
|
-
showTimer.current = null;
|
|
4820
|
-
}, []);
|
|
4813
|
+
}, [closing]);
|
|
4821
4814
|
useEffect(() => {
|
|
4822
|
-
if (
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
hover: false,
|
|
4827
|
-
focus: false
|
|
4828
|
-
};
|
|
4829
|
-
setPos(null);
|
|
4830
|
-
}
|
|
4831
|
-
return cancelShow;
|
|
4832
|
-
}, [
|
|
4833
|
-
cancelShow,
|
|
4834
|
-
disabled,
|
|
4835
|
-
openOnClick,
|
|
4836
|
-
pinned
|
|
4837
|
-
]);
|
|
4838
|
-
const show = () => {
|
|
4839
|
-
if (disabled) return;
|
|
4840
|
-
const el = anchor.current;
|
|
4841
|
-
/* v8 ignore next -- the ref is attached by event time: events fire on the cloned anchor. */
|
|
4842
|
-
if (el === null) return;
|
|
4843
|
-
const r = el.getBoundingClientRect();
|
|
4844
|
-
setPos({
|
|
4845
|
-
x: side === "right" ? r.right + 10 : align === "end" ? r.right : r.left + r.width / 2,
|
|
4846
|
-
top: r.top,
|
|
4847
|
-
bottom: r.bottom
|
|
4848
|
-
});
|
|
4849
|
-
announce(true);
|
|
4850
|
-
};
|
|
4851
|
-
const showAfterDelay = (delay) => {
|
|
4852
|
-
cancelShow();
|
|
4853
|
-
if (delay <= 0) {
|
|
4854
|
-
show();
|
|
4855
|
-
return;
|
|
4856
|
-
}
|
|
4857
|
-
showTimer.current = setTimeout(() => {
|
|
4858
|
-
showTimer.current = null;
|
|
4859
|
-
show();
|
|
4860
|
-
}, delay);
|
|
4861
|
-
};
|
|
4862
|
-
const withdraw = useCallback(() => {
|
|
4863
|
-
setPinned(false);
|
|
4864
|
-
setPos(null);
|
|
4865
|
-
announce(false);
|
|
4866
|
-
}, [announce]);
|
|
4867
|
-
const hide = () => {
|
|
4868
|
-
cancelShow();
|
|
4869
|
-
if (!triggers.current.hover && !triggers.current.focus && !pinned) withdraw();
|
|
4870
|
-
};
|
|
4871
|
-
const dismiss = useCallback(() => {
|
|
4872
|
-
cancelShow();
|
|
4873
|
-
triggers.current = {
|
|
4874
|
-
hover: false,
|
|
4875
|
-
focus: false
|
|
4876
|
-
};
|
|
4877
|
-
withdraw();
|
|
4878
|
-
}, [cancelShow, withdraw]);
|
|
4879
|
-
useDismissOnOutsidePointer(anchor, openOnClick && visible, dismiss, bubble);
|
|
4880
|
-
useEffect(() => {
|
|
4881
|
-
if (!openOnClick || !visible) return;
|
|
4882
|
-
const onKeyDown = (event) => {
|
|
4883
|
-
if (event.key !== "Escape" && event.key !== "Tab") return;
|
|
4884
|
-
if (event.key === "Escape") {
|
|
4885
|
-
event.preventDefault();
|
|
4886
|
-
event.stopPropagation();
|
|
4887
|
-
}
|
|
4888
|
-
dismiss();
|
|
4889
|
-
};
|
|
4890
|
-
document.addEventListener("keydown", onKeyDown, true);
|
|
4891
|
-
return () => {
|
|
4892
|
-
document.removeEventListener("keydown", onKeyDown, true);
|
|
4893
|
-
};
|
|
4894
|
-
}, [
|
|
4895
|
-
dismiss,
|
|
4896
|
-
openOnClick,
|
|
4897
|
-
visible
|
|
4898
|
-
]);
|
|
4899
|
-
const content = visible && !suppressed && jsxs("span", {
|
|
4900
|
-
ref: bubble,
|
|
4901
|
-
id: openOnClick ? id : void 0,
|
|
4902
|
-
className: css$17.bubble,
|
|
4903
|
-
"data-side": side,
|
|
4904
|
-
"data-portal": portal || void 0,
|
|
4905
|
-
"data-pinned": pinned || void 0,
|
|
4906
|
-
"data-align": align,
|
|
4907
|
-
"data-has-shortcut": shortcutKeys?.length ? true : void 0,
|
|
4908
|
-
style: {
|
|
4909
|
-
left: pos.x,
|
|
4910
|
-
top: y,
|
|
4911
|
-
visibility: "hidden",
|
|
4912
|
-
...maxWidth === void 0 ? {} : { maxWidth }
|
|
4913
|
-
},
|
|
4914
|
-
role: "tooltip",
|
|
4915
|
-
"aria-label": shortcutKeys?.length ? [resolvedLabel, shortcutKeys.join(" ")].filter(Boolean).join(" ") : void 0,
|
|
4916
|
-
children: [resolvedLabel && jsx("span", {
|
|
4917
|
-
className: css$17.label,
|
|
4918
|
-
children: resolvedLabel
|
|
4919
|
-
}), shortcutKeys !== void 0 && shortcutKeys.length > 0 && jsx(ShortcutKeys, {
|
|
4920
|
-
keys: shortcutKeys,
|
|
4921
|
-
variant: "tooltip"
|
|
4922
|
-
})]
|
|
4923
|
-
});
|
|
4924
|
-
return jsxs(TooltipSuppression.Provider, {
|
|
4925
|
-
value: setSuppressed,
|
|
4926
|
-
children: [cloneElement(children, {
|
|
4927
|
-
ref: mergedRef,
|
|
4928
|
-
"aria-describedby": openOnClick && visible ? [children.props["aria-describedby"], id].filter(Boolean).join(" ") : children.props["aria-describedby"],
|
|
4929
|
-
onMouseEnter: (e) => {
|
|
4930
|
-
children.props.onMouseEnter?.(e);
|
|
4931
|
-
triggers.current.hover = true;
|
|
4932
|
-
showAfterDelay(delayMs);
|
|
4933
|
-
},
|
|
4934
|
-
onMouseLeave: (e) => {
|
|
4935
|
-
children.props.onMouseLeave?.(e);
|
|
4936
|
-
triggers.current.hover = false;
|
|
4937
|
-
cancelShow();
|
|
4938
|
-
if (!pinned) withdraw();
|
|
4939
|
-
},
|
|
4940
|
-
onClick: (e) => {
|
|
4941
|
-
children.props.onClick?.(e);
|
|
4942
|
-
triggers.current.focus = false;
|
|
4943
|
-
cancelShow();
|
|
4944
|
-
if (openOnClick && !disabled && !pinned) {
|
|
4945
|
-
setPinned(true);
|
|
4946
|
-
show();
|
|
4947
|
-
} else withdraw();
|
|
4948
|
-
},
|
|
4949
|
-
onFocus: (e) => {
|
|
4950
|
-
children.props.onFocus?.(e);
|
|
4951
|
-
if (pointerModality()) return;
|
|
4952
|
-
triggers.current.focus = true;
|
|
4953
|
-
showAfterDelay(focusDelayMs);
|
|
4954
|
-
},
|
|
4955
|
-
onBlur: (e) => {
|
|
4956
|
-
children.props.onBlur?.(e);
|
|
4957
|
-
triggers.current.focus = false;
|
|
4958
|
-
hide();
|
|
4959
|
-
}
|
|
4960
|
-
}), portal ? content !== false && createPortal(content, document.body) : content]
|
|
4961
|
-
});
|
|
4962
|
-
}
|
|
4963
|
-
//#endregion
|
|
4964
|
-
//#region lib/types/HoverCard.js
|
|
4965
|
-
/** Preview opacity transition and retained lifetime during dismissal. */
|
|
4966
|
-
const PREVIEW_FADE_MS = 100;
|
|
4967
|
-
const PREVIEW_MAX_HEIGHT = 420;
|
|
4968
|
-
const PREVIEW_INSET = 24;
|
|
4969
|
-
const INLINE_PREVIEW_WIDTH = 300;
|
|
4970
|
-
const ANCHOR_GAP = 8;
|
|
4971
|
-
const VIEWPORT_MARGIN = 8;
|
|
4972
|
-
/**
|
|
4973
|
-
* Render an anchor with a hover-triggered preview card, hidden while a tooltip within the anchor is visible.
|
|
4974
|
-
* @param props.anchor - the hover target (rendered in place inside a wrapper span).
|
|
4975
|
-
* @param props.content - card content; the pointer may rest on it, so it is
|
|
4976
|
-
* readable and selectable, but it carries no dismissal affordance of its own.
|
|
4977
|
-
* @param props.openDelayMs - hover dwell before the card shows (default 500).
|
|
4978
|
-
* @param props.variant - compact card beside the anchor, or a preview above/below it
|
|
4979
|
-
* with 24px side insets, a 420px height cap, frame-top clearance, and 100ms opacity transitions.
|
|
4980
|
-
* @param props.widthAnchorRef - optional element whose width and horizontal position size the preview.
|
|
4981
|
-
* @param props.inline - keep the anchor in prose; show a contained preview on hover or keyboard focus.
|
|
4982
|
-
* @param props.disabled - suppress opening; turning true dismisses an open card.
|
|
4983
|
-
* @param props.copyText - optional primary value copied by activation and
|
|
4984
|
-
* included in the card's accessible name.
|
|
4985
|
-
* @param props.copyLabel - localized accessible activation-label prefix.
|
|
4986
|
-
* @param props.copiedLabel - localized visible success label.
|
|
4987
|
-
* @returns anchor wrapper with the conditional portaled card.
|
|
4988
|
-
*/
|
|
4989
|
-
function HoverCard({ anchor, content, openDelayMs = 500, disabled = false, copyText, copyLabel, copiedLabel, variant = "compact", widthAnchorRef, inline = false }) {
|
|
4990
|
-
const rootRef = useRef(null);
|
|
4991
|
-
const cardRef = useRef(null);
|
|
4992
|
-
const timerRef = useRef(null);
|
|
4993
|
-
const copyTimerRef = useRef(null);
|
|
4994
|
-
const copyHeightRef = useRef(null);
|
|
4995
|
-
const copyEpochRef = useRef(0);
|
|
4996
|
-
const copyingRef = useRef(false);
|
|
4997
|
-
const mountedRef = useRef(true);
|
|
4998
|
-
const [phase, setPhase] = useState("closed");
|
|
4999
|
-
const open = phase !== "closed";
|
|
5000
|
-
const closing = phase === "closing";
|
|
5001
|
-
const [pos, setPos] = useState(null);
|
|
5002
|
-
const positioned = pos !== null;
|
|
5003
|
-
const [copied, setCopied] = useState(false);
|
|
5004
|
-
const [suppressed, setSuppressed] = useState(false);
|
|
5005
|
-
const clearCopied = useCallback(() => {
|
|
5006
|
-
if (copyTimerRef.current !== null) {
|
|
5007
|
-
clearTimeout(copyTimerRef.current);
|
|
5008
|
-
copyTimerRef.current = null;
|
|
5009
|
-
}
|
|
5010
|
-
copyHeightRef.current = null;
|
|
5011
|
-
setCopied(false);
|
|
5012
|
-
}, []);
|
|
5013
|
-
const close = useCallback(() => {
|
|
5014
|
-
copyEpochRef.current += 1;
|
|
5015
|
-
clearCopied();
|
|
5016
|
-
setPhase((current) => variant === "preview" && current !== "closed" ? "closing" : "closed");
|
|
5017
|
-
}, [clearCopied, variant]);
|
|
5018
|
-
const { arm: armClose, cancel: cancelClose } = usePointerGrace(close);
|
|
5019
|
-
const clearTimer = () => {
|
|
5020
|
-
if (timerRef.current !== null) {
|
|
5021
|
-
clearTimeout(timerRef.current);
|
|
5022
|
-
timerRef.current = null;
|
|
5023
|
-
}
|
|
5024
|
-
};
|
|
5025
|
-
useEffect(() => {
|
|
5026
|
-
if (!closing) return;
|
|
5027
|
-
const timer = setTimeout(() => {
|
|
5028
|
-
setPhase("closed");
|
|
5029
|
-
}, PREVIEW_FADE_MS);
|
|
5030
|
-
return () => {
|
|
5031
|
-
clearTimeout(timer);
|
|
5032
|
-
};
|
|
5033
|
-
}, [closing]);
|
|
5034
|
-
useEffect(() => {
|
|
5035
|
-
if (!disabled) return;
|
|
5036
|
-
clearTimer();
|
|
5037
|
-
cancelClose();
|
|
5038
|
-
close();
|
|
4815
|
+
if (!disabled) return;
|
|
4816
|
+
clearTimer();
|
|
4817
|
+
cancelClose();
|
|
4818
|
+
close();
|
|
5039
4819
|
}, [
|
|
5040
4820
|
disabled,
|
|
5041
4821
|
cancelClose,
|
|
@@ -5146,7 +4926,7 @@ function HoverCard({ anchor, content, openDelayMs = 500, disabled = false, copyT
|
|
|
5146
4926
|
inline
|
|
5147
4927
|
]);
|
|
5148
4928
|
useLayoutEffect(() => {
|
|
5149
|
-
if (!open || pos === null || variant === "preview" || inline
|
|
4929
|
+
if (!open || pos === null || variant === "preview" || inline) return;
|
|
5150
4930
|
/* v8 ignore next -- the card is mounted whenever pos is set, so the ref is attached here. */
|
|
5151
4931
|
const h = cardRef.current?.offsetHeight ?? 0;
|
|
5152
4932
|
if (pos.top + h > window.innerHeight - VIEWPORT_MARGIN) setPos({
|
|
@@ -5157,8 +4937,7 @@ function HoverCard({ anchor, content, openDelayMs = 500, disabled = false, copyT
|
|
|
5157
4937
|
open,
|
|
5158
4938
|
pos,
|
|
5159
4939
|
variant,
|
|
5160
|
-
inline
|
|
5161
|
-
suppressed
|
|
4940
|
+
inline
|
|
5162
4941
|
]);
|
|
5163
4942
|
const copy = async (text) => {
|
|
5164
4943
|
if (copied || copyingRef.current) return;
|
|
@@ -5180,9 +4959,9 @@ function HoverCard({ anchor, content, openDelayMs = 500, disabled = false, copyT
|
|
|
5180
4959
|
cancelClose();
|
|
5181
4960
|
close();
|
|
5182
4961
|
};
|
|
5183
|
-
const card = open && pos !== null &&
|
|
4962
|
+
const card = open && pos !== null && jsx("div", {
|
|
5184
4963
|
ref: cardRef,
|
|
5185
|
-
className: clsx(css$
|
|
4964
|
+
className: clsx(css$17.card, variant === "preview" && css$17.preview, inline && css$17.media, copyable && css$17.copyable, copied && css$17.feedback),
|
|
5186
4965
|
"data-closing": closing || void 0,
|
|
5187
4966
|
style: {
|
|
5188
4967
|
...pos,
|
|
@@ -5205,14 +4984,14 @@ function HoverCard({ anchor, content, openDelayMs = 500, disabled = false, copyT
|
|
|
5205
4984
|
copy(copyText);
|
|
5206
4985
|
} : void 0,
|
|
5207
4986
|
children: copied ? jsx("span", {
|
|
5208
|
-
className: css$
|
|
4987
|
+
className: css$17.copied,
|
|
5209
4988
|
"aria-hidden": "true",
|
|
5210
4989
|
children: copiedLabel
|
|
5211
4990
|
}) : content
|
|
5212
4991
|
});
|
|
5213
4992
|
return jsxs("span", {
|
|
5214
4993
|
ref: rootRef,
|
|
5215
|
-
className: clsx(css$
|
|
4994
|
+
className: clsx(css$17.root, inline && css$17.inline),
|
|
5216
4995
|
onFocus: inline ? (event) => {
|
|
5217
4996
|
if (!disabled && event.target.matches(":focus-visible")) {
|
|
5218
4997
|
cancelClose();
|
|
@@ -5234,7 +5013,8 @@ function HoverCard({ anchor, content, openDelayMs = 500, disabled = false, copyT
|
|
|
5234
5013
|
return;
|
|
5235
5014
|
}
|
|
5236
5015
|
clearTimer();
|
|
5237
|
-
|
|
5016
|
+
if (group?.isWarm()) setPhase("open");
|
|
5017
|
+
else timerRef.current = setTimeout(() => {
|
|
5238
5018
|
setPhase("open");
|
|
5239
5019
|
}, openDelayMs);
|
|
5240
5020
|
},
|
|
@@ -5245,12 +5025,9 @@ function HoverCard({ anchor, content, openDelayMs = 500, disabled = false, copyT
|
|
|
5245
5025
|
onPointerDownCapture: dismissFromAnchor,
|
|
5246
5026
|
onClickCapture: dismissFromAnchor,
|
|
5247
5027
|
children: [
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
}),
|
|
5252
|
-
open && !suppressed && copyable && jsx("span", {
|
|
5253
|
-
className: css$18.status,
|
|
5028
|
+
anchor,
|
|
5029
|
+
open && copyable && jsx("span", {
|
|
5030
|
+
className: css$17.status,
|
|
5254
5031
|
role: "status",
|
|
5255
5032
|
children: copied ? copiedLabel : ""
|
|
5256
5033
|
}),
|
|
@@ -5285,11 +5062,11 @@ function Modal({ open, onClose, title, closeLabel, description, children, footer
|
|
|
5285
5062
|
useModalLayer(dialog, open, onClose);
|
|
5286
5063
|
if (!open) return null;
|
|
5287
5064
|
return createPortal(jsxs("div", {
|
|
5288
|
-
className: css$
|
|
5065
|
+
className: css$18.root,
|
|
5289
5066
|
role: "presentation",
|
|
5290
5067
|
onKeyDownCapture,
|
|
5291
5068
|
children: [jsx("div", {
|
|
5292
|
-
className: css$
|
|
5069
|
+
className: css$18.mask,
|
|
5293
5070
|
style: backdropBlur ? void 0 : { backdropFilter: "none" },
|
|
5294
5071
|
"aria-hidden": "true",
|
|
5295
5072
|
onClick: onClose
|
|
@@ -5297,37 +5074,37 @@ function Modal({ open, onClose, title, closeLabel, description, children, footer
|
|
|
5297
5074
|
ref: dialog,
|
|
5298
5075
|
tabIndex: -1,
|
|
5299
5076
|
"data-shortcut-modal": shortcutModal,
|
|
5300
|
-
className: clsx(css$
|
|
5077
|
+
className: clsx(css$18.dialog, className),
|
|
5301
5078
|
role: "dialog",
|
|
5302
5079
|
"aria-modal": "true",
|
|
5303
5080
|
"aria-label": title,
|
|
5304
5081
|
children: headless ? children : jsxs(Fragment, { children: [jsxs("div", {
|
|
5305
|
-
className: clsx(css$
|
|
5082
|
+
className: clsx(css$18.content, contentClassName),
|
|
5306
5083
|
children: [
|
|
5307
5084
|
jsxs("div", {
|
|
5308
|
-
className: css$
|
|
5085
|
+
className: css$18.header,
|
|
5309
5086
|
children: [jsx("h2", {
|
|
5310
|
-
className: css$
|
|
5087
|
+
className: css$18.title,
|
|
5311
5088
|
children: title
|
|
5312
5089
|
}), jsx("button", {
|
|
5313
5090
|
type: "button",
|
|
5314
|
-
className: css$
|
|
5091
|
+
className: css$18.close,
|
|
5315
5092
|
"aria-label": closeLabel,
|
|
5316
5093
|
onClick: onClose,
|
|
5317
5094
|
children: jsx(IconCloseOutlineRegular, { size: 14 })
|
|
5318
5095
|
})]
|
|
5319
5096
|
}),
|
|
5320
5097
|
description !== void 0 && description !== "" && jsx("p", {
|
|
5321
|
-
className: css$
|
|
5098
|
+
className: css$18.description,
|
|
5322
5099
|
children: description
|
|
5323
5100
|
}),
|
|
5324
5101
|
children !== void 0 && jsx("div", {
|
|
5325
|
-
className: css$
|
|
5102
|
+
className: css$18.body,
|
|
5326
5103
|
children
|
|
5327
5104
|
})
|
|
5328
5105
|
]
|
|
5329
5106
|
}), footer !== void 0 && jsx("div", {
|
|
5330
|
-
className: css$
|
|
5107
|
+
className: css$18.footer,
|
|
5331
5108
|
children: footer
|
|
5332
5109
|
})] })
|
|
5333
5110
|
})]
|
|
@@ -5349,28 +5126,28 @@ function RiskConfirmation({ open, title, description, acknowledgeLabel, cancelLa
|
|
|
5349
5126
|
onClose: onCancel,
|
|
5350
5127
|
title,
|
|
5351
5128
|
closeLabel,
|
|
5352
|
-
className: css$
|
|
5353
|
-
contentClassName: css$
|
|
5129
|
+
className: css$19.confirmation ?? "",
|
|
5130
|
+
contentClassName: css$19.confirmationContent ?? "",
|
|
5354
5131
|
footer: jsxs(Fragment, { children: [jsx(Button, {
|
|
5355
5132
|
variant: "outline",
|
|
5356
|
-
className: css$
|
|
5133
|
+
className: css$19.modalAction,
|
|
5357
5134
|
onClick: onCancel,
|
|
5358
5135
|
children: cancelLabel
|
|
5359
5136
|
}), jsx(Button, {
|
|
5360
5137
|
variant: "primary",
|
|
5361
|
-
className: css$
|
|
5138
|
+
className: css$19.confirmAction,
|
|
5362
5139
|
disabled: disabled || !acknowledged,
|
|
5363
5140
|
onClick: onConfirm,
|
|
5364
5141
|
children: confirmLabel
|
|
5365
5142
|
})] }),
|
|
5366
5143
|
children: [jsxs("div", {
|
|
5367
|
-
className: css$
|
|
5144
|
+
className: css$19.warning,
|
|
5368
5145
|
children: [jsx(IconWarningOutlineRegular, {
|
|
5369
5146
|
size: 18,
|
|
5370
|
-
className: css$
|
|
5147
|
+
className: css$19.warningIcon
|
|
5371
5148
|
}), jsx("p", { children: description })]
|
|
5372
5149
|
}), jsxs("label", {
|
|
5373
|
-
className: css$
|
|
5150
|
+
className: css$19.acknowledgement,
|
|
5374
5151
|
children: [jsx("input", {
|
|
5375
5152
|
type: "checkbox",
|
|
5376
5153
|
checked: acknowledged,
|
|
@@ -5418,44 +5195,44 @@ function ConnectionIndicator({ state, disconnectedLabel, connectingLabel, recove
|
|
|
5418
5195
|
};
|
|
5419
5196
|
}, [state, rendered]);
|
|
5420
5197
|
if (rendered === void 0) return null;
|
|
5421
|
-
const leavingClass = leaving ? ` ${css$
|
|
5198
|
+
const leavingClass = leaving ? ` ${css$20.leaving}` : "";
|
|
5422
5199
|
if (rendered === "recovered") return jsxs("div", {
|
|
5423
|
-
className: `${css$
|
|
5200
|
+
className: `${css$20.indicator} ${css$20.success}${leavingClass}`,
|
|
5424
5201
|
role: "status",
|
|
5425
5202
|
"aria-label": recoveredLabel,
|
|
5426
5203
|
children: [jsx("span", {
|
|
5427
|
-
className: css$
|
|
5204
|
+
className: css$20.icon,
|
|
5428
5205
|
"aria-hidden": "true",
|
|
5429
5206
|
children: jsx(IconCheckOutlineRegular, { size: 14 })
|
|
5430
5207
|
}), jsx("span", {
|
|
5431
|
-
className: css$
|
|
5208
|
+
className: css$20.label,
|
|
5432
5209
|
children: recoveredLabel
|
|
5433
5210
|
})]
|
|
5434
5211
|
});
|
|
5435
5212
|
const connecting = rendered === "connecting";
|
|
5436
5213
|
return jsxs("button", {
|
|
5437
5214
|
type: "button",
|
|
5438
|
-
className: `${css$
|
|
5215
|
+
className: `${css$20.indicator} ${css$20.warning}${leavingClass}`,
|
|
5439
5216
|
"data-phase": rendered,
|
|
5440
5217
|
"aria-label": connecting ? restartActionLabel : reconnectActionLabel,
|
|
5441
5218
|
onClick: onReconnect,
|
|
5442
5219
|
children: [jsx("span", {
|
|
5443
|
-
className: css$
|
|
5220
|
+
className: css$20.icon,
|
|
5444
5221
|
"aria-hidden": "true",
|
|
5445
5222
|
children: connecting ? jsx(StateDot, { state: "ongoing" }) : jsx(IconRefreshOutlineRegular, { size: 14 })
|
|
5446
5223
|
}), jsx("span", {
|
|
5447
|
-
className: css$
|
|
5224
|
+
className: css$20.label,
|
|
5448
5225
|
children: connecting ? jsxs(Fragment, { children: [connectingLabel, jsxs("span", {
|
|
5449
|
-
className: css$
|
|
5226
|
+
className: css$20.dots,
|
|
5450
5227
|
"aria-hidden": "true",
|
|
5451
5228
|
children: [
|
|
5452
5229
|
jsx("span", { children: "." }),
|
|
5453
5230
|
jsx("span", {
|
|
5454
|
-
className: css$
|
|
5231
|
+
className: css$20.secondDot,
|
|
5455
5232
|
children: "."
|
|
5456
5233
|
}),
|
|
5457
5234
|
jsx("span", {
|
|
5458
|
-
className: css$
|
|
5235
|
+
className: css$20.thirdDot,
|
|
5459
5236
|
children: "."
|
|
5460
5237
|
})
|
|
5461
5238
|
]
|
|
@@ -5697,6 +5474,28 @@ function FullAccessArtwork({ size = 16, className, strokeWidth }) {
|
|
|
5697
5474
|
]
|
|
5698
5475
|
});
|
|
5699
5476
|
}
|
|
5477
|
+
function AutoReviewArtwork({ size = 16, className, strokeWidth }) {
|
|
5478
|
+
return jsxs("svg", {
|
|
5479
|
+
width: size,
|
|
5480
|
+
height: size,
|
|
5481
|
+
className,
|
|
5482
|
+
viewBox: "0 0 16 16",
|
|
5483
|
+
fill: "none",
|
|
5484
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5485
|
+
"aria-hidden": "true",
|
|
5486
|
+
strokeWidth,
|
|
5487
|
+
children: [jsx("path", {
|
|
5488
|
+
d: "M6.59624 2.14853C7.50155 1.80917 8.49914 1.80919 9.40444 2.14859L13.9245 3.84317V7.11961C13.9245 11.6089 10.5565 13.5975 8.00035 14.5779C5.44423 13.5975 2.07544 11.6089 2.07544 7.11961V3.84317L6.59624 2.14853Z",
|
|
5489
|
+
stroke: "currentColor",
|
|
5490
|
+
strokeLinejoin: "round"
|
|
5491
|
+
}), jsx("path", {
|
|
5492
|
+
d: "M5.75 10.15L8 4.95L10.25 10.15M6.43 8.59H9.57",
|
|
5493
|
+
stroke: "currentColor",
|
|
5494
|
+
strokeLinecap: "round",
|
|
5495
|
+
strokeLinejoin: "round"
|
|
5496
|
+
})]
|
|
5497
|
+
});
|
|
5498
|
+
}
|
|
5700
5499
|
/**
|
|
5701
5500
|
* Render the read-only permission icon with a one-pixel stroke.
|
|
5702
5501
|
* @param props - Size and optional class.
|
|
@@ -5763,6 +5562,28 @@ function PermissionIconFullAccessMedium(props) {
|
|
|
5763
5562
|
strokeWidth: ICON_MEDIUM_STROKE
|
|
5764
5563
|
});
|
|
5765
5564
|
}
|
|
5565
|
+
/**
|
|
5566
|
+
* Render the auto-review permission icon with a one-pixel stroke.
|
|
5567
|
+
* @param props - Size and optional class.
|
|
5568
|
+
* @returns The regular decorative permission glyph.
|
|
5569
|
+
*/
|
|
5570
|
+
function PermissionIconAutoReviewRegular(props) {
|
|
5571
|
+
return jsx(AutoReviewArtwork, {
|
|
5572
|
+
...props,
|
|
5573
|
+
strokeWidth: 1
|
|
5574
|
+
});
|
|
5575
|
+
}
|
|
5576
|
+
/**
|
|
5577
|
+
* Render the auto-review permission icon with a 1.3px stroke.
|
|
5578
|
+
* @param props - Size and optional class.
|
|
5579
|
+
* @returns The medium decorative permission glyph.
|
|
5580
|
+
*/
|
|
5581
|
+
function PermissionIconAutoReviewMedium(props) {
|
|
5582
|
+
return jsx(AutoReviewArtwork, {
|
|
5583
|
+
...props,
|
|
5584
|
+
strokeWidth: ICON_MEDIUM_STROKE
|
|
5585
|
+
});
|
|
5586
|
+
}
|
|
5766
5587
|
//#endregion
|
|
5767
5588
|
//#region lib/types/ReferenceIcon.js
|
|
5768
5589
|
/**
|
|
@@ -6486,7 +6307,7 @@ function FileTypeIcon(props) {
|
|
|
6486
6307
|
type: resolvedType,
|
|
6487
6308
|
size,
|
|
6488
6309
|
className
|
|
6489
|
-
}) : glyph(resolvedType, size, clsx(css$
|
|
6310
|
+
}) : glyph(resolvedType, size, clsx(css$21.icon, css$21[resolvedType], className));
|
|
6490
6311
|
}
|
|
6491
6312
|
//#endregion
|
|
6492
6313
|
//#region lib/types/SiteGlyph.js
|
|
@@ -6755,111 +6576,362 @@ function LinkIconMedium(props) {
|
|
|
6755
6576
|
}
|
|
6756
6577
|
//#endregion
|
|
6757
6578
|
//#region lib/types/user-text.js
|
|
6758
|
-
/**
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
* @param slashNames - names a `/name` token may decorate as: the skills the
|
|
6767
|
-
* host loaded for this message, or the command a command bubble echoes
|
|
6768
|
-
* (unsent queue rows pass none).
|
|
6769
|
-
* @param slashKind - the chip kind those tokens render as.
|
|
6770
|
-
* @param references - optional file and skill preview actions; session and command tokens stay labels.
|
|
6771
|
-
* @returns inline nodes covering the whole text.
|
|
6772
|
-
*/
|
|
6773
|
-
function projectUserText(text, sessionLabels, slashNames = [], slashKind = "skill", references) {
|
|
6774
|
-
const ranges = [];
|
|
6775
|
-
SESSION_WIRE_RE.lastIndex = 0;
|
|
6776
|
-
let wire;
|
|
6777
|
-
while ((wire = SESSION_WIRE_RE.exec(text)) !== null) ranges.push({
|
|
6778
|
-
start: wire.index,
|
|
6779
|
-
end: wire.index + wire[0].length,
|
|
6780
|
-
label: wire[0],
|
|
6781
|
-
kind: "session",
|
|
6782
|
-
display: wire[1]
|
|
6783
|
-
});
|
|
6784
|
-
for (const rawLabel of [...new Set(sessionLabels)].sort((a, b) => b.length - a.length)) {
|
|
6785
|
-
const label = `@${rawLabel}`;
|
|
6786
|
-
let start = text.indexOf(label);
|
|
6787
|
-
while (start >= 0) {
|
|
6788
|
-
ranges.push({
|
|
6789
|
-
start,
|
|
6790
|
-
end: start + label.length,
|
|
6791
|
-
label,
|
|
6792
|
-
kind: "session"
|
|
6793
|
-
});
|
|
6794
|
-
start = text.indexOf(label, start + label.length);
|
|
6795
|
-
}
|
|
6796
|
-
}
|
|
6797
|
-
const re = /(^|\s)(\/[\w-]+(?=\s|$)|@"[^"\n]+"|@[^\s]+)/gu;
|
|
6798
|
-
let m;
|
|
6799
|
-
while ((m = re.exec(text)) !== null) {
|
|
6800
|
-
const tokenStart = m.index + m[1].length;
|
|
6801
|
-
const rawLabel = m[2];
|
|
6802
|
-
const label = rawLabel.startsWith("@\"") ? rawLabel : rawLabel.replace(TRAILING_PUNCTUATION_RE, "");
|
|
6803
|
-
if (label.length <= 1) continue;
|
|
6804
|
-
if (label.startsWith("/") && !slashNames.includes(label.slice(1))) continue;
|
|
6805
|
-
ranges.push({
|
|
6806
|
-
start: tokenStart,
|
|
6807
|
-
end: tokenStart + label.length,
|
|
6808
|
-
label,
|
|
6809
|
-
kind: "plain"
|
|
6810
|
-
});
|
|
6811
|
-
}
|
|
6812
|
-
const rankOf = (range) => range.kind === "session" ? 0 : 1;
|
|
6813
|
-
ranges.sort((a, b) => a.start - b.start || rankOf(a) - rankOf(b) || b.end - a.end);
|
|
6814
|
-
const parts = [];
|
|
6815
|
-
let cursor = 0;
|
|
6816
|
-
const pushPlain = (from, to) => {
|
|
6817
|
-
parts.push(jsx("span", {
|
|
6818
|
-
className: css$23.plainRun,
|
|
6819
|
-
children: text.slice(from, to)
|
|
6820
|
-
}, `t${from}`));
|
|
6821
|
-
};
|
|
6822
|
-
for (const range of ranges) {
|
|
6823
|
-
if (range.start < cursor) continue;
|
|
6824
|
-
const { start: tokenStart, end, label, kind } = range;
|
|
6825
|
-
if (tokenStart > cursor) pushPlain(cursor, tokenStart);
|
|
6826
|
-
const referenceKind = kind === "session" ? "session" : label.startsWith("@") ? label.replace(/^@"|"$/gu, "").endsWith("/") ? "folder" : "file" : void 0;
|
|
6827
|
-
const displayLabel = range.display ?? (referenceKind === void 0 ? label : referenceKind === "session" ? label.slice(1) : label.slice(1).replace(/^"|"$/gu, "").split(/[\\/]/u).filter(Boolean).at(-1) ?? label.slice(1));
|
|
6828
|
-
const contents = jsxs(Fragment, { children: [referenceKind !== void 0 && jsx(ReferenceIconRegular, {
|
|
6829
|
-
kind: referenceKind,
|
|
6830
|
-
size: 16,
|
|
6831
|
-
className: css$23.refIcon
|
|
6832
|
-
}), displayLabel] });
|
|
6833
|
-
const open = references === void 0 ? void 0 : referenceKind === "file" ? () => {
|
|
6834
|
-
references.openFile(label.slice(1).replace(/^"|"$/gu, ""));
|
|
6835
|
-
} : referenceKind === void 0 && slashKind === "skill" ? () => {
|
|
6836
|
-
references.openSkill(label.slice(1));
|
|
6837
|
-
} : void 0;
|
|
6838
|
-
const className = clsx(css$23.refChip, referenceKind === void 0 && css$23.slashChip);
|
|
6839
|
-
parts.push(open === void 0 ? jsx("span", {
|
|
6840
|
-
className,
|
|
6841
|
-
"data-ref-chip": referenceKind ?? slashKind,
|
|
6842
|
-
title: label,
|
|
6843
|
-
children: contents
|
|
6844
|
-
}, tokenStart) : jsx("button", {
|
|
6845
|
-
type: "button",
|
|
6846
|
-
className: clsx(className, markdownCss.fileMention),
|
|
6847
|
-
"data-ref-chip": referenceKind ?? slashKind,
|
|
6848
|
-
title: label,
|
|
6849
|
-
onClick: (event) => {
|
|
6850
|
-
if (event.detail > 1 || event.detail !== 0 && event.currentTarget.ownerDocument.getSelection()?.isCollapsed === false) return;
|
|
6851
|
-
open();
|
|
6852
|
-
},
|
|
6853
|
-
children: contents
|
|
6854
|
-
}, tokenStart));
|
|
6855
|
-
cursor = end;
|
|
6856
|
-
}
|
|
6857
|
-
if (parts.length === 0) return jsx("span", {
|
|
6858
|
-
className: css$23.plainRun,
|
|
6579
|
+
/**
|
|
6580
|
+
* Render an uninterpreted inline text run.
|
|
6581
|
+
* @param props - text retained verbatim from the caller's document.
|
|
6582
|
+
* @returns one inline run without Markdown or reference recognition.
|
|
6583
|
+
*/
|
|
6584
|
+
function UserTextRun({ text }) {
|
|
6585
|
+
return jsx("span", {
|
|
6586
|
+
className: css$22.plainRun,
|
|
6859
6587
|
children: text
|
|
6860
6588
|
});
|
|
6861
|
-
|
|
6862
|
-
|
|
6589
|
+
}
|
|
6590
|
+
/**
|
|
6591
|
+
* Render a reference label or its explicitly supplied activation action.
|
|
6592
|
+
* Text selection and repeated pointer clicks do not activate the reference.
|
|
6593
|
+
* @param props - resolved visual fields and optional action from the owning renderer.
|
|
6594
|
+
* @returns an inline label, or a keyboard-accessible button when activation is supplied.
|
|
6595
|
+
*/
|
|
6596
|
+
function ReferenceChip({ appearance, label, title, onActivate }) {
|
|
6597
|
+
const slash = appearance === "skill" || appearance === "command";
|
|
6598
|
+
const contents = jsxs(Fragment, { children: [!slash && jsx(ReferenceIconRegular, {
|
|
6599
|
+
kind: appearance,
|
|
6600
|
+
size: 16,
|
|
6601
|
+
className: css$22.refIcon
|
|
6602
|
+
}), label] });
|
|
6603
|
+
const className = clsx(css$22.refChip, slash && css$22.slashChip);
|
|
6604
|
+
return onActivate === void 0 ? jsx("span", {
|
|
6605
|
+
className,
|
|
6606
|
+
"data-ref-chip": appearance,
|
|
6607
|
+
title,
|
|
6608
|
+
children: contents
|
|
6609
|
+
}) : jsx("button", {
|
|
6610
|
+
type: "button",
|
|
6611
|
+
className: clsx(className, markdownCss.fileMention),
|
|
6612
|
+
"data-ref-chip": appearance,
|
|
6613
|
+
title,
|
|
6614
|
+
onClick: (event) => {
|
|
6615
|
+
if (event.detail > 1 || event.detail !== 0 && event.currentTarget.ownerDocument.getSelection()?.isCollapsed === false) return;
|
|
6616
|
+
onActivate();
|
|
6617
|
+
},
|
|
6618
|
+
children: contents
|
|
6619
|
+
});
|
|
6620
|
+
}
|
|
6621
|
+
//#endregion
|
|
6622
|
+
//#region lib/types/input-modality.js
|
|
6623
|
+
/**
|
|
6624
|
+
* Document-wide input tracking shared by tooltips and focus-ring styles.
|
|
6625
|
+
* Tooltips follow the last input; rings follow navigation or a key followed by
|
|
6626
|
+
* focus on a different control. Modifiers and refocusing alone keep rings silent.
|
|
6627
|
+
* Module-level listeners live for the document lifetime; Node imports are inert.
|
|
6628
|
+
*/
|
|
6629
|
+
/** Modality values published on the document element. */
|
|
6630
|
+
const INPUT_MODALITY = {
|
|
6631
|
+
pointer: "pointer",
|
|
6632
|
+
keyboard: "keyboard"
|
|
6633
|
+
};
|
|
6634
|
+
/** Attribute carrying whether focus navigation last owned focus. */
|
|
6635
|
+
const INPUT_MODALITY_ATTRIBUTE = "data-input-modality";
|
|
6636
|
+
const FOCUS_NAVIGATION = new Set([
|
|
6637
|
+
"Tab",
|
|
6638
|
+
"Home",
|
|
6639
|
+
"End",
|
|
6640
|
+
"PageUp",
|
|
6641
|
+
"PageDown"
|
|
6642
|
+
]);
|
|
6643
|
+
let pointer = false;
|
|
6644
|
+
let pointerOwnsFocus = false;
|
|
6645
|
+
let keyFocusOrigin;
|
|
6646
|
+
function publish() {
|
|
6647
|
+
document.documentElement.setAttribute(INPUT_MODALITY_ATTRIBUTE, pointerOwnsFocus ? INPUT_MODALITY.pointer : INPUT_MODALITY.keyboard);
|
|
6648
|
+
}
|
|
6649
|
+
/**
|
|
6650
|
+
* Whether the last input came from a pointer, independently of ring visibility.
|
|
6651
|
+
* @returns True after pointer input; false after any key.
|
|
6652
|
+
*/
|
|
6653
|
+
function pointerModality() {
|
|
6654
|
+
return pointer;
|
|
6655
|
+
}
|
|
6656
|
+
if (typeof window !== "undefined") {
|
|
6657
|
+
window.addEventListener("pointerdown", () => {
|
|
6658
|
+
pointer = true;
|
|
6659
|
+
pointerOwnsFocus = true;
|
|
6660
|
+
keyFocusOrigin = void 0;
|
|
6661
|
+
publish();
|
|
6662
|
+
}, true);
|
|
6663
|
+
window.addEventListener("keydown", (event) => {
|
|
6664
|
+
pointer = false;
|
|
6665
|
+
if (event.isComposing) {
|
|
6666
|
+
keyFocusOrigin = void 0;
|
|
6667
|
+
return;
|
|
6668
|
+
}
|
|
6669
|
+
keyFocusOrigin = event.composedPath()[0];
|
|
6670
|
+
if (!FOCUS_NAVIGATION.has(event.key) && !event.key.startsWith("Arrow")) return;
|
|
6671
|
+
pointerOwnsFocus = false;
|
|
6672
|
+
publish();
|
|
6673
|
+
}, true);
|
|
6674
|
+
window.addEventListener("focusin", (event) => {
|
|
6675
|
+
if (keyFocusOrigin === void 0 || event.composedPath()[0] === keyFocusOrigin) return;
|
|
6676
|
+
keyFocusOrigin = void 0;
|
|
6677
|
+
if (!pointerOwnsFocus) return;
|
|
6678
|
+
pointerOwnsFocus = false;
|
|
6679
|
+
publish();
|
|
6680
|
+
}, true);
|
|
6681
|
+
window.addEventListener("blur", () => {
|
|
6682
|
+
keyFocusOrigin = void 0;
|
|
6683
|
+
});
|
|
6684
|
+
}
|
|
6685
|
+
//#endregion
|
|
6686
|
+
//#region lib/types/Tooltip.js
|
|
6687
|
+
/** Anchor-preserving tooltips; an optional body portal escapes clipping containers and stacking contexts that cap the bubble's z-index. */
|
|
6688
|
+
/**
|
|
6689
|
+
* Suppression channel for nested tooltips: a visible descendant tooltip
|
|
6690
|
+
* withdraws the enclosing tooltip while its bubble is shown.
|
|
6691
|
+
*/
|
|
6692
|
+
const TooltipSuppression = createContext(null);
|
|
6693
|
+
/**
|
|
6694
|
+
* Attach a hover/focus tooltip to an anchor element.
|
|
6695
|
+
* @param props.label - bubble text, or a resolver evaluated only while visible; an empty string shows only shortcut keys.
|
|
6696
|
+
* @param props.shortcutKeys - effective key labels rendered as platform-formatted keycaps after optional text.
|
|
6697
|
+
* @param props.side - placement relative to the anchor (default 'right').
|
|
6698
|
+
* @param props.align - horizontal anchor-edge alignment for 'bottom'/'top' bubbles: 'end' pins
|
|
6699
|
+
* the bubble's right edge to the anchor's (for anchors beside other hover surfaces the centered
|
|
6700
|
+
* bubble would overlap); default 'center'. Ignored for side 'right'.
|
|
6701
|
+
* @param props.portal - render the bubble under document.body, so an ancestor's clipping or its
|
|
6702
|
+
* stacking context (which confines the bubble's z-index to that context) cannot hide it.
|
|
6703
|
+
* @param props.delayMs - hover delay in milliseconds (default 0).
|
|
6704
|
+
* @param props.focusDelayMs - keyboard focus delay in milliseconds (default 0); blur, click,
|
|
6705
|
+
* mouse leave, disabling, and unmount cancel a pending show.
|
|
6706
|
+
* @param props.gap - anchor-to-bubble distance in pixels for 'bottom'/'top' bubbles (default 8);
|
|
6707
|
+
* ignored for side 'right'.
|
|
6708
|
+
* @param props.disabled - suppress the bubble while true; the anchor renders identically so
|
|
6709
|
+
* toggling never remounts it (which would cut its CSS transitions).
|
|
6710
|
+
* @param props.maxWidth - bubble width cap in pixels, for labels long enough that the default
|
|
6711
|
+
* half-viewport cap would render a slab wider than the surface the anchor sits on.
|
|
6712
|
+
* @param props.openOnClick - clicking also pins the bubble for reading; another click, Escape,
|
|
6713
|
+
* Tab, or an outside pointerdown dismisses it. Defaults to false for ordinary action tooltips.
|
|
6714
|
+
* @param props.children - a single anchor element; its own ref (callback or object) is forwarded alongside the tooltip's.
|
|
6715
|
+
* @returns the cloned anchor plus a fixed-position bubble, optionally portaled to the body.
|
|
6716
|
+
* The bubble stays hidden until ResizeObserver supplies its size for viewport fitting; clicking the
|
|
6717
|
+
* anchor dismisses the bubble unless openOnClick is enabled, and focus arriving after a pointer
|
|
6718
|
+
* interaction (a closing menu refocusing its trigger) never raises it.
|
|
6719
|
+
*/
|
|
6720
|
+
function Tooltip({ label, shortcutKeys, side = "right", align = "center", delayMs = 0, focusDelayMs = 0, gap = 8, disabled = false, portal = false, maxWidth, openOnClick = false, children }) {
|
|
6721
|
+
const id = useId();
|
|
6722
|
+
const [pinned, setPinned] = useState(false);
|
|
6723
|
+
const anchor = useRef(null);
|
|
6724
|
+
const childRef = children.ref;
|
|
6725
|
+
const mergedRef = useCallback((el) => {
|
|
6726
|
+
anchor.current = el;
|
|
6727
|
+
if (typeof childRef === "function") childRef(el);
|
|
6728
|
+
else if (childRef != null) childRef.current = el;
|
|
6729
|
+
}, [childRef]);
|
|
6730
|
+
const [pos, setPos] = useState(null);
|
|
6731
|
+
const bubble = useRef(null);
|
|
6732
|
+
const resolvedLabel = pos === null ? null : typeof label === "function" ? label() : label;
|
|
6733
|
+
const y = pos === null ? 0 : side === "right" ? pos.top + (pos.bottom - pos.top) / 2 : side === "top" ? pos.top - gap : pos.bottom + gap;
|
|
6734
|
+
const showTimer = useRef(null);
|
|
6735
|
+
const triggers = useRef({
|
|
6736
|
+
hover: false,
|
|
6737
|
+
focus: false
|
|
6738
|
+
});
|
|
6739
|
+
const suppressAncestors = useContext(TooltipSuppression);
|
|
6740
|
+
const [suppressed, setSuppressed] = useState(false);
|
|
6741
|
+
const announce = useCallback((active) => {
|
|
6742
|
+
suppressAncestors?.(active);
|
|
6743
|
+
}, [suppressAncestors]);
|
|
6744
|
+
const visible = pos !== null && !disabled;
|
|
6745
|
+
useEffect(() => {
|
|
6746
|
+
const el = bubble.current;
|
|
6747
|
+
if (pos === null || !visible || suppressed || el === null) return;
|
|
6748
|
+
const edgeMargin = 12;
|
|
6749
|
+
let size;
|
|
6750
|
+
let placement = side;
|
|
6751
|
+
const fit = () => {
|
|
6752
|
+
if (size === void 0) return;
|
|
6753
|
+
const { inlineSize: width, blockSize: height } = size;
|
|
6754
|
+
const offset = side === "right" ? 0 : align === "end" ? width : width / 2;
|
|
6755
|
+
const left = Math.max(edgeMargin, Math.min(pos.x - offset, window.innerWidth - edgeMargin - width));
|
|
6756
|
+
const fitsBelow = pos.bottom + gap + height <= window.innerHeight - edgeMargin;
|
|
6757
|
+
const fitsAbove = pos.top - gap - height >= edgeMargin;
|
|
6758
|
+
if (placement === "bottom" && !fitsBelow && fitsAbove) placement = "top";
|
|
6759
|
+
else if (placement === "top" && !fitsAbove && fitsBelow) placement = "bottom";
|
|
6760
|
+
el.style.left = `${left + offset}px`;
|
|
6761
|
+
el.style.top = `${placement === "right" ? (pos.top + pos.bottom) / 2 : placement === "top" ? pos.top - gap : pos.bottom + gap}px`;
|
|
6762
|
+
el.dataset.side = placement;
|
|
6763
|
+
el.style.visibility = "visible";
|
|
6764
|
+
};
|
|
6765
|
+
const observer = new ResizeObserver((entries) => {
|
|
6766
|
+
size = entries[0]?.borderBoxSize[0];
|
|
6767
|
+
fit();
|
|
6768
|
+
});
|
|
6769
|
+
observer.observe(el, { box: "border-box" });
|
|
6770
|
+
window.addEventListener("resize", fit);
|
|
6771
|
+
return () => {
|
|
6772
|
+
observer.disconnect();
|
|
6773
|
+
window.removeEventListener("resize", fit);
|
|
6774
|
+
};
|
|
6775
|
+
}, [
|
|
6776
|
+
align,
|
|
6777
|
+
gap,
|
|
6778
|
+
pos,
|
|
6779
|
+
side,
|
|
6780
|
+
suppressed,
|
|
6781
|
+
visible
|
|
6782
|
+
]);
|
|
6783
|
+
useEffect(() => {
|
|
6784
|
+
announce(visible);
|
|
6785
|
+
return () => {
|
|
6786
|
+
announce(false);
|
|
6787
|
+
};
|
|
6788
|
+
}, [announce, visible]);
|
|
6789
|
+
const cancelShow = useCallback(() => {
|
|
6790
|
+
if (showTimer.current === null) return;
|
|
6791
|
+
clearTimeout(showTimer.current);
|
|
6792
|
+
showTimer.current = null;
|
|
6793
|
+
}, []);
|
|
6794
|
+
useEffect(() => {
|
|
6795
|
+
if (pinned && (disabled || !openOnClick)) setPinned(false);
|
|
6796
|
+
if (disabled) {
|
|
6797
|
+
cancelShow();
|
|
6798
|
+
triggers.current = {
|
|
6799
|
+
hover: false,
|
|
6800
|
+
focus: false
|
|
6801
|
+
};
|
|
6802
|
+
setPos(null);
|
|
6803
|
+
}
|
|
6804
|
+
return cancelShow;
|
|
6805
|
+
}, [
|
|
6806
|
+
cancelShow,
|
|
6807
|
+
disabled,
|
|
6808
|
+
openOnClick,
|
|
6809
|
+
pinned
|
|
6810
|
+
]);
|
|
6811
|
+
const show = () => {
|
|
6812
|
+
if (disabled) return;
|
|
6813
|
+
const el = anchor.current;
|
|
6814
|
+
/* v8 ignore next -- the ref is attached by event time: events fire on the cloned anchor. */
|
|
6815
|
+
if (el === null) return;
|
|
6816
|
+
const r = el.getBoundingClientRect();
|
|
6817
|
+
setPos({
|
|
6818
|
+
x: side === "right" ? r.right + 10 : align === "end" ? r.right : r.left + r.width / 2,
|
|
6819
|
+
top: r.top,
|
|
6820
|
+
bottom: r.bottom
|
|
6821
|
+
});
|
|
6822
|
+
announce(true);
|
|
6823
|
+
};
|
|
6824
|
+
const showAfterDelay = (delay) => {
|
|
6825
|
+
cancelShow();
|
|
6826
|
+
if (delay <= 0) {
|
|
6827
|
+
show();
|
|
6828
|
+
return;
|
|
6829
|
+
}
|
|
6830
|
+
showTimer.current = setTimeout(() => {
|
|
6831
|
+
showTimer.current = null;
|
|
6832
|
+
show();
|
|
6833
|
+
}, delay);
|
|
6834
|
+
};
|
|
6835
|
+
const withdraw = useCallback(() => {
|
|
6836
|
+
setPinned(false);
|
|
6837
|
+
setPos(null);
|
|
6838
|
+
announce(false);
|
|
6839
|
+
}, [announce]);
|
|
6840
|
+
const hide = () => {
|
|
6841
|
+
cancelShow();
|
|
6842
|
+
if (!triggers.current.hover && !triggers.current.focus && !pinned) withdraw();
|
|
6843
|
+
};
|
|
6844
|
+
const dismiss = useCallback(() => {
|
|
6845
|
+
cancelShow();
|
|
6846
|
+
triggers.current = {
|
|
6847
|
+
hover: false,
|
|
6848
|
+
focus: false
|
|
6849
|
+
};
|
|
6850
|
+
withdraw();
|
|
6851
|
+
}, [cancelShow, withdraw]);
|
|
6852
|
+
useDismissOnOutsidePointer(anchor, openOnClick && visible, dismiss, bubble);
|
|
6853
|
+
useEffect(() => {
|
|
6854
|
+
if (!openOnClick || !visible) return;
|
|
6855
|
+
const onKeyDown = (event) => {
|
|
6856
|
+
if (event.key !== "Escape" && event.key !== "Tab") return;
|
|
6857
|
+
if (event.key === "Escape") {
|
|
6858
|
+
event.preventDefault();
|
|
6859
|
+
event.stopPropagation();
|
|
6860
|
+
}
|
|
6861
|
+
dismiss();
|
|
6862
|
+
};
|
|
6863
|
+
document.addEventListener("keydown", onKeyDown, true);
|
|
6864
|
+
return () => {
|
|
6865
|
+
document.removeEventListener("keydown", onKeyDown, true);
|
|
6866
|
+
};
|
|
6867
|
+
}, [
|
|
6868
|
+
dismiss,
|
|
6869
|
+
openOnClick,
|
|
6870
|
+
visible
|
|
6871
|
+
]);
|
|
6872
|
+
const content = visible && !suppressed && jsxs("span", {
|
|
6873
|
+
ref: bubble,
|
|
6874
|
+
id: openOnClick ? id : void 0,
|
|
6875
|
+
className: css$23.bubble,
|
|
6876
|
+
"data-side": side,
|
|
6877
|
+
"data-portal": portal || void 0,
|
|
6878
|
+
"data-pinned": pinned || void 0,
|
|
6879
|
+
"data-align": align,
|
|
6880
|
+
"data-has-shortcut": shortcutKeys?.length ? true : void 0,
|
|
6881
|
+
style: {
|
|
6882
|
+
left: pos.x,
|
|
6883
|
+
top: y,
|
|
6884
|
+
visibility: "hidden",
|
|
6885
|
+
...maxWidth === void 0 ? {} : { maxWidth }
|
|
6886
|
+
},
|
|
6887
|
+
role: "tooltip",
|
|
6888
|
+
"aria-label": shortcutKeys?.length ? [resolvedLabel, shortcutKeys.join(" ")].filter(Boolean).join(" ") : void 0,
|
|
6889
|
+
children: [resolvedLabel && jsx("span", {
|
|
6890
|
+
className: css$23.label,
|
|
6891
|
+
children: resolvedLabel
|
|
6892
|
+
}), shortcutKeys !== void 0 && shortcutKeys.length > 0 && jsx(ShortcutKeys, {
|
|
6893
|
+
keys: shortcutKeys,
|
|
6894
|
+
variant: "tooltip"
|
|
6895
|
+
})]
|
|
6896
|
+
});
|
|
6897
|
+
return jsxs(TooltipSuppression.Provider, {
|
|
6898
|
+
value: setSuppressed,
|
|
6899
|
+
children: [cloneElement(children, {
|
|
6900
|
+
ref: mergedRef,
|
|
6901
|
+
"aria-describedby": openOnClick && visible ? [children.props["aria-describedby"], id].filter(Boolean).join(" ") : children.props["aria-describedby"],
|
|
6902
|
+
onMouseEnter: (e) => {
|
|
6903
|
+
children.props.onMouseEnter?.(e);
|
|
6904
|
+
triggers.current.hover = true;
|
|
6905
|
+
showAfterDelay(delayMs);
|
|
6906
|
+
},
|
|
6907
|
+
onMouseLeave: (e) => {
|
|
6908
|
+
children.props.onMouseLeave?.(e);
|
|
6909
|
+
triggers.current.hover = false;
|
|
6910
|
+
cancelShow();
|
|
6911
|
+
if (!pinned) withdraw();
|
|
6912
|
+
},
|
|
6913
|
+
onClick: (e) => {
|
|
6914
|
+
children.props.onClick?.(e);
|
|
6915
|
+
triggers.current.focus = false;
|
|
6916
|
+
cancelShow();
|
|
6917
|
+
if (openOnClick && !disabled && !pinned) {
|
|
6918
|
+
setPinned(true);
|
|
6919
|
+
show();
|
|
6920
|
+
} else withdraw();
|
|
6921
|
+
},
|
|
6922
|
+
onFocus: (e) => {
|
|
6923
|
+
children.props.onFocus?.(e);
|
|
6924
|
+
if (pointerModality()) return;
|
|
6925
|
+
triggers.current.focus = true;
|
|
6926
|
+
showAfterDelay(focusDelayMs);
|
|
6927
|
+
},
|
|
6928
|
+
onBlur: (e) => {
|
|
6929
|
+
children.props.onBlur?.(e);
|
|
6930
|
+
triggers.current.focus = false;
|
|
6931
|
+
hide();
|
|
6932
|
+
}
|
|
6933
|
+
}), portal ? content !== false && createPortal(content, document.body) : content]
|
|
6934
|
+
});
|
|
6863
6935
|
}
|
|
6864
6936
|
//#endregion
|
|
6865
6937
|
//#region lib/types/Toast.js
|
|
@@ -9468,7 +9540,7 @@ function renderLine$1(line) {
|
|
|
9468
9540
|
* @param props - see {@link TerminalBlockProps}.
|
|
9469
9541
|
* @returns the terminal block element.
|
|
9470
9542
|
*/
|
|
9471
|
-
function TerminalBlock({ command, cwd, home, output, exitCode, signal, running = false, maxLines = 16, copyText, runStateDot = true, className, labels }) {
|
|
9543
|
+
function TerminalBlock({ command, cwd, home, output, exitCode, signal, running = false, background = false, maxLines = 16, copyText, runStateDot = true, className, labels }) {
|
|
9472
9544
|
const copy = labels;
|
|
9473
9545
|
const text = output ?? "";
|
|
9474
9546
|
const lines = useMemo(() => {
|
|
@@ -9481,14 +9553,15 @@ function TerminalBlock({ command, cwd, home, output, exitCode, signal, running =
|
|
|
9481
9553
|
const onToggle = useCallback(() => {
|
|
9482
9554
|
setExpanded((value) => !value);
|
|
9483
9555
|
}, []);
|
|
9484
|
-
const status = statusText(exitCode, signal, copy);
|
|
9556
|
+
const status = background ? void 0 : statusText(exitCode, signal, copy);
|
|
9485
9557
|
const state = runState(running, exitCode, signal, copy);
|
|
9558
|
+
const showState = runStateDot && (!background || running);
|
|
9486
9559
|
const commandLines = useMemo(() => {
|
|
9487
9560
|
return (command.endsWith("\n") ? command.slice(0, -1) : command).split("\n");
|
|
9488
9561
|
}, [command]);
|
|
9489
9562
|
const empty = lines.every((line) => line.every((span) => span.text.trim() === ""));
|
|
9490
9563
|
const { hidden, capped, headLines, tailLines } = headTailCap(lines.length, maxLines, expanded);
|
|
9491
|
-
const body = !running || !empty;
|
|
9564
|
+
const body = !background && (!running || !empty);
|
|
9492
9565
|
return jsxs("div", {
|
|
9493
9566
|
className: clsx(css$28.block, className),
|
|
9494
9567
|
"data-terminal": "",
|
|
@@ -9499,13 +9572,13 @@ function TerminalBlock({ command, cwd, home, output, exitCode, signal, running =
|
|
|
9499
9572
|
children: [
|
|
9500
9573
|
jsxs("div", {
|
|
9501
9574
|
className: css$28.prompt,
|
|
9502
|
-
children: [
|
|
9575
|
+
children: [showState && jsx("span", {
|
|
9503
9576
|
className: css$28.runStateLabel,
|
|
9504
9577
|
children: state.label
|
|
9505
9578
|
}), commandLines.map((line, index) => jsxs("div", {
|
|
9506
9579
|
className: css$28.promptLine,
|
|
9507
9580
|
children: [
|
|
9508
|
-
index === 0 &&
|
|
9581
|
+
index === 0 && showState && jsx(StateDot, {
|
|
9509
9582
|
state: state.state,
|
|
9510
9583
|
className: css$28.runState
|
|
9511
9584
|
}),
|
|
@@ -9525,7 +9598,7 @@ function TerminalBlock({ command, cwd, home, output, exitCode, signal, running =
|
|
|
9525
9598
|
className: css$28.status,
|
|
9526
9599
|
children: status
|
|
9527
9600
|
}),
|
|
9528
|
-
(copyText !== void 0 || !running && !empty) && jsx("button", {
|
|
9601
|
+
(copyText !== void 0 || !background && !running && !empty) && jsx("button", {
|
|
9529
9602
|
type: "button",
|
|
9530
9603
|
className: css$28.copyButton,
|
|
9531
9604
|
onClick: onCopy,
|
|
@@ -12505,6 +12578,6 @@ function GuideArtworkFiles({ size = 36, className }) {
|
|
|
12505
12578
|
});
|
|
12506
12579
|
}
|
|
12507
12580
|
//#endregion
|
|
12508
|
-
export { BrandWordmark, Button, CODE_HIGHLIGHT_EXTENSIONS, Checkbox, CodeBlock, CommandText, ConnectionIndicator, DEFAULT_DIFF_MAX_LINES, DEFAULT_READ_MAX_LINES, DEFAULT_SEARCH_MAX_LINES, DEFAULT_TERMINAL_MAX_LINES, DiffBlock, DisclosureRow, FISH_LOGO_PATH, FISH_LOGO_VIEWBOX, FileTypeIcon, FishLogo, GuideArtworkBrowser, GuideArtworkFiles, HoverCard, ICON_MEDIUM_STROKE, ICON_REGULAR_STROKE, IconAgentPresetOutlineMedium, IconAgentPresetOutlineRegular, IconAlarmClockOutlineMedium, IconAlarmClockOutlineRegular, IconApiOutlineMedium, IconApiOutlineRegular, IconArchiveCheckOutlineMedium, IconArchiveCheckOutlineRegular, IconArchiveOffOutlineMedium, IconArchiveOffOutlineRegular, IconArchiveOutlineMedium, IconArchiveOutlineRegular, IconBranchOutlineMedium, IconBranchOutlineRegular, IconBrowseOutlineMedium, IconBrowseOutlineRegular, IconCheckCircleFillMedium, IconCheckCircleFillRegular, IconCheckCircleOutlineMedium, IconCheckCircleOutlineRegular, IconCheckOutlineMedium, IconCheckOutlineRegular, IconChecklistOutlineMedium, IconChecklistOutlineRegular, IconChevronDownOutlineMedium, IconChevronDownOutlineRegular, IconChevronLeftOutlineMedium, IconChevronLeftOutlineRegular, IconChevronRightOutlineMedium, IconChevronRightOutlineRegular, IconChevronUpOutlineMedium, IconChevronUpOutlineRegular, IconChevronsUpDownOutlineMedium, IconChevronsUpDownOutlineRegular, IconClockOutlineMedium, IconClockOutlineRegular, IconCloseCircleFillMedium, IconCloseCircleFillRegular, IconCloseFillMedium, IconCloseFillRegular, IconCloseOutlineMedium, IconCloseOutlineRegular, IconCodeOutlineMedium, IconCodeOutlineRegular, IconCompactOutlineMedium, IconCompactOutlineRegular, IconCompareSplitOutlineMedium, IconCompareSplitOutlineRegular, IconContextInjectionOutlineMedium, IconContextInjectionOutlineRegular, IconCopyOutlineMedium, IconCopyOutlineRegular, IconCordisPluginOutlineMedium, IconCordisPluginOutlineRegular, IconDarkOutlineMedium, IconDarkOutlineRegular, IconDataOutlineMedium, IconDataOutlineRegular, IconDatabaseOutlineMedium, IconDatabaseOutlineRegular, IconDeliverDocMedium, IconDeliverDocRegular, IconDislikeFillMedium, IconDislikeFillRegular, IconDislikeOutlineMedium, IconDislikeOutlineRegular, IconDownloadOutlineMedium, IconDownloadOutlineRegular, IconEditOutlineMedium, IconEditOutlineRegular, IconEllipsisOutlineMedium, IconEllipsisOutlineRegular, IconEnhanceOutlineMedium, IconEnhanceOutlineRegular, IconFlatListOutlineMedium, IconFlatListOutlineRegular, IconFolderCloseMedium, IconFolderCloseRegular, IconFolderOpenMedium, IconFolderOpenOutlineMedium, IconFolderOpenOutlineRegular, IconFolderOpenRegular, IconFollowsystemOutlineMedium, IconFollowsystemOutlineRegular, IconFullscreenOutlineMedium, IconFullscreenOutlineRegular, IconGaugeOutlineMedium, IconGaugeOutlineRegular, IconGlobeOutlineMedium, IconGlobeOutlineRegular, IconGoalOutlineMedium, IconGoalOutlineRegular, IconInfoOutlineMedium, IconInfoOutlineRegular, IconInspectOutlineMedium, IconInspectOutlineRegular, IconLightOutlineMedium, IconLightOutlineRegular, IconLikeFillMedium, IconLikeFillRegular, IconLikeOutlineMedium, IconLikeOutlineRegular, IconLinkOutlineMedium, IconLinkOutlineRegular, IconListPenOutlineMedium, IconListPenOutlineRegular, IconLoadingOutlineMedium, IconLoadingOutlineRegular, IconMicrophoneOutlineMedium, IconMicrophoneOutlineRegular, IconNewChatOutlineMedium, IconNewChatOutlineRegular, IconNowrapFillMedium, IconNowrapFillRegular, IconPanelLeftOutlineMedium, IconPanelLeftOutlineRegular, IconPaperPlaneOutlineMedium, IconPaperPlaneOutlineRegular, IconPaperclipOutlineMedium, IconPaperclipOutlineRegular, IconPauseOutlineMedium, IconPauseOutlineRegular, IconPersonalizationOutlineMedium, IconPersonalizationOutlineRegular, IconPinFillMedium, IconPinFillRegular, IconPinOutlineMedium, IconPinOutlineRegular, IconPlanOutlineMedium, IconPlanOutlineRegular, IconPlayOutlineMedium, IconPlayOutlineRegular, IconPluginPinwheelOutlineMedium, IconPluginPinwheelOutlineRegular, IconPlusOutlineMedium, IconPlusOutlineRegular, IconProjectAddOutlineMedium, IconProjectAddOutlineRegular, IconQuestionOutlineMedium, IconQuestionOutlineRegular, IconQueueOutlineMedium, IconQueueOutlineRegular, IconRefreshOutlineMedium, IconRefreshOutlineRegular, IconRightUpOutlineMedium, IconRightUpOutlineRegular, IconSearchOutlineMedium, IconSearchOutlineRegular, IconSendOutlineMedium, IconSendOutlineRegular, IconSettingsOutlineMedium, IconSettingsOutlineRegular, IconShareOutlineMedium, IconShareOutlineRegular, IconShieldOutlineMedium, IconShieldOutlineRegular, IconSkillOutlineMedium, IconSkillOutlineRegular, IconSlidersTwoOutlineMedium, IconSlidersTwoOutlineRegular, IconSparkleMedium, IconSparkleRegular, IconStopFillMedium, IconStopFillRegular, IconThinkOutlineMedium, IconThinkOutlineRegular, IconTrashOutlineMedium, IconTrashOutlineRegular, IconTreeCornerMedium, IconTreeCornerRegular, IconTriangleRightFillMedium, IconTriangleRightFillRegular, IconUnarchiveOutlineMedium, IconUnarchiveOutlineRegular, IconUserOutlineMedium, IconUserOutlineRegular, IconUsersOutlineMedium, IconUsersOutlineRegular, IconWarningOutlineMedium, IconWarningOutlineRegular, IconWarningTriangleOutlineMedium, IconWarningTriangleOutlineRegular, IconWorkspaceTreeOutlineMedium, IconWorkspaceTreeOutlineRegular, IconWrapFillMedium, IconWrapFillRegular, IconWrapLinesOutlineMedium, IconWrapLinesOutlineRegular, ImageLightbox, InlineEditor, Input, JsonBlock, JsonTree, LinkIconMedium, LinkIconRegular, MarkdownDelegateProvider, MarkdownText, Menu, MenuGroup, MenuItemButton, MenuSurface, Modal, PathLabel, PermissionIconFullAccessMedium, PermissionIconFullAccessRegular, PermissionIconReadOnlyMedium, PermissionIconReadOnlyRegular, PermissionIconWorkspaceWriteMedium, PermissionIconWorkspaceWriteRegular, Pill, PluginArtworkDefault, PluginArtworkLoop, PluginArtworkSearch, PluginArtworkSubagent, PluginArtworkTerminal, ReadBlock, ReferenceIconMedium, ReferenceIconRegular, RiskConfirmation, SHIELD_OUTLINE_PATH, SearchBlock, SegmentedControl, SegmentedTabs, SettingsForm, SettingsFormModel, SettingsSecretField, SettingsValueField, ShortcutKeys, StateDot, Switch, Tag, TerminalBlock, TextShimmer, Toast, Tooltip, WebBlock, classifyFileType, classifyLinkPath, closeTopModal, diffTotals, extractMarkdownPlainText, fileExtension, fileSizeText, focusWithoutRing, isBehindModal, isDarwinDesktop, languageForPath, modalSelector, observeComposition, observeStickyMenuGroups, pointerModality,
|
|
12581
|
+
export { BrandWordmark, Button, CODE_HIGHLIGHT_EXTENSIONS, Checkbox, CodeBlock, CommandText, ConnectionIndicator, DEFAULT_DIFF_MAX_LINES, DEFAULT_READ_MAX_LINES, DEFAULT_SEARCH_MAX_LINES, DEFAULT_TERMINAL_MAX_LINES, DiffBlock, DisclosureRow, FISH_LOGO_PATH, FISH_LOGO_VIEWBOX, FileTypeIcon, FishLogo, GuideArtworkBrowser, GuideArtworkFiles, HoverCard, HoverCardGroup, ICON_MEDIUM_STROKE, ICON_REGULAR_STROKE, IconAgentPresetOutlineMedium, IconAgentPresetOutlineRegular, IconAlarmClockOutlineMedium, IconAlarmClockOutlineRegular, IconApiOutlineMedium, IconApiOutlineRegular, IconArchiveCheckOutlineMedium, IconArchiveCheckOutlineRegular, IconArchiveOffOutlineMedium, IconArchiveOffOutlineRegular, IconArchiveOutlineMedium, IconArchiveOutlineRegular, IconBranchOutlineMedium, IconBranchOutlineRegular, IconBrowseOutlineMedium, IconBrowseOutlineRegular, IconCheckCircleFillMedium, IconCheckCircleFillRegular, IconCheckCircleOutlineMedium, IconCheckCircleOutlineRegular, IconCheckOutlineMedium, IconCheckOutlineRegular, IconChecklistOutlineMedium, IconChecklistOutlineRegular, IconChevronDownOutlineMedium, IconChevronDownOutlineRegular, IconChevronLeftOutlineMedium, IconChevronLeftOutlineRegular, IconChevronRightOutlineMedium, IconChevronRightOutlineRegular, IconChevronUpOutlineMedium, IconChevronUpOutlineRegular, IconChevronsUpDownOutlineMedium, IconChevronsUpDownOutlineRegular, IconClockOutlineMedium, IconClockOutlineRegular, IconCloseCircleFillMedium, IconCloseCircleFillRegular, IconCloseFillMedium, IconCloseFillRegular, IconCloseOutlineMedium, IconCloseOutlineRegular, IconCodeOutlineMedium, IconCodeOutlineRegular, IconCompactOutlineMedium, IconCompactOutlineRegular, IconCompareSplitOutlineMedium, IconCompareSplitOutlineRegular, IconContextInjectionOutlineMedium, IconContextInjectionOutlineRegular, IconCopyOutlineMedium, IconCopyOutlineRegular, IconCordisPluginOutlineMedium, IconCordisPluginOutlineRegular, IconDarkOutlineMedium, IconDarkOutlineRegular, IconDataOutlineMedium, IconDataOutlineRegular, IconDatabaseOutlineMedium, IconDatabaseOutlineRegular, IconDeliverDocMedium, IconDeliverDocRegular, IconDislikeFillMedium, IconDislikeFillRegular, IconDislikeOutlineMedium, IconDislikeOutlineRegular, IconDownloadOutlineMedium, IconDownloadOutlineRegular, IconEditOutlineMedium, IconEditOutlineRegular, IconEllipsisOutlineMedium, IconEllipsisOutlineRegular, IconEnhanceOutlineMedium, IconEnhanceOutlineRegular, IconFlatListOutlineMedium, IconFlatListOutlineRegular, IconFolderCloseMedium, IconFolderCloseRegular, IconFolderOpenMedium, IconFolderOpenOutlineMedium, IconFolderOpenOutlineRegular, IconFolderOpenRegular, IconFollowsystemOutlineMedium, IconFollowsystemOutlineRegular, IconFullscreenOutlineMedium, IconFullscreenOutlineRegular, IconGaugeOutlineMedium, IconGaugeOutlineRegular, IconGlobeOutlineMedium, IconGlobeOutlineRegular, IconGoalOutlineMedium, IconGoalOutlineRegular, IconInfoOutlineMedium, IconInfoOutlineRegular, IconInspectOutlineMedium, IconInspectOutlineRegular, IconLightOutlineMedium, IconLightOutlineRegular, IconLikeFillMedium, IconLikeFillRegular, IconLikeOutlineMedium, IconLikeOutlineRegular, IconLinkOutlineMedium, IconLinkOutlineRegular, IconListPenOutlineMedium, IconListPenOutlineRegular, IconLoadingOutlineMedium, IconLoadingOutlineRegular, IconMicrophoneOutlineMedium, IconMicrophoneOutlineRegular, IconNewChatOutlineMedium, IconNewChatOutlineRegular, IconNowrapFillMedium, IconNowrapFillRegular, IconPanelLeftOutlineMedium, IconPanelLeftOutlineRegular, IconPaperPlaneOutlineMedium, IconPaperPlaneOutlineRegular, IconPaperclipOutlineMedium, IconPaperclipOutlineRegular, IconPauseOutlineMedium, IconPauseOutlineRegular, IconPersonalizationOutlineMedium, IconPersonalizationOutlineRegular, IconPinFillMedium, IconPinFillRegular, IconPinOutlineMedium, IconPinOutlineRegular, IconPlanOutlineMedium, IconPlanOutlineRegular, IconPlayOutlineMedium, IconPlayOutlineRegular, IconPluginPinwheelOutlineMedium, IconPluginPinwheelOutlineRegular, IconPlusOutlineMedium, IconPlusOutlineRegular, IconProjectAddOutlineMedium, IconProjectAddOutlineRegular, IconQuestionOutlineMedium, IconQuestionOutlineRegular, IconQueueOutlineMedium, IconQueueOutlineRegular, IconRefreshOutlineMedium, IconRefreshOutlineRegular, IconRightUpOutlineMedium, IconRightUpOutlineRegular, IconSearchOutlineMedium, IconSearchOutlineRegular, IconSendOutlineMedium, IconSendOutlineRegular, IconSettingsOutlineMedium, IconSettingsOutlineRegular, IconShareOutlineMedium, IconShareOutlineRegular, IconShieldOutlineMedium, IconShieldOutlineRegular, IconSkillOutlineMedium, IconSkillOutlineRegular, IconSlidersTwoOutlineMedium, IconSlidersTwoOutlineRegular, IconSparkleMedium, IconSparkleRegular, IconStopFillMedium, IconStopFillRegular, IconThinkOutlineMedium, IconThinkOutlineRegular, IconTrashOutlineMedium, IconTrashOutlineRegular, IconTreeCornerMedium, IconTreeCornerRegular, IconTriangleRightFillMedium, IconTriangleRightFillRegular, IconUnarchiveOutlineMedium, IconUnarchiveOutlineRegular, IconUserOutlineMedium, IconUserOutlineRegular, IconUsersOutlineMedium, IconUsersOutlineRegular, IconWarningOutlineMedium, IconWarningOutlineRegular, IconWarningTriangleOutlineMedium, IconWarningTriangleOutlineRegular, IconWorkspaceTreeOutlineMedium, IconWorkspaceTreeOutlineRegular, IconWrapFillMedium, IconWrapFillRegular, IconWrapLinesOutlineMedium, IconWrapLinesOutlineRegular, ImageLightbox, InlineEditor, Input, JsonBlock, JsonTree, LinkIconMedium, LinkIconRegular, MarkdownDelegateProvider, MarkdownText, Menu, MenuGroup, MenuItemButton, MenuSurface, Modal, PathLabel, PermissionIconAutoReviewMedium, PermissionIconAutoReviewRegular, PermissionIconFullAccessMedium, PermissionIconFullAccessRegular, PermissionIconReadOnlyMedium, PermissionIconReadOnlyRegular, PermissionIconWorkspaceWriteMedium, PermissionIconWorkspaceWriteRegular, Pill, PluginArtworkDefault, PluginArtworkLoop, PluginArtworkSearch, PluginArtworkSubagent, PluginArtworkTerminal, ReadBlock, ReferenceChip, ReferenceIconMedium, ReferenceIconRegular, RiskConfirmation, SHIELD_OUTLINE_PATH, SearchBlock, SegmentedControl, SegmentedTabs, SettingsForm, SettingsFormModel, SettingsSecretField, SettingsValueField, ShortcutKeys, StateDot, Switch, Tag, TerminalBlock, TextShimmer, Toast, Tooltip, UserTextRun, WebBlock, classifyFileType, classifyLinkPath, closeTopModal, diffTotals, extractMarkdownPlainText, fileExtension, fileSizeText, focusWithoutRing, isBehindModal, isDarwinDesktop, languageForPath, modalSelector, observeComposition, observeStickyMenuGroups, pointerModality, rankByName, relativeTime, settingsNumberField, settingsTextField, useAnchoredMaxHeight, useAnchoredPosition, useCodeHighlighter, useDismissOnOutsidePointer, useModalLayer, writeClipboard };
|
|
12509
12582
|
|
|
12510
12583
|
//# sourceMappingURL=index.js.map
|