@leavepulse/ui 0.14.8 → 0.14.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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, computed, openBlock, createBlock, withCtx,
|
|
1
|
+
import { defineComponent, computed, openBlock, createBlock, withCtx, resolveDynamicComponent, mergeProps, renderSlot } from "vue";
|
|
2
2
|
import { tv } from "tailwind-variants";
|
|
3
3
|
import { _ as _sfc_main$1 } from "./LpContextMenu-D0mzXqA7.js";
|
|
4
4
|
const __default__ = { inheritAttrs: false };
|
|
@@ -9,7 +9,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
9
9
|
variant: { default: "raised" },
|
|
10
10
|
padded: { type: Boolean, default: true },
|
|
11
11
|
interactive: { type: Boolean, default: false },
|
|
12
|
-
menuItems: {}
|
|
12
|
+
menuItems: {},
|
|
13
|
+
as: { default: "div" }
|
|
13
14
|
},
|
|
14
15
|
setup(__props) {
|
|
15
16
|
const card = tv({
|
|
@@ -32,6 +33,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
32
33
|
// NOTE: in Tailwind v4 `translate-*` writes the native `translate` property
|
|
33
34
|
// (not `transform`), so the transition list MUST name `translate` explicitly
|
|
34
35
|
// or the lift snaps while the rest eases.
|
|
36
|
+
//
|
|
37
|
+
// The glow reaches past the card, so a clipping ancestor (scroll area,
|
|
38
|
+
// dialog body) will slice it unless the list reserves room — see the
|
|
39
|
+
// `.lp-glow-room` helper in tokens.css, whose spread tokens describe exactly
|
|
40
|
+
// the distance this shadow travels.
|
|
35
41
|
interactive: {
|
|
36
42
|
true: "cursor-pointer transition-[translate,box-shadow,border-color] duration-medium ease-[var(--ease-emphasized)] hover:-translate-y-0.5 hover:border-brand/40 hover:shadow-[var(--lp-card-glow)] hover:[--surface-panel-shadow:var(--lp-card-glow)] [--lp-card-glow:0_8px_24px_-6px_color-mix(in_srgb,var(--color-brand)_38%,transparent)] motion-reduce:transition-none motion-reduce:hover:translate-y-0"
|
|
37
43
|
}
|
|
@@ -47,17 +53,23 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
47
53
|
items: __props.menuItems
|
|
48
54
|
}, {
|
|
49
55
|
default: withCtx(() => [
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
(openBlock(), createBlock(resolveDynamicComponent(__props.as), mergeProps({ class: classes.value }, _ctx.$attrs), {
|
|
57
|
+
default: withCtx(() => [
|
|
58
|
+
renderSlot(_ctx.$slots, "default")
|
|
59
|
+
]),
|
|
60
|
+
_: 3
|
|
61
|
+
}, 16, ["class"]))
|
|
53
62
|
]),
|
|
54
63
|
_: 3
|
|
55
|
-
}, 8, ["items"])) : (openBlock(),
|
|
64
|
+
}, 8, ["items"])) : (openBlock(), createBlock(resolveDynamicComponent(__props.as), mergeProps({
|
|
56
65
|
key: 1,
|
|
57
66
|
class: classes.value
|
|
58
|
-
}, _ctx.$attrs),
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
}, _ctx.$attrs), {
|
|
68
|
+
default: withCtx(() => [
|
|
69
|
+
renderSlot(_ctx.$slots, "default")
|
|
70
|
+
]),
|
|
71
|
+
_: 3
|
|
72
|
+
}, 16, ["class"]));
|
|
61
73
|
};
|
|
62
74
|
}
|
|
63
75
|
});
|
|
@@ -7,13 +7,18 @@ declare const __VLS_export: __VLS_WithSlots<import('vue').DefineComponent<{
|
|
|
7
7
|
interactive?: boolean;
|
|
8
8
|
/** Right-click menu for the card. Omit (or pass []) to keep the native one. */
|
|
9
9
|
menuItems?: ContextMenuItemDef[];
|
|
10
|
+
/** Element to render as. A card inside a <ul> has to be an `li` to be valid. */
|
|
11
|
+
as?: string;
|
|
10
12
|
}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{
|
|
11
13
|
variant?: "flat" | "ghost" | "raised" | undefined;
|
|
12
14
|
padded?: boolean;
|
|
13
15
|
interactive?: boolean;
|
|
14
16
|
/** Right-click menu for the card. Omit (or pass []) to keep the native one. */
|
|
15
17
|
menuItems?: ContextMenuItemDef[];
|
|
18
|
+
/** Element to render as. A card inside a <ul> has to be an `li` to be valid. */
|
|
19
|
+
as?: string;
|
|
16
20
|
}> & Readonly<{}>, {
|
|
21
|
+
as: string;
|
|
17
22
|
variant: "flat" | "ghost" | "raised";
|
|
18
23
|
padded: boolean;
|
|
19
24
|
interactive: boolean;
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { _ as _6 } from "./chunks/LpBadge-CXzBPnwO.js";
|
|
|
7
7
|
import { _ as _7 } from "./chunks/LpBreadcrumbs-B7Aqatzw.js";
|
|
8
8
|
import { _ as _8 } from "./chunks/LpButton-5VXXCjwF.js";
|
|
9
9
|
import { _ as _9 } from "./chunks/LpCalendar-B7ZL0ty3.js";
|
|
10
|
-
import { _ as _10 } from "./chunks/LpCard-
|
|
10
|
+
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";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leavepulse/ui",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "LeavePulse token-driven Vue component kit.",
|
|
6
6
|
"repository": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"./dist/*": "./dist/*"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
|
-
"registry": "https://
|
|
34
|
+
"registry": "https://registry.npmjs.org"
|
|
35
35
|
},
|
|
36
36
|
"sideEffects": [
|
|
37
37
|
"**/*.css",
|
|
@@ -30,6 +30,11 @@ const card = tv({
|
|
|
30
30
|
// NOTE: in Tailwind v4 `translate-*` writes the native `translate` property
|
|
31
31
|
// (not `transform`), so the transition list MUST name `translate` explicitly
|
|
32
32
|
// or the lift snaps while the rest eases.
|
|
33
|
+
//
|
|
34
|
+
// The glow reaches past the card, so a clipping ancestor (scroll area,
|
|
35
|
+
// dialog body) will slice it unless the list reserves room — see the
|
|
36
|
+
// `.lp-glow-room` helper in tokens.css, whose spread tokens describe exactly
|
|
37
|
+
// the distance this shadow travels.
|
|
33
38
|
interactive: {
|
|
34
39
|
true: "cursor-pointer transition-[translate,box-shadow,border-color] duration-medium ease-[var(--ease-emphasized)] hover:-translate-y-0.5 hover:border-brand/40 hover:shadow-[var(--lp-card-glow)] hover:[--surface-panel-shadow:var(--lp-card-glow)] [--lp-card-glow:0_8px_24px_-6px_color-mix(in_srgb,var(--color-brand)_38%,transparent)] motion-reduce:transition-none motion-reduce:hover:translate-y-0",
|
|
35
40
|
},
|
|
@@ -47,8 +52,10 @@ const props = withDefaults(
|
|
|
47
52
|
interactive?: boolean
|
|
48
53
|
/** Right-click menu for the card. Omit (or pass []) to keep the native one. */
|
|
49
54
|
menuItems?: ContextMenuItemDef[]
|
|
55
|
+
/** Element to render as. A card inside a <ul> has to be an `li` to be valid. */
|
|
56
|
+
as?: string
|
|
50
57
|
}>(),
|
|
51
|
-
{ variant: "raised", padded: true, interactive: false },
|
|
58
|
+
{ variant: "raised", padded: true, interactive: false, as: "div" },
|
|
52
59
|
)
|
|
53
60
|
|
|
54
61
|
const classes = computed(() =>
|
|
@@ -61,11 +68,11 @@ const classes = computed(() =>
|
|
|
61
68
|
(inheritAttrs:false above), so the card surface looks identical whether or
|
|
62
69
|
not it's wrapped in a context menu. -->
|
|
63
70
|
<LpContextMenu v-if="menuItems?.length" :items="menuItems">
|
|
64
|
-
<
|
|
71
|
+
<component :is="as" :class="classes" v-bind="$attrs">
|
|
65
72
|
<slot />
|
|
66
|
-
</
|
|
73
|
+
</component>
|
|
67
74
|
</LpContextMenu>
|
|
68
|
-
<
|
|
75
|
+
<component :is="as" v-else :class="classes" v-bind="$attrs">
|
|
69
76
|
<slot />
|
|
70
|
-
</
|
|
77
|
+
</component>
|
|
71
78
|
</template>
|
package/src/tokens/tokens.css
CHANGED
|
@@ -60,6 +60,16 @@
|
|
|
60
60
|
/* ── depth ───────────────────────────────────── */
|
|
61
61
|
--shadow-panel: 0 16px 48px rgba(0, 0, 0, 0.32);
|
|
62
62
|
|
|
63
|
+
/* How far an interactive card's hover glow spreads past its own box, and how
|
|
64
|
+
far the card lifts. A scroll area or any `overflow: hidden` parent clips
|
|
65
|
+
whatever crosses its edge, so a list of cards has to reserve this much room
|
|
66
|
+
around itself or the glow gets sliced off — see the `.lp-glow-room` helper.
|
|
67
|
+
Derived from LpCard's glow (0 8px 24px -6px): blur 24 minus spread 6 = 18
|
|
68
|
+
sideways and up, plus the 8px downward offset below. */
|
|
69
|
+
--lp-glow-spread: 18px;
|
|
70
|
+
--lp-glow-spread-bottom: 26px;
|
|
71
|
+
--lp-card-lift: 2px;
|
|
72
|
+
|
|
63
73
|
/* ── surface / skin ──────────────────────────────
|
|
64
74
|
The skin axis (flat default). applyTheme() overrides these at runtime per
|
|
65
75
|
TokenSet.surface; components paint panels via .lp-skin-panel which reads
|
|
@@ -131,16 +141,22 @@
|
|
|
131
141
|
* of appearing. Exit drops back the same way but shorter and on an accelerating
|
|
132
142
|
* curve, since a dismissal shouldn't be savoured.
|
|
133
143
|
*/
|
|
144
|
+
/*
|
|
145
|
+
* Centred-dialog enter/exit. Deliberately translate + fade with NO scale: the
|
|
146
|
+
* panel is a flex column with a max-height and its own scroll regions, and
|
|
147
|
+
* scaling it re-runs that layout every frame — the content visibly squashed and
|
|
148
|
+
* the animation stuttered. A short rise reads as arriving just as well.
|
|
149
|
+
*/
|
|
134
150
|
@keyframes pop-in {
|
|
135
151
|
from {
|
|
136
152
|
opacity: 0;
|
|
137
|
-
transform: translate(-50%, calc(-50% +
|
|
153
|
+
transform: translate(-50%, calc(-50% + 10px));
|
|
138
154
|
}
|
|
139
155
|
}
|
|
140
156
|
@keyframes pop-out {
|
|
141
157
|
to {
|
|
142
158
|
opacity: 0;
|
|
143
|
-
transform: translate(-50%, calc(-50% +
|
|
159
|
+
transform: translate(-50%, calc(-50% + 5px));
|
|
144
160
|
}
|
|
145
161
|
}
|
|
146
162
|
/*
|
|
@@ -294,6 +310,30 @@
|
|
|
294
310
|
z-index: 1;
|
|
295
311
|
}
|
|
296
312
|
|
|
313
|
+
/*
|
|
314
|
+
* Room for a hover glow. An interactive card's glow spreads past the card's own
|
|
315
|
+
* box, so inside anything that clips — a scroll area, a dialog body, a panel
|
|
316
|
+
* with `overflow: hidden` — the glow gets sliced off flat against the edge, and
|
|
317
|
+
* a card sitting at the very top or bottom of a list loses it entirely. The
|
|
318
|
+
* same clip takes the focus ring, which is likewise drawn outside the border;
|
|
319
|
+
* the glow is the wider of the two, so reserving for it covers both.
|
|
320
|
+
*
|
|
321
|
+
* Put this on the element that LAYS OUT the cards (the <ul>, the grid), not on
|
|
322
|
+
* the clipping parent: it pads the content inward by exactly the distance the
|
|
323
|
+
* glow travels, so the glow lands on padding instead of on the clip boundary.
|
|
324
|
+
* Negative margins pull that padding back out, so the cards stay where they
|
|
325
|
+
* were and nothing shifts — only the overflow gets somewhere to go.
|
|
326
|
+
*
|
|
327
|
+
* Bottom gets more room than the top because the glow is offset downward, and
|
|
328
|
+
* the top gets the lift added back, since a hovered card rises into it.
|
|
329
|
+
*/
|
|
330
|
+
.lp-glow-room {
|
|
331
|
+
padding: calc(var(--lp-glow-spread) + var(--lp-card-lift)) var(--lp-glow-spread)
|
|
332
|
+
var(--lp-glow-spread-bottom);
|
|
333
|
+
margin: calc(-1 * (var(--lp-glow-spread) + var(--lp-card-lift))) calc(-1 * var(--lp-glow-spread))
|
|
334
|
+
calc(-1 * var(--lp-glow-spread-bottom));
|
|
335
|
+
}
|
|
336
|
+
|
|
297
337
|
/* ── circular theme reveal (View Transitions) ────
|
|
298
338
|
applyThemeWithTransition() snapshots the page, swaps the theme tokens, then
|
|
299
339
|
shrinks a clip-path circle in the OLD snapshot from the toggle's position,
|