@leavepulse/ui 0.26.1 → 0.27.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/LpSection-BIvwZyE1.js +78 -0
- package/dist/component-names.d.ts +1 -1
- package/dist/components/LpSection.vue.d.ts +94 -0
- package/dist/components/LpSection.vue.js +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +42 -40
- package/package.json +1 -1
- package/src/component-names.ts +1 -0
- package/src/components/LpSection.vue +101 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { defineComponent, computed, openBlock, createElementBlock, normalizeClass, createElementVNode, createBlock, createCommentVNode, resolveDynamicComponent, withCtx, renderSlot, createTextVNode, toDisplayString } from "vue";
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
|
|
4
|
+
const _hoisted_1 = { class: "min-w-0" };
|
|
5
|
+
const _hoisted_2 = { class: "flex flex-wrap items-center gap-2" };
|
|
6
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
7
|
+
__name: "LpSection",
|
|
8
|
+
props: {
|
|
9
|
+
title: {},
|
|
10
|
+
description: {},
|
|
11
|
+
icon: {},
|
|
12
|
+
level: { default: "md" },
|
|
13
|
+
as: { default: "h2" }
|
|
14
|
+
},
|
|
15
|
+
setup(__props) {
|
|
16
|
+
const section = tv({
|
|
17
|
+
slots: {
|
|
18
|
+
// items-start, not items-center: once a description is present the actions
|
|
19
|
+
// must stay level with the TITLE, not drift to the middle of the block.
|
|
20
|
+
root: "flex flex-wrap items-start justify-between gap-x-4 gap-y-2",
|
|
21
|
+
title: "font-semibold text-ink",
|
|
22
|
+
description: "mt-1 text-sm text-muted",
|
|
23
|
+
actions: "flex shrink-0 flex-wrap items-center gap-2"
|
|
24
|
+
},
|
|
25
|
+
variants: {
|
|
26
|
+
level: {
|
|
27
|
+
sm: { title: "text-sm" },
|
|
28
|
+
md: { title: "text-base" },
|
|
29
|
+
lg: { title: "text-lg tracking-tight" },
|
|
30
|
+
xl: { title: "text-xl tracking-tight" }
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
defaultVariants: { level: "md" }
|
|
34
|
+
});
|
|
35
|
+
const props = __props;
|
|
36
|
+
const classes = computed(() => section({ level: props.level }));
|
|
37
|
+
return (_ctx, _cache) => {
|
|
38
|
+
return openBlock(), createElementBlock("div", {
|
|
39
|
+
class: normalizeClass(classes.value.root())
|
|
40
|
+
}, [
|
|
41
|
+
createElementVNode("div", _hoisted_1, [
|
|
42
|
+
createElementVNode("div", _hoisted_2, [
|
|
43
|
+
__props.icon ? (openBlock(), createBlock(_sfc_main$1, {
|
|
44
|
+
key: 0,
|
|
45
|
+
name: __props.icon,
|
|
46
|
+
size: 16,
|
|
47
|
+
class: "shrink-0 text-muted"
|
|
48
|
+
}, null, 8, ["name"])) : createCommentVNode("", true),
|
|
49
|
+
(openBlock(), createBlock(resolveDynamicComponent(__props.as), {
|
|
50
|
+
class: normalizeClass(classes.value.title())
|
|
51
|
+
}, {
|
|
52
|
+
default: withCtx(() => [
|
|
53
|
+
renderSlot(_ctx.$slots, "title", {}, () => [
|
|
54
|
+
createTextVNode(toDisplayString(__props.title), 1)
|
|
55
|
+
])
|
|
56
|
+
]),
|
|
57
|
+
_: 3
|
|
58
|
+
}, 8, ["class"])),
|
|
59
|
+
renderSlot(_ctx.$slots, "meta")
|
|
60
|
+
]),
|
|
61
|
+
__props.description ? (openBlock(), createElementBlock("p", {
|
|
62
|
+
key: 0,
|
|
63
|
+
class: normalizeClass(classes.value.description())
|
|
64
|
+
}, toDisplayString(__props.description), 3)) : createCommentVNode("", true)
|
|
65
|
+
]),
|
|
66
|
+
_ctx.$slots.actions ? (openBlock(), createElementBlock("div", {
|
|
67
|
+
key: 0,
|
|
68
|
+
class: normalizeClass(classes.value.actions())
|
|
69
|
+
}, [
|
|
70
|
+
renderSlot(_ctx.$slots, "actions")
|
|
71
|
+
], 2)) : createCommentVNode("", true)
|
|
72
|
+
], 2);
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
export {
|
|
77
|
+
_sfc_main as _
|
|
78
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const COMPONENT_NAMES: readonly ["LayoutCanvas", "LayoutNode", "LpAddressInput", "LpAlert", "LpAppShell", "LpAutocomplete", "LpAvatar", "LpBadge", "LpBreadcrumbs", "LpButton", "LpCalendar", "LpCard", "LpChart", "LpCheckbox", "LpCodeBlock", "LpCommandPalette", "LpConfirmDialog", "LpContextMenu", "LpDatePicker", "LpDisclosure", "LpDivider", "LpDrawer", "LpDropdownMenu", "LpEmptyState", "LpFileTree", "LpFileTreeNode", "LpFormField", "LpIcon", "LpInfraNode", "LpInput", "LpLaneNode", "LpLightbox", "LpLink", "LpLogViewer", "LpMapPicker", "LpModal", "LpNotificationBell", "LpNumberField", "LpNumberFlow", "LpOtpInput", "LpPagination", "LpPasswordInput", "LpPhoneInput", "LpPie", "LpPopover", "LpProgress", "LpRadio", "LpRadioGroup", "LpRollingText", "LpScrollArea", "LpSegmented", "LpSelect", "LpServiceNode", "LpShift", "LpShortcutsDialog", "LpSidebar", "LpSidebarNav", "LpSkeleton", "LpSlider", "LpSparkline", "LpStat", "LpStepper", "LpSwitch", "LpTable", "LpTableOfContents", "LpTabs", "LpTextarea", "LpThemeSwitcher", "LpTilt", "LpToaster", "LpTooltip", "LpTopologyCanvas", "LpUptimeBar", "LpWaypointEdge"];
|
|
1
|
+
export declare const COMPONENT_NAMES: readonly ["LayoutCanvas", "LayoutNode", "LpAddressInput", "LpAlert", "LpAppShell", "LpAutocomplete", "LpAvatar", "LpBadge", "LpBreadcrumbs", "LpButton", "LpCalendar", "LpCard", "LpChart", "LpCheckbox", "LpCodeBlock", "LpCommandPalette", "LpConfirmDialog", "LpContextMenu", "LpDatePicker", "LpDisclosure", "LpDivider", "LpDrawer", "LpDropdownMenu", "LpEmptyState", "LpFileTree", "LpFileTreeNode", "LpFormField", "LpIcon", "LpInfraNode", "LpInput", "LpLaneNode", "LpLightbox", "LpLink", "LpLogViewer", "LpMapPicker", "LpModal", "LpNotificationBell", "LpNumberField", "LpNumberFlow", "LpOtpInput", "LpPagination", "LpPasswordInput", "LpPhoneInput", "LpPie", "LpPopover", "LpProgress", "LpRadio", "LpRadioGroup", "LpRollingText", "LpScrollArea", "LpSection", "LpSegmented", "LpSelect", "LpServiceNode", "LpShift", "LpShortcutsDialog", "LpSidebar", "LpSidebarNav", "LpSkeleton", "LpSlider", "LpSparkline", "LpStat", "LpStepper", "LpSwitch", "LpTable", "LpTableOfContents", "LpTabs", "LpTextarea", "LpThemeSwitcher", "LpTilt", "LpToaster", "LpTooltip", "LpTopologyCanvas", "LpUptimeBar", "LpWaypointEdge"];
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { VariantProps } from 'tailwind-variants';
|
|
2
|
+
declare const section: import('tailwind-variants').TVReturnType<{
|
|
3
|
+
level: {
|
|
4
|
+
sm: {
|
|
5
|
+
title: string;
|
|
6
|
+
};
|
|
7
|
+
md: {
|
|
8
|
+
title: string;
|
|
9
|
+
};
|
|
10
|
+
lg: {
|
|
11
|
+
title: string;
|
|
12
|
+
};
|
|
13
|
+
xl: {
|
|
14
|
+
title: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
}, {
|
|
18
|
+
root: string;
|
|
19
|
+
title: string;
|
|
20
|
+
description: string;
|
|
21
|
+
actions: string;
|
|
22
|
+
}, undefined, {
|
|
23
|
+
level: {
|
|
24
|
+
sm: {
|
|
25
|
+
title: string;
|
|
26
|
+
};
|
|
27
|
+
md: {
|
|
28
|
+
title: string;
|
|
29
|
+
};
|
|
30
|
+
lg: {
|
|
31
|
+
title: string;
|
|
32
|
+
};
|
|
33
|
+
xl: {
|
|
34
|
+
title: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
}, {
|
|
38
|
+
root: string;
|
|
39
|
+
title: string;
|
|
40
|
+
description: string;
|
|
41
|
+
actions: string;
|
|
42
|
+
}, import('tailwind-variants').TVReturnType<{
|
|
43
|
+
level: {
|
|
44
|
+
sm: {
|
|
45
|
+
title: string;
|
|
46
|
+
};
|
|
47
|
+
md: {
|
|
48
|
+
title: string;
|
|
49
|
+
};
|
|
50
|
+
lg: {
|
|
51
|
+
title: string;
|
|
52
|
+
};
|
|
53
|
+
xl: {
|
|
54
|
+
title: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
}, {
|
|
58
|
+
root: string;
|
|
59
|
+
title: string;
|
|
60
|
+
description: string;
|
|
61
|
+
actions: string;
|
|
62
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
63
|
+
type SectionVariants = VariantProps<typeof section>;
|
|
64
|
+
type __VLS_Props = {
|
|
65
|
+
title?: string;
|
|
66
|
+
/** One line under the title. */
|
|
67
|
+
description?: string;
|
|
68
|
+
/** Iconify name shown before the title, e.g. "lucide:server". */
|
|
69
|
+
icon?: string;
|
|
70
|
+
/** Visual size. Independent of `as` — see the note above. */
|
|
71
|
+
level?: SectionVariants["level"];
|
|
72
|
+
/** The heading element to render. Pick it for the document outline. */
|
|
73
|
+
as?: "h1" | "h2" | "h3" | "h4" | "p";
|
|
74
|
+
};
|
|
75
|
+
type __VLS_Slots = {
|
|
76
|
+
/** Title markup, when a plain string is not enough. */
|
|
77
|
+
title?: () => unknown;
|
|
78
|
+
/** Right-aligned controls: buttons, filters, a count. */
|
|
79
|
+
actions?: () => unknown;
|
|
80
|
+
/** Extra content beside the title — a badge, a count, a status dot. */
|
|
81
|
+
meta?: () => unknown;
|
|
82
|
+
};
|
|
83
|
+
declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
84
|
+
as: "h1" | "h2" | "h3" | "h4" | "p";
|
|
85
|
+
level: "sm" | "md" | "lg" | "xl";
|
|
86
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
87
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
88
|
+
declare const _default: typeof __VLS_export;
|
|
89
|
+
export default _default;
|
|
90
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
91
|
+
new (): {
|
|
92
|
+
$slots: S;
|
|
93
|
+
};
|
|
94
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -73,6 +73,7 @@ export { default as LpRollingText } from './components/LpRollingText.vue';
|
|
|
73
73
|
export { default as LpScrollArea } from './components/LpScrollArea.vue';
|
|
74
74
|
export { default as LpSegmented } from './components/LpSegmented.vue';
|
|
75
75
|
export type { SegmentedOption } from './components/LpSegmented.vue';
|
|
76
|
+
export { default as LpSection } from './components/LpSection.vue';
|
|
76
77
|
export { default as LpSelect } from './components/LpSelect.vue';
|
|
77
78
|
export type { SelectOption, SelectValue } from './components/LpSelect.vue';
|
|
78
79
|
export { default as LpServiceNode } from './components/LpServiceNode.vue';
|
package/dist/index.js
CHANGED
|
@@ -51,28 +51,29 @@ import { _ as _44 } from "./chunks/LpRadioGroup-B4yDTmi6.js";
|
|
|
51
51
|
import { _ as _45 } from "./chunks/LpRollingText-CM5gkSeF.js";
|
|
52
52
|
import { _ as _46 } from "./chunks/LpScrollArea-D8xyKXcF.js";
|
|
53
53
|
import { _ as _47 } from "./chunks/LpSegmented-BmpanyAo.js";
|
|
54
|
-
import { _ as _48 } from "./chunks/
|
|
55
|
-
import { _ as _49 } from "./chunks/
|
|
56
|
-
import { _ as _50 } from "./chunks/
|
|
54
|
+
import { _ as _48 } from "./chunks/LpSection-BIvwZyE1.js";
|
|
55
|
+
import { _ as _49 } from "./chunks/LpSelect-Cw8-gL5F.js";
|
|
56
|
+
import { _ as _50 } from "./chunks/LpServiceNode-D8uJ8sGk.js";
|
|
57
|
+
import { _ as _51 } from "./chunks/LpShift-DXNsauQZ.js";
|
|
57
58
|
import { default as default3 } from "./components/LpShortcutsDialog.vue.js";
|
|
58
|
-
import { _ as
|
|
59
|
-
import { _ as
|
|
60
|
-
import { _ as
|
|
61
|
-
import { _ as
|
|
62
|
-
import { _ as
|
|
63
|
-
import { _ as
|
|
64
|
-
import { _ as
|
|
65
|
-
import { _ as
|
|
66
|
-
import { _ as
|
|
67
|
-
import { _ as
|
|
68
|
-
import { _ as
|
|
59
|
+
import { _ as _52 } from "./chunks/LpSidebar-7Vpy2IJc.js";
|
|
60
|
+
import { _ as _53 } from "./chunks/LpSkeleton-DpXLDcQm.js";
|
|
61
|
+
import { _ as _54 } from "./chunks/LpSlider-B1SF3pRV.js";
|
|
62
|
+
import { _ as _55 } from "./chunks/LpSparkline-C6xQ2dwv.js";
|
|
63
|
+
import { _ as _56 } from "./chunks/LpStat-CDanpzU0.js";
|
|
64
|
+
import { _ as _57 } from "./chunks/LpStepper-Wtl-6nUh.js";
|
|
65
|
+
import { _ as _58 } from "./chunks/LpSwitch-v6fnccSM.js";
|
|
66
|
+
import { _ as _59 } from "./chunks/LpTable-DTj52qlg.js";
|
|
67
|
+
import { _ as _60 } from "./chunks/LpTableOfContents-CjvxPMpU.js";
|
|
68
|
+
import { _ as _61 } from "./chunks/LpTabs-Cefe_lys.js";
|
|
69
|
+
import { _ as _62 } from "./chunks/LpTextarea-1ENb3ZAO.js";
|
|
69
70
|
import { p as presets, a as parseTheme, s as serializeTheme } from "./chunks/LpThemeSwitcher-7mAK6bI7.js";
|
|
70
|
-
import { D, _ as
|
|
71
|
-
import { _ as
|
|
72
|
-
import { _ as
|
|
73
|
-
import { _ as
|
|
74
|
-
import { _ as
|
|
75
|
-
import { _ as
|
|
71
|
+
import { D, _ as _63, N, T, b, c, d, e, f, g, i, l, h, j, n, r, t, k, m, u, v } from "./chunks/LpThemeSwitcher-7mAK6bI7.js";
|
|
72
|
+
import { _ as _64 } from "./chunks/LpTilt-DuyKbpkA.js";
|
|
73
|
+
import { _ as _65 } from "./chunks/LpToaster-gDB1EaU3.js";
|
|
74
|
+
import { _ as _66 } from "./chunks/LpTooltip-hCLPAqMG.js";
|
|
75
|
+
import { _ as _67 } from "./chunks/LpTopologyCanvas-ebP67CLx.js";
|
|
76
|
+
import { _ as _68 } from "./chunks/LpUptimeBar-DcQ8HikG.js";
|
|
76
77
|
import { deserializeLayout, serializeLayout } from "./layout/tree.js";
|
|
77
78
|
import { addLeaf, addTab, countBlocks, countLeaves, makeLayout, moveLeaf, removeBlock, removeLeaf, reorderTab, resizeAt, setActiveTab } from "./layout/tree.js";
|
|
78
79
|
import { blockTitle, defineBlocks } from "./layout/registry.js";
|
|
@@ -167,28 +168,29 @@ export {
|
|
|
167
168
|
_44 as LpRadioGroup,
|
|
168
169
|
_45 as LpRollingText,
|
|
169
170
|
_46 as LpScrollArea,
|
|
171
|
+
_48 as LpSection,
|
|
170
172
|
_47 as LpSegmented,
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
173
|
+
_49 as LpSelect,
|
|
174
|
+
_50 as LpServiceNode,
|
|
175
|
+
_51 as LpShift,
|
|
174
176
|
default3 as LpShortcutsDialog,
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
177
|
+
_52 as LpSidebar,
|
|
178
|
+
_53 as LpSkeleton,
|
|
179
|
+
_54 as LpSlider,
|
|
180
|
+
_55 as LpSparkline,
|
|
181
|
+
_56 as LpStat,
|
|
182
|
+
_57 as LpStepper,
|
|
183
|
+
_58 as LpSwitch,
|
|
184
|
+
_59 as LpTable,
|
|
185
|
+
_60 as LpTableOfContents,
|
|
186
|
+
_61 as LpTabs,
|
|
187
|
+
_62 as LpTextarea,
|
|
188
|
+
_63 as LpThemeSwitcher,
|
|
189
|
+
_64 as LpTilt,
|
|
190
|
+
_65 as LpToaster,
|
|
191
|
+
_66 as LpTooltip,
|
|
192
|
+
_67 as LpTopologyCanvas,
|
|
193
|
+
_68 as LpUptimeBar,
|
|
192
194
|
N as NO_BACKDROP_ATTR,
|
|
193
195
|
OSM_TILES,
|
|
194
196
|
T as THEME_COOKIE,
|
package/package.json
CHANGED
package/src/component-names.ts
CHANGED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/*
|
|
3
|
+
* A section heading: a title, an optional line under it, and actions on the
|
|
4
|
+
* right.
|
|
5
|
+
*
|
|
6
|
+
* <LpSection title="Recent invoices">
|
|
7
|
+
* <template #actions><LpButton size="sm">Export</LpButton></template>
|
|
8
|
+
* </LpSection>
|
|
9
|
+
*
|
|
10
|
+
* This is the block every app rebuilt: ~140 hand-written headings across the
|
|
11
|
+
* three of them, each picking its own size, its own gap, its own alignment.
|
|
12
|
+
* LeaveHosting had already extracted its own `PageHeader.vue` — same title,
|
|
13
|
+
* same description, same actions slot — which is the clearest evidence the
|
|
14
|
+
* shape is shared rather than one app's habit.
|
|
15
|
+
*
|
|
16
|
+
* What it deliberately does NOT do:
|
|
17
|
+
*
|
|
18
|
+
* - It draws no container. In the panel these headings sit inside LpCard; in
|
|
19
|
+
* the cabinet they sit inside `glass rounded-3xl` blocks and, more often,
|
|
20
|
+
* directly on the page. Owning a border here would fight two of the three.
|
|
21
|
+
* - It has no icon slot of its own beyond `icon`. The panel coloured each
|
|
22
|
+
* heading's icon from the raw palette — amber beside rose beside sky — in
|
|
23
|
+
* pages where none of those states were amber, rose or blue. One muted
|
|
24
|
+
* colour, or none.
|
|
25
|
+
*
|
|
26
|
+
* `level` is the visual size and is independent of `as`, the heading element:
|
|
27
|
+
* a page's main heading may need to be an h1 rendered small, and a card's
|
|
28
|
+
* heading an h3 rendered large. Tying them together is what made consumers
|
|
29
|
+
* reach past the component for a raw <h2> again.
|
|
30
|
+
*/
|
|
31
|
+
import { computed } from "vue"
|
|
32
|
+
import { tv, type VariantProps } from "tailwind-variants"
|
|
33
|
+
import LpIcon from "./LpIcon.vue"
|
|
34
|
+
|
|
35
|
+
const section = tv({
|
|
36
|
+
slots: {
|
|
37
|
+
// items-start, not items-center: once a description is present the actions
|
|
38
|
+
// must stay level with the TITLE, not drift to the middle of the block.
|
|
39
|
+
root: "flex flex-wrap items-start justify-between gap-x-4 gap-y-2",
|
|
40
|
+
title: "font-semibold text-ink",
|
|
41
|
+
description: "mt-1 text-sm text-muted",
|
|
42
|
+
actions: "flex shrink-0 flex-wrap items-center gap-2",
|
|
43
|
+
},
|
|
44
|
+
variants: {
|
|
45
|
+
level: {
|
|
46
|
+
sm: { title: "text-sm" },
|
|
47
|
+
md: { title: "text-base" },
|
|
48
|
+
lg: { title: "text-lg tracking-tight" },
|
|
49
|
+
xl: { title: "text-xl tracking-tight" },
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
defaultVariants: { level: "md" },
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
type SectionVariants = VariantProps<typeof section>
|
|
56
|
+
|
|
57
|
+
const props = withDefaults(
|
|
58
|
+
defineProps<{
|
|
59
|
+
title?: string
|
|
60
|
+
/** One line under the title. */
|
|
61
|
+
description?: string
|
|
62
|
+
/** Iconify name shown before the title, e.g. "lucide:server". */
|
|
63
|
+
icon?: string
|
|
64
|
+
/** Visual size. Independent of `as` — see the note above. */
|
|
65
|
+
level?: SectionVariants["level"]
|
|
66
|
+
/** The heading element to render. Pick it for the document outline. */
|
|
67
|
+
as?: "h1" | "h2" | "h3" | "h4" | "p"
|
|
68
|
+
}>(),
|
|
69
|
+
{ level: "md", as: "h2" },
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
defineSlots<{
|
|
73
|
+
/** Title markup, when a plain string is not enough. */
|
|
74
|
+
title?: () => unknown
|
|
75
|
+
/** Right-aligned controls: buttons, filters, a count. */
|
|
76
|
+
actions?: () => unknown
|
|
77
|
+
/** Extra content beside the title — a badge, a count, a status dot. */
|
|
78
|
+
meta?: () => unknown
|
|
79
|
+
}>()
|
|
80
|
+
|
|
81
|
+
const classes = computed(() => section({ level: props.level }))
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<template>
|
|
85
|
+
<div :class="classes.root()">
|
|
86
|
+
<div class="min-w-0">
|
|
87
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
88
|
+
<LpIcon v-if="icon" :name="icon" :size="16" class="shrink-0 text-muted" />
|
|
89
|
+
<component :is="as" :class="classes.title()">
|
|
90
|
+
<slot name="title">{{ title }}</slot>
|
|
91
|
+
</component>
|
|
92
|
+
<slot name="meta" />
|
|
93
|
+
</div>
|
|
94
|
+
<p v-if="description" :class="classes.description()">{{ description }}</p>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<div v-if="$slots.actions" :class="classes.actions()">
|
|
98
|
+
<slot name="actions" />
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</template>
|
package/src/index.ts
CHANGED
|
@@ -110,6 +110,7 @@ export { default as LpRollingText } from "./components/LpRollingText.vue"
|
|
|
110
110
|
export { default as LpScrollArea } from "./components/LpScrollArea.vue"
|
|
111
111
|
export { default as LpSegmented } from "./components/LpSegmented.vue"
|
|
112
112
|
export type { SegmentedOption } from "./components/LpSegmented.vue"
|
|
113
|
+
export { default as LpSection } from "./components/LpSection.vue"
|
|
113
114
|
export { default as LpSelect } from "./components/LpSelect.vue"
|
|
114
115
|
export type { SelectOption, SelectValue } from "./components/LpSelect.vue"
|
|
115
116
|
export { default as LpServiceNode } from "./components/LpServiceNode.vue"
|