@simon_he/vue-tui 1.0.0 → 1.0.2

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.
@@ -77,6 +77,13 @@ export declare const TVirtualRows: import("vue").DefineComponent<import("vue").E
77
77
  type: NumberConstructor;
78
78
  required: true;
79
79
  };
80
+ itemChangedRange: {
81
+ type: PropType<() => {
82
+ start: number;
83
+ end: number;
84
+ } | null | undefined>;
85
+ default: undefined;
86
+ };
80
87
  getItem: {
81
88
  type: PropType<(index: number) => unknown>;
82
89
  required: true;
@@ -156,6 +163,13 @@ export declare const TVirtualRows: import("vue").DefineComponent<import("vue").E
156
163
  type: NumberConstructor;
157
164
  required: true;
158
165
  };
166
+ itemChangedRange: {
167
+ type: PropType<() => {
168
+ start: number;
169
+ end: number;
170
+ } | null | undefined>;
171
+ default: undefined;
172
+ };
159
173
  getItem: {
160
174
  type: PropType<(index: number) => unknown>;
161
175
  required: true;
@@ -241,6 +255,10 @@ export declare const TVirtualRows: import("vue").DefineComponent<import("vue").E
241
255
  rowScrollMode: TVirtualRowsRowScrollMode;
242
256
  scrollTop: number;
243
257
  selectionText: (item: unknown, index: number) => string;
258
+ itemChangedRange: () => {
259
+ start: number;
260
+ end: number;
261
+ } | null | undefined;
244
262
  renderItemNodes: (ctx: TVirtualRowsRenderNodesContext) => VNodeChild;
245
263
  selectionSpanText: (ctx: TVirtualRowsSelectionSpanTextContext) => string;
246
264
  wheelScroll: boolean;
@@ -56,6 +56,10 @@ export type TTranscriptDataSource = Readonly<{
56
56
  getRow(index: number): TTranscriptRow;
57
57
  getRowKey?: (index: number) => string | number;
58
58
  getRowVersion?: (index: number) => string | number;
59
+ getChangedRange?: () => {
60
+ start: number;
61
+ end: number;
62
+ } | null | undefined;
59
63
  firstRowIndex?: () => number;
60
64
  }>;
61
65
  export type TTranscriptVisualSegment = Readonly<{
package/dist/vue.cjs CHANGED
@@ -7457,22 +7457,40 @@ function normalizeVisibleLimit(value) {
7457
7457
  function isCommandPaletteRowSelectable(item) {
7458
7458
  return Boolean(item && item.kind !== "separator" && item.kind !== "group" && !item.disabled);
7459
7459
  }
7460
- function substringMatcher(item, query) {
7461
- const q = query.trim().toLowerCase();
7462
- if (!q)
7463
- return { score: 0 };
7464
- const labelRanges = computeCommandPaletteMatchRanges(item.label, q);
7465
- const detailRanges = item.detail ? computeCommandPaletteMatchRanges(item.detail, q) : [];
7466
- const keywordMatch = (item.keywords ?? []).some(
7467
- (keyword) => String(keyword ?? "").toLowerCase().includes(q)
7468
- );
7469
- if (!labelRanges.length && !detailRanges.length && !keywordMatch)
7470
- return null;
7471
- return {
7472
- score: labelRanges.length ? 100 : detailRanges.length ? 50 : 10,
7473
- labelRanges,
7474
- detailRanges
7475
- };
7460
+ function defaultSubstringEntries(sourceItems, query) {
7461
+ const q = query.trim();
7462
+ if (!q) {
7463
+ return sourceItems.map((item, sourceIndex) => ({
7464
+ item,
7465
+ sourceIndex,
7466
+ match: { score: 0 }
7467
+ }));
7468
+ }
7469
+ const needle = q.toLowerCase();
7470
+ const labelMatches = [];
7471
+ const detailMatches = [];
7472
+ const keywordMatches = [];
7473
+ for (let sourceIndex = 0; sourceIndex < sourceItems.length; sourceIndex++) {
7474
+ const item = sourceItems[sourceIndex];
7475
+ if (item.kind === "separator" || item.kind === "group")
7476
+ continue;
7477
+ const label = String(item.label ?? "");
7478
+ const detail = item.detail == null ? "" : String(item.detail);
7479
+ if (label.toLowerCase().includes(needle)) {
7480
+ labelMatches.push({ item, sourceIndex, match: { score: 100 } });
7481
+ continue;
7482
+ }
7483
+ if (detail.toLowerCase().includes(needle)) {
7484
+ detailMatches.push({ item, sourceIndex, match: { score: 50 } });
7485
+ continue;
7486
+ }
7487
+ if ((item.keywords ?? []).some(
7488
+ (keyword) => String(keyword ?? "").toLowerCase().includes(needle)
7489
+ )) {
7490
+ keywordMatches.push({ item, sourceIndex, match: { score: 10 } });
7491
+ }
7492
+ }
7493
+ return labelMatches.concat(detailMatches, keywordMatches);
7476
7494
  }
7477
7495
  function fuzzyMatcher(item, query) {
7478
7496
  const q = query.trim().toLowerCase();
@@ -7640,14 +7658,22 @@ var TCommandPalette = (0, import_vue15.defineComponent)({
7640
7658
  const filteredEntries = (0, import_vue15.computed)(() => {
7641
7659
  const q = query.value.trim();
7642
7660
  const sourceItems = props.itemsProvider ? providerItems.value ?? [] : props.items;
7643
- const matcher = props.matcher ?? (props.filterStrategy === "fuzzy" ? fuzzyMatcher : substringMatcher);
7644
- const entries = sourceItems.flatMap((item, sourceIndex) => {
7661
+ if (!props.matcher && props.filterStrategy === "substring") {
7662
+ return defaultSubstringEntries(sourceItems, q);
7663
+ }
7664
+ const matcher = props.matcher ?? fuzzyMatcher;
7665
+ const entries = [];
7666
+ for (let sourceIndex = 0; sourceIndex < sourceItems.length; sourceIndex++) {
7667
+ const item = sourceItems[sourceIndex];
7645
7668
  if (item.kind === "separator" || item.kind === "group") {
7646
- return q ? [] : [{ item, sourceIndex, match: { score: 0 } }];
7669
+ if (!q)
7670
+ entries.push({ item, sourceIndex, match: { score: 0 } });
7671
+ continue;
7647
7672
  }
7648
7673
  const match = matcher(item, q);
7649
- return match ? [{ item, sourceIndex, match }] : [];
7650
- });
7674
+ if (match)
7675
+ entries.push({ item, sourceIndex, match });
7676
+ }
7651
7677
  entries.sort((a, b) => b.match.score - a.match.score || a.sourceIndex - b.sourceIndex);
7652
7678
  return entries;
7653
7679
  });
@@ -8371,6 +8397,20 @@ function rowKey(row, index, key) {
8371
8397
  function sameRowKey(a, b) {
8372
8398
  return Object.is(a, b);
8373
8399
  }
8400
+ function selectedRowKeyIndex(keys) {
8401
+ if (!keys?.length)
8402
+ return null;
8403
+ const indexed = /* @__PURE__ */ new Set();
8404
+ for (let index = 0; index < keys.length; index++) {
8405
+ if (!(index in keys))
8406
+ continue;
8407
+ const key = keys[index];
8408
+ if (typeof key === "number" && key === 0)
8409
+ return null;
8410
+ indexed.add(key);
8411
+ }
8412
+ return indexed;
8413
+ }
8374
8414
  var TTable = (0, import_vue16.defineComponent)({
8375
8415
  name: "TTable",
8376
8416
  props: {
@@ -8443,10 +8483,22 @@ var TTable = (0, import_vue16.defineComponent)({
8443
8483
  const activeRowStyle = (0, import_vue16.computed)(
8444
8484
  () => mergeStyle(theme.value.components.TTable?.activeStyle, props.activeStyle)
8445
8485
  );
8486
+ const selectedRowKeysIndex = (0, import_vue16.computed)(() => selectedRowKeyIndex(props.selectedRowKeys));
8446
8487
  const bodyRows = (0, import_vue16.computed)(() => {
8447
8488
  const top = props.header ? 2 : 0;
8448
8489
  return props.rows.slice(0, Math.max(0, props.h - top));
8449
8490
  });
8491
+ function isRowSelected(key) {
8492
+ if (props.selectedRowKey !== void 0 && sameRowKey(key, props.selectedRowKey))
8493
+ return true;
8494
+ const selectedKeys = props.selectedRowKeys;
8495
+ if (!selectedKeys?.length)
8496
+ return false;
8497
+ const indexed = selectedRowKeysIndex.value;
8498
+ if (indexed)
8499
+ return indexed.has(key);
8500
+ return selectedKeys.some((candidate) => sameRowKey(candidate, key));
8501
+ }
8450
8502
  return () => {
8451
8503
  const children = [];
8452
8504
  if (props.header && props.h > 0) {
@@ -8524,7 +8576,7 @@ var TTable = (0, import_vue16.defineComponent)({
8524
8576
  const row = bodyRows.value[index];
8525
8577
  const y = (props.header ? 2 : 0) + index;
8526
8578
  const key = rowKey(row, index, props.rowKey);
8527
- const selected = props.selectedRowKey !== void 0 && sameRowKey(key, props.selectedRowKey) || Boolean(props.selectedRowKeys?.some((candidate) => sameRowKey(candidate, key)));
8579
+ const selected = isRowSelected(key);
8528
8580
  const active = props.activeRowKey !== void 0 && sameRowKey(key, props.activeRowKey);
8529
8581
  children.push(
8530
8582
  (0, import_vue16.h)(
@@ -8693,44 +8745,59 @@ var TDataTable = (0, import_vue17.defineComponent)({
8693
8745
  },
8694
8746
  setup(props, { emit }) {
8695
8747
  const innerScrollTop = (0, import_vue17.ref)(0);
8696
- const indexedRows = (0, import_vue17.computed)(
8697
- () => props.rows.map((row, originalIndex) => ({ row, originalIndex }))
8748
+ const hasLocalFilter = (0, import_vue17.computed)(
8749
+ () => !props.manualFilter && props.filterable && Boolean(props.filter.trim())
8750
+ );
8751
+ const hasLocalSort = (0, import_vue17.computed)(
8752
+ () => !props.manualSort && props.sortable && Boolean(props.sortBy)
8698
8753
  );
8754
+ const indexedRows = (0, import_vue17.computed)(() => {
8755
+ if (!hasLocalFilter.value && !hasLocalSort.value)
8756
+ return null;
8757
+ return props.rows.map((row, originalIndex) => ({ row, originalIndex }));
8758
+ });
8699
8759
  const filteredRows = (0, import_vue17.computed)(() => {
8700
- if (props.manualFilter)
8701
- return indexedRows.value;
8702
- if (!props.filterable || !props.filter.trim())
8703
- return indexedRows.value;
8760
+ const rows = indexedRows.value;
8761
+ if (!rows)
8762
+ return null;
8763
+ if (!hasLocalFilter.value)
8764
+ return rows;
8704
8765
  const query = props.filter.trim().toLowerCase();
8705
8766
  if (props.filterPredicate) {
8706
- return indexedRows.value.filter(
8767
+ return rows.filter(
8707
8768
  ({ row, originalIndex }) => props.filterPredicate(row, query, props.columns, originalIndex)
8708
8769
  );
8709
8770
  }
8710
- return indexedRows.value.filter(
8771
+ return rows.filter(
8711
8772
  ({ row, originalIndex }) => props.columns.some(
8712
8773
  (column) => displayValue(column, row, originalIndex).toLowerCase().includes(query)
8713
8774
  )
8714
8775
  );
8715
8776
  });
8716
8777
  const sortedRows = (0, import_vue17.computed)(() => {
8717
- const rows = [...filteredRows.value];
8718
- if (props.manualSort || !props.sortable || !props.sortBy)
8778
+ const rows = filteredRows.value;
8779
+ if (!rows)
8780
+ return null;
8781
+ if (!hasLocalSort.value)
8719
8782
  return rows;
8783
+ const sorted = [...rows];
8720
8784
  const column = props.columns.find((candidate) => candidate.key === props.sortBy);
8721
- rows.sort((a, b) => {
8785
+ sorted.sort((a, b) => {
8722
8786
  const result = props.sorter && column ? props.sorter(a.row, b.row, column) : compareValues(a.row[props.sortBy], b.row[props.sortBy]);
8723
8787
  return props.sortDirection === "desc" ? -result : result;
8724
8788
  });
8725
- return rows;
8789
+ return sorted;
8726
8790
  });
8727
8791
  function nonNegativeInteger(value) {
8728
8792
  const n = Math.floor(Number(value));
8729
8793
  return Number.isFinite(n) ? Math.max(0, n) : 0;
8730
8794
  }
8731
8795
  const visibleRowCapacity = (0, import_vue17.computed)(() => Math.max(0, nonNegativeInteger(props.h) - 2));
8796
+ function processedRowCount() {
8797
+ return sortedRows.value?.length ?? props.rows.length;
8798
+ }
8732
8799
  function maxScrollTop2() {
8733
- return Math.max(0, sortedRows.value.length - visibleRowCapacity.value);
8800
+ return Math.max(0, processedRowCount() - visibleRowCapacity.value);
8734
8801
  }
8735
8802
  function clampScrollTop2(value) {
8736
8803
  return Math.min(maxScrollTop2(), nonNegativeInteger(value));
@@ -8754,12 +8821,27 @@ var TDataTable = (0, import_vue17.defineComponent)({
8754
8821
  },
8755
8822
  { immediate: true }
8756
8823
  );
8757
- const visibleRows = (0, import_vue17.computed)(
8758
- () => sortedRows.value.slice(
8759
- normalizedScrollTop.value,
8760
- normalizedScrollTop.value + visibleRowCapacity.value
8761
- )
8762
- );
8824
+ function dataEntryAt(absoluteIndex) {
8825
+ const rows = sortedRows.value;
8826
+ if (rows)
8827
+ return rows[absoluteIndex];
8828
+ const row = props.rows[absoluteIndex];
8829
+ return row ? { row, originalIndex: absoluteIndex } : void 0;
8830
+ }
8831
+ function originalIndexForAbsoluteIndex(absoluteIndex) {
8832
+ return dataEntryAt(absoluteIndex)?.originalIndex ?? absoluteIndex;
8833
+ }
8834
+ const visibleRows = (0, import_vue17.computed)(() => {
8835
+ const top = normalizedScrollTop.value;
8836
+ const bottom = top + visibleRowCapacity.value;
8837
+ const rows = sortedRows.value;
8838
+ if (rows)
8839
+ return rows.slice(top, bottom);
8840
+ return props.rows.slice(top, bottom).map((row, index) => ({
8841
+ row,
8842
+ originalIndex: top + index
8843
+ }));
8844
+ });
8763
8845
  const tableRows = (0, import_vue17.computed)(() => visibleRows.value.map(({ row }) => row));
8764
8846
  const activeAbsoluteIndex = (0, import_vue17.ref)(null);
8765
8847
  const activeRowIdentity = (0, import_vue17.ref)(NO_ACTIVE_ROW);
@@ -8768,7 +8850,7 @@ var TDataTable = (0, import_vue17.defineComponent)({
8768
8850
  () => props.columns.map((column) => {
8769
8851
  const format = column.format ? (value, row, visibleIndex) => {
8770
8852
  const absoluteIndex = normalizedScrollTop.value + visibleIndex;
8771
- const originalIndex = sortedRows.value[absoluteIndex]?.originalIndex ?? absoluteIndex;
8853
+ const originalIndex = originalIndexForAbsoluteIndex(absoluteIndex);
8772
8854
  return column.format(value, row, originalIndex);
8773
8855
  } : void 0;
8774
8856
  if (!props.sortable || column.key !== props.sortBy) {
@@ -8780,7 +8862,7 @@ var TDataTable = (0, import_vue17.defineComponent)({
8780
8862
  );
8781
8863
  function originalIndexAt(index) {
8782
8864
  const absoluteIndex = normalizedScrollTop.value + index;
8783
- return sortedRows.value[absoluteIndex]?.originalIndex ?? absoluteIndex;
8865
+ return originalIndexForAbsoluteIndex(absoluteIndex);
8784
8866
  }
8785
8867
  function dataTableRowKey(row, index) {
8786
8868
  return rowKey2(row, originalIndexAt(index), props.rowKey);
@@ -8801,14 +8883,28 @@ var TDataTable = (0, import_vue17.defineComponent)({
8801
8883
  const activeRowKey = (0, import_vue17.computed)(
8802
8884
  () => activeRowIdentity.value === NO_ACTIVE_ROW ? void 0 : activeRowIdentity.value
8803
8885
  );
8886
+ const activeRawRowKey = (0, import_vue17.computed)(() => {
8887
+ if (activeAbsoluteIndex.value == null || sortedRows.value)
8888
+ return NO_ACTIVE_ROW;
8889
+ const index = activeAbsoluteIndex.value;
8890
+ const row = props.rows[index];
8891
+ return row ? rowKey2(row, index, props.rowKey) : NO_ACTIVE_ROW;
8892
+ });
8893
+ function findDataIndexByKey(key) {
8894
+ const rows = sortedRows.value;
8895
+ if (rows) {
8896
+ return rows.findIndex((entry) => Object.is(dataRowKey(entry), key));
8897
+ }
8898
+ return props.rows.findIndex(
8899
+ (row, index) => Object.is(rowKey2(row, index, props.rowKey), key)
8900
+ );
8901
+ }
8804
8902
  (0, import_vue17.watch)(
8805
- () => [props.rowKey, ...sortedRows.value.map((entry) => dataRowKey(entry))],
8903
+ () => [props.rowKey, props.rows, sortedRows.value, activeRowIdentity.value],
8806
8904
  () => {
8807
8905
  if (activeRowIdentity.value === NO_ACTIVE_ROW)
8808
8906
  return;
8809
- const nextIndex = sortedRows.value.findIndex(
8810
- (entry) => Object.is(dataRowKey(entry), activeRowIdentity.value)
8811
- );
8907
+ const nextIndex = findDataIndexByKey(activeRowIdentity.value);
8812
8908
  if (nextIndex < 0) {
8813
8909
  clearActiveRow();
8814
8910
  return;
@@ -8816,9 +8912,22 @@ var TDataTable = (0, import_vue17.defineComponent)({
8816
8912
  activeAbsoluteIndex.value = nextIndex;
8817
8913
  }
8818
8914
  );
8915
+ (0, import_vue17.watch)(
8916
+ () => [props.rowKey, activeRawRowKey.value],
8917
+ ([, key]) => {
8918
+ if (activeRowIdentity.value === NO_ACTIVE_ROW)
8919
+ return;
8920
+ if (key === NO_ACTIVE_ROW) {
8921
+ clearActiveRow();
8922
+ return;
8923
+ }
8924
+ if (!Object.is(activeRowIdentity.value, key))
8925
+ activeRowIdentity.value = key;
8926
+ }
8927
+ );
8819
8928
  function setActiveAbsoluteIndex(absoluteIndex) {
8820
- const clamped = Math.max(0, Math.min(sortedRows.value.length - 1, absoluteIndex));
8821
- const entry = sortedRows.value[clamped];
8929
+ const clamped = Math.max(0, Math.min(processedRowCount() - 1, absoluteIndex));
8930
+ const entry = dataEntryAt(clamped);
8822
8931
  if (!entry) {
8823
8932
  clearActiveRow();
8824
8933
  return null;
@@ -8894,7 +9003,7 @@ var TDataTable = (0, import_vue17.defineComponent)({
8894
9003
  const active = setActiveAbsoluteIndex(current);
8895
9004
  if (!active)
8896
9005
  return;
8897
- const entry = sortedRows.value[active.dataIndex];
9006
+ const entry = dataEntryAt(active.dataIndex);
8898
9007
  if (!entry)
8899
9008
  return;
8900
9009
  const visibleIndex = active.dataIndex - active.scrollTop;
@@ -9444,7 +9553,7 @@ function clamp6(n, min, max) {
9444
9553
  function setFingerprintFn(buffer, fn) {
9445
9554
  buffer.fingerprintFn = fn;
9446
9555
  const len = buffer.rows * buffer.cols;
9447
- if (!len) {
9556
+ if (!fn || !len) {
9448
9557
  buffer.soaFingerprints = null;
9449
9558
  return;
9450
9559
  }
@@ -9462,7 +9571,12 @@ function setFingerprintFn(buffer, fn) {
9462
9571
  function getRowFingerprints(buffer, y) {
9463
9572
  if (!buffer.soaFingerprints)
9464
9573
  return null;
9465
- const physY = physicalRowIndex(buffer, y);
9574
+ if (buffer.rows <= 0 || buffer.cols <= 0)
9575
+ return null;
9576
+ const yy = Math.floor(y);
9577
+ if (!Number.isFinite(yy) || yy < 0 || yy >= buffer.rows)
9578
+ return null;
9579
+ const physY = physicalRowIndex(buffer, yy);
9466
9580
  const base = physY * buffer.cols;
9467
9581
  return buffer.soaFingerprints.subarray(base, base + buffer.cols);
9468
9582
  }
@@ -10745,11 +10859,17 @@ function createTerminal(opts) {
10745
10859
  },
10746
10860
  setFingerprintFn(fn) {
10747
10861
  assertNotDisposed();
10748
- base.setFingerprintFn(fn);
10862
+ const state = getPlaneState(plane);
10863
+ setFingerprintFn(state.buffer, fn);
10749
10864
  },
10750
10865
  getRowFingerprints(y) {
10751
10866
  assertNotDisposed();
10752
- return base.getRowFingerprints(y);
10867
+ const yy = Math.floor(y);
10868
+ const state = getPlaneState(plane);
10869
+ if (!Number.isFinite(yy) || yy < 0 || yy >= state.buffer.rows) {
10870
+ throw new RangeError("Row out of bounds");
10871
+ }
10872
+ return getRowFingerprints(state.buffer, yy);
10753
10873
  }
10754
10874
  };
10755
10875
  planeTerminals.set(plane, api);
@@ -10943,7 +11063,11 @@ function createTerminal(opts) {
10943
11063
  },
10944
11064
  getRowFingerprints(y) {
10945
11065
  assertNotDisposed();
10946
- return getRowFingerprints(compositeBuffer, y);
11066
+ const yy = Math.floor(y);
11067
+ if (!Number.isFinite(yy) || yy < 0 || yy >= compositeBuffer.rows) {
11068
+ throw new RangeError("Row out of bounds");
11069
+ }
11070
+ return getRowFingerprints(compositeBuffer, yy);
10947
11071
  }
10948
11072
  };
10949
11073
  base[TERMINAL_PLANE_INTERNALS] = {
@@ -22493,6 +22617,49 @@ var TSelect = (0, import_vue41.defineComponent)({
22493
22617
  const typeaheadQuery = (0, import_vue41.ref)("");
22494
22618
  const query = (0, import_vue41.computed)(() => props.query ?? innerQuery.value);
22495
22619
  const options = (0, import_vue41.computed)(() => providerOptions.value ?? props.options);
22620
+ function getOptionLabel(opt) {
22621
+ return isOptionObject(opt) ? opt.label : opt;
22622
+ }
22623
+ function getOptionKind(opt) {
22624
+ return isOptionObject(opt) ? opt.kind : void 0;
22625
+ }
22626
+ function getOptionValue(opt, index) {
22627
+ if (props.valueMode === "index")
22628
+ return index;
22629
+ if (props.valueMode === "option")
22630
+ return opt;
22631
+ return isOptionObject(opt) && "value" in opt ? opt.value : getOptionLabel(opt);
22632
+ }
22633
+ const optionValueIndex = (0, import_vue41.computed)(() => {
22634
+ if (props.valueMode === "index")
22635
+ return null;
22636
+ const indexed = /* @__PURE__ */ new Map();
22637
+ const opts = options.value;
22638
+ for (let index = 0; index < opts.length; index++) {
22639
+ const value = getOptionValue(opts[index], index);
22640
+ if (typeof value === "number" && value === 0)
22641
+ continue;
22642
+ if (!indexed.has(value))
22643
+ indexed.set(value, index);
22644
+ }
22645
+ return indexed;
22646
+ });
22647
+ function valuesEqual(a, b) {
22648
+ return Object.is(a, b);
22649
+ }
22650
+ function modelIndex(value, useValueIndex = props.multiple) {
22651
+ if (props.valueMode === "index")
22652
+ return normalizeModelIndex(value);
22653
+ if (useValueIndex) {
22654
+ const indexed = optionValueIndex.value;
22655
+ const cached = indexed?.get(value);
22656
+ if (cached != null)
22657
+ return cached;
22658
+ }
22659
+ return options.value.findIndex(
22660
+ (opt, optIndex) => valuesEqual(getOptionValue(opt, optIndex), value)
22661
+ );
22662
+ }
22496
22663
  const initialActive = (() => {
22497
22664
  const max = Math.max(0, options.value.length - 1);
22498
22665
  if (!props.multiple) {
@@ -22550,29 +22717,6 @@ var TSelect = (0, import_vue41.defineComponent)({
22550
22717
  }
22551
22718
  innerActive.value = clamp11(active.value, 0, max);
22552
22719
  });
22553
- function getOptionLabel(opt) {
22554
- return isOptionObject(opt) ? opt.label : opt;
22555
- }
22556
- function getOptionKind(opt) {
22557
- return isOptionObject(opt) ? opt.kind : void 0;
22558
- }
22559
- function getOptionValue(opt, index) {
22560
- if (props.valueMode === "index")
22561
- return index;
22562
- if (props.valueMode === "option")
22563
- return opt;
22564
- return isOptionObject(opt) && "value" in opt ? opt.value : getOptionLabel(opt);
22565
- }
22566
- function valuesEqual(a, b) {
22567
- return Object.is(a, b);
22568
- }
22569
- function modelIndex(value) {
22570
- if (props.valueMode === "index")
22571
- return normalizeModelIndex(value);
22572
- return options.value.findIndex(
22573
- (opt, optIndex) => valuesEqual(getOptionValue(opt, optIndex), value)
22574
- );
22575
- }
22576
22720
  function isOptionInteractive(opt) {
22577
22721
  if (!opt)
22578
22722
  return false;
@@ -23356,16 +23500,24 @@ var TTransition = (0, import_vue42.defineComponent)({
23356
23500
 
23357
23501
  // src/vue/components/TTree.ts
23358
23502
  var import_vue43 = require("vue");
23359
- function flattenTree(nodes, expanded, depth = 0, out = []) {
23503
+ function flattenTree(nodes, expanded, limit, depth = 0, out = []) {
23504
+ if (out.length >= limit)
23505
+ return out;
23360
23506
  for (const node of nodes) {
23507
+ if (out.length >= limit)
23508
+ break;
23361
23509
  const expandable = Boolean(node.children?.length);
23362
23510
  const isExpanded = expanded.has(node.id);
23363
23511
  out.push({ node, depth, expandable, expanded: isExpanded });
23364
23512
  if (expandable && isExpanded)
23365
- flattenTree(node.children, expanded, depth + 1, out);
23513
+ flattenTree(node.children, expanded, limit, depth + 1, out);
23366
23514
  }
23367
23515
  return out;
23368
23516
  }
23517
+ function visibleRowLimit(height) {
23518
+ const limit = Math.floor(height);
23519
+ return Number.isFinite(limit) ? Math.max(0, limit) : 0;
23520
+ }
23369
23521
  var TTree = (0, import_vue43.defineComponent)({
23370
23522
  name: "TTree",
23371
23523
  props: {
@@ -23399,7 +23551,9 @@ var TTree = (0, import_vue43.defineComponent)({
23399
23551
  const { defaultStyle } = useTerminal();
23400
23552
  const baseStyle = (0, import_vue43.computed)(() => mergeStyle(defaultStyle.value, props.style));
23401
23553
  const expandedSet = (0, import_vue43.computed)(() => new Set(props.expandedIds));
23402
- const rows = (0, import_vue43.computed)(() => flattenTree(props.nodes, expandedSet.value).slice(0, props.h));
23554
+ const rows = (0, import_vue43.computed)(
23555
+ () => flattenTree(props.nodes, expandedSet.value, visibleRowLimit(props.h))
23556
+ );
23403
23557
  function toggle(item) {
23404
23558
  if (item.node.disabled || !item.expandable)
23405
23559
  return;
package/dist/vue.js CHANGED
@@ -1,16 +1,16 @@
1
- import "./create-terminal-C2oiWFJU.js";
1
+ import "./create-terminal-DBFNYr8f.js";
2
2
  import { charCellWidth } from "./hyperlink-Bn02UXJb.js";
3
3
  import "./sgr-BmzxEjAO.js";
4
4
  import "./ansi-palette-CNXqFciC.js";
5
- import "./dom-renderer-BqGijQID.js";
5
+ import "./dom-renderer-BniJSQyX.js";
6
6
  import { EventZIndexContextKey, LayoutContextKey, RenderStackKey, TInputPluginsContextKey, TPathPickerProviderContextKey, VisibilityContextKey, applyWheelScroll, createWheelScrollState, injectionKey, intersectRect, padEndByCells$1 as padEndByCells, repeatChar, sanitizeInlineText, sanitizeTextBlock, sliceByCells, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useRenderStack, useTerminal, useTerminalNode, useVisibility, wrapByCells } from "./wheel-scroll-vBRaQ7p-.js";
7
7
  import { TView, createTheme, linkifyTextSegments, tuiDefaultTheme } from "./linkify-D_gzn9Xq.js";
8
8
  import "./runtime-rfcZCyJq.js";
9
9
  import "./trace-CjzYeIxN.js";
10
10
  import "./env-Cl8qmNFN.js";
11
- import { TAutocompleteInput, TBadge, TCheckbox, TCode, TDataTable, TDivider, TForm, TFormContextKey, TFormField, TLink, TLinkifyText, TList, TPasswordInput, TProgress, TRadioGroup, TSlider, TSpinner, TSwitch, TTable, TTag, TToastViewport, TTree, TerminalProvider, createTInputHostPlugin, useTForm } from "./TTree-DK_DQBYm.js";
11
+ import { TAutocompleteInput, TBadge, TCheckbox, TCode, TDataTable, TDivider, TForm, TFormContextKey, TFormField, TLink, TLinkifyText, TList, TPasswordInput, TProgress, TRadioGroup, TSlider, TSpinner, TSwitch, TTable, TTag, TToastViewport, TTree, TerminalProvider, createTInputHostPlugin, useTForm } from "./TTree-kzhlB5P0.js";
12
12
  import "./terminal-selection-DBinO6p5.js";
13
- import { TBox, TCommandPalette, TDialog, TInput, TRenderPlane, TSelect, TText, clamp as clamp$1, clamp$1 as clamp, computeCommandPaletteMatchRanges, createOverlayFocusStack, fitCellText, isCommitMention, isWhitespace, mentionChipStyle, mergeStyle, padEndByCells as padEndByCells$1, resolveOverlayPlacement, sliceByCellsWindow, textCellWidth as textCellWidth$1 } from "./TSelect-BwJJbuTt.js";
13
+ import { TBox, TCommandPalette, TDialog, TInput, TRenderPlane, TSelect, TText, clamp as clamp$1, clamp$1 as clamp, computeCommandPaletteMatchRanges, createOverlayFocusStack, fitCellText, isCommitMention, isWhitespace, mentionChipStyle, mergeStyle, padEndByCells as padEndByCells$1, resolveOverlayPlacement, sliceByCellsWindow, textCellWidth as textCellWidth$1 } from "./TSelect-DR0FomSu.js";
14
14
  import "./frame-perf-C6Xfg85O.js";
15
15
  import { normalizePath, stripTrailingSlash } from "./path-mnSgEpCm.js";
16
16
  import { parsePathQuery, resolveUserPath, suggestPaths } from "./path-suggest-BNqcuE3-.js";
package/package.json CHANGED
@@ -1,23 +1,40 @@
1
1
  {
2
2
  "name": "@simon_he/vue-tui",
3
- "version": "1.0.0",
4
- "description": "Vue 3 terminal UI toolkit for browser DOM and CLI stdout renderers",
3
+ "version": "1.0.2",
4
+ "description": "Vue 3 terminal UI components and renderers for browser DOM, CLI stdout, logs, markdown transcripts, and agent consoles",
5
5
  "keywords": [
6
+ "agent-console",
7
+ "agent-ui",
6
8
  "ansi",
9
+ "ansi-renderer",
10
+ "browser-terminal",
7
11
  "cli",
12
+ "cli-ui",
8
13
  "component-library",
9
14
  "dom-renderer",
10
15
  "log-viewer",
11
16
  "markdown",
17
+ "markdown-renderer",
18
+ "markdown-transcript",
12
19
  "stdout",
20
+ "stdout-renderer",
21
+ "streaming-markdown",
13
22
  "terminal",
23
+ "terminal-components",
24
+ "terminal-dashboard",
25
+ "terminal-log-viewer",
26
+ "terminal-renderer",
14
27
  "terminal-ui",
15
28
  "tui",
29
+ "typescript",
16
30
  "virtual-list",
17
31
  "vue",
32
+ "vue-cli-ui",
33
+ "vue-terminal",
34
+ "vue-tui",
18
35
  "vue3"
19
36
  ],
20
- "homepage": "https://github.com/Simon-He95/vue-tui#readme",
37
+ "homepage": "https://vue-tui.pages.dev/",
21
38
  "bugs": {
22
39
  "url": "https://github.com/Simon-He95/vue-tui/issues"
23
40
  },
@@ -177,27 +194,27 @@
177
194
  "stream-markdown-parser": "1.0.0"
178
195
  },
179
196
  "devDependencies": {
180
- "@arethetypeswrong/core": "^0.18.2",
197
+ "@arethetypeswrong/core": "^0.18.3",
181
198
  "@playwright/test": "^1.60.0",
182
199
  "@types/node": "^18.19.130",
183
- "@vitest/coverage-v8": "^4.1.6",
200
+ "@vitest/coverage-v8": "^4.1.8",
184
201
  "bumpp": "^8.2.1",
185
202
  "esbuild": "^0.20.2",
186
203
  "happy-dom": "^17.6.3",
187
204
  "lint-staged": "^13.3.0",
188
205
  "oxfmt": "^0.47.0",
189
- "oxlint": "^1.65.0",
206
+ "oxlint": "^1.67.0",
190
207
  "picocolors": "^1.1.1",
191
208
  "pinia": "^3.0.4",
192
209
  "publint": "^0.3.21",
193
210
  "rimraf": "^3.0.2",
194
211
  "tsdown": "^0.9.9",
195
- "tsx": "^4.22.0",
212
+ "tsx": "^4.22.4",
196
213
  "typescript": "^5.9.3",
197
214
  "vite": "6.4.1",
198
215
  "vitepress": "^1.6.4",
199
- "vitest": "^4.1.6",
200
- "vue": "^3.5.34"
216
+ "vitest": "^4.1.8",
217
+ "vue": "^3.5.35"
201
218
  },
202
219
  "peerDependencies": {
203
220
  "vue": ">=3.3.0 <4"
@@ -247,9 +264,10 @@
247
264
  "release": "pnpm run release:workflow-only",
248
265
  "release:verify": "pnpm run release:dry-run",
249
266
  "release:ci": "pnpm run release:verify",
267
+ "publish:npm:patch": "pnpm exec bumpp patch --yes --no-commit --no-tag --no-push && (npm whoami >/dev/null 2>&1 || npm login) && VUE_TUI_ALLOW_DIRECT_PUBLISH=1 pnpm publish --access public --no-git-checks",
250
268
  "release:local": "pnpm run release:dry-run && VUE_TUI_ALLOW_DIRECT_PUBLISH=1 npm publish .release/*.tgz --access public --tag rc",
251
269
  "release:local:dry-run": "pnpm run release:dry-run && VUE_TUI_ALLOW_DIRECT_PUBLISH=1 npm publish .release/*.tgz --access public --dry-run --tag rc",
252
- "release:bench": "pnpm run bench:baseline",
270
+ "release:bench": "pnpm run bench:baseline && FRAMES=2000 pnpm run bench:stdout-column-diff",
253
271
  "release:check": "pnpm run check:hidden-unicode && pnpm run format:check && pnpm run lint && pnpm run typecheck && pnpm run test && pnpm run test:coverage:core && pnpm run build:checked && pnpm run test:package-exports:dist && pnpm run check:dist-dts && pnpm run test:types:dist && pnpm run test:browser-vite-import:dist && pnpm run docs:build && pnpm run api:diff && git diff --exit-code -- docs/generated",
254
272
  "release:dry-run": "pnpm run release:check && pnpm run release:bench && pnpm run release:smoke && pnpm run release:pack-smoke",
255
273
  "release:pack": "rimraf .release && pnpm run build:checked && pnpm pack --pack-destination .release",
@@ -281,6 +299,7 @@
281
299
  "bench:baseline": "tsx scripts/check-bench-baselines.ts",
282
300
  "bench:baseline:timing": "BENCH_TIMING=1 tsx scripts/check-bench-baselines.ts",
283
301
  "bench:phase2": "tsx scripts/bench-phase2.ts",
284
- "bench:scroll-mailbox": "tsx scripts/bench-scroll-mailbox.ts"
302
+ "bench:scroll-mailbox": "tsx scripts/bench-scroll-mailbox.ts",
303
+ "bench:stdout-column-diff": "tsx scripts/bench-stdout-column-diff.ts"
285
304
  }
286
305
  }