@iris-ui-kit/vue 0.2.22 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3089,12 +3089,17 @@ function useUndoStack(options) {
3089
3089
  index: raw.index
3090
3090
  });
3091
3091
  const sync = () => {
3092
- state.value = {
3092
+ const next = {
3093
3093
  canUndo: raw.canUndo(),
3094
3094
  canRedo: raw.canRedo(),
3095
3095
  depth: raw.depth,
3096
3096
  index: raw.index
3097
3097
  };
3098
+ const cur = state.value;
3099
+ if (next.canUndo === cur.canUndo && next.canRedo === cur.canRedo && next.depth === cur.depth && next.index === cur.index) {
3100
+ return;
3101
+ }
3102
+ state.value = next;
3098
3103
  };
3099
3104
  const stack = trackUndoStack(raw, sync);
3100
3105
  const push = (snapshot) => stack.push(snapshot);
@@ -6345,7 +6350,10 @@ var IrisList = vue.defineComponent({
6345
6350
  const { state, isContent, stateKey, stateProps } = useDataState(() => ({
6346
6351
  loading: props.loading,
6347
6352
  error: props.error,
6348
- empty: props.items.length === 0
6353
+ empty: props.items.length === 0,
6354
+ // Already-loaded items stay mounted during a revalidate (SWR): a load
6355
+ // in flight no longer replaces them with the loading/error state.
6356
+ hasContent: props.items.length > 0
6349
6357
  }));
6350
6358
  const isEnabled = (i) => !props.items[i]?.disabled;
6351
6359
  const nav = core.createKeyboardNav({
@@ -6482,7 +6490,9 @@ var IrisList = vue.defineComponent({
6482
6490
  role: "listbox",
6483
6491
  "aria-label": props.ariaLabel,
6484
6492
  "aria-multiselectable": props.multi ? "true" : void 0,
6485
- "aria-busy": state.value === "loading" ? "true" : void 0,
6493
+ // Decoupled from resolved state: signals both the initial load and
6494
+ // an in-flight background revalidate (content stays mounted).
6495
+ "aria-busy": props.loading ? "true" : void 0,
6486
6496
  "data-iris-list": "",
6487
6497
  onKeydown: onKeyDown,
6488
6498
  style: {
@@ -12059,7 +12069,10 @@ var IrisTree = vue.defineComponent({
12059
12069
  const { state, isContent, stateKey, stateProps } = useDataState(() => ({
12060
12070
  loading: props.loading,
12061
12071
  error: props.error,
12062
- empty: props.nodes.length === 0
12072
+ empty: props.nodes.length === 0,
12073
+ // Already-loaded nodes stay mounted during a revalidate (SWR): a load
12074
+ // in flight no longer replaces them with the loading/error state.
12075
+ hasContent: props.nodes.length > 0
12063
12076
  }));
12064
12077
  const lazyCache = vue.ref(/* @__PURE__ */ new Map());
12065
12078
  const loadingIds = vue.ref(/* @__PURE__ */ new Set());
@@ -12379,7 +12392,9 @@ var IrisTree = vue.defineComponent({
12379
12392
  role: "tree",
12380
12393
  "aria-label": props.ariaLabel ?? t("tree.label"),
12381
12394
  "aria-multiselectable": props.selectionMode === "multi" ? "true" : void 0,
12382
- "aria-busy": state.value === "loading" ? "true" : void 0,
12395
+ // Decoupled from resolved state: signals both the initial load and
12396
+ // an in-flight background revalidate (content stays mounted).
12397
+ "aria-busy": props.loading ? "true" : void 0,
12383
12398
  "data-iris-tree": "",
12384
12399
  style: {
12385
12400
  display: "flex",
@@ -18439,14 +18454,32 @@ var IrisDashboardTemplate = vue.defineComponent({
18439
18454
  activeId: { type: String, default: "" },
18440
18455
  /** Cards to render in the main grid. Skip to use the `default` slot only. */
18441
18456
  cards: { type: Array, default: () => [] },
18442
- defaultCollapsed: { type: Boolean, default: false }
18457
+ defaultCollapsed: { type: Boolean, default: false },
18458
+ /**
18459
+ * Controlled collapsed state. When unset (`undefined`), the component
18460
+ * manages its own state seeded from `defaultCollapsed`; when set, this
18461
+ * value takes precedence and changes are re-emitted via
18462
+ * `update:collapsed` (`v-model:collapsed`).
18463
+ */
18464
+ collapsed: { type: Boolean, default: void 0 }
18443
18465
  },
18444
18466
  emits: {
18445
18467
  "update:activeId": (_id) => true,
18446
18468
  "update:collapsed": (_value) => true
18447
18469
  },
18448
18470
  setup(props, { attrs, slots, emit }) {
18449
- const collapsed = vue.ref(props.defaultCollapsed);
18471
+ const isControlled = vue.computed(() => props.collapsed !== void 0);
18472
+ const internalCollapsed = vue.ref(props.defaultCollapsed);
18473
+ const collapsed = vue.computed(
18474
+ () => isControlled.value ? Boolean(props.collapsed) : internalCollapsed.value
18475
+ );
18476
+ vue.watch(
18477
+ () => props.collapsed,
18478
+ (value) => {
18479
+ if (value !== void 0) internalCollapsed.value = value;
18480
+ },
18481
+ { immediate: true }
18482
+ );
18450
18483
  const onSelectNav = (id) => {
18451
18484
  emit("update:activeId", id);
18452
18485
  };
@@ -18468,7 +18501,7 @@ var IrisDashboardTemplate = vue.defineComponent({
18468
18501
  {
18469
18502
  collapsed: collapsed.value,
18470
18503
  "onUpdate:collapsed": (v) => {
18471
- collapsed.value = v;
18504
+ if (!isControlled.value) internalCollapsed.value = v;
18472
18505
  emit("update:collapsed", v);
18473
18506
  },
18474
18507
  width: 240,
@@ -18655,6 +18688,72 @@ function handlePosition2(handle) {
18655
18688
  s.cursor = HANDLE_CURSORS2[handle];
18656
18689
  return s;
18657
18690
  }
18691
+ var ResizableHandle = vue.defineComponent({
18692
+ name: "ResizableHandle",
18693
+ props: {
18694
+ handle: { type: String, required: true },
18695
+ disabled: { type: Boolean, default: false },
18696
+ keepAspect: { type: Boolean, default: false },
18697
+ minWidth: { type: Number, default: 40 },
18698
+ minHeight: { type: Number, default: 40 },
18699
+ maxWidth: { type: Number, default: Infinity },
18700
+ maxHeight: { type: Number, default: Infinity },
18701
+ /** Stable computed ref from the parent; read only (never mutated). */
18702
+ sizeRef: { type: Object, required: true },
18703
+ /** Stable setup-level callbacks from the parent. */
18704
+ onUpdate: { type: Function, required: true },
18705
+ onResizeStart: {
18706
+ type: Function,
18707
+ default: void 0
18708
+ },
18709
+ onResizeEnd: { type: Function, default: void 0 }
18710
+ },
18711
+ setup(props) {
18712
+ const handleRef = vue.ref(null);
18713
+ let startSize = { width: 0, height: 0 };
18714
+ let aspect = 1;
18715
+ useDrag({
18716
+ handle: handleRef,
18717
+ disabled: vue.computed(() => props.disabled),
18718
+ onStart: () => {
18719
+ startSize = { ...props.sizeRef.value };
18720
+ aspect = startSize.width / Math.max(1, startSize.height);
18721
+ props.onResizeStart?.(startSize);
18722
+ },
18723
+ onDrag: ({ dx, dy }) => {
18724
+ const t = props.handle.includes("top");
18725
+ const b = props.handle.includes("bottom");
18726
+ const l = props.handle.includes("left");
18727
+ const r = props.handle.includes("right");
18728
+ let nextW = startSize.width;
18729
+ let nextH = startSize.height;
18730
+ if (r) nextW = startSize.width + dx;
18731
+ if (l) nextW = startSize.width - dx;
18732
+ if (b) nextH = startSize.height + dy;
18733
+ if (t) nextH = startSize.height - dy;
18734
+ if (props.keepAspect && (t || b) && (l || r)) {
18735
+ nextH = nextW / aspect;
18736
+ }
18737
+ nextW = Math.max(props.minWidth, Math.min(props.maxWidth, nextW));
18738
+ nextH = Math.max(props.minHeight, Math.min(props.maxHeight, nextH));
18739
+ props.onUpdate({ width: nextW, height: nextH });
18740
+ },
18741
+ onEnd: () => props.onResizeEnd?.()
18742
+ });
18743
+ return () => vue.h("div", {
18744
+ ref: (el) => {
18745
+ handleRef.value = el ?? null;
18746
+ },
18747
+ "data-iris-resizable-handle": props.handle,
18748
+ style: {
18749
+ ...handlePosition2(props.handle),
18750
+ touchAction: "none",
18751
+ background: "transparent",
18752
+ zIndex: "1"
18753
+ }
18754
+ });
18755
+ }
18756
+ });
18658
18757
  var IrisResizable = vue.defineComponent({
18659
18758
  name: "IrisResizable",
18660
18759
  inheritAttrs: false,
@@ -18687,53 +18786,8 @@ var IrisResizable = vue.defineComponent({
18687
18786
  if (!isControlled.value) internal.value = next;
18688
18787
  emit("update:size", next);
18689
18788
  };
18690
- const renderHandle = (handle) => {
18691
- const handleRef = vue.ref(null);
18692
- let startSize = { width: 0, height: 0 };
18693
- let aspect = 1;
18694
- useDrag({
18695
- handle: handleRef,
18696
- disabled: vue.computed(() => props.disabled),
18697
- onStart: () => {
18698
- startSize = { ...size.value };
18699
- aspect = startSize.width / Math.max(1, startSize.height);
18700
- emit("resizeStart", startSize);
18701
- },
18702
- onDrag: ({ dx, dy }) => {
18703
- const t = handle.includes("top");
18704
- const b = handle.includes("bottom");
18705
- const l = handle.includes("left");
18706
- const r = handle.includes("right");
18707
- let nextW = startSize.width;
18708
- let nextH = startSize.height;
18709
- if (r) nextW = startSize.width + dx;
18710
- if (l) nextW = startSize.width - dx;
18711
- if (b) nextH = startSize.height + dy;
18712
- if (t) nextH = startSize.height - dy;
18713
- if (props.keepAspect && (t || b) && (l || r)) {
18714
- nextH = nextW / aspect;
18715
- }
18716
- nextW = Math.max(props.minWidth, Math.min(props.maxWidth, nextW));
18717
- nextH = Math.max(props.minHeight, Math.min(props.maxHeight, nextH));
18718
- setSize({ width: nextW, height: nextH });
18719
- },
18720
- onEnd: () => {
18721
- emit("resizeEnd", size.value);
18722
- }
18723
- });
18724
- return vue.h("div", {
18725
- ref: (el) => {
18726
- handleRef.value = el ?? null;
18727
- },
18728
- "data-iris-resizable-handle": handle,
18729
- style: {
18730
- ...handlePosition2(handle),
18731
- touchAction: "none",
18732
- background: "transparent",
18733
- zIndex: "1"
18734
- }
18735
- });
18736
- };
18789
+ const emitResizeStart = (s) => emit("resizeStart", s);
18790
+ const emitResizeEnd = () => emit("resizeEnd", size.value);
18737
18791
  return () => vue.h(
18738
18792
  "div",
18739
18793
  {
@@ -18748,7 +18802,25 @@ var IrisResizable = vue.defineComponent({
18748
18802
  ...attrs.style ?? {}
18749
18803
  }
18750
18804
  },
18751
- [slots.default?.(), ...props.handles.map(renderHandle)]
18805
+ [
18806
+ slots.default?.(),
18807
+ ...props.handles.map(
18808
+ (handle) => vue.h(ResizableHandle, {
18809
+ key: handle,
18810
+ handle,
18811
+ disabled: props.disabled,
18812
+ keepAspect: props.keepAspect,
18813
+ minWidth: props.minWidth,
18814
+ minHeight: props.minHeight,
18815
+ maxWidth: props.maxWidth,
18816
+ maxHeight: props.maxHeight,
18817
+ sizeRef: size,
18818
+ onUpdate: setSize,
18819
+ onResizeStart: emitResizeStart,
18820
+ onResizeEnd: emitResizeEnd
18821
+ })
18822
+ )
18823
+ ]
18752
18824
  );
18753
18825
  }
18754
18826
  });