@leavepulse/ui 0.15.1 → 0.15.3

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.
@@ -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-DpBHQpbU.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: {
@@ -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
+ };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpConfirmDialog-WHkymac5.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/LpModal-DpBHQpbU.js";
1
+ import { _ as _sfc_main } from "../chunks/LpModal-d6SZpfBH.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { _ as _10 } from "./chunks/LpCard-BmrTvWOe.js";
11
11
  import { _ as _11 } from "./chunks/LpCheckbox-BO0zuuPh.js";
12
12
  import { _ as _12 } from "./chunks/LpCodeBlock-CSiOSPs8.js";
13
13
  import { default as default2 } from "./components/LpCommandPalette.vue.js";
14
- import { _ as _13 } from "./chunks/LpConfirmDialog-WHkymac5.js";
14
+ import { _ as _13 } from "./chunks/LpConfirmDialog-D6Rhge21.js";
15
15
  import { _ as _14 } from "./chunks/LpContextMenu-D0mzXqA7.js";
16
16
  import { _ as _15 } from "./chunks/LpDatePicker-dY2q4dr4.js";
17
17
  import { _ as _16 } from "./chunks/LpDisclosure-DP6yfgfM.js";
@@ -27,7 +27,7 @@ import { _ as _24 } from "./chunks/LpInfraNode-C_PHcthC.js";
27
27
  import { _ as _25 } from "./chunks/LpInput-BauZRyzm.js";
28
28
  import { _ as _26 } from "./chunks/LpLink-DHwOEp4e.js";
29
29
  import { _ as _27 } from "./chunks/LpLogViewer-BvzRZPjs.js";
30
- import { _ as _28 } from "./chunks/LpModal-DpBHQpbU.js";
30
+ import { _ as _28 } from "./chunks/LpModal-d6SZpfBH.js";
31
31
  import { _ as _29 } from "./chunks/LpNotificationBell-BtfRoL2i.js";
32
32
  import { _ as _30 } from "./chunks/LpNumberField-C5ar-OwE.js";
33
33
  import { _ as _31 } from "./chunks/LpOtpInput-DqaT0Z75.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.15.1",
3
+ "version": "0.15.3",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -71,8 +71,17 @@ const bodyPad = computed(() =>
71
71
  <DialogOverlay
72
72
  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]"
73
73
  />
74
+ <!-- Centred by a full-screen flex wrapper rather than by translating the
75
+ panel off its own centre. With `top:50% / -translate-y-1/2` the panel
76
+ is pinned by its MIDDLE, so every height change — content arriving,
77
+ an image loading, a list filling in — moved it up and down by half
78
+ the difference, and while the open animation was still running that
79
+ read as a stutter. Anchoring the wrapper instead means the panel only
80
+ grows downward and the animation has nothing to fight.
81
+ `pointer-events-none` lets clicks through to the overlay behind it. -->
82
+ <div class="fixed inset-0 z-(--z-modal) flex items-center justify-center p-4 pointer-events-none">
74
83
  <DialogContent
75
- class="fixed left-1/2 top-1/2 z-(--z-modal) flex max-h-[min(90vh,calc(100dvh-2rem))] -translate-x-1/2 -translate-y-1/2 flex-col rounded-card border border-line bg-surface-raised shadow-panel outline-none data-[state=open]:animate-[pop-in_var(--duration-medium)_var(--ease-emphasized)] data-[state=closed]:animate-[pop-out_120ms_cubic-bezier(0.4,0,1,1)]"
84
+ class="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)]"
76
85
  :class="widthClass"
77
86
  :style="width ? { width } : undefined"
78
87
  >
@@ -118,6 +127,7 @@ const bodyPad = computed(() =>
118
127
  <slot name="footer" />
119
128
  </footer>
120
129
  </DialogContent>
130
+ </div>
121
131
  </DialogPortal>
122
132
  </DialogRoot>
123
133
  </template>
@@ -147,6 +147,8 @@
147
147
  * scaling it re-runs that layout every frame — the content visibly squashed and
148
148
  * the animation stuttered. A short rise reads as arriving just as well.
149
149
  */
150
+ /* For panels that translate off their own centre (the command palette pins its
151
+ left edge with -translate-x-1/2). */
150
152
  @keyframes pop-in {
151
153
  from {
152
154
  opacity: 0;
@@ -159,6 +161,20 @@
159
161
  transform: translate(-50%, calc(-50% + 5px));
160
162
  }
161
163
  }
164
+ /* For panels a flex/grid parent already centres, so the animation only has to
165
+ supply the rise — no -50% to preserve. LpModal uses these. */
166
+ @keyframes rise-in {
167
+ from {
168
+ opacity: 0;
169
+ transform: translateY(10px);
170
+ }
171
+ }
172
+ @keyframes rise-out {
173
+ to {
174
+ opacity: 0;
175
+ transform: translateY(5px);
176
+ }
177
+ }
162
178
  /*
163
179
  * Popover enter/exit. The -in/-out pair drifts DOWN from the trigger (content
164
180
  * placed below it). When the popper flips ABOVE the trigger (data-side=top),
@@ -1,128 +0,0 @@
1
- import { defineComponent, computed, useSlots, openBlock, createBlock, unref, withCtx, createVNode, normalizeStyle, normalizeClass, createElementBlock, createElementVNode, 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 = {
7
- key: 0,
8
- class: "flex shrink-0 items-start justify-between gap-4 p-5 pb-3"
9
- };
10
- const _hoisted_2 = { class: "flex flex-col gap-1" };
11
- const _hoisted_3 = {
12
- key: 3,
13
- class: "flex shrink-0 justify-end gap-2 p-5 pt-4"
14
- };
15
- const _sfc_main = /* @__PURE__ */ defineComponent({
16
- __name: "LpModal",
17
- props: {
18
- open: { type: Boolean },
19
- title: {},
20
- description: {},
21
- size: { default: "md" },
22
- width: {},
23
- fillBody: { type: Boolean }
24
- },
25
- emits: ["update:open"],
26
- setup(__props) {
27
- const props = __props;
28
- const widthClass = computed(() => {
29
- if (props.width) return "";
30
- return {
31
- sm: "w-[min(92vw,24rem)]",
32
- md: "w-[min(92vw,28rem)]",
33
- lg: "w-[min(92vw,34rem)]",
34
- xl: "w-[min(92vw,42rem)]",
35
- "2xl": "w-[min(94vw,56rem)]",
36
- "3xl": "w-[min(95vw,72rem)]",
37
- full: "w-[96vw]"
38
- }[props.size];
39
- });
40
- const slots = useSlots();
41
- const bodyPad = computed(
42
- () => [
43
- "px-5",
44
- props.title || slots.title ? "" : "pt-5",
45
- slots.footer ? "" : "pb-5"
46
- ].filter(Boolean).join(" ")
47
- );
48
- return (_ctx, _cache) => {
49
- return openBlock(), createBlock(unref(DialogRoot), {
50
- open: __props.open,
51
- "onUpdate:open": _cache[0] || (_cache[0] = (v) => _ctx.$emit("update:open", v))
52
- }, {
53
- default: withCtx(() => [
54
- createVNode(unref(DialogPortal), null, {
55
- default: withCtx(() => [
56
- 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]" }),
57
- createVNode(unref(DialogContent), {
58
- class: normalizeClass(["fixed left-1/2 top-1/2 z-(--z-modal) flex max-h-[min(90vh,calc(100dvh-2rem))] -translate-x-1/2 -translate-y-1/2 flex-col rounded-card border border-line bg-surface-raised shadow-panel outline-none data-[state=open]:animate-[pop-in_var(--duration-medium)_var(--ease-emphasized)] data-[state=closed]:animate-[pop-out_120ms_cubic-bezier(0.4,0,1,1)]", widthClass.value]),
59
- style: normalizeStyle(__props.width ? { width: __props.width } : void 0)
60
- }, {
61
- default: withCtx(() => [
62
- __props.title || _ctx.$slots.title ? (openBlock(), createElementBlock("header", _hoisted_1, [
63
- createElementVNode("div", _hoisted_2, [
64
- createVNode(unref(DialogTitle), { class: "text-base font-semibold text-ink" }, {
65
- default: withCtx(() => [
66
- renderSlot(_ctx.$slots, "title", {}, () => [
67
- createTextVNode(toDisplayString(__props.title), 1)
68
- ])
69
- ]),
70
- _: 3
71
- }),
72
- __props.description ? (openBlock(), createBlock(unref(DialogDescription), {
73
- key: 0,
74
- class: "text-sm text-muted"
75
- }, {
76
- default: withCtx(() => [
77
- createTextVNode(toDisplayString(__props.description), 1)
78
- ]),
79
- _: 1
80
- })) : createCommentVNode("", true)
81
- ]),
82
- createVNode(unref(DialogClose), {
83
- 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",
84
- "aria-label": "Close"
85
- }, {
86
- default: withCtx(() => [
87
- createVNode(_sfc_main$1, {
88
- name: "lucide:x",
89
- size: 18,
90
- class: normalizeClass(unref(CLOSE_ICON))
91
- }, null, 8, ["class"])
92
- ]),
93
- _: 1
94
- })
95
- ])) : createCommentVNode("", true),
96
- __props.fillBody ? (openBlock(), createElementBlock("div", {
97
- key: 1,
98
- class: normalizeClass(["flex min-h-0 flex-1 flex-col overflow-hidden text-sm text-ink/90", bodyPad.value])
99
- }, [
100
- renderSlot(_ctx.$slots, "default")
101
- ], 2)) : (openBlock(), createBlock(_sfc_main$2, {
102
- key: 2,
103
- class: "min-h-0 flex-1 text-sm text-ink/90",
104
- "content-class": bodyPad.value
105
- }, {
106
- default: withCtx(() => [
107
- renderSlot(_ctx.$slots, "default")
108
- ]),
109
- _: 3
110
- }, 8, ["content-class"])),
111
- _ctx.$slots.footer ? (openBlock(), createElementBlock("footer", _hoisted_3, [
112
- renderSlot(_ctx.$slots, "footer")
113
- ])) : createCommentVNode("", true)
114
- ]),
115
- _: 3
116
- }, 8, ["class", "style"])
117
- ]),
118
- _: 3
119
- })
120
- ]),
121
- _: 3
122
- }, 8, ["open"]);
123
- };
124
- }
125
- });
126
- export {
127
- _sfc_main as _
128
- };