@leavepulse/ui 0.29.5 → 0.30.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/chunks/LpActionBar-CxmBZpGu.js +173 -0
- package/dist/chunks/{LpAppShell-BJk3b-u4.js → LpAppShell-DnocEJAu.js} +1 -1
- package/dist/chunks/{LpCodeBlock-rS_6mO3D.js → LpCodeBlock-BWX1KZwk.js} +7 -13
- package/dist/chunks/LpColorPicker-CFC6iaNK.js +491 -0
- package/dist/chunks/{LpDisclosure-BnwP4Q-b.js → LpDisclosure-C1_YkMrd.js} +8 -2
- package/dist/chunks/{LpLogViewer-CVaGfTF_.js → LpLogViewer-TSRyt3t9.js} +3 -6
- package/dist/chunks/{LpSidebar-C_Mr-JPI.js → LpSidebar-CWSbczWi.js} +11 -2
- package/dist/component-names.d.ts +1 -1
- package/dist/components/LpActionBar.vue.d.ts +84 -0
- package/dist/components/LpActionBar.vue.js +4 -0
- package/dist/components/LpAppShell.vue.js +1 -1
- package/dist/components/LpCodeBlock.vue.js +1 -1
- package/dist/components/LpColorPicker.vue.d.ts +124 -0
- package/dist/components/LpColorPicker.vue.js +4 -0
- package/dist/components/LpDisclosure.vue.js +1 -1
- package/dist/components/LpLogViewer.vue.js +1 -1
- package/dist/components/LpNotificationBell.vue.d.ts +2 -2
- package/dist/components/LpSidebar.vue.d.ts +21 -0
- package/dist/components/LpSidebar.vue.js +1 -1
- package/dist/components/actionBar.d.ts +19 -0
- package/dist/components/actionBar.js +31 -0
- package/dist/components/color.d.ts +65 -0
- package/dist/components/color.js +158 -0
- package/dist/composables/useClipboard.d.ts +46 -0
- package/dist/composables/useClipboard.js +28 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +145 -126
- package/package.json +1 -1
- package/src/component-names.ts +2 -0
- package/src/components/LpActionBar.vue +268 -0
- package/src/components/LpCodeBlock.vue +5 -10
- package/src/components/LpColorPicker.vue +784 -0
- package/src/components/LpDisclosure.vue +17 -2
- package/src/components/LpLogViewer.vue +5 -8
- package/src/components/LpSidebar.vue +42 -6
- package/src/components/actionBar.ts +73 -0
- package/src/components/color.ts +257 -0
- package/src/composables/useClipboard.ts +107 -0
- package/src/index.ts +21 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { defineComponent, useSlots, computed, ref, watch, nextTick, openBlock, createBlock, Teleport, createVNode, Transition, withCtx, createElementBlock, normalizeStyle, normalizeClass, createElementVNode, createCommentVNode, renderSlot, toDisplayString, Fragment, renderList, createTextVNode, unref } from "vue";
|
|
2
|
+
import { useBarStack } from "../components/actionBar.js";
|
|
3
|
+
import { CLOSE_ICON } from "../components/dropdown.js";
|
|
4
|
+
import { _ as _sfc_main$2 } from "./LpButton-5VXXCjwF.js";
|
|
5
|
+
import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
|
|
6
|
+
const _hoisted_1 = ["aria-label"];
|
|
7
|
+
const _hoisted_2 = {
|
|
8
|
+
key: 1,
|
|
9
|
+
class: "min-w-0 flex-1"
|
|
10
|
+
};
|
|
11
|
+
const _hoisted_3 = {
|
|
12
|
+
key: 0,
|
|
13
|
+
class: "truncate text-sm font-medium text-ink"
|
|
14
|
+
};
|
|
15
|
+
const _hoisted_4 = {
|
|
16
|
+
key: 1,
|
|
17
|
+
class: "truncate text-xs text-muted"
|
|
18
|
+
};
|
|
19
|
+
const _hoisted_5 = {
|
|
20
|
+
key: 2,
|
|
21
|
+
class: "flex-1"
|
|
22
|
+
};
|
|
23
|
+
const _hoisted_6 = { class: "flex shrink-0 items-center gap-2" };
|
|
24
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
25
|
+
__name: "LpActionBar",
|
|
26
|
+
props: {
|
|
27
|
+
open: { type: Boolean, default: true },
|
|
28
|
+
title: {},
|
|
29
|
+
description: {},
|
|
30
|
+
icon: {},
|
|
31
|
+
actions: { default: () => [] },
|
|
32
|
+
dismissible: { type: Boolean },
|
|
33
|
+
variant: { default: "default" },
|
|
34
|
+
width: { default: "contained" },
|
|
35
|
+
maxWidth: {},
|
|
36
|
+
ariaLabel: {}
|
|
37
|
+
},
|
|
38
|
+
emits: ["update:open", "dismiss"],
|
|
39
|
+
setup(__props, { emit: __emit }) {
|
|
40
|
+
const props = __props;
|
|
41
|
+
const emit = __emit;
|
|
42
|
+
const slots = useSlots();
|
|
43
|
+
const resolvedActions = computed(
|
|
44
|
+
() => props.actions.map((a, i) => ({
|
|
45
|
+
...a,
|
|
46
|
+
variant: a.variant ?? (i === props.actions.length - 1 ? props.variant === "danger" ? "danger" : "solid" : "ghost")
|
|
47
|
+
}))
|
|
48
|
+
);
|
|
49
|
+
const hasBody = computed(() => !!props.title || !!props.description || !!slots.default);
|
|
50
|
+
const maxWidth = computed(() => props.maxWidth ?? (props.width === "full" ? "72rem" : "36rem"));
|
|
51
|
+
function run(action) {
|
|
52
|
+
if (action.disabled || action.loading) return;
|
|
53
|
+
void action.onClick?.();
|
|
54
|
+
}
|
|
55
|
+
function dismiss() {
|
|
56
|
+
emit("dismiss");
|
|
57
|
+
emit("update:open", false);
|
|
58
|
+
}
|
|
59
|
+
const root = ref(null);
|
|
60
|
+
const { register, unregister, setHeight, offset, bars } = useBarStack();
|
|
61
|
+
const stackOffset = computed(() => {
|
|
62
|
+
void bars.value;
|
|
63
|
+
return offset();
|
|
64
|
+
});
|
|
65
|
+
watch(
|
|
66
|
+
() => props.open,
|
|
67
|
+
async (isOpen) => {
|
|
68
|
+
if (!isOpen) {
|
|
69
|
+
unregister();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
register();
|
|
73
|
+
await nextTick();
|
|
74
|
+
if (root.value) setHeight(root.value.getBoundingClientRect().height);
|
|
75
|
+
},
|
|
76
|
+
{ immediate: true }
|
|
77
|
+
);
|
|
78
|
+
return (_ctx, _cache) => {
|
|
79
|
+
return openBlock(), createBlock(Teleport, { to: "body" }, [
|
|
80
|
+
createVNode(Transition, {
|
|
81
|
+
"enter-active-class": "animate-[rise-in_var(--duration-medium)_var(--ease-emphasized)]",
|
|
82
|
+
"leave-active-class": "animate-[rise-out_var(--duration-fast)_ease]"
|
|
83
|
+
}, {
|
|
84
|
+
default: withCtx(() => [
|
|
85
|
+
__props.open ? (openBlock(), createElementBlock("div", {
|
|
86
|
+
key: 0,
|
|
87
|
+
ref_key: "root",
|
|
88
|
+
ref: root,
|
|
89
|
+
role: "region",
|
|
90
|
+
"aria-label": __props.ariaLabel ?? __props.title,
|
|
91
|
+
class: normalizeClass(["pointer-events-none fixed inset-x-0 bottom-0 z-(--z-modal) flex justify-center transition-[translate] duration-[var(--duration-medium)] ease-[var(--ease-emphasized)] motion-reduce:transition-none", __props.width === "full" ? "" : "p-3 sm:p-4"]),
|
|
92
|
+
style: normalizeStyle({ translate: `0 -${stackOffset.value}px` })
|
|
93
|
+
}, [
|
|
94
|
+
createElementVNode("div", {
|
|
95
|
+
class: normalizeClass(["lp-skin-panel pointer-events-auto flex items-center gap-3 border-solid bg-surface-overlay", [
|
|
96
|
+
// A full-width bar is the page's own furniture: square, edge to
|
|
97
|
+
// edge, and only its top border drawn, so it reads as a frame
|
|
98
|
+
// rather than as a card that happens to be very wide.
|
|
99
|
+
__props.width === "full" ? "w-full justify-center border-x-0 border-b-0 px-4 py-3 sm:px-6" : "w-full rounded-card px-4 py-3",
|
|
100
|
+
__props.variant === "danger" ? "border-danger/40" : "border-line"
|
|
101
|
+
]]),
|
|
102
|
+
style: normalizeStyle(__props.width === "full" ? void 0 : { maxWidth: maxWidth.value })
|
|
103
|
+
}, [
|
|
104
|
+
createElementVNode("div", {
|
|
105
|
+
class: "flex w-full items-center gap-3",
|
|
106
|
+
style: normalizeStyle({ maxWidth: maxWidth.value })
|
|
107
|
+
}, [
|
|
108
|
+
__props.icon ? (openBlock(), createBlock(_sfc_main$1, {
|
|
109
|
+
key: 0,
|
|
110
|
+
name: __props.icon,
|
|
111
|
+
size: 18,
|
|
112
|
+
class: normalizeClass(["shrink-0", __props.variant === "danger" ? "text-danger" : "text-brand"])
|
|
113
|
+
}, null, 8, ["name", "class"])) : createCommentVNode("", true),
|
|
114
|
+
hasBody.value ? (openBlock(), createElementBlock("div", _hoisted_2, [
|
|
115
|
+
renderSlot(_ctx.$slots, "default", {}, () => [
|
|
116
|
+
__props.title ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
|
|
117
|
+
__props.description ? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString(__props.description), 1)) : createCommentVNode("", true)
|
|
118
|
+
])
|
|
119
|
+
])) : (openBlock(), createElementBlock("div", _hoisted_5)),
|
|
120
|
+
createElementVNode("div", _hoisted_6, [
|
|
121
|
+
renderSlot(_ctx.$slots, "actions", {}, () => [
|
|
122
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(resolvedActions.value, (action, i) => {
|
|
123
|
+
return openBlock(), createBlock(_sfc_main$2, {
|
|
124
|
+
key: i,
|
|
125
|
+
variant: action.variant,
|
|
126
|
+
size: "sm",
|
|
127
|
+
disabled: action.disabled || action.loading,
|
|
128
|
+
onClick: ($event) => run(action)
|
|
129
|
+
}, {
|
|
130
|
+
default: withCtx(() => [
|
|
131
|
+
action.loading ? (openBlock(), createBlock(_sfc_main$1, {
|
|
132
|
+
key: 0,
|
|
133
|
+
name: "lucide:loader-circle",
|
|
134
|
+
size: 15,
|
|
135
|
+
class: "animate-spin"
|
|
136
|
+
})) : action.icon ? (openBlock(), createBlock(_sfc_main$1, {
|
|
137
|
+
key: 1,
|
|
138
|
+
name: action.icon,
|
|
139
|
+
size: 15
|
|
140
|
+
}, null, 8, ["name"])) : createCommentVNode("", true),
|
|
141
|
+
createTextVNode(" " + toDisplayString(action.label), 1)
|
|
142
|
+
]),
|
|
143
|
+
_: 2
|
|
144
|
+
}, 1032, ["variant", "disabled", "onClick"]);
|
|
145
|
+
}), 128))
|
|
146
|
+
]),
|
|
147
|
+
__props.dismissible ? (openBlock(), createElementBlock("button", {
|
|
148
|
+
key: 0,
|
|
149
|
+
type: "button",
|
|
150
|
+
"aria-label": "Dismiss",
|
|
151
|
+
class: "group -mr-1 flex size-8 shrink-0 items-center justify-center rounded-control text-muted outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink focus-visible:ring-2 focus-visible:ring-ring",
|
|
152
|
+
onClick: dismiss
|
|
153
|
+
}, [
|
|
154
|
+
createVNode(_sfc_main$1, {
|
|
155
|
+
name: "lucide:x",
|
|
156
|
+
size: 16,
|
|
157
|
+
class: normalizeClass(unref(CLOSE_ICON))
|
|
158
|
+
}, null, 8, ["class"])
|
|
159
|
+
])) : createCommentVNode("", true)
|
|
160
|
+
])
|
|
161
|
+
], 4)
|
|
162
|
+
], 6)
|
|
163
|
+
], 14, _hoisted_1)) : createCommentVNode("", true)
|
|
164
|
+
]),
|
|
165
|
+
_: 3
|
|
166
|
+
})
|
|
167
|
+
]);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
export {
|
|
172
|
+
_sfc_main as _
|
|
173
|
+
};
|
|
@@ -3,7 +3,7 @@ import { _ as _sfc_main$2 } from "./LpButton-5VXXCjwF.js";
|
|
|
3
3
|
import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
|
|
4
4
|
import { _ as _sfc_main$5 } from "./LpScrollArea-D8xyKXcF.js";
|
|
5
5
|
import { _ as _sfc_main$4 } from "./LpShift-DXNsauQZ.js";
|
|
6
|
-
import { _ as _sfc_main$1 } from "./LpSidebar-
|
|
6
|
+
import { _ as _sfc_main$1 } from "./LpSidebar-CWSbczWi.js";
|
|
7
7
|
const _hoisted_1 = { class: "flex h-dvh overflow-hidden bg-surface text-ink" };
|
|
8
8
|
const _hoisted_2 = { class: "flex min-w-0 flex-1 flex-col" };
|
|
9
9
|
const _hoisted_3 = { class: "relative flex h-16 shrink-0 items-center gap-3 border-b border-line bg-surface px-4 md:px-6" };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineComponent, computed, reactive, watch,
|
|
1
|
+
import { defineComponent, computed, reactive, watch, openBlock, createElementBlock, toDisplayString, createCommentVNode, createElementVNode, createVNode, unref, normalizeClass, normalizeStyle, Fragment, renderList } from "vue";
|
|
2
|
+
import { useClipboard } from "../composables/useClipboard.js";
|
|
2
3
|
import { tokenizeLine } from "../components/codeHighlight.js";
|
|
3
4
|
import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
|
|
4
5
|
const _hoisted_1 = { class: "overflow-hidden rounded-card border border-line bg-surface font-mono text-xs" };
|
|
@@ -130,15 +131,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
130
131
|
const showHeader = computed(
|
|
131
132
|
() => Boolean(props.title || props.lang !== "plain" || props.copyable || props.lockToggle)
|
|
132
133
|
);
|
|
133
|
-
const copied =
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
await navigator.clipboard.writeText(copyText.value);
|
|
137
|
-
copied.value = true;
|
|
138
|
-
window.setTimeout(() => copied.value = false, 1400);
|
|
139
|
-
} catch {
|
|
140
|
-
}
|
|
141
|
-
}
|
|
134
|
+
const { copied, copy: writeClipboard } = useClipboard();
|
|
135
|
+
const copy = () => writeClipboard(copyText.value);
|
|
142
136
|
function toggleLock() {
|
|
143
137
|
emit("update:locked", !props.locked);
|
|
144
138
|
}
|
|
@@ -168,13 +162,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
168
162
|
key: 1,
|
|
169
163
|
type: "button",
|
|
170
164
|
class: "group/copy flex items-center gap-1 rounded px-1.5 py-1 outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink focus-visible:ring-2 focus-visible:ring-ring",
|
|
171
|
-
"aria-label": copied
|
|
165
|
+
"aria-label": unref(copied) ? "Copied" : "Copy code",
|
|
172
166
|
onClick: copy
|
|
173
167
|
}, [
|
|
174
168
|
createVNode(_sfc_main$1, {
|
|
175
|
-
name: copied
|
|
169
|
+
name: unref(copied) ? "lucide:check" : "lucide:copy",
|
|
176
170
|
size: 13,
|
|
177
|
-
class: normalizeClass(copied
|
|
171
|
+
class: normalizeClass(unref(copied) ? "text-action" : "")
|
|
178
172
|
}, null, 8, ["name", "class"])
|
|
179
173
|
], 8, _hoisted_7)) : createCommentVNode("", true)
|
|
180
174
|
])
|