@leavepulse/ui 0.12.0 → 0.14.6

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.
Files changed (162) hide show
  1. package/dist/assets/LpCommandPalette-D315B47-.css +16 -0
  2. package/dist/chunks/LayoutCanvas-Dd20boUG.js +50 -0
  3. package/dist/chunks/LayoutNode-DGpZA9LX.js +225 -0
  4. package/dist/chunks/LpAlert-BAYHDSS1.js +69 -0
  5. package/dist/chunks/LpAppShell-DBTsNQaM.js +170 -0
  6. package/dist/chunks/LpAutocomplete-B9uoCs4t.js +196 -0
  7. package/dist/chunks/LpAvatar-B1Ez0ZAx.js +88 -0
  8. package/dist/chunks/LpBadge-CXzBPnwO.js +42 -0
  9. package/dist/chunks/LpBreadcrumbs-B7Aqatzw.js +42 -0
  10. package/dist/chunks/LpButton-5VXXCjwF.js +101 -0
  11. package/dist/chunks/LpCalendar-B7ZL0ty3.js +150 -0
  12. package/dist/chunks/LpCard-1yvWT9fx.js +66 -0
  13. package/dist/chunks/LpCheckbox-BO0zuuPh.js +55 -0
  14. package/dist/chunks/LpCodeBlock-CSiOSPs8.js +253 -0
  15. package/dist/chunks/LpConfirmDialog-KLtTtCiT.js +62 -0
  16. package/dist/chunks/LpContextMenu-D0mzXqA7.js +151 -0
  17. package/dist/chunks/LpDatePicker-dY2q4dr4.js +122 -0
  18. package/dist/chunks/LpDisclosure-DP6yfgfM.js +76 -0
  19. package/dist/chunks/LpDivider-CUX46KR0.js +43 -0
  20. package/dist/chunks/LpDrawer-Ce6g9ZMr.js +310 -0
  21. package/dist/chunks/LpDropdownMenu-DJpoqRCb.js +65 -0
  22. package/dist/chunks/LpEmptyState-CrfyRJUG.js +47 -0
  23. package/dist/chunks/LpFormField-Bn-ZwC6z.js +47 -0
  24. package/dist/chunks/LpIcon-CCnX5_2j.js +41 -0
  25. package/dist/chunks/LpInfraNode-C_PHcthC.js +99 -0
  26. package/dist/chunks/LpInput-BauZRyzm.js +136 -0
  27. package/dist/chunks/LpLaneNode-HtnQf2FF.js +33 -0
  28. package/dist/chunks/LpLink-DHwOEp4e.js +36 -0
  29. package/dist/chunks/LpLogViewer-hC0OKkeE.js +482 -0
  30. package/dist/chunks/LpModal-CWoOExzT.js +128 -0
  31. package/dist/chunks/LpNotificationBell-BDy0tQwr.js +232 -0
  32. package/dist/chunks/LpNumberField-C5ar-OwE.js +55 -0
  33. package/dist/chunks/LpOtpInput-DqaT0Z75.js +65 -0
  34. package/dist/chunks/LpPagination-CeGuNe_q.js +132 -0
  35. package/dist/chunks/LpPasswordInput-DIHFw4u0.js +64 -0
  36. package/dist/chunks/LpPhoneInput-LQvVFGMw.js +199 -0
  37. package/dist/chunks/LpPopover-8268UmlC.js +54 -0
  38. package/dist/chunks/LpProgress-BhI0IbjC.js +37 -0
  39. package/dist/chunks/LpRadio-CL-pI0_O.js +39 -0
  40. package/dist/chunks/LpRadioGroup-B4yDTmi6.js +52 -0
  41. package/dist/chunks/LpScrollArea-K1x-azgY.js +67 -0
  42. package/dist/chunks/LpSegmented-BmpanyAo.js +74 -0
  43. package/dist/chunks/LpSelect-DznhPEWX.js +222 -0
  44. package/dist/chunks/LpServiceNode-Dc-Ut5RS.js +51 -0
  45. package/dist/chunks/LpSidebar-BPQabjae.js +152 -0
  46. package/dist/chunks/LpSidebarNav-CpF7rZxx.js +126 -0
  47. package/dist/chunks/LpSkeleton-eSFIo4kD.js +22 -0
  48. package/dist/chunks/LpSlider-B1SF3pRV.js +53 -0
  49. package/dist/chunks/LpStat-CdbEFOvn.js +88 -0
  50. package/dist/chunks/LpStepper-5dFTrW21.js +53 -0
  51. package/dist/chunks/LpSwitch-v6fnccSM.js +28 -0
  52. package/dist/chunks/LpTable-CJ4Zt1UH.js +229 -0
  53. package/dist/chunks/LpTableOfContents-CjvxPMpU.js +155 -0
  54. package/dist/chunks/LpTabs-D7aTVPOb.js +115 -0
  55. package/dist/chunks/LpTextarea-CRAkhemZ.js +44 -0
  56. package/dist/chunks/LpThemeSwitcher-BgWwfkxs.js +601 -0
  57. package/dist/chunks/LpTilt-DuyKbpkA.js +49 -0
  58. package/dist/chunks/LpToaster-gDB1EaU3.js +196 -0
  59. package/dist/chunks/LpTooltip-CIwoRCag.js +49 -0
  60. package/dist/chunks/LpTopologyCanvas-DVwyQfKa.js +237 -0
  61. package/dist/chunks/LpUptimeBar-CB366k0O.js +127 -0
  62. package/dist/component-names.d.ts +1 -1
  63. package/dist/components/LayoutCanvas.vue.js +4 -0
  64. package/dist/components/LayoutNode.vue.js +4 -0
  65. package/dist/components/LpAlert.vue.js +4 -0
  66. package/dist/components/LpAppShell.vue.js +4 -0
  67. package/dist/components/LpAutocomplete.vue.js +4 -0
  68. package/dist/components/LpAvatar.vue.js +4 -0
  69. package/dist/components/LpBadge.vue.js +4 -0
  70. package/dist/components/LpBreadcrumbs.vue.js +4 -0
  71. package/dist/components/LpButton.vue.js +4 -0
  72. package/dist/components/LpCalendar.vue.js +4 -0
  73. package/dist/components/LpCard.vue.js +4 -0
  74. package/dist/components/LpCheckbox.vue.js +4 -0
  75. package/dist/components/LpCodeBlock.vue.js +4 -0
  76. package/dist/components/LpCommandPalette.vue.js +310 -0
  77. package/dist/components/LpConfirmDialog.vue.js +4 -0
  78. package/dist/components/LpContextMenu.vue.d.ts +7 -0
  79. package/dist/components/LpContextMenu.vue.js +4 -0
  80. package/dist/components/LpDatePicker.vue.js +4 -0
  81. package/dist/components/LpDisclosure.vue.js +4 -0
  82. package/dist/components/LpDivider.vue.js +4 -0
  83. package/dist/components/LpDrawer.vue.d.ts +8 -0
  84. package/dist/components/LpDrawer.vue.js +4 -0
  85. package/dist/components/LpDropdownMenu.vue.js +4 -0
  86. package/dist/components/LpEmptyState.vue.js +4 -0
  87. package/dist/components/LpFormField.vue.js +4 -0
  88. package/dist/components/LpIcon.vue.js +4 -0
  89. package/dist/components/LpInfraNode.vue.js +4 -0
  90. package/dist/components/LpInput.vue.js +4 -0
  91. package/dist/components/LpLaneNode.vue.js +4 -0
  92. package/dist/components/LpLink.vue.js +4 -0
  93. package/dist/components/LpLogViewer.vue.js +4 -0
  94. package/dist/components/LpModal.vue.js +4 -0
  95. package/dist/components/LpNotificationBell.vue.js +4 -0
  96. package/dist/components/LpNumberField.vue.js +4 -0
  97. package/dist/components/LpOtpInput.vue.js +4 -0
  98. package/dist/components/LpPagination.vue.js +4 -0
  99. package/dist/components/LpPasswordInput.vue.js +4 -0
  100. package/dist/components/LpPhoneInput.vue.js +4 -0
  101. package/dist/components/LpPopover.vue.js +4 -0
  102. package/dist/components/LpProgress.vue.js +4 -0
  103. package/dist/components/LpRadio.vue.js +4 -0
  104. package/dist/components/LpRadioGroup.vue.js +4 -0
  105. package/dist/components/LpScrollArea.vue.d.ts +2 -2
  106. package/dist/components/LpScrollArea.vue.js +4 -0
  107. package/dist/components/LpSegmented.vue.js +4 -0
  108. package/dist/components/LpSelect.vue.d.ts +2 -0
  109. package/dist/components/LpSelect.vue.js +4 -0
  110. package/dist/components/LpServiceNode.vue.js +4 -0
  111. package/dist/components/LpSidebar.vue.js +4 -0
  112. package/dist/components/LpSidebarNav.vue.js +4 -0
  113. package/dist/components/LpSkeleton.vue.js +4 -0
  114. package/dist/components/LpSlider.vue.js +4 -0
  115. package/dist/components/LpStat.vue.js +4 -0
  116. package/dist/components/LpStepper.vue.js +4 -0
  117. package/dist/components/LpSwitch.vue.js +4 -0
  118. package/dist/components/LpTable.vue.js +4 -0
  119. package/dist/components/LpTableOfContents.vue.js +4 -0
  120. package/dist/components/LpTabs.vue.d.ts +4 -2
  121. package/dist/components/LpTabs.vue.js +4 -0
  122. package/dist/components/LpTextarea.vue.js +4 -0
  123. package/dist/components/LpThemeSwitcher.vue.js +4 -0
  124. package/dist/components/LpTilt.vue.d.ts +31 -0
  125. package/dist/components/LpTilt.vue.js +4 -0
  126. package/dist/components/LpToaster.vue.js +4 -0
  127. package/dist/components/LpTooltip.vue.js +4 -0
  128. package/dist/components/LpTopologyCanvas.vue.js +4 -0
  129. package/dist/components/LpUptimeBar.vue.js +4 -0
  130. package/dist/components/codeHighlight.js +230 -0
  131. package/dist/{countries-data-9rgqJWHo.js → components/countries-data.js} +2 -2
  132. package/dist/components/countries.js +38 -0
  133. package/dist/components/dropdown.js +14 -0
  134. package/dist/components/sidebar.js +1 -0
  135. package/dist/composables/useInputFilter.js +44 -0
  136. package/dist/composables/usePillTransition.js +11 -0
  137. package/dist/composables/useTilt.d.ts +23 -0
  138. package/dist/composables/useTilt.js +57 -0
  139. package/dist/composables/useToast.d.ts +2 -0
  140. package/dist/composables/useToast.js +49 -0
  141. package/dist/index.d.ts +3 -0
  142. package/dist/index.js +197 -17596
  143. package/dist/layout/registry.js +10 -0
  144. package/dist/layout/tree.js +192 -0
  145. package/dist/layout/useLayout.js +61 -0
  146. package/package.json +5 -3
  147. package/src/component-names.ts +1 -0
  148. package/src/components/LpContextMenu.vue +14 -4
  149. package/src/components/LpDrawer.vue +29 -1
  150. package/src/components/LpLogViewer.vue +180 -31
  151. package/src/components/LpScrollArea.vue +20 -15
  152. package/src/components/LpSelect.vue +0 -0
  153. package/src/components/LpSidebar.vue +5 -2
  154. package/src/components/LpTabs.vue +19 -6
  155. package/src/components/LpThemeSwitcher.vue +13 -2
  156. package/src/components/LpTilt.vue +61 -0
  157. package/src/components/LpToaster.vue +11 -4
  158. package/src/composables/useTilt.ts +103 -0
  159. package/src/composables/useToast.ts +2 -0
  160. package/src/index.ts +3 -0
  161. package/src/nuxt.ts +10 -1
  162. package/dist/index.css +0 -1
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpTextarea-CRAkhemZ.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpThemeSwitcher-BgWwfkxs.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,31 @@
1
+ type __VLS_Props = {
2
+ /** Max rotation toward the pointer, in degrees. */
3
+ max?: number;
4
+ /** Upward lift on hover, in px. */
5
+ lift?: number;
6
+ /** Scale on hover. */
7
+ scale?: number;
8
+ /** Render a pointer-tracking glare highlight over the content. */
9
+ glare?: boolean;
10
+ /** Perspective depth for the 3D stage, in px. Lower = stronger. */
11
+ perspective?: number;
12
+ };
13
+ declare var __VLS_1: {};
14
+ type __VLS_Slots = {} & {
15
+ default?: (props: typeof __VLS_1) => any;
16
+ };
17
+ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
18
+ scale: number;
19
+ max: number;
20
+ perspective: number;
21
+ lift: number;
22
+ glare: boolean;
23
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
24
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
25
+ declare const _default: typeof __VLS_export;
26
+ export default _default;
27
+ type __VLS_WithSlots<T, S> = T & {
28
+ new (): {
29
+ $slots: S;
30
+ };
31
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpTilt-DuyKbpkA.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpToaster-gDB1EaU3.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpTooltip-CIwoRCag.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpTopologyCanvas-DVwyQfKa.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpUptimeBar-CB366k0O.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,230 @@
1
+ const C = {
2
+ comment: "text-muted italic",
3
+ string: "text-action",
4
+ number: "text-accent",
5
+ keyword: "text-brand",
6
+ boolean: "text-accent",
7
+ property: "text-muted-strong",
8
+ func: "text-brand",
9
+ punct: "text-muted"
10
+ };
11
+ const KEYWORDS = /* @__PURE__ */ new Set([
12
+ // JS/TS
13
+ "const",
14
+ "let",
15
+ "var",
16
+ "function",
17
+ "return",
18
+ "if",
19
+ "else",
20
+ "for",
21
+ "while",
22
+ "import",
23
+ "export",
24
+ "from",
25
+ "default",
26
+ "class",
27
+ "extends",
28
+ "new",
29
+ "await",
30
+ "async",
31
+ "type",
32
+ "interface",
33
+ "enum",
34
+ "public",
35
+ "private",
36
+ "readonly",
37
+ "as",
38
+ "in",
39
+ "of",
40
+ "try",
41
+ "catch",
42
+ "finally",
43
+ "throw",
44
+ "switch",
45
+ "case",
46
+ "break",
47
+ "continue",
48
+ "typeof",
49
+ "instanceof",
50
+ "void",
51
+ "yield",
52
+ // shell
53
+ "echo",
54
+ "cd",
55
+ "sudo",
56
+ "npm",
57
+ "npx",
58
+ "git",
59
+ "curl",
60
+ // python
61
+ "def",
62
+ "elif",
63
+ "lambda",
64
+ "pass",
65
+ "with",
66
+ "global",
67
+ "nonlocal",
68
+ "del",
69
+ "raise",
70
+ "except",
71
+ "and",
72
+ "or",
73
+ "not",
74
+ "is",
75
+ "assert",
76
+ "yield",
77
+ "match",
78
+ // rust
79
+ "fn",
80
+ "mut",
81
+ "impl",
82
+ "trait",
83
+ "struct",
84
+ "mod",
85
+ "pub",
86
+ "use",
87
+ "crate",
88
+ "self",
89
+ "Self",
90
+ "move",
91
+ "ref",
92
+ "where",
93
+ "dyn",
94
+ "unsafe",
95
+ "loop",
96
+ "macro",
97
+ "use",
98
+ "super",
99
+ "static",
100
+ // kotlin
101
+ "fun",
102
+ "val",
103
+ "object",
104
+ "companion",
105
+ "data",
106
+ "sealed",
107
+ "override",
108
+ "open",
109
+ "internal",
110
+ "lateinit",
111
+ "init",
112
+ "when",
113
+ "is",
114
+ "vararg",
115
+ "inline",
116
+ "reified",
117
+ "suspend",
118
+ "operator",
119
+ "infix",
120
+ "tailrec",
121
+ "external",
122
+ "annotation",
123
+ "constructor",
124
+ "by",
125
+ "get",
126
+ "set",
127
+ "field",
128
+ "it",
129
+ "run",
130
+ "let",
131
+ "apply",
132
+ "also",
133
+ "with",
134
+ // java (extra, beyond shared C-family already above)
135
+ "package",
136
+ "implements",
137
+ "abstract",
138
+ "final",
139
+ "synchronized",
140
+ "volatile",
141
+ "transient",
142
+ "native",
143
+ "strictfp",
144
+ "protected",
145
+ "throws",
146
+ "boolean",
147
+ "int",
148
+ "long",
149
+ "short",
150
+ "byte",
151
+ "char",
152
+ "float",
153
+ "double",
154
+ "String",
155
+ "record",
156
+ // groovy adds few over java: def, trait already covered; add its extras
157
+ "def",
158
+ "each",
159
+ "closure"
160
+ ]);
161
+ const BOOLEANS = /* @__PURE__ */ new Set([
162
+ "true",
163
+ "false",
164
+ "null",
165
+ "undefined",
166
+ // js
167
+ "None",
168
+ "True",
169
+ "False",
170
+ // python
171
+ "Some",
172
+ "Ok",
173
+ "Err"
174
+ // rust common variants read as constants
175
+ ]);
176
+ const MASTER = new RegExp(
177
+ [
178
+ "(\\/\\/[^\\n]*|#[^\\n]*|\\/\\*[\\s\\S]*?\\*\\/)",
179
+ // 1 comment
180
+ "(\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`(?:\\\\.|[^`\\\\])*`)",
181
+ // 2 string
182
+ "(@[A-Za-z_$][\\w$]*)",
183
+ // 3 annotation (@Override, @ConfigSerializable — JVM)
184
+ "(\\b\\d[\\d_]*(?:\\.\\d+)?(?:e[+-]?\\d+)?[fFlLdD]?\\b)",
185
+ // 4 number (JVM suffixes)
186
+ "([A-Za-z_$][\\w$]*)",
187
+ // 5 identifier (keyword/bool/func/prop/plain)
188
+ "([{}()\\[\\];:,.<>=+\\-*/%!&|?]+)"
189
+ // 6 punctuation
190
+ ].join("|"),
191
+ "g"
192
+ );
193
+ function classifyIdent(name, before, after) {
194
+ if (KEYWORDS.has(name)) return C.keyword;
195
+ if (BOOLEANS.has(name)) return C.boolean;
196
+ if (after.startsWith("(")) return C.func;
197
+ if (before.endsWith(".")) return C.property;
198
+ return "";
199
+ }
200
+ function tokenizeLine(line, lang) {
201
+ const out = [];
202
+ let last = 0;
203
+ let m;
204
+ MASTER.lastIndex = 0;
205
+ while ((m = MASTER.exec(line)) !== null) {
206
+ if (m.index > last) out.push({ text: line.slice(last, m.index), cls: "" });
207
+ const [full, comment, str, annotation, num, ident, punct] = m;
208
+ if (comment != null) out.push({ text: full, cls: C.comment });
209
+ else if (annotation != null) out.push({ text: full, cls: C.func });
210
+ else if (str != null) {
211
+ const isKey = lang === "json" && line.slice(m.index + full.length).trimStart().startsWith(":");
212
+ out.push({ text: full, cls: isKey ? C.property : C.string });
213
+ } else if (num != null) out.push({ text: full, cls: C.number });
214
+ else if (ident != null) {
215
+ const after = line.slice(m.index + full.length).trimStart();
216
+ const before = line.slice(0, m.index).trimEnd();
217
+ const isConfigKey = lang === "yaml" && before === "" && after.startsWith(":") || lang === "toml" && before === "" && after.startsWith("=");
218
+ out.push({
219
+ text: full,
220
+ cls: isConfigKey ? C.property : classifyIdent(ident, before, after)
221
+ });
222
+ } else if (punct != null) out.push({ text: full, cls: C.punct });
223
+ last = m.index + full.length;
224
+ }
225
+ if (last < line.length) out.push({ text: line.slice(last), cls: "" });
226
+ return out;
227
+ }
228
+ export {
229
+ tokenizeLine
230
+ };
@@ -1,4 +1,4 @@
1
- const a = [
1
+ const COUNTRIES = [
2
2
  { iso2: "AF", name: "Afghanistan", dial: "93" },
3
3
  { iso2: "AL", name: "Albania", dial: "355" },
4
4
  { iso2: "DZ", name: "Algeria", dial: "213" },
@@ -199,5 +199,5 @@ const a = [
199
199
  { iso2: "ZW", name: "Zimbabwe", dial: "263" }
200
200
  ];
201
201
  export {
202
- a as COUNTRIES
202
+ COUNTRIES
203
203
  };
@@ -0,0 +1,38 @@
1
+ function flagEmoji(iso2) {
2
+ if (!/^[A-Za-z]{2}$/.test(iso2)) return "";
3
+ const base = 127462 - 65;
4
+ return String.fromCodePoint(
5
+ ...iso2.toUpperCase().split("").map((c) => base + c.charCodeAt(0))
6
+ );
7
+ }
8
+ let cache;
9
+ async function loadCountries() {
10
+ if (cache) return cache;
11
+ const mod = await import("./countries-data.js");
12
+ cache = mod.COUNTRIES;
13
+ return cache;
14
+ }
15
+ const PRIMARY_BY_DIAL = {
16
+ "1": "US",
17
+ "7": "RU",
18
+ "39": "IT"
19
+ };
20
+ function matchCountryByValue(value, list) {
21
+ const digits = value.replace(/[^\d]/g, "");
22
+ if (!digits) return void 0;
23
+ let best;
24
+ for (const c of list) {
25
+ if (!digits.startsWith(c.dial)) continue;
26
+ if (!best || c.dial.length > best.dial.length) {
27
+ best = c;
28
+ } else if (c.dial.length === best.dial.length && PRIMARY_BY_DIAL[c.dial] === c.iso2) {
29
+ best = c;
30
+ }
31
+ }
32
+ return best;
33
+ }
34
+ export {
35
+ flagEmoji,
36
+ loadCountries,
37
+ matchCountryByValue
38
+ };
@@ -0,0 +1,14 @@
1
+ const POPOVER_ANIM = "data-[state=open]:animate-[popover-in_140ms_var(--ease-emphasized)] data-[state=closed]:animate-[popover-out_120ms_ease] data-[side=top]:data-[state=open]:animate-[popover-in-up_140ms_var(--ease-emphasized)] data-[side=top]:data-[state=closed]:animate-[popover-out-up_120ms_ease]";
2
+ const TOOLTIP_ANIM = "data-[state=delayed-open]:animate-[popover-in_120ms_var(--ease-emphasized)] data-[state=closed]:animate-[popover-out_100ms_ease] data-[side=top]:data-[state=delayed-open]:animate-[popover-in-up_120ms_var(--ease-emphasized)] data-[side=top]:data-[state=closed]:animate-[popover-out-up_100ms_ease]";
3
+ const PANEL_SURFACE = "group rounded-control border border-line bg-surface-overlay shadow-panel backdrop-blur";
4
+ const POPOVER_PANEL = PANEL_SURFACE + " " + POPOVER_ANIM;
5
+ const OPTION_ITEM = "flex cursor-pointer items-center gap-2 rounded-md px-2.5 py-1.5 text-sm text-ink outline-none animate-[option-in_180ms_var(--ease-emphasized)_both] group-data-[side=top]:animate-[option-in-up_180ms_var(--ease-emphasized)_both] data-[highlighted]:bg-brand-soft data-[highlighted]:text-brand";
6
+ const CLOSE_ICON = "transition-transform duration-medium ease-[var(--ease-emphasized)] group-hover:rotate-90 group-active:scale-90 motion-reduce:group-hover:rotate-0";
7
+ export {
8
+ CLOSE_ICON,
9
+ OPTION_ITEM,
10
+ PANEL_SURFACE,
11
+ POPOVER_ANIM,
12
+ POPOVER_PANEL,
13
+ TOOLTIP_ANIM
14
+ };
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,44 @@
1
+ import { computed, toValue } from "vue";
2
+ function toAnchored(p) {
3
+ if (p instanceof RegExp) {
4
+ const src = p.source.replace(/^\^/, "").replace(/\$$/, "");
5
+ return new RegExp(`^(?:${src})$`, p.flags.replace(/[gy]/g, ""));
6
+ }
7
+ return new RegExp(`^(?:${p})$`);
8
+ }
9
+ function allAllowed(text, charRe) {
10
+ const re = new RegExp(charRe.source, charRe.flags.replace(/[gy]/g, ""));
11
+ for (const ch of text) {
12
+ if (!re.test(ch)) return false;
13
+ }
14
+ return true;
15
+ }
16
+ function useInputFilter(options = {}) {
17
+ const restrict = computed(() => toValue(options.restrict));
18
+ const patternRe = computed(() => {
19
+ const p = toValue(options.pattern);
20
+ return p === void 0 ? void 0 : toAnchored(p);
21
+ });
22
+ function isInvalid(value) {
23
+ const re = patternRe.value;
24
+ if (!re || !value) return false;
25
+ return !re.test(value);
26
+ }
27
+ function onBeforeInput(event) {
28
+ const re = restrict.value;
29
+ if (!re || event.isComposing) return;
30
+ const data = event.data;
31
+ if (data == null) return;
32
+ if (!allAllowed(data, re)) event.preventDefault();
33
+ }
34
+ function onPaste(event) {
35
+ const re = restrict.value;
36
+ if (!re) return;
37
+ const text = event.clipboardData?.getData("text") ?? "";
38
+ if (text && !allAllowed(text, re)) event.preventDefault();
39
+ }
40
+ return { isInvalid, onBeforeInput, onPaste, patternRe, restrict };
41
+ }
42
+ export {
43
+ useInputFilter
44
+ };
@@ -0,0 +1,11 @@
1
+ import { useReducedMotion } from "motion-v";
2
+ import { computed } from "vue";
3
+ function usePillTransition() {
4
+ const reduceMotion = useReducedMotion();
5
+ return computed(
6
+ () => reduceMotion.value ? { duration: 0 } : { type: "spring", stiffness: 520, damping: 40 }
7
+ );
8
+ }
9
+ export {
10
+ usePillTransition
11
+ };
@@ -0,0 +1,23 @@
1
+ import { ComputedRef, CSSProperties, Ref } from 'vue';
2
+ export interface UseTiltOptions {
3
+ /** Max rotation toward the pointer, in degrees (per axis). Default 10. */
4
+ max?: number;
5
+ /** Upward lift on hover, in px. Default 8. */
6
+ lift?: number;
7
+ /** Scale on hover. Default 1.03. */
8
+ scale?: number;
9
+ /** Glare highlight following the pointer. Default false. */
10
+ glare?: boolean;
11
+ }
12
+ export interface UseTilt {
13
+ /** Bind to the tilting element's style. */
14
+ style: ComputedRef<CSSProperties>;
15
+ /** Radial-gradient background for an optional glare overlay (0 when idle). */
16
+ glareStyle: ComputedRef<CSSProperties>;
17
+ onPointerMove: (e: PointerEvent) => void;
18
+ onPointerEnter: () => void;
19
+ onPointerLeave: () => void;
20
+ /** True while the pointer is over the element (drives lift/scale). */
21
+ active: Ref<boolean>;
22
+ }
23
+ export declare function useTilt(options?: UseTiltOptions): UseTilt;
@@ -0,0 +1,57 @@
1
+ import { useReducedMotion } from "motion-v";
2
+ import { ref, computed } from "vue";
3
+ function useTilt(options = {}) {
4
+ const max = options.max ?? 10;
5
+ const lift = options.lift ?? 8;
6
+ const scale = options.scale ?? 1.03;
7
+ const reduceMotion = useReducedMotion();
8
+ const active = ref(false);
9
+ const nx = ref(0);
10
+ const ny = ref(0);
11
+ function onPointerMove(e) {
12
+ if (reduceMotion.value) return;
13
+ const el = e.currentTarget;
14
+ if (!el) return;
15
+ const r = el.getBoundingClientRect();
16
+ nx.value = (e.clientX - r.left) / r.width * 2 - 1;
17
+ ny.value = (e.clientY - r.top) / r.height * 2 - 1;
18
+ }
19
+ function onPointerEnter() {
20
+ active.value = true;
21
+ }
22
+ function onPointerLeave() {
23
+ active.value = false;
24
+ nx.value = 0;
25
+ ny.value = 0;
26
+ }
27
+ const style = computed(() => {
28
+ if (reduceMotion.value) {
29
+ return { transition: "transform 0.2s ease" };
30
+ }
31
+ const rx = active.value ? -ny.value * max : 0;
32
+ const ry = active.value ? nx.value * max : 0;
33
+ const z = active.value ? lift : 0;
34
+ const s = active.value ? scale : 1;
35
+ return {
36
+ transform: `translate3d(0, ${-z}px, 0) rotateX(${rx}deg) rotateY(${ry}deg) scale(${s})`,
37
+ transformStyle: "preserve-3d",
38
+ transition: active.value ? "transform 0.12s ease-out" : "transform 0.5s cubic-bezier(0.22, 1, 0.36, 1)"
39
+ };
40
+ });
41
+ const glareStyle = computed(() => {
42
+ if (!options.glare || reduceMotion.value || !active.value) {
43
+ return { opacity: 0 };
44
+ }
45
+ const px = (nx.value + 1) * 50;
46
+ const py = (ny.value + 1) * 50;
47
+ return {
48
+ opacity: 1,
49
+ background: `radial-gradient(circle at ${px}% ${py}%, rgba(255,255,255,0.35), transparent 55%)`,
50
+ transition: "opacity 0.2s ease"
51
+ };
52
+ });
53
+ return { style, glareStyle, onPointerMove, onPointerEnter, onPointerLeave, active };
54
+ }
55
+ export {
56
+ useTilt
57
+ };
@@ -1,6 +1,8 @@
1
1
  export type ToastVariant = "info" | "success" | "warning" | "error";
2
2
  export interface ToastAction {
3
3
  label: string;
4
+ /** Optional leading icon (any name LpIcon accepts, e.g. "lucide:copy"). */
5
+ icon?: string;
4
6
  onClick: () => void | Promise<void>;
5
7
  }
6
8
  export interface ToastItem {
@@ -0,0 +1,49 @@
1
+ import { reactive } from "vue";
2
+ const DEFAULT_DURATION = 4500;
3
+ const MAX_ACTIVE = 4;
4
+ const STATE_KEY = /* @__PURE__ */ Symbol.for("@leavepulse/ui:toast-queue");
5
+ const g = globalThis;
6
+ const state = g[STATE_KEY] ??= { queue: reactive([]), nextId: 0 };
7
+ const queue = state.queue;
8
+ function push(variant, message, options = {}) {
9
+ const id = state.nextId++;
10
+ const duration = options.duration ?? DEFAULT_DURATION;
11
+ const item = {
12
+ id,
13
+ title: options.title,
14
+ message,
15
+ variant,
16
+ duration,
17
+ dismissAt: duration > 0 ? Date.now() + duration : null,
18
+ actions: options.actions,
19
+ onClick: options.onClick
20
+ };
21
+ const overflow = queue.length - (MAX_ACTIVE - 1);
22
+ if (overflow > 0) queue.splice(0, overflow);
23
+ queue.push(item);
24
+ return id;
25
+ }
26
+ function dismiss(id) {
27
+ const i = queue.findIndex((t) => t.id === id);
28
+ if (i !== -1) queue.splice(i, 1);
29
+ }
30
+ function clear() {
31
+ queue.splice(0, queue.length);
32
+ }
33
+ function useToast() {
34
+ return {
35
+ queue,
36
+ toast: (message, o) => push("info", message, o),
37
+ info: (message, o) => push("info", message, o),
38
+ success: (message, o) => push("success", message, o),
39
+ warning: (message, o) => push("warning", message, o),
40
+ error: (message, o) => push("error", message, o),
41
+ /** Low-level push for bridges (e.g. @leavepulse/ui-sdk apiError). */
42
+ push,
43
+ dismiss,
44
+ clear
45
+ };
46
+ }
47
+ export {
48
+ useToast
49
+ };
package/dist/index.d.ts CHANGED
@@ -72,6 +72,7 @@ export { default as LpTabs } from './components/LpTabs.vue';
72
72
  export type { TabItem } from './components/LpTabs.vue';
73
73
  export { default as LpTextarea } from './components/LpTextarea.vue';
74
74
  export { default as LpThemeSwitcher } from './components/LpThemeSwitcher.vue';
75
+ export { default as LpTilt } from './components/LpTilt.vue';
75
76
  export { default as LpToaster } from './components/LpToaster.vue';
76
77
  export { default as LpTooltip } from './components/LpTooltip.vue';
77
78
  export { default as LpTopologyCanvas } from './components/LpTopologyCanvas.vue';
@@ -96,5 +97,7 @@ export { parseConfig, serializeConfig, UI_CONFIG_VERSION } from './theme/config'
96
97
  export type { UiConfig } from './theme/config';
97
98
  export { useInputFilter } from './composables/useInputFilter';
98
99
  export type { UseInputFilterOptions } from './composables/useInputFilter';
100
+ export { useTilt } from './composables/useTilt';
101
+ export type { UseTilt, UseTiltOptions } from './composables/useTilt';
99
102
  export { useToast } from './composables/useToast';
100
103
  export type { ToastAction, ToastItem, ToastOptions, ToastVariant, } from './composables/useToast';