@simon_he/vue-tui 1.1.6 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +1 -0
  2. package/dist/TAgentTerminalGraphic-B8-YZfuP.js +1198 -0
  3. package/dist/{TSelect-CMBOOFwK.js → TSelect-CCsjjCOr.js} +41 -12
  4. package/dist/{TTree-kk8ntrpg.js → TTree-3W5A2_EH.js} +4 -3
  5. package/dist/TVideo-D9AOiyq2.js +948 -0
  6. package/dist/agent.cjs +4926 -4364
  7. package/dist/agent.js +11 -9
  8. package/dist/{block-source-DByORvKG.js → block-source-BhvdZomx.js} +3 -3
  9. package/dist/cli.cjs +8 -8
  10. package/dist/cli.js +15 -5
  11. package/dist/core.js +2 -2
  12. package/dist/experimental/browser.cjs +3705 -0
  13. package/dist/experimental/browser.d.cts +3 -0
  14. package/dist/experimental/browser.d.ts +3 -0
  15. package/dist/experimental/browser.js +413 -0
  16. package/dist/experimental.cjs +1 -1
  17. package/dist/experimental.js +9 -947
  18. package/dist/{linkify-CL9wwnZN.js → frame-mailbox-DaTrfyaF.js} +2 -297
  19. package/dist/index.cjs +25 -8
  20. package/dist/index.js +6 -5
  21. package/dist/linkify-CklfA1vp.js +298 -0
  22. package/dist/markdown.cjs +4907 -4362
  23. package/dist/markdown.js +4 -4
  24. package/dist/{mermaid-CWy4wtCL.js → mermaid-D0ov4_A1.js} +3 -3
  25. package/dist/mermaid.cjs +1 -1
  26. package/dist/mermaid.js +4 -4
  27. package/dist/{path-suggest-Dndu4dTi.js → path-suggest-fPzRsgPv.js} +1 -1
  28. package/dist/renderer/terminal-graphics.d.ts +1 -1
  29. package/dist/{terminal-graphics-D6KErRBY.js → terminal-graphics-DpSL29OQ.js} +1 -1
  30. package/dist/{tlog-theme-DIrlCw6m.js → tlog-theme-BnILsD3n.js} +10 -1203
  31. package/dist/vue/browser/types.d.ts +52 -0
  32. package/dist/vue/components/TBrowser.d.ts +231 -0
  33. package/dist/vue.cjs +25 -8
  34. package/dist/vue.js +8 -7
  35. package/package.json +16 -2
  36. /package/dist/{TMermaidText-wLnMMvVS.js → TMermaidText-C1akgJPU.js} +0 -0
  37. /package/dist/{math-image-BZhmfUeu.js → math-image-CcUpBnW0.js} +0 -0
  38. /package/dist/{path-mnSgEpCm.js → path-BI9W15Zt.js} +0 -0
  39. /package/dist/{wheel-scroll-DASkEZr-.js → wheel-scroll-CQ22Hcyj.js} +0 -0
@@ -1,111 +1,6 @@
1
- import { sanitizeDomHref } from "./hyperlink-clbb_ha_.js";
2
- import { EventZIndexContextKey, LayoutContextKey, RenderStackKey, injectionKey, intersectRect, padEndByCells$1 as padEndByCells, sanitizeInlineText, sanitizeTextBlock, sliceByCells, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useRenderStack, useTerminal, useTerminalNode, useVisibility, wrapByCells } from "./rect-JzWMJxxc.js";
1
+ import { EventZIndexContextKey, LayoutContextKey, RenderStackKey, intersectRect, padEndByCells$1 as padEndByCells, sanitizeInlineText, sanitizeTextBlock, sliceByCells, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useRenderStack, useTerminal, useTerminalNode, useVisibility, wrapByCells } from "./rect-JzWMJxxc.js";
3
2
  import { computed, defineComponent, h, inject, provide, shallowReactive, watchEffect } from "vue";
4
3
 
5
- //#region src/vue/theme.ts
6
- const tuiDefaultTheme = Object.freeze({
7
- colors: Object.freeze({
8
- link: "cyanBright",
9
- linkVisited: "magentaBright",
10
- danger: "redBright",
11
- success: "greenBright",
12
- warning: "yellowBright",
13
- info: "cyanBright",
14
- muted: "white",
15
- accent: "blueBright"
16
- }),
17
- components: Object.freeze({
18
- TLink: Object.freeze({
19
- style: Object.freeze({
20
- fg: "cyanBright",
21
- underline: true
22
- }),
23
- hoverStyle: Object.freeze({ underline: true }),
24
- focusStyle: Object.freeze({ inverse: true }),
25
- visitedStyle: Object.freeze({
26
- fg: "magentaBright",
27
- underline: true
28
- }),
29
- underline: true,
30
- hoverUnderline: true
31
- }),
32
- TTable: Object.freeze({
33
- headerStyle: Object.freeze({
34
- bold: true,
35
- underline: true
36
- }),
37
- borderStyle: Object.freeze({ dim: true }),
38
- rowStyle: Object.freeze({}),
39
- selectedStyle: Object.freeze({ inverse: true }),
40
- activeStyle: Object.freeze({ underline: true })
41
- }),
42
- TFormField: Object.freeze({
43
- labelStyle: Object.freeze({ bold: true }),
44
- helpStyle: Object.freeze({ dim: true }),
45
- errorStyle: Object.freeze({ fg: "redBright" })
46
- })
47
- })
48
- });
49
- function mergeStyleToken(base, override) {
50
- if (!base && !override) return void 0;
51
- return {
52
- ...base ?? {},
53
- ...override ?? {}
54
- };
55
- }
56
- function createTheme(overrides = {}) {
57
- const components = overrides.components ?? {};
58
- const link = components.TLink;
59
- const table = components.TTable;
60
- const formField = components.TFormField;
61
- const defaultLink = tuiDefaultTheme.components.TLink;
62
- const defaultTable = tuiDefaultTheme.components.TTable;
63
- const defaultFormField = tuiDefaultTheme.components.TFormField;
64
- const colors = {
65
- ...tuiDefaultTheme.colors,
66
- ...overrides.colors ?? {}
67
- };
68
- const defaultLinkFromColors = {
69
- ...defaultLink ?? {},
70
- style: mergeStyleToken(defaultLink?.style, colors.link ? { fg: colors.link } : void 0),
71
- visitedStyle: mergeStyleToken(defaultLink?.visitedStyle, colors.linkVisited ? { fg: colors.linkVisited } : void 0)
72
- };
73
- const linkStyle = link?.underline === false ? mergeStyleToken(mergeStyleToken(defaultLinkFromColors.style, link?.style), { underline: false }) : mergeStyleToken(defaultLinkFromColors.style, link?.style);
74
- const linkVisitedStyle = link?.underline === false ? mergeStyleToken(mergeStyleToken(defaultLinkFromColors.visitedStyle, link?.visitedStyle), { underline: false }) : mergeStyleToken(defaultLinkFromColors.visitedStyle, link?.visitedStyle);
75
- const linkHoverStyle = mergeStyleToken(defaultLinkFromColors.hoverStyle, link?.hoverStyle);
76
- return {
77
- colors,
78
- components: {
79
- TLink: {
80
- ...defaultLinkFromColors,
81
- ...link ?? {},
82
- style: linkStyle,
83
- hoverStyle: link?.hoverUnderline === false && link?.hoverStyle?.underline == null ? mergeStyleToken(linkHoverStyle, { underline: false }) : linkHoverStyle,
84
- focusStyle: mergeStyleToken(defaultLinkFromColors.focusStyle, link?.focusStyle),
85
- visitedStyle: linkVisitedStyle
86
- },
87
- TTable: {
88
- ...defaultTable ?? {},
89
- ...table ?? {},
90
- headerStyle: mergeStyleToken(defaultTable?.headerStyle, table?.headerStyle),
91
- borderStyle: mergeStyleToken(defaultTable?.borderStyle, table?.borderStyle),
92
- rowStyle: mergeStyleToken(defaultTable?.rowStyle, table?.rowStyle),
93
- selectedStyle: mergeStyleToken(defaultTable?.selectedStyle, table?.selectedStyle),
94
- activeStyle: mergeStyleToken(defaultTable?.activeStyle, table?.activeStyle)
95
- },
96
- TFormField: {
97
- ...defaultFormField ?? {},
98
- ...formField ?? {},
99
- labelStyle: mergeStyleToken(defaultFormField?.labelStyle, formField?.labelStyle),
100
- helpStyle: mergeStyleToken(defaultFormField?.helpStyle, formField?.helpStyle),
101
- errorStyle: mergeStyleToken(defaultFormField?.errorStyle, formField?.errorStyle)
102
- }
103
- }
104
- };
105
- }
106
- const TuiThemeContextKey = injectionKey("TuiTheme");
107
-
108
- //#endregion
109
4
  //#region src/vue/components/TText.ts
110
5
  function fitText(text, max) {
111
6
  if (max <= 0) return "";
@@ -428,35 +323,6 @@ const TView = defineComponent({
428
323
  }
429
324
  });
430
325
 
431
- //#endregion
432
- //#region src/vue/components/simple-utils.ts
433
- function clamp(n, min, max) {
434
- return Math.max(min, Math.min(max, n));
435
- }
436
- function mergeStyle(...styles) {
437
- const out = {};
438
- for (const style of styles) {
439
- if (!style) continue;
440
- Object.assign(out, style);
441
- }
442
- return out;
443
- }
444
- function fitCellText(value, width, align = "left") {
445
- const w = Math.max(0, Math.floor(width));
446
- if (w <= 0) return "";
447
- const text = sliceByCells(sanitizeInlineText(String(value ?? "")), w);
448
- if (align === "right") {
449
- const cells = textCellWidth(text);
450
- return `${" ".repeat(Math.max(0, w - cells))}${text}`;
451
- }
452
- return padEndByCells(text, w);
453
- }
454
- function repeatToCells(ch, width) {
455
- const w = Math.max(0, Math.floor(width));
456
- if (w <= 0) return "";
457
- return ch.repeat(w);
458
- }
459
-
460
326
  //#endregion
461
327
  //#region src/vue/scheduler/frame-mailbox.ts
462
328
  const EMPTY = Symbol("frame-mailbox-empty");
@@ -588,165 +454,4 @@ function createFrameMailbox(options) {
588
454
  }
589
455
 
590
456
  //#endregion
591
- //#region src/vue/utils/style-cache.ts
592
- const EMPTY_STYLE = Object.freeze({});
593
- const inverseStyleCache = new WeakMap();
594
- const dimStyleCache = new WeakMap();
595
- function cacheBase(base) {
596
- for (const key in base) if (Object.prototype.hasOwnProperty.call(base, key)) return base;
597
- return EMPTY_STYLE;
598
- }
599
- function cacheable(base) {
600
- return Object.isFrozen(base);
601
- }
602
- function defaultActiveStyle(base) {
603
- if (base.inverse) return base;
604
- base = cacheBase(base);
605
- if (!cacheable(base)) return {
606
- ...base,
607
- inverse: true
608
- };
609
- let cached = inverseStyleCache.get(base);
610
- if (!cached) {
611
- cached = Object.freeze({
612
- ...base,
613
- inverse: true
614
- });
615
- inverseStyleCache.set(base, cached);
616
- }
617
- return cached;
618
- }
619
- function defaultDimStyle(base) {
620
- if (base.dim) return base;
621
- base = cacheBase(base);
622
- if (!cacheable(base)) return {
623
- ...base,
624
- dim: true
625
- };
626
- let cached = dimStyleCache.get(base);
627
- if (!cached) {
628
- cached = Object.freeze({
629
- ...base,
630
- dim: true
631
- });
632
- dimStyleCache.set(base, cached);
633
- }
634
- return cached;
635
- }
636
-
637
- //#endregion
638
- //#region src/vue/linkify.ts
639
- const DEFAULT_PROTOCOLS = Object.freeze([
640
- "http",
641
- "https",
642
- "mailto"
643
- ]);
644
- const URL_TEXT_RE = /(?:https?:\/\/|mailto:|\.{1,2}\/|\/|#|\?)[^\s<>"'`,。;:!?、]+/giu;
645
- const TRAILING_PUNCTUATION_RE = /[.,;:!?,。;:!?、]/u;
646
- const TRAILING_CLOSER_RE = /[)\]})】》」』”’]/u;
647
- const TEXT_BOUNDARY_RE = /[\s([{<:="'`,。;:!?、(【《「『“‘]/u;
648
- const CLOSE_TO_OPEN = {
649
- ")": "(",
650
- "]": "[",
651
- "}": "{",
652
- ")": "(",
653
- "】": "【",
654
- "》": "《",
655
- "」": "「",
656
- "』": "『",
657
- "”": "“",
658
- "’": "‘"
659
- };
660
- function protocolSet(options) {
661
- return new Set(options.protocols ?? DEFAULT_PROTOCOLS);
662
- }
663
- function scheme(raw) {
664
- return raw.match(/^[a-z][a-z0-9+.-]*:/i)?.[0].slice(0, -1).toLowerCase() ?? null;
665
- }
666
- function isRelativeCandidate(raw) {
667
- if (raw.startsWith("./")) return raw.length > 2;
668
- if (raw.startsWith("../")) return raw.length > 3;
669
- if (raw.startsWith("/")) return raw.length > 1;
670
- if (raw.startsWith("#")) return raw.length > 1;
671
- if (raw.startsWith("?")) return raw.length > 1;
672
- return false;
673
- }
674
- function hasTextBoundary(text, index) {
675
- return index === 0 || TEXT_BOUNDARY_RE.test(text[index - 1] ?? "");
676
- }
677
- function lastChar(value) {
678
- return value[value.length - 1] ?? "";
679
- }
680
- function splitTrailingPunctuation(raw) {
681
- let body = raw;
682
- let suffix = "";
683
- let changed = true;
684
- while (changed && body) {
685
- changed = false;
686
- while (body && TRAILING_PUNCTUATION_RE.test(lastChar(body))) {
687
- suffix = lastChar(body) + suffix;
688
- body = body.slice(0, -1);
689
- changed = true;
690
- }
691
- while (body && TRAILING_CLOSER_RE.test(lastChar(body))) {
692
- const ch = lastChar(body);
693
- const open = CLOSE_TO_OPEN[ch];
694
- if (!open) break;
695
- let opens = 0;
696
- let closes = 0;
697
- for (const c of body) if (c === open) opens++;
698
- else if (c === ch) closes++;
699
- if (closes <= opens) break;
700
- suffix = ch + suffix;
701
- body = body.slice(0, -1);
702
- changed = true;
703
- }
704
- }
705
- return {
706
- body,
707
- suffix
708
- };
709
- }
710
- function normalizeLinkifiedHref(body, options) {
711
- const protocols = protocolSet(options);
712
- const maxUrlLength = options.maxUrlLength;
713
- if (maxUrlLength != null && body.length > Math.max(0, Math.floor(maxUrlLength))) return null;
714
- const rawScheme = scheme(body);
715
- if (rawScheme === "http" || rawScheme === "https" || rawScheme === "mailto") {
716
- if (!protocols.has(rawScheme)) return null;
717
- return sanitizeDomHref(body, { allowRelative: false });
718
- }
719
- if (options.allowRelative && isRelativeCandidate(body)) return sanitizeDomHref(body, { allowRelative: true });
720
- return null;
721
- }
722
- function linkifyTextSegments(text, options = {}) {
723
- if (!text) return [];
724
- const out = [];
725
- const regex = new RegExp(URL_TEXT_RE.source, URL_TEXT_RE.flags);
726
- let cursor = 0;
727
- let match;
728
- while ((match = regex.exec(text)) != null) {
729
- const raw = match[0] ?? "";
730
- if (!raw) {
731
- regex.lastIndex = Math.max(regex.lastIndex, match.index + 1);
732
- continue;
733
- }
734
- const { body, suffix } = splitTrailingPunctuation(raw);
735
- if (!hasTextBoundary(text, match.index)) continue;
736
- if (isRelativeCandidate(body) && text[match.index - 1] === ":" && /[a-z0-9]/iu.test(text[match.index - 2] ?? "")) continue;
737
- const href = normalizeLinkifiedHref(body, options);
738
- if (!href) continue;
739
- if (match.index > cursor) out.push({ text: text.slice(cursor, match.index) });
740
- out.push({
741
- text: body,
742
- href
743
- });
744
- if (suffix) out.push({ text: suffix });
745
- cursor = match.index + raw.length;
746
- }
747
- if (cursor < text.length) out.push({ text: text.slice(cursor) });
748
- return out.length ? out : [{ text }];
749
- }
750
-
751
- //#endregion
752
- export { TText, TView, TuiThemeContextKey, clamp, createFrameMailbox, createTheme, defaultActiveStyle, defaultDimStyle, fitCellText, linkifyTextSegments, mergeStyle, repeatToCells, tuiDefaultTheme };
457
+ export { TText, TView, createFrameMailbox };
package/dist/index.cjs CHANGED
@@ -9334,21 +9334,32 @@ var nextImeOwnerId = 0, nextPasteImageId = 0, TInput = (0, import_vue20.defineCo
9334
9334
  let hasValue = getValue().length > 0, hasMentions = (props.mentions?.length ?? 0) > 0, hasMultiline = (props.multilineTexts?.length ?? 0) > 0;
9335
9335
  !hasValue && !hasMentions && !hasMultiline || (anchor.value = null, hasMentions && emitMentions([]), hasMultiline && emit("update:multilineTexts", []), hasValue || cursor.value !== 0 ? (pushUndoSnapshot(""), applyEdit("", 0)) : (ensureCursorVisible(), syncImeAnchorNow(), scheduler.invalidate()));
9336
9336
  }
9337
- function deleteSelectionIfAny(value) {
9338
- let sel = selection.value;
9339
- if (!sel)
9337
+ function deleteRangeIfAny(value, start, end) {
9338
+ let from = clamp5(Math.min(start, end), 0, value.length), to = clamp5(Math.max(start, end), 0, value.length);
9339
+ if (to <= from)
9340
9340
  return { value, cursor: cursor.value, deleted: !1 };
9341
- let tokenStart = countMultilineTokens2(value, sel.start), tokenEnd = countMultilineTokens2(value, sel.end);
9341
+ let tokenStart = countMultilineTokens2(value, from), tokenEnd = countMultilineTokens2(value, to);
9342
9342
  if (tokenEnd > tokenStart) {
9343
9343
  let current = props.multilineTexts ?? [], nextMultiline = [...current.slice(0, tokenStart), ...current.slice(tokenEnd)];
9344
9344
  emit("update:multilineTexts", nextMultiline);
9345
9345
  }
9346
- let mentionStart = countMentionTokens2(value, sel.start), mentionEnd = countMentionTokens2(value, sel.end);
9346
+ let mentionStart = countMentionTokens2(value, from), mentionEnd = countMentionTokens2(value, to);
9347
9347
  if (mentionEnd > mentionStart) {
9348
9348
  let current = pendingMentions.value ?? props.mentions ?? [], nextMentions = [...current.slice(0, mentionStart), ...current.slice(mentionEnd)];
9349
9349
  emitMentions(nextMentions);
9350
9350
  }
9351
- return { value: value.slice(0, sel.start) + value.slice(sel.end), cursor: sel.start, deleted: !0 };
9351
+ return { value: value.slice(0, from) + value.slice(to), cursor: from, deleted: !0 };
9352
+ }
9353
+ function deleteSelectionIfAny(value) {
9354
+ let sel = selection.value;
9355
+ return sel ? deleteRangeIfAny(value, sel.start, sel.end) : { value, cursor: cursor.value, deleted: !1 };
9356
+ }
9357
+ function deleteToLineBoundary(value, direction) {
9358
+ let sel = selection.value;
9359
+ if (sel)
9360
+ return deleteRangeIfAny(value, sel.start, sel.end);
9361
+ let { line, lines } = indexToLineCellCol(value, cursor.value), target = direction === "start" ? lines[line].start : lines[line].end;
9362
+ return deleteRangeIfAny(value, cursor.value, target);
9352
9363
  }
9353
9364
  function insertText(rawText) {
9354
9365
  let text = rawText || "";
@@ -9904,7 +9915,13 @@ var nextImeOwnerId = 0, nextPasteImageId = 0, TInput = (0, import_vue20.defineCo
9904
9915
  }
9905
9916
  return;
9906
9917
  }
9907
- let clearWithDeleteOrBackspace = !!(!e.altKey && (e.ctrlKey && !e.metaKey || e.metaKey && !e.ctrlKey));
9918
+ let clearWithDeleteOrBackspace = !!(!e.altKey && e.ctrlKey && !e.metaKey);
9919
+ if (e.metaKey && !e.ctrlKey && !e.altKey && (e.key === "Backspace" || e.key === "Delete")) {
9920
+ e.preventDefault(), e.stopPropagation();
9921
+ let next = deleteToLineBoundary(value, e.key === "Backspace" ? "start" : "end");
9922
+ next.deleted && (pushUndoSnapshot(next.value), applyEdit(next.value, next.cursor));
9923
+ return;
9924
+ }
9908
9925
  if (e.key === "Delete" && clearWithDeleteOrBackspace) {
9909
9926
  e.preventDefault(), e.stopPropagation(), clearAll();
9910
9927
  return;
@@ -10362,7 +10379,7 @@ var nextImeOwnerId = 0, nextPasteImageId = 0, TInput = (0, import_vue20.defineCo
10362
10379
  }
10363
10380
  }
10364
10381
  })), (0, import_vue20.onBeforeUnmount)(() => {
10365
- stopBlink();
10382
+ stopBlink(), imeAnchor?.value?.ownerId === imeOwnerId && (imeAnchor.value = null);
10366
10383
  }), () => (0, import_vue20.h)("span", rootProps);
10367
10384
  }
10368
10385
  });
package/dist/index.js CHANGED
@@ -3,16 +3,17 @@ import "./ansi-palette-BHF1rN7R.js";
3
3
  import "./hyperlink-clbb_ha_.js";
4
4
  import { createDomRenderer } from "./dom-renderer-BfwAEQMf.js";
5
5
  import "./rect-JzWMJxxc.js";
6
- import { TText, TView, createTheme, linkifyTextSegments, tuiDefaultTheme } from "./linkify-CL9wwnZN.js";
6
+ import { createTheme, linkifyTextSegments, tuiDefaultTheme } from "./linkify-CklfA1vp.js";
7
7
  import "./runtime-Byf8XXOT.js";
8
8
  import "./frame-perf-CHpWhbC4.js";
9
9
  import "./trace-Bh8WnoMo.js";
10
10
  import "./env-Cl8qmNFN.js";
11
- import { TAutocompleteInput, TBadge, TCheckbox, TCode, TDataTable, TDivider, TFormField, TLink, TLinkifyText, TList, TPasswordInput, TRadioGroup, TSlider, TSwitch, TTable, TTag, TTree, TerminalProvider, createTInputHostPlugin } from "./TTree-kk8ntrpg.js";
11
+ import { TAutocompleteInput, TBadge, TCheckbox, TCode, TDataTable, TDivider, TFormField, TLink, TLinkifyText, TList, TPasswordInput, TRadioGroup, TSlider, TSwitch, TTable, TTag, TTree, TerminalProvider, createTInputHostPlugin } from "./TTree-3W5A2_EH.js";
12
12
  import "./terminal-selection-4W1SJj4c.js";
13
13
  import "./debug-logger-CmsGI4of.js";
14
- import { TBox, TCommandPalette, TDialog, TInput, TSelect, computeCommandPaletteMatchRanges } from "./TSelect-CMBOOFwK.js";
15
- import "./path-mnSgEpCm.js";
16
- import "./wheel-scroll-DASkEZr-.js";
14
+ import { TBox, TCommandPalette, TDialog, TInput, TSelect, computeCommandPaletteMatchRanges } from "./TSelect-CCsjjCOr.js";
15
+ import { TText, TView } from "./frame-mailbox-DaTrfyaF.js";
16
+ import "./path-BI9W15Zt.js";
17
+ import "./wheel-scroll-CQ22Hcyj.js";
17
18
 
18
19
  export { TAutocompleteInput, TBadge, TBox, TCheckbox, TCode, TCommandPalette, TDataTable, TDialog, TDivider, TFormField, TInput, TLink, TLinkifyText, TList, TPasswordInput, TRadioGroup, TSelect, TSlider, TSwitch, TTable, TTag, TText, TTree, TView, TerminalProvider, computeCommandPaletteMatchRanges, createDomRenderer, createTInputHostPlugin, createTerminal, createTheme, linkifyTextSegments, tuiDefaultTheme };
@@ -0,0 +1,298 @@
1
+ import { sanitizeDomHref } from "./hyperlink-clbb_ha_.js";
2
+ import { injectionKey, padEndByCells$1 as padEndByCells, sanitizeInlineText, sliceByCells, textCellWidth$1 as textCellWidth } from "./rect-JzWMJxxc.js";
3
+
4
+ //#region src/vue/theme.ts
5
+ const tuiDefaultTheme = Object.freeze({
6
+ colors: Object.freeze({
7
+ link: "cyanBright",
8
+ linkVisited: "magentaBright",
9
+ danger: "redBright",
10
+ success: "greenBright",
11
+ warning: "yellowBright",
12
+ info: "cyanBright",
13
+ muted: "white",
14
+ accent: "blueBright"
15
+ }),
16
+ components: Object.freeze({
17
+ TLink: Object.freeze({
18
+ style: Object.freeze({
19
+ fg: "cyanBright",
20
+ underline: true
21
+ }),
22
+ hoverStyle: Object.freeze({ underline: true }),
23
+ focusStyle: Object.freeze({ inverse: true }),
24
+ visitedStyle: Object.freeze({
25
+ fg: "magentaBright",
26
+ underline: true
27
+ }),
28
+ underline: true,
29
+ hoverUnderline: true
30
+ }),
31
+ TTable: Object.freeze({
32
+ headerStyle: Object.freeze({
33
+ bold: true,
34
+ underline: true
35
+ }),
36
+ borderStyle: Object.freeze({ dim: true }),
37
+ rowStyle: Object.freeze({}),
38
+ selectedStyle: Object.freeze({ inverse: true }),
39
+ activeStyle: Object.freeze({ underline: true })
40
+ }),
41
+ TFormField: Object.freeze({
42
+ labelStyle: Object.freeze({ bold: true }),
43
+ helpStyle: Object.freeze({ dim: true }),
44
+ errorStyle: Object.freeze({ fg: "redBright" })
45
+ })
46
+ })
47
+ });
48
+ function mergeStyleToken(base, override) {
49
+ if (!base && !override) return void 0;
50
+ return {
51
+ ...base ?? {},
52
+ ...override ?? {}
53
+ };
54
+ }
55
+ function createTheme(overrides = {}) {
56
+ const components = overrides.components ?? {};
57
+ const link = components.TLink;
58
+ const table = components.TTable;
59
+ const formField = components.TFormField;
60
+ const defaultLink = tuiDefaultTheme.components.TLink;
61
+ const defaultTable = tuiDefaultTheme.components.TTable;
62
+ const defaultFormField = tuiDefaultTheme.components.TFormField;
63
+ const colors = {
64
+ ...tuiDefaultTheme.colors,
65
+ ...overrides.colors ?? {}
66
+ };
67
+ const defaultLinkFromColors = {
68
+ ...defaultLink ?? {},
69
+ style: mergeStyleToken(defaultLink?.style, colors.link ? { fg: colors.link } : void 0),
70
+ visitedStyle: mergeStyleToken(defaultLink?.visitedStyle, colors.linkVisited ? { fg: colors.linkVisited } : void 0)
71
+ };
72
+ const linkStyle = link?.underline === false ? mergeStyleToken(mergeStyleToken(defaultLinkFromColors.style, link?.style), { underline: false }) : mergeStyleToken(defaultLinkFromColors.style, link?.style);
73
+ const linkVisitedStyle = link?.underline === false ? mergeStyleToken(mergeStyleToken(defaultLinkFromColors.visitedStyle, link?.visitedStyle), { underline: false }) : mergeStyleToken(defaultLinkFromColors.visitedStyle, link?.visitedStyle);
74
+ const linkHoverStyle = mergeStyleToken(defaultLinkFromColors.hoverStyle, link?.hoverStyle);
75
+ return {
76
+ colors,
77
+ components: {
78
+ TLink: {
79
+ ...defaultLinkFromColors,
80
+ ...link ?? {},
81
+ style: linkStyle,
82
+ hoverStyle: link?.hoverUnderline === false && link?.hoverStyle?.underline == null ? mergeStyleToken(linkHoverStyle, { underline: false }) : linkHoverStyle,
83
+ focusStyle: mergeStyleToken(defaultLinkFromColors.focusStyle, link?.focusStyle),
84
+ visitedStyle: linkVisitedStyle
85
+ },
86
+ TTable: {
87
+ ...defaultTable ?? {},
88
+ ...table ?? {},
89
+ headerStyle: mergeStyleToken(defaultTable?.headerStyle, table?.headerStyle),
90
+ borderStyle: mergeStyleToken(defaultTable?.borderStyle, table?.borderStyle),
91
+ rowStyle: mergeStyleToken(defaultTable?.rowStyle, table?.rowStyle),
92
+ selectedStyle: mergeStyleToken(defaultTable?.selectedStyle, table?.selectedStyle),
93
+ activeStyle: mergeStyleToken(defaultTable?.activeStyle, table?.activeStyle)
94
+ },
95
+ TFormField: {
96
+ ...defaultFormField ?? {},
97
+ ...formField ?? {},
98
+ labelStyle: mergeStyleToken(defaultFormField?.labelStyle, formField?.labelStyle),
99
+ helpStyle: mergeStyleToken(defaultFormField?.helpStyle, formField?.helpStyle),
100
+ errorStyle: mergeStyleToken(defaultFormField?.errorStyle, formField?.errorStyle)
101
+ }
102
+ }
103
+ };
104
+ }
105
+ const TuiThemeContextKey = injectionKey("TuiTheme");
106
+
107
+ //#endregion
108
+ //#region src/vue/components/simple-utils.ts
109
+ function clamp(n, min, max) {
110
+ return Math.max(min, Math.min(max, n));
111
+ }
112
+ function mergeStyle(...styles) {
113
+ const out = {};
114
+ for (const style of styles) {
115
+ if (!style) continue;
116
+ Object.assign(out, style);
117
+ }
118
+ return out;
119
+ }
120
+ function fitCellText(value, width, align = "left") {
121
+ const w = Math.max(0, Math.floor(width));
122
+ if (w <= 0) return "";
123
+ const text = sliceByCells(sanitizeInlineText(String(value ?? "")), w);
124
+ if (align === "right") {
125
+ const cells = textCellWidth(text);
126
+ return `${" ".repeat(Math.max(0, w - cells))}${text}`;
127
+ }
128
+ return padEndByCells(text, w);
129
+ }
130
+ function repeatToCells(ch, width) {
131
+ const w = Math.max(0, Math.floor(width));
132
+ if (w <= 0) return "";
133
+ return ch.repeat(w);
134
+ }
135
+
136
+ //#endregion
137
+ //#region src/vue/utils/style-cache.ts
138
+ const EMPTY_STYLE = Object.freeze({});
139
+ const inverseStyleCache = new WeakMap();
140
+ const dimStyleCache = new WeakMap();
141
+ function cacheBase(base) {
142
+ for (const key in base) if (Object.prototype.hasOwnProperty.call(base, key)) return base;
143
+ return EMPTY_STYLE;
144
+ }
145
+ function cacheable(base) {
146
+ return Object.isFrozen(base);
147
+ }
148
+ function defaultActiveStyle(base) {
149
+ if (base.inverse) return base;
150
+ base = cacheBase(base);
151
+ if (!cacheable(base)) return {
152
+ ...base,
153
+ inverse: true
154
+ };
155
+ let cached = inverseStyleCache.get(base);
156
+ if (!cached) {
157
+ cached = Object.freeze({
158
+ ...base,
159
+ inverse: true
160
+ });
161
+ inverseStyleCache.set(base, cached);
162
+ }
163
+ return cached;
164
+ }
165
+ function defaultDimStyle(base) {
166
+ if (base.dim) return base;
167
+ base = cacheBase(base);
168
+ if (!cacheable(base)) return {
169
+ ...base,
170
+ dim: true
171
+ };
172
+ let cached = dimStyleCache.get(base);
173
+ if (!cached) {
174
+ cached = Object.freeze({
175
+ ...base,
176
+ dim: true
177
+ });
178
+ dimStyleCache.set(base, cached);
179
+ }
180
+ return cached;
181
+ }
182
+
183
+ //#endregion
184
+ //#region src/vue/linkify.ts
185
+ const DEFAULT_PROTOCOLS = Object.freeze([
186
+ "http",
187
+ "https",
188
+ "mailto"
189
+ ]);
190
+ const URL_TEXT_RE = /(?:https?:\/\/|mailto:|\.{1,2}\/|\/|#|\?)[^\s<>"'`,。;:!?、]+/giu;
191
+ const TRAILING_PUNCTUATION_RE = /[.,;:!?,。;:!?、]/u;
192
+ const TRAILING_CLOSER_RE = /[)\]})】》」』”’]/u;
193
+ const TEXT_BOUNDARY_RE = /[\s([{<:="'`,。;:!?、(【《「『“‘]/u;
194
+ const CLOSE_TO_OPEN = {
195
+ ")": "(",
196
+ "]": "[",
197
+ "}": "{",
198
+ ")": "(",
199
+ "】": "【",
200
+ "》": "《",
201
+ "」": "「",
202
+ "』": "『",
203
+ "”": "“",
204
+ "’": "‘"
205
+ };
206
+ function protocolSet(options) {
207
+ return new Set(options.protocols ?? DEFAULT_PROTOCOLS);
208
+ }
209
+ function scheme(raw) {
210
+ return raw.match(/^[a-z][a-z0-9+.-]*:/i)?.[0].slice(0, -1).toLowerCase() ?? null;
211
+ }
212
+ function isRelativeCandidate(raw) {
213
+ if (raw.startsWith("./")) return raw.length > 2;
214
+ if (raw.startsWith("../")) return raw.length > 3;
215
+ if (raw.startsWith("/")) return raw.length > 1;
216
+ if (raw.startsWith("#")) return raw.length > 1;
217
+ if (raw.startsWith("?")) return raw.length > 1;
218
+ return false;
219
+ }
220
+ function hasTextBoundary(text, index) {
221
+ return index === 0 || TEXT_BOUNDARY_RE.test(text[index - 1] ?? "");
222
+ }
223
+ function lastChar(value) {
224
+ return value[value.length - 1] ?? "";
225
+ }
226
+ function splitTrailingPunctuation(raw) {
227
+ let body = raw;
228
+ let suffix = "";
229
+ let changed = true;
230
+ while (changed && body) {
231
+ changed = false;
232
+ while (body && TRAILING_PUNCTUATION_RE.test(lastChar(body))) {
233
+ suffix = lastChar(body) + suffix;
234
+ body = body.slice(0, -1);
235
+ changed = true;
236
+ }
237
+ while (body && TRAILING_CLOSER_RE.test(lastChar(body))) {
238
+ const ch = lastChar(body);
239
+ const open = CLOSE_TO_OPEN[ch];
240
+ if (!open) break;
241
+ let opens = 0;
242
+ let closes = 0;
243
+ for (const c of body) if (c === open) opens++;
244
+ else if (c === ch) closes++;
245
+ if (closes <= opens) break;
246
+ suffix = ch + suffix;
247
+ body = body.slice(0, -1);
248
+ changed = true;
249
+ }
250
+ }
251
+ return {
252
+ body,
253
+ suffix
254
+ };
255
+ }
256
+ function normalizeLinkifiedHref(body, options) {
257
+ const protocols = protocolSet(options);
258
+ const maxUrlLength = options.maxUrlLength;
259
+ if (maxUrlLength != null && body.length > Math.max(0, Math.floor(maxUrlLength))) return null;
260
+ const rawScheme = scheme(body);
261
+ if (rawScheme === "http" || rawScheme === "https" || rawScheme === "mailto") {
262
+ if (!protocols.has(rawScheme)) return null;
263
+ return sanitizeDomHref(body, { allowRelative: false });
264
+ }
265
+ if (options.allowRelative && isRelativeCandidate(body)) return sanitizeDomHref(body, { allowRelative: true });
266
+ return null;
267
+ }
268
+ function linkifyTextSegments(text, options = {}) {
269
+ if (!text) return [];
270
+ const out = [];
271
+ const regex = new RegExp(URL_TEXT_RE.source, URL_TEXT_RE.flags);
272
+ let cursor = 0;
273
+ let match;
274
+ while ((match = regex.exec(text)) != null) {
275
+ const raw = match[0] ?? "";
276
+ if (!raw) {
277
+ regex.lastIndex = Math.max(regex.lastIndex, match.index + 1);
278
+ continue;
279
+ }
280
+ const { body, suffix } = splitTrailingPunctuation(raw);
281
+ if (!hasTextBoundary(text, match.index)) continue;
282
+ if (isRelativeCandidate(body) && text[match.index - 1] === ":" && /[a-z0-9]/iu.test(text[match.index - 2] ?? "")) continue;
283
+ const href = normalizeLinkifiedHref(body, options);
284
+ if (!href) continue;
285
+ if (match.index > cursor) out.push({ text: text.slice(cursor, match.index) });
286
+ out.push({
287
+ text: body,
288
+ href
289
+ });
290
+ if (suffix) out.push({ text: suffix });
291
+ cursor = match.index + raw.length;
292
+ }
293
+ if (cursor < text.length) out.push({ text: text.slice(cursor) });
294
+ return out.length ? out : [{ text }];
295
+ }
296
+
297
+ //#endregion
298
+ export { TuiThemeContextKey, clamp, createTheme, defaultActiveStyle, defaultDimStyle, fitCellText, linkifyTextSegments, mergeStyle, repeatToCells, tuiDefaultTheme };