@iris-ui-kit/vue 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -4359,6 +4359,16 @@ declare const IrisTable: vue.DefineComponent<vue.ExtractPropTypes<{
4359
4359
  type: PropType<(row: Record<string, unknown>) => Array<Record<string, unknown>> | undefined>;
4360
4360
  default: undefined;
4361
4361
  };
4362
+ /**
4363
+ * Cascade multi-row selection through the complete tree supplied by
4364
+ * `getSubRows`. Selecting a branch selects every descendant (including
4365
+ * collapsed rows); partially selected branches render indeterminate.
4366
+ * Ignored outside tree mode and for non-multi selection.
4367
+ */
4368
+ treeSelectionCascade: {
4369
+ type: BooleanConstructor;
4370
+ default: boolean;
4371
+ };
4362
4372
  selectable: {
4363
4373
  type: PropType<"none" | "single" | "multi">;
4364
4374
  default: string;
@@ -4493,6 +4503,16 @@ declare const IrisTable: vue.DefineComponent<vue.ExtractPropTypes<{
4493
4503
  type: PropType<(row: Record<string, unknown>) => Array<Record<string, unknown>> | undefined>;
4494
4504
  default: undefined;
4495
4505
  };
4506
+ /**
4507
+ * Cascade multi-row selection through the complete tree supplied by
4508
+ * `getSubRows`. Selecting a branch selects every descendant (including
4509
+ * collapsed rows); partially selected branches render indeterminate.
4510
+ * Ignored outside tree mode and for non-multi selection.
4511
+ */
4512
+ treeSelectionCascade: {
4513
+ type: BooleanConstructor;
4514
+ default: boolean;
4515
+ };
4496
4516
  selectable: {
4497
4517
  type: PropType<"none" | "single" | "multi">;
4498
4518
  default: string;
@@ -4550,6 +4570,7 @@ declare const IrisTable: vue.DefineComponent<vue.ExtractPropTypes<{
4550
4570
  rowExpandable: IrisTableRowExpandable<Record<string, unknown>>;
4551
4571
  defaultExpandedRowKeys: (string | number)[];
4552
4572
  getSubRows: (row: Record<string, unknown>) => Array<Record<string, unknown>> | undefined;
4573
+ treeSelectionCascade: boolean;
4553
4574
  selectable: "none" | "single" | "multi";
4554
4575
  selection: (string | number)[];
4555
4576
  defaultSelection: (string | number)[];
package/dist/index.d.ts CHANGED
@@ -4359,6 +4359,16 @@ declare const IrisTable: vue.DefineComponent<vue.ExtractPropTypes<{
4359
4359
  type: PropType<(row: Record<string, unknown>) => Array<Record<string, unknown>> | undefined>;
4360
4360
  default: undefined;
4361
4361
  };
4362
+ /**
4363
+ * Cascade multi-row selection through the complete tree supplied by
4364
+ * `getSubRows`. Selecting a branch selects every descendant (including
4365
+ * collapsed rows); partially selected branches render indeterminate.
4366
+ * Ignored outside tree mode and for non-multi selection.
4367
+ */
4368
+ treeSelectionCascade: {
4369
+ type: BooleanConstructor;
4370
+ default: boolean;
4371
+ };
4362
4372
  selectable: {
4363
4373
  type: PropType<"none" | "single" | "multi">;
4364
4374
  default: string;
@@ -4493,6 +4503,16 @@ declare const IrisTable: vue.DefineComponent<vue.ExtractPropTypes<{
4493
4503
  type: PropType<(row: Record<string, unknown>) => Array<Record<string, unknown>> | undefined>;
4494
4504
  default: undefined;
4495
4505
  };
4506
+ /**
4507
+ * Cascade multi-row selection through the complete tree supplied by
4508
+ * `getSubRows`. Selecting a branch selects every descendant (including
4509
+ * collapsed rows); partially selected branches render indeterminate.
4510
+ * Ignored outside tree mode and for non-multi selection.
4511
+ */
4512
+ treeSelectionCascade: {
4513
+ type: BooleanConstructor;
4514
+ default: boolean;
4515
+ };
4496
4516
  selectable: {
4497
4517
  type: PropType<"none" | "single" | "multi">;
4498
4518
  default: string;
@@ -4550,6 +4570,7 @@ declare const IrisTable: vue.DefineComponent<vue.ExtractPropTypes<{
4550
4570
  rowExpandable: IrisTableRowExpandable<Record<string, unknown>>;
4551
4571
  defaultExpandedRowKeys: (string | number)[];
4552
4572
  getSubRows: (row: Record<string, unknown>) => Array<Record<string, unknown>> | undefined;
4573
+ treeSelectionCascade: boolean;
4553
4574
  selectable: "none" | "single" | "multi";
4554
4575
  selection: (string | number)[];
4555
4576
  defaultSelection: (string | number)[];
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ export { FormInjectionKey, IrisForm, useField, useFieldArray, useForm, useFormCo
33
33
  import { useI18n } from './chunk-TCAXRWT6.js';
34
34
  export { I18nInjectionKey, IrisI18nProvider, useI18n } from './chunk-TCAXRWT6.js';
35
35
  import { defineComponent, computed, watch, ref, useId, provide, inject, h, nextTick, Teleport, onScopeDispose, Fragment, onMounted, onBeforeUnmount, onBeforeMount, shallowRef, toValue, Comment, onUnmounted } from 'vue';
36
- import { createFloatingMachine, createHoverIntent, createKeyboardNav, getPageRange, createSelectionModel, flattenLeafColumns, buildHeaderMatrix, createExpansion, flattenTree, withSortedChildren, createCellRange, computeVirtualRange, aggregate, createStore, createTreeSelection, firstEnabledIndex, startOfMonth, clampDate, isSameMonth, buildMonthMatrix, getWeekdayNames, formatMonthYear, startOfDay, endOfMonth, isSameDay, isOutOfRange, formatLocalISO, hexToRgba, rgbaToHsva, hsvaToRgba, rgbToHex, addMonths, createVirtualizer, compareValues, nextGridCell, nextEnabledIndex, copyText, addDays, clamp01, createAutoDismiss, createReconnectingSource, createResilientFetcher, createDisposableScope, toCsv, downloadFile, toSpreadsheetXml, generateId } from '@iris-ui-kit/core';
36
+ import { createFloatingMachine, createHoverIntent, createKeyboardNav, getPageRange, createSelectionModel, flattenLeafColumns, buildHeaderMatrix, createExpansion, flattenTree, withSortedChildren, createTreeSelection, createCellRange, computeVirtualRange, aggregate, createStore, firstEnabledIndex, startOfMonth, clampDate, isSameMonth, buildMonthMatrix, getWeekdayNames, formatMonthYear, startOfDay, endOfMonth, isSameDay, isOutOfRange, formatLocalISO, hexToRgba, rgbaToHsva, hsvaToRgba, rgbToHex, addMonths, createVirtualizer, compareValues, nextGridCell, nextEnabledIndex, copyText, addDays, clamp01, createAutoDismiss, createReconnectingSource, createResilientFetcher, createDisposableScope, toCsv, downloadFile, toSpreadsheetXml, generateId } from '@iris-ui-kit/core';
37
37
  export { addDays, addMonths, buildMonthMatrix, clamp01, clampDate, composeEventHandlers, createFloatingMachine, createMachine, createStore, endOfMonth, formatLocalISO, formatMonthYear, generateId, getPageRange, getWeekdayNames, hexToRgba, hsvToRgb, hsvaToRgba, isOutOfRange, isSameDay, isSameMonth, mergeProps, rgbToHex, rgbToHsv, rgbaToHsva, startOfDay, startOfMonth } from '@iris-ui-kit/core';
38
38
  import { getDirection } from '@iris-ui-kit/theme';
39
39
  export { applyTheme, createThemeStore, getCssVar, toCssVarName } from '@iris-ui-kit/theme';
@@ -5422,7 +5422,14 @@ var IrisTable = defineComponent({
5422
5422
  getSubRows: {
5423
5423
  type: Function,
5424
5424
  default: void 0
5425
- }
5425
+ },
5426
+ /**
5427
+ * Cascade multi-row selection through the complete tree supplied by
5428
+ * `getSubRows`. Selecting a branch selects every descendant (including
5429
+ * collapsed rows); partially selected branches render indeterminate.
5430
+ * Ignored outside tree mode and for non-multi selection.
5431
+ */
5432
+ treeSelectionCascade: { type: Boolean, default: false }
5426
5433
  },
5427
5434
  emits: {
5428
5435
  "update:selection": (_value) => true,
@@ -5508,27 +5515,97 @@ var IrisTable = defineComponent({
5508
5515
  const bodyData = computed(
5509
5516
  () => flatTree.value ? flatTree.value.map((t2) => t2.row) : sortedRows.value
5510
5517
  );
5511
- const isSelected = (id) => displaySelection.value.includes(id);
5512
- const allRowIds = computed(() => bodyData.value.map((r, i) => rowId(r, i)));
5518
+ const cascadingTreeSelection = computed(
5519
+ () => props.treeSelectionCascade && props.selectable === "multi" && treeMode.value
5520
+ );
5521
+ const treeSelectionNodes = computed(() => {
5522
+ const getChildren = props.getSubRows;
5523
+ if (!cascadingTreeSelection.value || !getChildren) return [];
5524
+ const nodes = [];
5525
+ const seen = /* @__PURE__ */ new Set();
5526
+ let rowIndex = 0;
5527
+ const walk = (rows, parentKey) => {
5528
+ for (const row of rows) {
5529
+ const key = rowId(row, rowIndex);
5530
+ rowIndex += 1;
5531
+ if (seen.has(key)) continue;
5532
+ seen.add(key);
5533
+ nodes.push({ key, parentKey });
5534
+ const children = getChildren(row);
5535
+ if (children && children.length > 0) walk(children, key);
5536
+ }
5537
+ };
5538
+ walk(sortedRows.value);
5539
+ return nodes;
5540
+ });
5541
+ const compactTreeSelectionSeed = (keys) => {
5542
+ const selected = new Set(keys);
5543
+ const parentByKey = new Map(
5544
+ treeSelectionNodes.value.map((node) => [node.key, node.parentKey])
5545
+ );
5546
+ return keys.filter((key) => {
5547
+ const visited = /* @__PURE__ */ new Set();
5548
+ let parent = parentByKey.get(key);
5549
+ while (parent !== void 0 && !visited.has(parent)) {
5550
+ if (selected.has(parent)) return false;
5551
+ visited.add(parent);
5552
+ parent = parentByKey.get(parent);
5553
+ }
5554
+ return true;
5555
+ });
5556
+ };
5557
+ const resolvedTreeSelection = computed(
5558
+ () => cascadingTreeSelection.value ? createTreeSelection({
5559
+ nodes: treeSelectionNodes.value,
5560
+ // Canonical payloads contain fully-selected branches and their
5561
+ // leaves. Seed only the highest selected ancestors so rebuilding a
5562
+ // large fully-selected tree does not cascade once per descendant.
5563
+ defaultChecked: compactTreeSelectionSeed(displaySelection.value)
5564
+ }) : null
5565
+ );
5566
+ const isSelected = (id) => resolvedTreeSelection.value?.isChecked(id) ?? displaySelection.value.includes(id);
5567
+ const isSelectionIndeterminate = (id) => resolvedTreeSelection.value?.isIndeterminate(id) ?? false;
5568
+ const allRowIds = computed(
5569
+ () => cascadingTreeSelection.value ? treeSelectionNodes.value.map((node) => node.key) : bodyData.value.map((row, index) => rowId(row, index))
5570
+ );
5513
5571
  const allSelected = computed(() => {
5514
- const sel = displaySelection.value;
5515
- return allRowIds.value.length > 0 && allRowIds.value.every((id) => sel.includes(id));
5572
+ return allRowIds.value.length > 0 && allRowIds.value.every((id) => isSelected(id));
5516
5573
  });
5517
5574
  const someSelected = computed(() => {
5518
- const sel = displaySelection.value;
5519
- return !allSelected.value && allRowIds.value.some((id) => sel.includes(id));
5575
+ return !allSelected.value && allRowIds.value.some((id) => isSelected(id) || isSelectionIndeterminate(id));
5520
5576
  });
5521
5577
  const toggleRow = (id) => {
5522
5578
  rebaseToProp();
5523
5579
  if (props.selectable === "single") {
5524
5580
  selectionModel.set(selectionModel.isSelected(id) ? [] : [id]);
5525
5581
  } else if (props.selectable === "multi") {
5526
- selectionModel.toggle(id);
5582
+ if (cascadingTreeSelection.value) {
5583
+ const treeSelection = createTreeSelection({
5584
+ nodes: treeSelectionNodes.value,
5585
+ defaultChecked: compactTreeSelectionSeed(displaySelection.value)
5586
+ });
5587
+ treeSelection.toggle(id);
5588
+ selectionModel.set(treeSelection.getChecked());
5589
+ } else {
5590
+ selectionModel.toggle(id);
5591
+ }
5527
5592
  }
5528
5593
  };
5529
5594
  const toggleAll = () => {
5530
5595
  rebaseToProp();
5531
- selectionModel.set(allSelected.value ? [] : [...allRowIds.value]);
5596
+ if (allSelected.value) {
5597
+ selectionModel.set([]);
5598
+ return;
5599
+ }
5600
+ if (cascadingTreeSelection.value) {
5601
+ const treeSelection = createTreeSelection({
5602
+ nodes: treeSelectionNodes.value,
5603
+ defaultChecked: allRowIds.value
5604
+ });
5605
+ selectionModel.set(treeSelection.getChecked());
5606
+ return;
5607
+ }
5608
+ selectionModel.set([...allRowIds.value]);
5532
5609
  };
5533
5610
  const editingCellId = ref(null);
5534
5611
  const editingDraft = ref("");
@@ -6090,7 +6167,7 @@ var IrisTable = defineComponent({
6090
6167
  },
6091
6168
  [
6092
6169
  h(IrisCheckbox, {
6093
- modelValue: selected,
6170
+ modelValue: isSelectionIndeterminate(id) ? "indeterminate" : selected,
6094
6171
  size: "sm",
6095
6172
  ariaLabel: t("table.selectRow", { key: id }),
6096
6173
  "onUpdate:modelValue": () => toggleRow(id),