@leavepulse/ui 0.31.1 → 0.32.0
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/assets/{LpDropzone-DVDC-ABU.css → LpDropzone-BBoWvi-J.css} +12 -12
- package/dist/assets/{LpImageEditor-DqP5JKCy.css → LpImageEditor-BsSwej47.css} +6 -6
- package/dist/chunks/{LpAddressInput-BDkp3-Bp.js → LpAddressInput-C35TsJXt.js} +19 -14
- package/dist/chunks/{LpAppShell-Chz8Vbtu.js → LpAppShell-lVvpENMH.js} +18 -13
- package/dist/chunks/{LpBreadcrumbs-5uvViCXi.js → LpBreadcrumbs-p4jHe_V-.js} +9 -7
- package/dist/chunks/{LpCalendar-B7ZL0ty3.js → LpCalendar-B7Ko5RdR.js} +12 -7
- package/dist/chunks/{LpCard-D0M2ZCnB.js → LpCard-1SeUYPBT.js} +36 -9
- package/dist/chunks/{LpCheckbox-BO0zuuPh.js → LpCheckbox-CVccKYaH.js} +9 -4
- package/dist/chunks/{LpCodeBlock-BWX1KZwk.js → LpCodeBlock-Bo0B4TFR.js} +37 -32
- package/dist/chunks/{LpDatePicker-dY2q4dr4.js → LpDatePicker-6JFXllj5.js} +1 -1
- package/dist/chunks/{LpDisclosure-B4kVAWfg.js → LpDisclosure-y7wDBgLa.js} +11 -6
- package/dist/chunks/{LpEmptyState-BV3q7Qyi.js → LpEmptyState-Dsdqz1Wj.js} +13 -5
- package/dist/chunks/{LpFileTree-DfFqY__1.js → LpFileTree-C-NFRT0H.js} +19 -14
- package/dist/chunks/{LpFileTreeNode-COchUMNn.js → LpFileTreeNode-DNJUJiiB.js} +13 -6
- package/dist/chunks/{LpFormField-fV_2ZdCk.js → LpFormField-CazBc2-a.js} +14 -9
- package/dist/chunks/{LpInput-Bt4J71xn.js → LpInput-9EXWUM9B.js} +1 -1
- package/dist/chunks/{LpLightbox-Ci35Y_xP.js → LpLightbox-Cixfxezw.js} +29 -6
- package/dist/chunks/{LpLink-BHZ1CLlF.js → LpLink-DCND-zyu.js} +16 -9
- package/dist/chunks/{LpLogViewer-TSRyt3t9.js → LpLogViewer-y53ZqSVq.js} +20 -10
- package/dist/chunks/{LpMapPicker-CXvoTrAe.js → LpMapPicker-ul4oYno6.js} +14 -9
- package/dist/chunks/LpMediaGallery-t1z3bQcY.js +187 -0
- package/dist/chunks/{LpNotificationBell-gdvQY89m.js → LpNotificationBell-lHePf89W.js} +1 -1
- package/dist/chunks/{LpNumberField-NPE8Bumx.js → LpNumberField-CWuX08iX.js} +12 -5
- package/dist/chunks/{LpOtpInput-DqaT0Z75.js → LpOtpInput-y2v-pmiN.js} +11 -6
- package/dist/chunks/{LpPagination-CeGuNe_q.js → LpPagination-5FxjmmB5.js} +21 -19
- package/dist/chunks/{LpPasswordInput-BqMAc5HA.js → LpPasswordInput--sjYCkLS.js} +1 -1
- package/dist/chunks/{LpPhoneInput-NXXjciJJ.js → LpPhoneInput-BDSKVl_z.js} +16 -9
- package/dist/chunks/{LpPie-BL1vTDSM.js → LpPie-c2-q4DJu.js} +14 -8
- package/dist/chunks/{LpRadio-CL-pI0_O.js → LpRadio-B5AfqTpZ.js} +13 -5
- package/dist/chunks/{LpRadioGroup-B4yDTmi6.js → LpRadioGroup-xPIuVDO_.js} +12 -5
- package/dist/chunks/{LpSegmented-BmpanyAo.js → LpSegmented-fV0Sk92p.js} +16 -6
- package/dist/chunks/{LpSidebar-BiWM_lDB.js → LpSidebar-DcYavim2.js} +2 -2
- package/dist/chunks/{LpSidebarNav-CsgeuGAu.js → LpSidebarNav-CqwvT4H8.js} +21 -16
- package/dist/chunks/{LpSlider-B1SF3pRV.js → LpSlider-BwNIBkAK.js} +12 -5
- package/dist/chunks/{LpStat-CDanpzU0.js → LpStat-CQaW8R--.js} +23 -18
- package/dist/chunks/{LpStepper-Wtl-6nUh.js → LpStepper-Bk-XaQYU.js} +15 -10
- package/dist/chunks/{LpSwitch-v6fnccSM.js → LpSwitch-xgnRU2k0.js} +12 -5
- package/dist/chunks/{LpTextarea-BMIOfw5l.js → LpTextarea-t7F6gv8E.js} +1 -1
- package/dist/chunks/{LpUptimeBar-DcQ8HikG.js → LpUptimeBar-DvAMno0S.js} +26 -21
- package/dist/component-names.d.ts +1 -1
- package/dist/components/LpAddressInput.vue.d.ts +34 -17
- package/dist/components/LpAddressInput.vue.js +1 -1
- package/dist/components/LpAppShell.vue.d.ts +65 -31
- package/dist/components/LpAppShell.vue.js +1 -1
- package/dist/components/LpBreadcrumbs.vue.d.ts +12 -6
- package/dist/components/LpBreadcrumbs.vue.js +1 -1
- package/dist/components/LpCalendar.vue.d.ts +15 -6
- package/dist/components/LpCalendar.vue.js +1 -1
- package/dist/components/LpCard.vue.d.ts +26 -0
- package/dist/components/LpCard.vue.js +1 -1
- package/dist/components/LpChart.vue.d.ts +54 -12
- package/dist/components/LpChart.vue.js +15 -9
- package/dist/components/LpCheckbox.vue.d.ts +16 -12
- package/dist/components/LpCheckbox.vue.js +1 -1
- package/dist/components/LpCodeBlock.vue.d.ts +25 -6
- package/dist/components/LpCodeBlock.vue.js +1 -1
- package/dist/components/LpDatePicker.vue.js +1 -1
- package/dist/components/LpDisclosure.vue.d.ts +24 -14
- package/dist/components/LpDisclosure.vue.js +1 -1
- package/dist/components/LpDropzone.vue.d.ts +38 -14
- package/dist/components/LpDropzone.vue.js +17 -11
- package/dist/components/LpEmptyState.vue.d.ts +15 -10
- package/dist/components/LpEmptyState.vue.js +1 -1
- package/dist/components/LpFileTree.vue.d.ts +51 -31
- package/dist/components/LpFileTree.vue.js +1 -1
- package/dist/components/LpFileTreeNode.vue.d.ts +31 -16
- package/dist/components/LpFileTreeNode.vue.js +1 -1
- package/dist/components/LpFormField.vue.d.ts +14 -13
- package/dist/components/LpFormField.vue.js +1 -1
- package/dist/components/LpImageEditor.vue.d.ts +33 -10
- package/dist/components/LpImageEditor.vue.js +13 -7
- package/dist/components/LpInput.vue.js +1 -1
- package/dist/components/LpLightbox.vue.js +1 -1
- package/dist/components/LpLink.vue.d.ts +46 -11
- package/dist/components/LpLink.vue.js +1 -1
- package/dist/components/LpLogViewer.vue.d.ts +63 -6
- package/dist/components/LpLogViewer.vue.js +1 -1
- package/dist/components/LpMapPicker.vue.d.ts +25 -10
- package/dist/components/LpMapPicker.vue.js +1 -1
- package/dist/components/LpMediaGallery.vue.d.ts +76 -0
- package/dist/components/LpMediaGallery.vue.js +4 -0
- package/dist/components/LpNotificationBell.vue.js +1 -1
- package/dist/components/LpNumberField.vue.d.ts +12 -6
- package/dist/components/LpNumberField.vue.js +1 -1
- package/dist/components/LpOtpInput.vue.d.ts +18 -6
- package/dist/components/LpOtpInput.vue.js +1 -1
- package/dist/components/LpPagination.vue.d.ts +16 -6
- package/dist/components/LpPagination.vue.js +1 -1
- package/dist/components/LpPasswordInput.vue.js +1 -1
- package/dist/components/LpPhoneInput.vue.d.ts +18 -6
- package/dist/components/LpPhoneInput.vue.js +1 -1
- package/dist/components/LpPie.vue.d.ts +96 -34
- package/dist/components/LpPie.vue.js +1 -1
- package/dist/components/LpRadio.vue.d.ts +10 -10
- package/dist/components/LpRadio.vue.js +1 -1
- package/dist/components/LpRadioGroup.vue.d.ts +12 -12
- package/dist/components/LpRadioGroup.vue.js +1 -1
- package/dist/components/LpSegmented.vue.d.ts +12 -6
- package/dist/components/LpSegmented.vue.js +1 -1
- package/dist/components/LpSidebar.vue.js +1 -1
- package/dist/components/LpSidebarNav.vue.d.ts +28 -17
- package/dist/components/LpSidebarNav.vue.js +1 -1
- package/dist/components/LpSlider.vue.d.ts +13 -6
- package/dist/components/LpSlider.vue.js +1 -1
- package/dist/components/LpStat.vue.d.ts +35 -11
- package/dist/components/LpStat.vue.js +1 -1
- package/dist/components/LpStepper.vue.d.ts +17 -5
- package/dist/components/LpStepper.vue.js +1 -1
- package/dist/components/LpSwitch.vue.d.ts +8 -6
- package/dist/components/LpSwitch.vue.js +1 -1
- package/dist/components/LpTable.vue.js +1 -1
- package/dist/components/LpTextarea.vue.js +1 -1
- package/dist/components/LpUptimeBar.vue.d.ts +21 -5
- package/dist/components/LpUptimeBar.vue.js +1 -1
- package/dist/composables/useMergedClass.d.ts +20 -0
- package/dist/composables/useMergedClass.js +11 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +95 -89
- package/package.json +1 -3
- package/src/component-names.ts +1 -0
- package/src/components/LpAddressInput.vue +16 -1
- package/src/components/LpAppShell.vue +16 -1
- package/src/components/LpBreadcrumbs.vue +16 -1
- package/src/components/LpCalendar.vue +15 -1
- package/src/components/LpCard.vue +50 -5
- package/src/components/LpChart.vue +16 -1
- package/src/components/LpCheckbox.vue +16 -1
- package/src/components/LpCodeBlock.vue +16 -1
- package/src/components/LpDisclosure.vue +15 -1
- package/src/components/LpDropzone.vue +21 -6
- package/src/components/LpEmptyState.vue +21 -3
- package/src/components/LpFileTree.vue +16 -1
- package/src/components/LpFileTreeNode.vue +15 -1
- package/src/components/LpFormField.vue +16 -1
- package/src/components/LpImageEditor.vue +16 -1
- package/src/components/LpLightbox.vue +54 -2
- package/src/components/LpLink.vue +25 -9
- package/src/components/LpLogViewer.vue +20 -2
- package/src/components/LpMapPicker.vue +15 -1
- package/src/components/LpMediaGallery.vue +280 -0
- package/src/components/LpNumberField.vue +15 -1
- package/src/components/LpOtpInput.vue +15 -1
- package/src/components/LpPagination.vue +16 -1
- package/src/components/LpPhoneInput.vue +23 -8
- package/src/components/LpPie.vue +16 -1
- package/src/components/LpRadio.vue +20 -3
- package/src/components/LpRadioGroup.vue +15 -1
- package/src/components/LpSegmented.vue +21 -2
- package/src/components/LpSidebarNav.vue +16 -1
- package/src/components/LpSlider.vue +15 -1
- package/src/components/LpStat.vue +16 -1
- package/src/components/LpStepper.vue +16 -1
- package/src/components/LpSwitch.vue +15 -1
- package/src/components/LpUptimeBar.vue +16 -1
- package/src/composables/useMergedClass.ts +30 -0
- package/src/index.ts +2 -0
- package/src/tokens/tokens.css +29 -0
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The consumer's `class` is merged into the root's own (below) rather than
|
|
3
|
+
// appended to it, so opt out of the automatic pass-through that would add it
|
|
4
|
+
// a second time, unmerged.
|
|
5
|
+
export default { inheritAttrs: false }
|
|
6
|
+
</script>
|
|
7
|
+
|
|
1
8
|
<script setup lang="ts">
|
|
2
9
|
// Single-value slider (reka Slider). reka models value as an array; we expose
|
|
3
10
|
// a plain number for the common single-thumb case. Themed via tokens.
|
|
4
11
|
import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from "reka-ui"
|
|
12
|
+
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
5
13
|
|
|
6
14
|
const props = withDefaults(
|
|
7
15
|
defineProps<{
|
|
@@ -29,6 +37,11 @@ function onUpdate(v: number[] | undefined) {
|
|
|
29
37
|
function onCommit(v: number[] | undefined) {
|
|
30
38
|
if (v && v.length) emit("change", v[0])
|
|
31
39
|
}
|
|
40
|
+
|
|
41
|
+
// A slider is full-width by default; putting one in a toolbar means constraining it, and a fixed h-5 has to yield to a denser row.
|
|
42
|
+
const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
43
|
+
"relative flex h-5 w-full touch-none select-none items-center data-[disabled]:opacity-55",
|
|
44
|
+
)
|
|
32
45
|
</script>
|
|
33
46
|
|
|
34
47
|
<template>
|
|
@@ -38,7 +51,8 @@ function onCommit(v: number[] | undefined) {
|
|
|
38
51
|
:max="max"
|
|
39
52
|
:step="step"
|
|
40
53
|
:disabled="disabled"
|
|
41
|
-
class="
|
|
54
|
+
:class="rootClass"
|
|
55
|
+
v-bind="rest"
|
|
42
56
|
@update:model-value="onUpdate"
|
|
43
57
|
@value-commit="onCommit"
|
|
44
58
|
>
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The consumer's `class` is merged into the root's own (below) rather than
|
|
3
|
+
// appended to it, so opt out of the automatic pass-through that would add it
|
|
4
|
+
// a second time, unmerged.
|
|
5
|
+
export default { inheritAttrs: false }
|
|
6
|
+
</script>
|
|
7
|
+
|
|
1
8
|
<script setup lang="ts">
|
|
2
9
|
// Stat tile: dot + caps label, big mono value, optional delta/trend badge and a
|
|
3
10
|
// subtitle. A product pattern, fully token-driven — re-skins with the theme.
|
|
4
11
|
import { computed } from "vue"
|
|
5
12
|
import LpIcon from "./LpIcon.vue"
|
|
6
13
|
import LpNumberFlow from "./LpNumberFlow.vue"
|
|
14
|
+
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
7
15
|
|
|
8
16
|
const props = withDefaults(
|
|
9
17
|
defineProps<{
|
|
@@ -86,10 +94,17 @@ const deltaDecimals = computed(() => {
|
|
|
86
94
|
const [, fraction] = String(props.delta).split(".")
|
|
87
95
|
return Math.min(fraction?.length ?? 0, 4)
|
|
88
96
|
})
|
|
97
|
+
|
|
98
|
+
// A stat tile spaces its label and value on a fixed gap; a dense KPI row needs that tighter.
|
|
99
|
+
const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
100
|
+
"flex flex-col gap-2",
|
|
101
|
+
)
|
|
89
102
|
</script>
|
|
90
103
|
|
|
91
104
|
<template>
|
|
92
|
-
<div
|
|
105
|
+
<div
|
|
106
|
+
:class="rootClass"
|
|
107
|
+
v-bind="rest">
|
|
93
108
|
<div class="flex items-center gap-2">
|
|
94
109
|
<span v-if="online" class="size-1.5 rounded-full bg-action" />
|
|
95
110
|
<LpIcon v-if="icon" :name="icon" :size="14" class="text-muted" />
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The consumer's `class` is merged into the root's own (below) rather than
|
|
3
|
+
// appended to it, so opt out of the automatic pass-through that would add it
|
|
4
|
+
// a second time, unmerged.
|
|
5
|
+
export default { inheritAttrs: false }
|
|
6
|
+
</script>
|
|
7
|
+
|
|
1
8
|
<script setup lang="ts">
|
|
2
9
|
import { computed } from "vue"
|
|
3
10
|
import LpIcon from "./LpIcon.vue"
|
|
11
|
+
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
4
12
|
|
|
5
13
|
export interface Step {
|
|
6
14
|
label: string
|
|
@@ -38,10 +46,17 @@ function isCompleted(step: Step, i: number): boolean {
|
|
|
38
46
|
function isCurrent(i: number): boolean {
|
|
39
47
|
return i === currentIndex.value
|
|
40
48
|
}
|
|
49
|
+
|
|
50
|
+
// The stepper spaces its steps evenly; a compact wizard header needs that spacing under the consumer's control.
|
|
51
|
+
const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
52
|
+
"flex items-center gap-2",
|
|
53
|
+
)
|
|
41
54
|
</script>
|
|
42
55
|
|
|
43
56
|
<template>
|
|
44
|
-
<ol
|
|
57
|
+
<ol
|
|
58
|
+
:class="rootClass"
|
|
59
|
+
v-bind="rest">
|
|
45
60
|
<li
|
|
46
61
|
v-for="(step, i) in steps"
|
|
47
62
|
:key="step.key ?? i"
|
|
@@ -1,15 +1,29 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The consumer's `class` is merged into the root's own (below) rather than
|
|
3
|
+
// appended to it, so opt out of the automatic pass-through that would add it
|
|
4
|
+
// a second time, unmerged.
|
|
5
|
+
export default { inheritAttrs: false }
|
|
6
|
+
</script>
|
|
7
|
+
|
|
1
8
|
<script setup lang="ts">
|
|
2
9
|
import { SwitchRoot, SwitchThumb } from "reka-ui"
|
|
10
|
+
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
3
11
|
|
|
4
12
|
defineProps<{ modelValue?: boolean; disabled?: boolean }>()
|
|
5
13
|
defineEmits<{ (e: "update:modelValue", value: boolean): void }>()
|
|
14
|
+
|
|
15
|
+
// A switch has a fixed track size, so a consumer asking for a bigger one must not have to depend on stylesheet order to get it.
|
|
16
|
+
const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
17
|
+
"group inline-flex h-5 w-9 shrink-0 items-center rounded-pill border border-line bg-surface-soft px-0.5 outline-none transition-colors duration-[var(--duration-fast)] focus-visible:ring-2 focus-visible:ring-ring data-[state=checked]:border-transparent data-[state=checked]:bg-brand disabled:cursor-not-allowed disabled:opacity-55",
|
|
18
|
+
)
|
|
6
19
|
</script>
|
|
7
20
|
|
|
8
21
|
<template>
|
|
9
22
|
<SwitchRoot
|
|
10
23
|
:model-value="modelValue"
|
|
11
24
|
:disabled="disabled"
|
|
12
|
-
class="
|
|
25
|
+
:class="rootClass"
|
|
26
|
+
v-bind="rest"
|
|
13
27
|
@update:model-value="(v) => $emit('update:modelValue', v)"
|
|
14
28
|
>
|
|
15
29
|
<SwitchThumb
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The consumer's `class` is merged into the root's own (below) rather than
|
|
3
|
+
// appended to it, so opt out of the automatic pass-through that would add it
|
|
4
|
+
// a second time, unmerged.
|
|
5
|
+
export default { inheritAttrs: false }
|
|
6
|
+
</script>
|
|
7
|
+
|
|
1
8
|
<script setup lang="ts">
|
|
2
9
|
import { computed, ref } from "vue"
|
|
3
10
|
import LpNumberFlow from "./LpNumberFlow.vue"
|
|
4
11
|
import LpRollingText from "./LpRollingText.vue"
|
|
5
12
|
import LpTooltip from "./LpTooltip.vue"
|
|
13
|
+
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
6
14
|
|
|
7
15
|
export type UptimeStatus = "operational" | "degraded" | "down" | "maintenance" | "empty"
|
|
8
16
|
|
|
@@ -115,10 +123,17 @@ const uptimeDecimals = computed(() => {
|
|
|
115
123
|
const trimmed = Number(v.toFixed(2))
|
|
116
124
|
return Number.isInteger(trimmed) ? 0 : String(trimmed).split(".")[1].length
|
|
117
125
|
})
|
|
126
|
+
|
|
127
|
+
// The bar sets its own gap between the strip and its caption, which a compact status row has to close.
|
|
128
|
+
const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
129
|
+
"flex flex-col gap-1.5",
|
|
130
|
+
)
|
|
118
131
|
</script>
|
|
119
132
|
|
|
120
133
|
<template>
|
|
121
|
-
<div
|
|
134
|
+
<div
|
|
135
|
+
:class="rootClass"
|
|
136
|
+
v-bind="rest">
|
|
122
137
|
<div v-if="title" class="text-xs">
|
|
123
138
|
<span class="font-medium text-ink">{{ title }}</span>
|
|
124
139
|
</div>
|
|
@@ -46,6 +46,36 @@ export function useMergedClass(
|
|
|
46
46
|
return computed(() => cn(toValue(own), attrs.class as string | undefined) ?? "")
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* `useMergedClass` plus the rest of `$attrs`, for the common `inheritAttrs:
|
|
51
|
+
* false` shape: bind `class` and `attrs` and the consumer's `class` lands once,
|
|
52
|
+
* merged, while ids, handlers and aria-* still reach the element.
|
|
53
|
+
*
|
|
54
|
+
* ```ts
|
|
55
|
+
* const { class: rootClass, attrs: rest } = useMergedAttrs(() => card({ padded }))
|
|
56
|
+
* ```
|
|
57
|
+
* ```vue
|
|
58
|
+
* <div :class="rootClass" v-bind="rest">
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* Binding the raw `$attrs` alongside a merged class is the bug this avoids:
|
|
62
|
+
* Vue appends that second `class` to the merged one, and stylesheet order —
|
|
63
|
+
* not the caller — decides which wins.
|
|
64
|
+
*/
|
|
65
|
+
export function useMergedAttrs(own: MaybeRefOrGetter<string | undefined>): {
|
|
66
|
+
class: ComputedRef<string>
|
|
67
|
+
attrs: ComputedRef<Record<string, unknown>>
|
|
68
|
+
} {
|
|
69
|
+
const attrs = useAttrs()
|
|
70
|
+
return {
|
|
71
|
+
class: useMergedClass(own),
|
|
72
|
+
attrs: computed(() => {
|
|
73
|
+
const { class: _omitted, ...rest } = attrs
|
|
74
|
+
return rest
|
|
75
|
+
}),
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
49
79
|
/**
|
|
50
80
|
* The same merge as a plain function, for the places that already have both
|
|
51
81
|
* strings in hand and do not need the attrs lookup — a render helper, or a
|
package/src/index.ts
CHANGED
|
@@ -103,6 +103,7 @@ export { fileNameOf } from "./components/lightbox"
|
|
|
103
103
|
export { default as LpLink } from "./components/LpLink.vue"
|
|
104
104
|
export { default as LpLogViewer } from "./components/LpLogViewer.vue"
|
|
105
105
|
export type { LogLevel, LogLine } from "./components/LpLogViewer.vue"
|
|
106
|
+
export { default as LpMediaGallery } from "./components/LpMediaGallery.vue"
|
|
106
107
|
export { default as LpModal } from "./components/LpModal.vue"
|
|
107
108
|
export { default as LpNotificationBell } from "./components/LpNotificationBell.vue"
|
|
108
109
|
export type {
|
|
@@ -227,6 +228,7 @@ export { useClipboard } from "./composables/useClipboard"
|
|
|
227
228
|
export type { CopyOptions, UseClipboard } from "./composables/useClipboard"
|
|
228
229
|
export { useHotkeys, isAppleKeyboard, appleModifierLabel } from "./composables/useHotkeys"
|
|
229
230
|
export type { HotkeyBinding } from "./composables/useHotkeys"
|
|
231
|
+
export { useMergedClass, useMergedAttrs, mergeClass } from "./composables/useMergedClass"
|
|
230
232
|
export { useInputFilter } from "./composables/useInputFilter"
|
|
231
233
|
export type { UseInputFilterOptions } from "./composables/useInputFilter"
|
|
232
234
|
export { easeOut, easeTravel, easingToken, prefersReducedMotion } from "./composables/easing"
|
package/src/tokens/tokens.css
CHANGED
|
@@ -555,6 +555,35 @@
|
|
|
555
555
|
var(--lp-glow-spread-bottom);
|
|
556
556
|
}
|
|
557
557
|
|
|
558
|
+
/*
|
|
559
|
+
* Accent stripe down a card's leading edge (LpCard's `accent`).
|
|
560
|
+
*
|
|
561
|
+
* Drawn as an inset box-shadow rather than a border or a positioned child,
|
|
562
|
+
* because those two cannot do the job here:
|
|
563
|
+
*
|
|
564
|
+
* - A `border-left` occupies layout. It pushes the content 3px inward, so an
|
|
565
|
+
* accented card and a plain one in the same list no longer agree on where
|
|
566
|
+
* their text starts — measured 23px against 21px. Compensating in the
|
|
567
|
+
* padding leaves the card fighting `--surface-border-width`, which the skin
|
|
568
|
+
* axis changes per theme.
|
|
569
|
+
* - An absolutely positioned child collapses: `.lp-skin-panel > *` gives every
|
|
570
|
+
* direct child `position: relative`, which takes `inset-y-0` away from the
|
|
571
|
+
* stripe and paints it at zero width. `::before` is not free either — the
|
|
572
|
+
* skin painter already uses it for the overlay gradient.
|
|
573
|
+
*
|
|
574
|
+
* An inset shadow takes no space, follows `border-radius` round the corners on
|
|
575
|
+
* its own, and needs nothing of the content. It composes rather than replaces:
|
|
576
|
+
* the skin painter's own inset + drop shadows follow the stripe in the same
|
|
577
|
+
* list, so an accented `raised` card keeps its elevation, and `interactive`
|
|
578
|
+
* still swaps `--surface-panel-shadow` underneath on hover.
|
|
579
|
+
*/
|
|
580
|
+
.lp-card-accent {
|
|
581
|
+
box-shadow:
|
|
582
|
+
inset var(--lp-card-accent-width, 3px) 0 0 0 var(--lp-card-accent, transparent),
|
|
583
|
+
var(--surface-panel-inset),
|
|
584
|
+
var(--surface-panel-shadow);
|
|
585
|
+
}
|
|
586
|
+
|
|
558
587
|
/* ── circular theme reveal (View Transitions) ────
|
|
559
588
|
applyThemeWithTransition() snapshots the page, swaps the theme tokens, then
|
|
560
589
|
shrinks a clip-path circle in the OLD snapshot from the toggle's position,
|