@leavepulse/ui 0.15.0 → 0.15.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.
Files changed (44) hide show
  1. package/dist/chunks/{LpAppShell-BLKZDLh8.js → LpAppShell-CV194os6.js} +2 -2
  2. package/dist/chunks/{LpAutocomplete-B9uoCs4t.js → LpAutocomplete-DIgXmtCA.js} +13 -5
  3. package/dist/chunks/{LpConfirmDialog-BA45MvRL.js → LpConfirmDialog-D6Rhge21.js} +1 -1
  4. package/dist/chunks/{LpDrawer-6n5Hd-iF.js → LpDrawer-BHzCy-Aa.js} +1 -1
  5. package/dist/chunks/{LpFileTree-D0DEpKof.js → LpFileTree-BQz8Rfgz.js} +49 -32
  6. package/dist/chunks/{LpFileTreeNode-3e71ywJV.js → LpFileTreeNode-DFg4PhOK.js} +10 -7
  7. package/dist/chunks/{LpLogViewer-BBgaY38i.js → LpLogViewer-BvzRZPjs.js} +2 -1
  8. package/dist/chunks/LpModal-d6SZpfBH.js +131 -0
  9. package/dist/chunks/{LpNotificationBell-B9VHks_D.js → LpNotificationBell-BtfRoL2i.js} +1 -1
  10. package/dist/chunks/{LpScrollArea-BtnZCCBT.js → LpScrollArea-De9DLpa1.js} +2 -2
  11. package/dist/chunks/{LpSidebar-tZ2z-PnM.js → LpSidebar-B11IDRQi.js} +2 -2
  12. package/dist/chunks/{LpSidebarNav-D-YvtwsH.js → LpSidebarNav-TIUNHZX-.js} +1 -1
  13. package/dist/chunks/{LpTable-CzHVcr3v.js → LpTable-CKGaUbEM.js} +1 -1
  14. package/dist/components/LpAppShell.vue.js +1 -1
  15. package/dist/components/LpAutocomplete.vue.js +1 -1
  16. package/dist/components/LpCommandPalette.vue.js +1 -1
  17. package/dist/components/LpConfirmDialog.vue.js +1 -1
  18. package/dist/components/LpDrawer.vue.js +1 -1
  19. package/dist/components/LpFileTree.vue.js +1 -1
  20. package/dist/components/LpFileTreeNode.vue.d.ts +3 -1
  21. package/dist/components/LpFileTreeNode.vue.js +1 -1
  22. package/dist/components/LpLogViewer.vue.js +1 -1
  23. package/dist/components/LpModal.vue.js +1 -1
  24. package/dist/components/LpNotificationBell.vue.js +1 -1
  25. package/dist/components/LpScrollArea.vue.d.ts +4 -2
  26. package/dist/components/LpScrollArea.vue.js +1 -1
  27. package/dist/components/LpSidebar.vue.js +1 -1
  28. package/dist/components/LpSidebarNav.vue.js +1 -1
  29. package/dist/components/LpTable.vue.js +1 -1
  30. package/dist/components/fileTree.d.ts +16 -0
  31. package/dist/components/fileTree.js +49 -0
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.js +13 -12
  34. package/package.json +1 -1
  35. package/src/components/LpAutocomplete.vue +19 -2
  36. package/src/components/LpFileTree.vue +67 -35
  37. package/src/components/LpFileTreeNode.vue +16 -9
  38. package/src/components/LpLogViewer.vue +4 -0
  39. package/src/components/LpModal.vue +11 -1
  40. package/src/components/LpScrollArea.vue +16 -11
  41. package/src/components/fileTree.ts +75 -0
  42. package/src/index.ts +2 -1
  43. package/src/tokens/tokens.css +16 -0
  44. package/dist/chunks/LpModal-B9CVVC5U.js +0 -128
@@ -1,8 +1,8 @@
1
1
  import { defineComponent, computed, watch, openBlock, createElementBlock, createVNode, createSlots, withCtx, renderSlot, normalizeProps, guardReactiveProps, createElementVNode, normalizeClass, toDisplayString, createCommentVNode, createBlock } from "vue";
2
2
  import { _ as _sfc_main$2 } from "./LpButton-5VXXCjwF.js";
3
3
  import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
4
- import { _ as _sfc_main$4 } from "./LpScrollArea-BtnZCCBT.js";
5
- import { _ as _sfc_main$1 } from "./LpSidebar-tZ2z-PnM.js";
4
+ import { _ as _sfc_main$4 } from "./LpScrollArea-De9DLpa1.js";
5
+ import { _ as _sfc_main$1 } from "./LpSidebar-B11IDRQi.js";
6
6
  const _hoisted_1 = { class: "flex h-dvh overflow-hidden bg-surface text-ink" };
7
7
  const _hoisted_2 = { class: "flex min-w-0 flex-1 flex-col" };
8
8
  const _hoisted_3 = { class: "flex h-16 shrink-0 items-center gap-3 border-b border-line bg-surface px-4 md:px-6" };
@@ -50,9 +50,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
50
50
  (o) => typeof o === "string" ? { value: o } : o
51
51
  )
52
52
  );
53
+ const typing = ref(false);
53
54
  const filtered = computed(() => {
54
55
  const q = text.value.trim().toLowerCase();
55
- if (!props.filter || !q) return items.value;
56
+ if (!props.filter || !typing.value || !q) return items.value;
56
57
  return items.value.filter((o) => {
57
58
  const hay = `${o.label ?? o.value} ${o.description ?? ""}`.toLowerCase();
58
59
  return hay.includes(q);
@@ -72,23 +73,30 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
72
73
  md: "h-(--size-control-md) text-sm",
73
74
  lg: "h-(--size-control-lg) text-sm"
74
75
  };
76
+ function onInput(event) {
77
+ typing.value = true;
78
+ text.value = event.target.value;
79
+ }
75
80
  function onFocus() {
81
+ typing.value = false;
76
82
  focused.value = true;
77
83
  if (canOpen.value) open.value = true;
78
84
  }
79
85
  function choose(opt) {
86
+ typing.value = false;
80
87
  emit("update:modelValue", opt.value);
81
88
  emit("select", opt.value);
82
89
  open.value = false;
83
90
  }
84
91
  function clear() {
92
+ typing.value = false;
85
93
  emit("update:modelValue", "");
86
94
  open.value = false;
87
95
  }
88
96
  return (_ctx, _cache) => {
89
97
  return openBlock(), createBlock(unref(ComboboxRoot), {
90
98
  open: open.value,
91
- "onUpdate:open": _cache[3] || (_cache[3] = ($event) => open.value = $event),
99
+ "onUpdate:open": _cache[2] || (_cache[2] = ($event) => open.value = $event),
92
100
  "ignore-filter": true,
93
101
  "reset-search-term-on-blur": false,
94
102
  "reset-search-term-on-select": false,
@@ -118,9 +126,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
118
126
  class: "min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted",
119
127
  onBeforeinput: unref(onBeforeInput),
120
128
  onPaste: unref(onPaste),
121
- onInput: _cache[0] || (_cache[0] = ($event) => text.value = $event.target.value),
129
+ onInput,
122
130
  onFocus,
123
- onBlur: _cache[1] || (_cache[1] = ($event) => focused.value = false)
131
+ onBlur: _cache[0] || (_cache[0] = ($event) => focused.value = false)
124
132
  }, null, 8, ["model-value", "placeholder", "disabled", "aria-invalid", "onBeforeinput", "onPaste"]),
125
133
  __props.clearable && hasValue.value ? (openBlock(), createElementBlock("button", {
126
134
  key: 1,
@@ -144,7 +152,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
144
152
  position: "popper",
145
153
  "side-offset": 6,
146
154
  class: normalizeClass([unref(POPOVER_PANEL), "z-(--z-popover) max-h-72 w-(--reka-combobox-trigger-width) overflow-hidden"]),
147
- onOpenAutoFocus: _cache[2] || (_cache[2] = withModifiers(() => {
155
+ onOpenAutoFocus: _cache[1] || (_cache[1] = withModifiers(() => {
148
156
  }, ["prevent"]))
149
157
  }, {
150
158
  default: withCtx(() => [
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, openBlock, createBlock, withCtx, renderSlot, createVNode, createTextVNode, toDisplayString } from "vue";
2
2
  import { _ as _sfc_main$2 } from "./LpButton-5VXXCjwF.js";
3
- import { _ as _sfc_main$1 } from "./LpModal-B9CVVC5U.js";
3
+ import { _ as _sfc_main$1 } from "./LpModal-d6SZpfBH.js";
4
4
  const _sfc_main = /* @__PURE__ */ defineComponent({
5
5
  __name: "LpConfirmDialog",
6
6
  props: {
@@ -3,7 +3,7 @@ import { usePointerSwipe } from "@vueuse/core";
3
3
  import { DrawerRoot, DrawerPortal, DrawerOverlay, DrawerContent, DrawerHandle, DrawerTitle, DrawerDescription, DrawerClose } from "vaul-vue";
4
4
  import { CLOSE_ICON } from "../components/dropdown.js";
5
5
  import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
6
- import { _ as _sfc_main$2 } from "./LpScrollArea-BtnZCCBT.js";
6
+ import { _ as _sfc_main$2 } from "./LpScrollArea-De9DLpa1.js";
7
7
  const _hoisted_1 = { class: "text-base font-semibold text-ink" };
8
8
  const _hoisted_2 = { class: "flex flex-col gap-1" };
9
9
  const _hoisted_3 = ["data-vaul-no-drag"];
@@ -1,8 +1,8 @@
1
1
  import { defineComponent, ref, watch, computed, openBlock, createElementBlock, Fragment, renderList, normalizeStyle, createBlock, createVNode, withCtx, createElementVNode, renderSlot, mergeProps, normalizeProps, guardReactiveProps, createTextVNode, toDisplayString, createCommentVNode } from "vue";
2
- import { subtreeIds, subtreeSize, formatSize, sortNodes, ancestorIds, checkStateOf } from "../components/fileTree.js";
2
+ import { formatSize, sortNodes, computeStats, subtreeIds, ancestorIds } from "../components/fileTree.js";
3
3
  import { _ as _sfc_main$1 } from "./LpEmptyState-CrfyRJUG.js";
4
- import { _ as _sfc_main$3 } from "./LpFileTreeNode-3e71ywJV.js";
5
- import { _ as _sfc_main$2 } from "./LpScrollArea-BtnZCCBT.js";
4
+ import { _ as _sfc_main$3 } from "./LpFileTreeNode-DFg4PhOK.js";
5
+ import { _ as _sfc_main$2 } from "./LpScrollArea-De9DLpa1.js";
6
6
  const _hoisted_1 = {
7
7
  key: 0,
8
8
  class: "flex flex-col gap-1"
@@ -53,43 +53,56 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
53
53
  if (ids) checkedIds.value = new Set(ids);
54
54
  }
55
55
  );
56
- const byId = computed(() => {
57
- const map = /* @__PURE__ */ new Map();
58
- function walk(list) {
56
+ const index = computed(() => {
57
+ const byId2 = /* @__PURE__ */ new Map();
58
+ const parentOfId = /* @__PURE__ */ new Map();
59
+ function walk(list, parent) {
59
60
  for (const node of list) {
60
- map.set(node.id, node);
61
- if (node.children) walk(node.children);
61
+ byId2.set(node.id, node);
62
+ if (parent !== void 0) parentOfId.set(node.id, parent);
63
+ if (node.children) walk(node.children, node.id);
62
64
  }
63
65
  }
64
66
  walk(props.nodes);
65
- return map;
67
+ return { byId: byId2, parentOfId };
66
68
  });
69
+ const byId = computed(() => index.value.byId);
67
70
  const summary = computed(() => {
68
71
  let files = 0;
69
72
  let dirs = 0;
70
73
  let bytes = 0;
71
74
  let sized = false;
72
- for (const id of checkedIds.value) {
73
- const node = byId.value.get(id);
74
- if (!node) continue;
75
- if (node.kind === "dir") {
76
- dirs++;
77
- const inside = node.children?.length ? subtreeIds(node).some((child) => child !== id && checkedIds.value.has(child)) : false;
78
- if (!inside) {
79
- const size = subtreeSize(node);
80
- if (size !== void 0) {
81
- bytes += size;
75
+ function walk(list) {
76
+ for (const node of list) {
77
+ const stat = stats.value.get(node.id);
78
+ if (!stat || stat.state === "unchecked") continue;
79
+ if (node.kind === "file") {
80
+ files++;
81
+ if (node.size !== void 0) {
82
+ bytes += node.size;
82
83
  sized = true;
83
84
  }
85
+ continue;
84
86
  }
85
- } else {
86
- files++;
87
- if (node.size !== void 0) {
88
- bytes += node.size;
87
+ dirs++;
88
+ if (stat.state === "checked" && stat.size !== void 0) {
89
+ bytes += stat.size;
89
90
  sized = true;
91
+ files += stat.total;
92
+ countDirs(node.children ?? []);
93
+ continue;
90
94
  }
95
+ walk(node.children ?? []);
91
96
  }
92
97
  }
98
+ function countDirs(list) {
99
+ for (const node of list) {
100
+ if (node.kind !== "dir") continue;
101
+ dirs++;
102
+ countDirs(node.children ?? []);
103
+ }
104
+ }
105
+ walk(props.nodes);
93
106
  return {
94
107
  files,
95
108
  dirs,
@@ -111,12 +124,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
111
124
  if (value) next.add(id);
112
125
  else next.delete(id);
113
126
  }
114
- for (const ancestorId of ancestorIds(props.nodes, node.id).reverse()) {
127
+ let ancestorId = index.value.parentOfId.get(node.id);
128
+ while (ancestorId !== void 0) {
115
129
  const ancestor = byId.value.get(ancestorId);
116
- if (!ancestor?.children?.length) continue;
117
- const all = ancestor.children.every((c) => c.disabled || next.has(c.id));
118
- if (all) next.add(ancestorId);
119
- else next.delete(ancestorId);
130
+ if (ancestor?.children?.length) {
131
+ const all = ancestor.children.every((c) => c.disabled || next.has(c.id));
132
+ if (all) next.add(ancestorId);
133
+ else next.delete(ancestorId);
134
+ }
135
+ ancestorId = index.value.parentOfId.get(ancestorId);
120
136
  }
121
137
  setChecked(next);
122
138
  }
@@ -130,6 +146,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
130
146
  }
131
147
  const requested = /* @__PURE__ */ new Set();
132
148
  const roots = computed(() => props.sort ? sortNodes(props.nodes) : props.nodes);
149
+ const stats = computed(() => computeStats(props.nodes, checkedIds.value));
133
150
  const visible = computed(() => {
134
151
  const out = [];
135
152
  function walk(list) {
@@ -204,8 +221,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
204
221
  if (node.kind === "file") emit("open", node);
205
222
  }
206
223
  function parentOf(id) {
207
- const trail = ancestorIds(props.nodes, id);
208
- const parentId = trail.at(-1);
224
+ const parentId = index.value.parentOfId.get(id);
209
225
  return parentId ? visible.value.find((n) => n.id === parentId) : void 0;
210
226
  }
211
227
  function move(delta) {
@@ -260,7 +276,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
260
276
  if (!node) return;
261
277
  e.preventDefault();
262
278
  if (props.checkable) {
263
- onCheck(node, checkStateOf(node, checkedIds.value) !== "checked");
279
+ onCheck(node, stats.value.get(node.id)?.state !== "checked");
264
280
  break;
265
281
  }
266
282
  onSelect(node);
@@ -338,6 +354,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
338
354
  "icon-size": __props.iconSize,
339
355
  checkable: __props.checkable,
340
356
  checked: checkedIds.value,
357
+ stats: stats.value,
341
358
  "show-size": __props.showSize,
342
359
  "show-modified": __props.showModified,
343
360
  onSelect,
@@ -349,7 +366,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
349
366
  renderSlot(_ctx.$slots, "row", mergeProps({ ref_for: true }, slotProps))
350
367
  ]),
351
368
  _: 3
352
- }, 8, ["node", "expanded", "loading", "selected-id", "focused-id", "sort", "icon-size", "checkable", "checked", "show-size", "show-modified"]);
369
+ }, 8, ["node", "expanded", "loading", "selected-id", "focused-id", "sort", "icon-size", "checkable", "checked", "stats", "show-size", "show-modified"]);
353
370
  }), 128))
354
371
  ], 40, _hoisted_3)
355
372
  ]),
@@ -1,19 +1,19 @@
1
1
  import { defineComponent, computed, resolveComponent, openBlock, createElementBlock, createVNode, withCtx, createElementVNode, withModifiers, normalizeStyle, normalizeClass, createBlock, createCommentVNode, unref, renderSlot, createTextVNode, toDisplayString, Transition, Fragment, renderList, mergeProps } from "vue";
2
- import { sortNodes, checkStateOf, subtreeSize, formatSize, checkedCount, formatModified, fileIcon } from "../components/fileTree.js";
2
+ import { sortNodes, formatSize, formatModified, fileIcon } from "../components/fileTree.js";
3
3
  import { _ as _sfc_main$3 } from "./LpCheckbox-BO0zuuPh.js";
4
4
  import { _ as _sfc_main$1 } from "./LpContextMenu-D0mzXqA7.js";
5
5
  import { _ as _sfc_main$2 } from "./LpIcon-CCnX5_2j.js";
6
6
  const _hoisted_1 = ["aria-level", "aria-selected", "aria-expanded", "aria-disabled"];
7
7
  const _hoisted_2 = ["data-node-id", "tabindex"];
8
8
  const _hoisted_3 = { class: "flex size-4 shrink-0 items-center justify-center" };
9
- const _hoisted_4 = { class: "min-w-0 flex-1 truncate" };
9
+ const _hoisted_4 = { class: "min-w-0 flex-1 shrink-[2] truncate" };
10
10
  const _hoisted_5 = {
11
11
  key: 1,
12
12
  class: "shrink-0 rounded-pill bg-brand-soft px-1.5 py-0.5 text-[11px] font-medium tabular-nums text-brand"
13
13
  };
14
14
  const _hoisted_6 = {
15
15
  key: 2,
16
- class: "shrink-0 text-xs text-muted"
16
+ class: "min-w-0 shrink truncate text-xs text-muted"
17
17
  };
18
18
  const _hoisted_7 = {
19
19
  key: 3,
@@ -41,6 +41,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
41
41
  iconSize: {},
42
42
  checkable: { type: Boolean },
43
43
  checked: {},
44
+ stats: {},
44
45
  showSize: { type: Boolean },
45
46
  showModified: { type: Boolean }
46
47
  },
@@ -59,17 +60,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
59
60
  const list = props.node.children ?? [];
60
61
  return props.sort ? sortNodes(list) : list;
61
62
  });
63
+ const stat = computed(() => props.stats.get(props.node.id));
62
64
  const checkState = computed(
63
- () => props.checkable ? checkStateOf(props.node, props.checked) : "unchecked"
65
+ () => props.checkable ? stat.value?.state ?? "unchecked" : "unchecked"
64
66
  );
65
67
  const sizeLabel = computed(() => {
66
68
  if (!props.showSize) return "";
67
- const bytes = subtreeSize(props.node);
69
+ const bytes = stat.value?.size;
68
70
  return bytes === void 0 ? "" : formatSize(bytes);
69
71
  });
70
72
  const countLabel = computed(() => {
71
73
  if (!props.checkable || !isDir.value) return "";
72
- const { checked, total } = checkedCount(props.node, props.checked);
74
+ const { checked = 0, total = 0 } = stat.value ?? {};
73
75
  return total && checked && checked < total ? `${checked} / ${total}` : "";
74
76
  });
75
77
  const modifiedLabel = computed(
@@ -201,6 +203,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
201
203
  "icon-size": __props.iconSize,
202
204
  checkable: __props.checkable,
203
205
  checked: __props.checked,
206
+ stats: __props.stats,
204
207
  "show-size": __props.showSize,
205
208
  "show-modified": __props.showModified,
206
209
  onSelect: _cache[2] || (_cache[2] = ($event) => emit("select", $event)),
@@ -212,7 +215,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
212
215
  renderSlot(_ctx.$slots, "row", mergeProps({ ref_for: true }, slotProps))
213
216
  ]),
214
217
  _: 3
215
- }, 8, ["style", "node", "depth", "expanded", "loading", "selected-id", "focused-id", "sort", "icon-size", "checkable", "checked", "show-size", "show-modified"]);
218
+ }, 8, ["style", "node", "depth", "expanded", "loading", "selected-id", "focused-id", "sort", "icon-size", "checkable", "checked", "stats", "show-size", "show-modified"]);
216
219
  }), 128))
217
220
  ])) : createCommentVNode("", true)
218
221
  ]),
@@ -1,7 +1,7 @@
1
1
  import { defineComponent, computed, ref, watch, nextTick, onMounted, onBeforeUnmount, openBlock, createElementBlock, createVNode, normalizeStyle, withCtx, createElementVNode, toDisplayString, createCommentVNode, Fragment, createBlock, resolveDynamicComponent, TransitionGroup, mergeProps, renderList, normalizeClass, createTextVNode, Transition } from "vue";
2
2
  import { _ as _sfc_main$3 } from "./LpContextMenu-D0mzXqA7.js";
3
3
  import { _ as _sfc_main$2 } from "./LpIcon-CCnX5_2j.js";
4
- import { _ as _sfc_main$1 } from "./LpScrollArea-BtnZCCBT.js";
4
+ import { _ as _sfc_main$1 } from "./LpScrollArea-De9DLpa1.js";
5
5
  const _hoisted_1 = { class: "relative overflow-hidden rounded-card border border-line bg-surface font-mono text-xs leading-relaxed" };
6
6
  const _hoisted_2 = {
7
7
  key: 0,
@@ -354,6 +354,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
354
354
  ref_key: "scrollRef",
355
355
  ref: scrollRef,
356
356
  fade: "",
357
+ instant: "",
357
358
  "content-class": __props.wrap ? "" : "min-w-max",
358
359
  style: normalizeStyle({ height: __props.height }),
359
360
  onScroll
@@ -0,0 +1,131 @@
1
+ import { defineComponent, computed, useSlots, openBlock, createBlock, unref, withCtx, createVNode, createElementVNode, normalizeStyle, normalizeClass, createElementBlock, renderSlot, createTextVNode, toDisplayString, createCommentVNode } from "vue";
2
+ import { DialogRoot, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription, DialogClose } from "reka-ui";
3
+ import { CLOSE_ICON } from "../components/dropdown.js";
4
+ import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
5
+ import { _ as _sfc_main$2 } from "./LpScrollArea-De9DLpa1.js";
6
+ const _hoisted_1 = { class: "fixed inset-0 z-(--z-modal) flex items-center justify-center p-4 pointer-events-none" };
7
+ const _hoisted_2 = {
8
+ key: 0,
9
+ class: "flex shrink-0 items-start justify-between gap-4 p-5 pb-3"
10
+ };
11
+ const _hoisted_3 = { class: "flex flex-col gap-1" };
12
+ const _hoisted_4 = {
13
+ key: 3,
14
+ class: "flex shrink-0 justify-end gap-2 p-5 pt-4"
15
+ };
16
+ const _sfc_main = /* @__PURE__ */ defineComponent({
17
+ __name: "LpModal",
18
+ props: {
19
+ open: { type: Boolean },
20
+ title: {},
21
+ description: {},
22
+ size: { default: "md" },
23
+ width: {},
24
+ fillBody: { type: Boolean }
25
+ },
26
+ emits: ["update:open"],
27
+ setup(__props) {
28
+ const props = __props;
29
+ const widthClass = computed(() => {
30
+ if (props.width) return "";
31
+ return {
32
+ sm: "w-[min(92vw,24rem)]",
33
+ md: "w-[min(92vw,28rem)]",
34
+ lg: "w-[min(92vw,34rem)]",
35
+ xl: "w-[min(92vw,42rem)]",
36
+ "2xl": "w-[min(94vw,56rem)]",
37
+ "3xl": "w-[min(95vw,72rem)]",
38
+ full: "w-[96vw]"
39
+ }[props.size];
40
+ });
41
+ const slots = useSlots();
42
+ const bodyPad = computed(
43
+ () => [
44
+ "px-5",
45
+ props.title || slots.title ? "" : "pt-5",
46
+ slots.footer ? "" : "pb-5"
47
+ ].filter(Boolean).join(" ")
48
+ );
49
+ return (_ctx, _cache) => {
50
+ return openBlock(), createBlock(unref(DialogRoot), {
51
+ open: __props.open,
52
+ "onUpdate:open": _cache[0] || (_cache[0] = (v) => _ctx.$emit("update:open", v))
53
+ }, {
54
+ default: withCtx(() => [
55
+ createVNode(unref(DialogPortal), null, {
56
+ default: withCtx(() => [
57
+ createVNode(unref(DialogOverlay), { class: "fixed inset-0 z-(--z-overlay) bg-black/50 backdrop-blur-sm data-[state=open]:animate-[fade-in_var(--duration-medium)_var(--ease-emphasized)] data-[state=closed]:animate-[fade-out_120ms_ease]" }),
58
+ createElementVNode("div", _hoisted_1, [
59
+ createVNode(unref(DialogContent), {
60
+ class: normalizeClass(["pointer-events-auto flex max-h-full flex-col rounded-card border border-line bg-surface-raised shadow-panel outline-none data-[state=open]:animate-[rise-in_var(--duration-medium)_var(--ease-emphasized)] data-[state=closed]:animate-[rise-out_120ms_cubic-bezier(0.4,0,1,1)]", widthClass.value]),
61
+ style: normalizeStyle(__props.width ? { width: __props.width } : void 0)
62
+ }, {
63
+ default: withCtx(() => [
64
+ __props.title || _ctx.$slots.title ? (openBlock(), createElementBlock("header", _hoisted_2, [
65
+ createElementVNode("div", _hoisted_3, [
66
+ createVNode(unref(DialogTitle), { class: "text-base font-semibold text-ink" }, {
67
+ default: withCtx(() => [
68
+ renderSlot(_ctx.$slots, "title", {}, () => [
69
+ createTextVNode(toDisplayString(__props.title), 1)
70
+ ])
71
+ ]),
72
+ _: 3
73
+ }),
74
+ __props.description ? (openBlock(), createBlock(unref(DialogDescription), {
75
+ key: 0,
76
+ class: "text-sm text-muted"
77
+ }, {
78
+ default: withCtx(() => [
79
+ createTextVNode(toDisplayString(__props.description), 1)
80
+ ]),
81
+ _: 1
82
+ })) : createCommentVNode("", true)
83
+ ]),
84
+ createVNode(unref(DialogClose), {
85
+ class: "group flex shrink-0 items-center rounded-md p-1 text-muted outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink focus-visible:ring-2 focus-visible:ring-ring",
86
+ "aria-label": "Close"
87
+ }, {
88
+ default: withCtx(() => [
89
+ createVNode(_sfc_main$1, {
90
+ name: "lucide:x",
91
+ size: 18,
92
+ class: normalizeClass(unref(CLOSE_ICON))
93
+ }, null, 8, ["class"])
94
+ ]),
95
+ _: 1
96
+ })
97
+ ])) : createCommentVNode("", true),
98
+ __props.fillBody ? (openBlock(), createElementBlock("div", {
99
+ key: 1,
100
+ class: normalizeClass(["flex min-h-0 flex-1 flex-col overflow-hidden text-sm text-ink/90", bodyPad.value])
101
+ }, [
102
+ renderSlot(_ctx.$slots, "default")
103
+ ], 2)) : (openBlock(), createBlock(_sfc_main$2, {
104
+ key: 2,
105
+ class: "min-h-0 flex-1 text-sm text-ink/90",
106
+ "content-class": bodyPad.value
107
+ }, {
108
+ default: withCtx(() => [
109
+ renderSlot(_ctx.$slots, "default")
110
+ ]),
111
+ _: 3
112
+ }, 8, ["content-class"])),
113
+ _ctx.$slots.footer ? (openBlock(), createElementBlock("footer", _hoisted_4, [
114
+ renderSlot(_ctx.$slots, "footer")
115
+ ])) : createCommentVNode("", true)
116
+ ]),
117
+ _: 3
118
+ }, 8, ["class", "style"])
119
+ ])
120
+ ]),
121
+ _: 3
122
+ })
123
+ ]),
124
+ _: 3
125
+ }, 8, ["open"]);
126
+ };
127
+ }
128
+ });
129
+ export {
130
+ _sfc_main as _
131
+ };
@@ -5,7 +5,7 @@ import { _ as _sfc_main$4 } from "./LpContextMenu-D0mzXqA7.js";
5
5
  import { _ as _sfc_main$2 } from "./LpEmptyState-CrfyRJUG.js";
6
6
  import { _ as _sfc_main$5 } from "./LpIcon-CCnX5_2j.js";
7
7
  import { _ as _sfc_main$1 } from "./LpPopover-8268UmlC.js";
8
- import { _ as _sfc_main$3 } from "./LpScrollArea-BtnZCCBT.js";
8
+ import { _ as _sfc_main$3 } from "./LpScrollArea-De9DLpa1.js";
9
9
  const _hoisted_1 = { class: "flex items-center justify-between gap-2 px-3 py-2.5" };
10
10
  const _hoisted_2 = { class: "text-sm font-semibold" };
11
11
  const _hoisted_3 = {
@@ -5,7 +5,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
5
5
  __name: "LpScrollArea",
6
6
  props: {
7
7
  fade: { type: Boolean },
8
- smooth: { type: Boolean },
8
+ instant: { type: Boolean, default: false },
9
9
  contentClass: {},
10
10
  barInsetTop: {}
11
11
  },
@@ -47,7 +47,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
47
47
  ref_key: "viewportRef",
48
48
  ref: viewportRef,
49
49
  class: normalizeClass(["size-full min-w-0 [&>div]:!block [&>div]:!min-w-0", [
50
- __props.smooth ? "scroll-smooth motion-reduce:scroll-auto" : "",
50
+ __props.instant ? "" : "scroll-smooth motion-reduce:scroll-auto",
51
51
  __props.fade ? "[mask-image:linear-gradient(to_bottom,transparent_0,black_14px,black_calc(100%-14px),transparent_100%)]" : ""
52
52
  ]]),
53
53
  onScrollPassive: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("scroll", $event))
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, computed, useId, openBlock, createElementBlock, Fragment, createElementVNode, mergeProps, normalizeClass, renderSlot, createCommentVNode, createVNode, createSlots, withCtx, normalizeProps, guardReactiveProps, createBlock } from "vue";
2
- import { _ as _sfc_main$2 } from "./LpDrawer-6n5Hd-iF.js";
3
- import { _ as _sfc_main$1 } from "./LpSidebarNav-D-YvtwsH.js";
2
+ import { _ as _sfc_main$2 } from "./LpDrawer-BHzCy-Aa.js";
3
+ import { _ as _sfc_main$1 } from "./LpSidebarNav-TIUNHZX-.js";
4
4
  const _hoisted_1 = {
5
5
  key: 1,
6
6
  class: "mt-2 flex shrink-0 flex-col gap-2"
@@ -4,7 +4,7 @@ import { usePillTransition } from "../composables/usePillTransition.js";
4
4
  import { _ as _sfc_main$4 } from "./LpBadge-CXzBPnwO.js";
5
5
  import { _ as _sfc_main$2 } from "./LpContextMenu-D0mzXqA7.js";
6
6
  import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
7
- import { _ as _sfc_main$1 } from "./LpScrollArea-BtnZCCBT.js";
7
+ import { _ as _sfc_main$1 } from "./LpScrollArea-De9DLpa1.js";
8
8
  const _hoisted_1 = {
9
9
  key: 0,
10
10
  class: "flex min-h-0 flex-1 flex-col gap-4"
@@ -2,7 +2,7 @@ import { defineComponent, computed, ref, watch, onBeforeUnmount, openBlock, crea
2
2
  import { _ as _sfc_main$2 } from "./LpCheckbox-BO0zuuPh.js";
3
3
  import { _ as _sfc_main$4 } from "./LpContextMenu-D0mzXqA7.js";
4
4
  import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
5
- import { _ as _sfc_main$1 } from "./LpScrollArea-BtnZCCBT.js";
5
+ import { _ as _sfc_main$1 } from "./LpScrollArea-De9DLpa1.js";
6
6
  const _hoisted_1 = { class: "w-full border-collapse text-sm" };
7
7
  const _hoisted_2 = { class: "border-b border-line bg-surface-soft" };
8
8
  const _hoisted_3 = {
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpAppShell-BLKZDLh8.js";
1
+ import { _ as _sfc_main } from "../chunks/LpAppShell-CV194os6.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpAutocomplete-B9uoCs4t.js";
1
+ import { _ as _sfc_main } from "../chunks/LpAutocomplete-DIgXmtCA.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,7 +1,7 @@
1
1
  import { defineComponent, ref, computed, watch, nextTick, onMounted, onBeforeUnmount, openBlock, createBlock, unref, withCtx, createVNode, withModifiers, createTextVNode, createElementVNode, withDirectives, withKeys, vModelText, createElementBlock, toDisplayString, createCommentVNode, Fragment, renderList, normalizeClass } from "vue";
2
2
  import { DialogRoot, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription } from "reka-ui";
3
3
  import { _ as _sfc_main$1 } from "../chunks/LpIcon-CCnX5_2j.js";
4
- import { _ as _sfc_main$2 } from "../chunks/LpScrollArea-BtnZCCBT.js";
4
+ import { _ as _sfc_main$2 } from "../chunks/LpScrollArea-De9DLpa1.js";
5
5
  import '../assets/LpCommandPalette-D315B47-.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
6
6
  const _hoisted_2 = ["placeholder", "onKeydown"];
7
7
  const _hoisted_3 = {
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpConfirmDialog-BA45MvRL.js";
1
+ import { _ as _sfc_main } from "../chunks/LpConfirmDialog-D6Rhge21.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpDrawer-6n5Hd-iF.js";
1
+ import { _ as _sfc_main } from "../chunks/LpDrawer-BHzCy-Aa.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpFileTree-D0DEpKof.js";
1
+ import { _ as _sfc_main } from "../chunks/LpFileTree-BQz8Rfgz.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { FileNode } from './fileTree';
1
+ import { FileNode, NodeStats } from './fileTree';
2
2
  type __VLS_Props = {
3
3
  node: FileNode;
4
4
  /** Nesting depth, 0 at the root — drives the indent guide and aria-level. */
@@ -13,6 +13,8 @@ type __VLS_Props = {
13
13
  /** Render a tri-state checkbox per row (multi-select mode). */
14
14
  checkable: boolean;
15
15
  checked: Set<string>;
16
+ /** Per-node state, derived once by the root for the whole tree. */
17
+ stats: Map<string, NodeStats>;
16
18
  showSize: boolean;
17
19
  showModified: boolean;
18
20
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpFileTreeNode-3e71ywJV.js";
1
+ import { _ as _sfc_main } from "../chunks/LpFileTreeNode-DFg4PhOK.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpLogViewer-BBgaY38i.js";
1
+ import { _ as _sfc_main } from "../chunks/LpLogViewer-BvzRZPjs.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpModal-B9CVVC5U.js";
1
+ import { _ as _sfc_main } from "../chunks/LpModal-d6SZpfBH.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpNotificationBell-B9VHks_D.js";
1
+ import { _ as _sfc_main } from "../chunks/LpNotificationBell-BtfRoL2i.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,6 +1,6 @@
1
1
  type __VLS_Props = {
2
2
  fade?: boolean;
3
- smooth?: boolean;
3
+ instant?: boolean;
4
4
  contentClass?: string;
5
5
  barInsetTop?: string;
6
6
  };
@@ -14,7 +14,9 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {
14
14
  scroll: (event: Event) => any;
15
15
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
16
16
  onScroll?: ((event: Event) => any) | undefined;
17
- }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
17
+ }>, {
18
+ instant: boolean;
19
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
18
20
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
19
21
  declare const _default: typeof __VLS_export;
20
22
  export default _default;