le-kit 0.1.4 → 0.1.5

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 (198) hide show
  1. package/dist/le-kit/assets/custom-elements.json +4305 -0
  2. package/dist/le-kit/index-Da-89pOc.js +4522 -0
  3. package/dist/le-kit/{index-D21JjI31.js.map → index-Da-89pOc.js.map} +1 -1
  4. package/dist/le-kit/index.esm.js +116 -2
  5. package/dist/le-kit/index.esm.js.map +1 -1
  6. package/dist/{esm → le-kit}/le-box.entry.js +3 -3
  7. package/dist/le-kit/le-button.entry.esm.js.map +1 -0
  8. package/dist/le-kit/le-button.entry.js +90 -0
  9. package/dist/{esm → le-kit}/le-card.entry.js +3 -3
  10. package/dist/le-kit/le-checkbox.entry.esm.js.map +1 -0
  11. package/dist/le-kit/le-checkbox.entry.js +59 -0
  12. package/dist/le-kit/le-component.entry.esm.js.map +1 -0
  13. package/dist/{collection/components/le-component/le-component.js → le-kit/le-component.entry.js} +19 -134
  14. package/dist/le-kit/le-kit.css +1010 -1
  15. package/dist/le-kit/le-kit.esm.js +48 -2
  16. package/dist/le-kit/le-kit.esm.js.map +1 -1
  17. package/dist/{esm → le-kit}/le-number-input.entry.js +5 -5
  18. package/dist/le-kit/le-popover.entry.esm.js.map +1 -0
  19. package/dist/{components/le-popover2.js → le-kit/le-popover.entry.js} +9 -45
  20. package/dist/{esm → le-kit}/le-popup.entry.js +6 -6
  21. package/dist/{esm → le-kit}/le-round-progress.entry.js +2 -2
  22. package/dist/le-kit/le-slot.entry.esm.js.map +1 -0
  23. package/dist/{collection/components/le-slot/le-slot.js → le-kit/le-slot.entry.js} +30 -279
  24. package/dist/{esm → le-kit}/le-stack.entry.js +3 -3
  25. package/dist/le-kit/le-string-input.entry.esm.js.map +1 -0
  26. package/dist/le-kit/le-string-input.entry.js +93 -0
  27. package/dist/{esm → le-kit}/le-text.entry.js +3 -3
  28. package/dist/{esm → le-kit}/le-turntable.entry.js +2 -2
  29. package/dist/{esm/utils-CJLZrrdC.js → le-kit/utils-FDOApZ53.js} +3 -3
  30. package/dist/le-kit/{utils-apol-Xc_.js.map → utils-FDOApZ53.js.map} +1 -1
  31. package/package.json +1 -1
  32. package/dist/cjs/index-CO4npcak.js +0 -1796
  33. package/dist/cjs/index-CO4npcak.js.map +0 -1
  34. package/dist/cjs/index.cjs.js +0 -117
  35. package/dist/cjs/index.cjs.js.map +0 -1
  36. package/dist/cjs/le-box.cjs.entry.js +0 -184
  37. package/dist/cjs/le-box.entry.cjs.js.map +0 -1
  38. package/dist/cjs/le-button.le-checkbox.le-component.le-popover.le-slot.le-string-input.entry.cjs.js.map +0 -1
  39. package/dist/cjs/le-button_6.cjs.entry.js +0 -1199
  40. package/dist/cjs/le-card.cjs.entry.js +0 -29
  41. package/dist/cjs/le-card.entry.cjs.js.map +0 -1
  42. package/dist/cjs/le-kit.cjs.js +0 -25
  43. package/dist/cjs/le-kit.cjs.js.map +0 -1
  44. package/dist/cjs/le-number-input.cjs.entry.js +0 -202
  45. package/dist/cjs/le-number-input.entry.cjs.js.map +0 -1
  46. package/dist/cjs/le-popup.cjs.entry.js +0 -212
  47. package/dist/cjs/le-popup.entry.cjs.js.map +0 -1
  48. package/dist/cjs/le-round-progress.cjs.entry.js +0 -106
  49. package/dist/cjs/le-round-progress.entry.cjs.js.map +0 -1
  50. package/dist/cjs/le-stack.cjs.entry.js +0 -135
  51. package/dist/cjs/le-stack.entry.cjs.js.map +0 -1
  52. package/dist/cjs/le-text.cjs.entry.js +0 -335
  53. package/dist/cjs/le-text.entry.cjs.js.map +0 -1
  54. package/dist/cjs/le-turntable.cjs.entry.js +0 -139
  55. package/dist/cjs/le-turntable.entry.cjs.js.map +0 -1
  56. package/dist/cjs/loader.cjs.js +0 -13
  57. package/dist/cjs/loader.cjs.js.map +0 -1
  58. package/dist/cjs/utils-BeT0iyCQ.js +0 -152
  59. package/dist/cjs/utils-BeT0iyCQ.js.map +0 -1
  60. package/dist/collection/collection-manifest.json +0 -26
  61. package/dist/collection/components/le-box/le-box.default.css +0 -37
  62. package/dist/collection/components/le-box/le-box.js +0 -614
  63. package/dist/collection/components/le-box/le-box.js.map +0 -1
  64. package/dist/collection/components/le-button/le-button.default.css +0 -263
  65. package/dist/collection/components/le-button/le-button.js +0 -368
  66. package/dist/collection/components/le-button/le-button.js.map +0 -1
  67. package/dist/collection/components/le-card/le-card.default.css +0 -74
  68. package/dist/collection/components/le-card/le-card.js +0 -102
  69. package/dist/collection/components/le-card/le-card.js.map +0 -1
  70. package/dist/collection/components/le-checkbox/le-checkbox.css +0 -93
  71. package/dist/collection/components/le-checkbox/le-checkbox.js +0 -192
  72. package/dist/collection/components/le-checkbox/le-checkbox.js.map +0 -1
  73. package/dist/collection/components/le-component/le-component.css +0 -189
  74. package/dist/collection/components/le-component/le-component.js.map +0 -1
  75. package/dist/collection/components/le-number-input/le-number-input.css +0 -135
  76. package/dist/collection/components/le-number-input/le-number-input.js +0 -515
  77. package/dist/collection/components/le-number-input/le-number-input.js.map +0 -1
  78. package/dist/collection/components/le-popover/le-popover.css +0 -143
  79. package/dist/collection/components/le-popover/le-popover.js +0 -693
  80. package/dist/collection/components/le-popover/le-popover.js.map +0 -1
  81. package/dist/collection/components/le-popup/le-popup.api.js +0 -101
  82. package/dist/collection/components/le-popup/le-popup.api.js.map +0 -1
  83. package/dist/collection/components/le-popup/le-popup.css +0 -222
  84. package/dist/collection/components/le-popup/le-popup.js +0 -596
  85. package/dist/collection/components/le-popup/le-popup.js.map +0 -1
  86. package/dist/collection/components/le-round-progress/le-round-progress.css +0 -34
  87. package/dist/collection/components/le-round-progress/le-round-progress.js +0 -184
  88. package/dist/collection/components/le-round-progress/le-round-progress.js.map +0 -1
  89. package/dist/collection/components/le-slot/le-slot.default.css +0 -222
  90. package/dist/collection/components/le-slot/le-slot.js.map +0 -1
  91. package/dist/collection/components/le-stack/le-stack.default.css +0 -37
  92. package/dist/collection/components/le-stack/le-stack.js +0 -389
  93. package/dist/collection/components/le-stack/le-stack.js.map +0 -1
  94. package/dist/collection/components/le-string-input/le-string-input.css +0 -83
  95. package/dist/collection/components/le-string-input/le-string-input.js +0 -359
  96. package/dist/collection/components/le-string-input/le-string-input.js.map +0 -1
  97. package/dist/collection/components/le-text/le-text.default.css +0 -169
  98. package/dist/collection/components/le-text/le-text.js +0 -475
  99. package/dist/collection/components/le-text/le-text.js.map +0 -1
  100. package/dist/collection/components/le-turntable/le-turntable.css +0 -10
  101. package/dist/collection/components/le-turntable/le-turntable.js +0 -210
  102. package/dist/collection/components/le-turntable/le-turntable.js.map +0 -1
  103. package/dist/collection/global/app.js +0 -130
  104. package/dist/collection/global/app.js.map +0 -1
  105. package/dist/collection/index.js +0 -15
  106. package/dist/collection/index.js.map +0 -1
  107. package/dist/collection/types/blocks.js +0 -115
  108. package/dist/collection/types/blocks.js.map +0 -1
  109. package/dist/collection/types/options.js +0 -2
  110. package/dist/collection/types/options.js.map +0 -1
  111. package/dist/collection/utils/utils.js +0 -141
  112. package/dist/collection/utils/utils.js.map +0 -1
  113. package/dist/components/index.js +0 -127
  114. package/dist/components/index.js.map +0 -1
  115. package/dist/components/le-box.js +0 -256
  116. package/dist/components/le-box.js.map +0 -1
  117. package/dist/components/le-button.js +0 -9
  118. package/dist/components/le-button.js.map +0 -1
  119. package/dist/components/le-button2.js +0 -1408
  120. package/dist/components/le-button2.js.map +0 -1
  121. package/dist/components/le-card.js +0 -83
  122. package/dist/components/le-card.js.map +0 -1
  123. package/dist/components/le-checkbox.js +0 -9
  124. package/dist/components/le-checkbox.js.map +0 -1
  125. package/dist/components/le-component.js +0 -9
  126. package/dist/components/le-component.js.map +0 -1
  127. package/dist/components/le-number-input.js +0 -271
  128. package/dist/components/le-number-input.js.map +0 -1
  129. package/dist/components/le-popover.js +0 -9
  130. package/dist/components/le-popover.js.map +0 -1
  131. package/dist/components/le-popover2.js.map +0 -1
  132. package/dist/components/le-popup.js +0 -279
  133. package/dist/components/le-popup.js.map +0 -1
  134. package/dist/components/le-round-progress.js +0 -135
  135. package/dist/components/le-round-progress.js.map +0 -1
  136. package/dist/components/le-slot.js +0 -9
  137. package/dist/components/le-slot.js.map +0 -1
  138. package/dist/components/le-stack.js +0 -198
  139. package/dist/components/le-stack.js.map +0 -1
  140. package/dist/components/le-string-input.js +0 -9
  141. package/dist/components/le-string-input.js.map +0 -1
  142. package/dist/components/le-text.js +0 -398
  143. package/dist/components/le-text.js.map +0 -1
  144. package/dist/components/le-turntable.js +0 -164
  145. package/dist/components/le-turntable.js.map +0 -1
  146. package/dist/docs.d.ts +0 -443
  147. package/dist/docs.json +0 -5185
  148. package/dist/esm/index-D71TXvJa.js +0 -1781
  149. package/dist/esm/index-D71TXvJa.js.map +0 -1
  150. package/dist/esm/index.js +0 -106
  151. package/dist/esm/index.js.map +0 -1
  152. package/dist/esm/le-box.entry.js.map +0 -1
  153. package/dist/esm/le-button.le-checkbox.le-component.le-popover.le-slot.le-string-input.entry.js.map +0 -1
  154. package/dist/esm/le-button_6.entry.js +0 -1192
  155. package/dist/esm/le-card.entry.js.map +0 -1
  156. package/dist/esm/le-kit.js +0 -21
  157. package/dist/esm/le-kit.js.map +0 -1
  158. package/dist/esm/le-number-input.entry.js.map +0 -1
  159. package/dist/esm/le-popup.entry.js.map +0 -1
  160. package/dist/esm/le-round-progress.entry.js.map +0 -1
  161. package/dist/esm/le-stack.entry.js.map +0 -1
  162. package/dist/esm/le-text.entry.js.map +0 -1
  163. package/dist/esm/le-turntable.entry.js.map +0 -1
  164. package/dist/esm/loader.js +0 -11
  165. package/dist/esm/loader.js.map +0 -1
  166. package/dist/esm/utils-CJLZrrdC.js.map +0 -1
  167. package/dist/index.cjs.js +0 -1
  168. package/dist/index.js +0 -1
  169. package/dist/le-kit/le-button.le-checkbox.le-component.le-popover.le-slot.le-string-input.entry.esm.js.map +0 -1
  170. package/dist/le-kit/p-024a764e.entry.js +0 -2
  171. package/dist/le-kit/p-024a764e.entry.js.map +0 -1
  172. package/dist/le-kit/p-073cf0b9.entry.js +0 -2
  173. package/dist/le-kit/p-073cf0b9.entry.js.map +0 -1
  174. package/dist/le-kit/p-0955b105.entry.js +0 -2
  175. package/dist/le-kit/p-0955b105.entry.js.map +0 -1
  176. package/dist/le-kit/p-18d79ee2.entry.js +0 -2
  177. package/dist/le-kit/p-18d79ee2.entry.js.map +0 -1
  178. package/dist/le-kit/p-4b1d3b6d.entry.js +0 -2
  179. package/dist/le-kit/p-4b1d3b6d.entry.js.map +0 -1
  180. package/dist/le-kit/p-79d179bd.entry.js +0 -2
  181. package/dist/le-kit/p-79d179bd.entry.js.map +0 -1
  182. package/dist/le-kit/p-D71TXvJa.js +0 -3
  183. package/dist/le-kit/p-D71TXvJa.js.map +0 -1
  184. package/dist/le-kit/p-c8a9288e.entry.js +0 -2
  185. package/dist/le-kit/p-c8a9288e.entry.js.map +0 -1
  186. package/dist/le-kit/p-cfc35bd3.entry.js +0 -2
  187. package/dist/le-kit/p-cfc35bd3.entry.js.map +0 -1
  188. package/dist/le-kit/p-d04da1f5.entry.js +0 -2
  189. package/dist/le-kit/p-d04da1f5.entry.js.map +0 -1
  190. package/dist/le-kit/p-qIai5-eB.js +0 -2
  191. package/dist/le-kit/p-qIai5-eB.js.map +0 -1
  192. package/dist/themes/base.css +0 -89
  193. package/dist/themes/dark.css +0 -100
  194. package/dist/themes/default.css +0 -108
  195. package/dist/themes/gradient.css +0 -100
  196. package/dist/themes/index.css +0 -413
  197. package/dist/themes/minimal.css +0 -100
  198. package/dist/themes/warm.css +0 -100
@@ -1,1408 +0,0 @@
1
- import { setMode, proxyCustomElement, HTMLElement, createEvent, h, Host, Fragment } from '@stencil/core/internal/client';
2
- import { d as defineCustomElement$5 } from './le-popover2.js';
3
-
4
- /**
5
- * Global mode initialization for le-kit components.
6
- *
7
- * Mode inheritance works as follows:
8
- * 1. Check the element's own `mode` attribute
9
- * 2. Traverse up the DOM to find a parent with `mode` attribute
10
- * 3. Check the document root element (html) for `mode` attribute
11
- * 4. Fall back to 'default'
12
- *
13
- * This allows setting mode at any level:
14
- * - `<html mode="admin">` - all components in admin mode
15
- * - `<le-card mode="admin">` - this card and its children in admin mode
16
- */
17
- function initializeMode() {
18
- setMode((el) => {
19
- // 1. Check element's own mode attribute
20
- const ownMode = el.getAttribute('mode');
21
- if (ownMode) {
22
- return ownMode;
23
- }
24
- // 2. Traverse up the DOM tree to find inherited mode
25
- let parent = el.parentElement;
26
- while (parent) {
27
- const parentMode = parent.getAttribute('mode');
28
- if (parentMode) {
29
- return parentMode;
30
- }
31
- parent = parent.parentElement;
32
- }
33
- // 3. Check document root element
34
- const rootMode = document.documentElement.getAttribute('mode');
35
- if (rootMode) {
36
- return rootMode;
37
- }
38
- // 4. Default mode
39
- return 'default';
40
- });
41
- }
42
- /**
43
- * Helper function to get the current mode for an element.
44
- * Can be used programmatically in components.
45
- *
46
- * This function traverses both regular DOM and shadow DOM boundaries
47
- * to find the nearest mode attribute.
48
- */
49
- function getMode(el) {
50
- // Check element's own mode
51
- const ownMode = el.getAttribute('mode');
52
- if (ownMode) {
53
- return ownMode;
54
- }
55
- // Traverse up DOM, crossing shadow boundaries
56
- let current = el;
57
- while (current) {
58
- // Try parent element first
59
- if (current instanceof Element && current.parentElement) {
60
- current = current.parentElement;
61
- const mode = current.getAttribute?.('mode');
62
- if (mode) {
63
- return mode;
64
- }
65
- }
66
- else {
67
- // No parent element - check if we're in a shadow root
68
- const root = current.getRootNode();
69
- if (root instanceof ShadowRoot) {
70
- // Cross the shadow boundary to the host element
71
- current = root.host;
72
- const mode = current.getAttribute?.('mode');
73
- if (mode) {
74
- return mode;
75
- }
76
- }
77
- else {
78
- // We've reached the document root
79
- break;
80
- }
81
- }
82
- }
83
- // Check document root
84
- const rootMode = document.documentElement.getAttribute('mode');
85
- if (rootMode) {
86
- return rootMode;
87
- }
88
- return 'default';
89
- }
90
- /**
91
- * Helper function to get the current theme for an element.
92
- * Theme inheritance works the same as mode - cascades through DOM.
93
- */
94
- function getTheme(el) {
95
- // Check element's own theme
96
- const ownTheme = el.getAttribute('theme');
97
- if (ownTheme) {
98
- return ownTheme;
99
- }
100
- // Traverse up DOM
101
- let parent = el.parentElement;
102
- while (parent) {
103
- const parentTheme = parent.getAttribute('theme');
104
- if (parentTheme) {
105
- return parentTheme;
106
- }
107
- parent = parent.parentElement;
108
- }
109
- // Check root
110
- const rootTheme = document.documentElement.getAttribute('theme');
111
- if (rootTheme) {
112
- return rootTheme;
113
- }
114
- return 'default';
115
- }
116
- /**
117
- * Helper function to set mode on the document root.
118
- * Useful for switching all components to admin mode.
119
- */
120
- function setGlobalMode(mode) {
121
- document.documentElement.setAttribute('mode', mode);
122
- }
123
- /**
124
- * Helper function to set theme on the document root.
125
- * Useful for switching all components to a different theme.
126
- */
127
- function setGlobalTheme(theme) {
128
- document.documentElement.setAttribute('theme', theme);
129
- }
130
-
131
- /**
132
- * Utility functions for le-kit components
133
- */
134
- /**
135
- * Generates a unique ID for component instances
136
- */
137
- function generateId(prefix = 'le') {
138
- return `${prefix}-${Math.random().toString(36).substring(2, 9)}`;
139
- }
140
- /**
141
- * Parses a comma-separated string into an array
142
- */
143
- function parseCommaSeparated(value) {
144
- if (!value)
145
- return [];
146
- return value
147
- .split(',')
148
- .map(s => s.trim())
149
- .filter(Boolean);
150
- }
151
- /**
152
- * Checks if a slot has content
153
- */
154
- function slotHasContent(el, slotName = '') {
155
- const selector = slotName ? `[slot="${slotName}"]` : ':not([slot])';
156
- return el.querySelector(selector) !== null;
157
- }
158
- /**
159
- * Sets up a MutationObserver to track mode changes on ancestor elements.
160
- * Returns a cleanup function to disconnect the observer.
161
- *
162
- * If the element or any ancestor has an explicit `mode` attribute, that creates
163
- * a "mode boundary" - the mode is determined from that point, not from further up.
164
- * This allows components like le-popover to force default mode for their children.
165
- *
166
- * @param el - The component's host element
167
- * @param callback - Function to call when mode changes, receives the new mode
168
- * @returns Cleanup function to disconnect the observer
169
- *
170
- * @example
171
- * ```tsx
172
- * export class MyComponent {
173
- * @Element() el: HTMLElement;
174
- * @State() adminMode: boolean = false;
175
- * private disconnectModeObserver?: () => void;
176
- *
177
- * connectedCallback() {
178
- * this.disconnectModeObserver = observeModeChanges(this.el, (mode) => {
179
- * this.adminMode = mode === 'admin';
180
- * });
181
- * }
182
- *
183
- * disconnectedCallback() {
184
- * this.disconnectModeObserver?.();
185
- * }
186
- * }
187
- * ```
188
- */
189
- function observeModeChanges(el, callback) {
190
- // Call immediately with current mode
191
- callback(getMode(el));
192
- // Set up observer for mode attribute changes
193
- const observer = new MutationObserver(() => {
194
- callback(getMode(el));
195
- });
196
- // Observe the element itself (for mode boundary changes)
197
- observer.observe(el, {
198
- attributes: true,
199
- attributeFilter: ['mode'],
200
- });
201
- // Observe document root
202
- observer.observe(document.documentElement, {
203
- attributes: true,
204
- attributeFilter: ['mode'],
205
- });
206
- // Traverse up, crossing shadow boundaries, and observe each element
207
- let current = el;
208
- while (current) {
209
- if (current instanceof Element && current.parentElement) {
210
- current = current.parentElement;
211
- observer.observe(current, {
212
- attributes: true,
213
- attributeFilter: ['mode'],
214
- });
215
- // If this element has an explicit mode, it's a boundary
216
- if (current.hasAttribute('mode')) {
217
- break;
218
- }
219
- }
220
- else {
221
- // Check if we're in a shadow root
222
- const root = current.getRootNode();
223
- if (root instanceof ShadowRoot) {
224
- // Cross the shadow boundary and observe the host
225
- current = root.host;
226
- observer.observe(current, {
227
- attributes: true,
228
- attributeFilter: ['mode'],
229
- });
230
- // If the host has an explicit mode, it's a boundary
231
- if (current.hasAttribute('mode')) {
232
- break;
233
- }
234
- }
235
- else {
236
- break;
237
- }
238
- }
239
- }
240
- // Return cleanup function
241
- return () => observer.disconnect();
242
- }
243
- /**
244
- * Combines multiple class names into a single string, filtering out falsy values.
245
- *
246
- * @param classes - arguments of class names, undefined, arrays, objects with boolean values and nested combinations of these
247
- * @returns Combined class names string
248
- */
249
- function classnames(...classes) {
250
- const result = [];
251
- classes.forEach(cls => {
252
- if (!cls)
253
- return;
254
- if (typeof cls === 'string') {
255
- result.push(cls);
256
- }
257
- else if (Array.isArray(cls)) {
258
- result.push(classnames(...cls));
259
- }
260
- else if (typeof cls === 'object') {
261
- Object.entries(cls).forEach(([key, value]) => {
262
- if (value) {
263
- result.push(key);
264
- }
265
- });
266
- }
267
- });
268
- return result.join(' ');
269
- }
270
-
271
- const leStringInputCss = ":host{display:block;--le-input-bg:var(--le-color-surface, #ffffff);--le-input-color:var(--le-color-text-primary, #333333);--le-input-border:var(--le-border-width, 2px) solid var(--le-color-border-input, #007bff);--le-input-radius:var(--le-radius-sm, 4px);--le-input-padding:2px 6px;--le-input-height:1.5rem;--le-input-label-color:var(--le-color-text-primary, #333333);--le-input-desc-color:var(--le-color-text-secondary, #666666);--le-input-placeholder-color:#999999}.le-input-wrapper{display:flex;flex-direction:column;gap:2px}.le-input-label{display:block;font-size:0.9em;font-weight:500;color:var(--le-input-label-color);margin-bottom:2px}.le-input-container{position:relative;display:flex;align-items:center;background:var(--le-input-bg);border:var(--le-input-border);border-radius:var(--le-input-radius);transition:border-color 0.2s}.le-input-container:focus-within{outline:2px solid var(--le-color-focus);outline-offset:2px}:host([disabled]) .le-input-container{opacity:0.6;background-color:rgba(0,0,0,0.05);cursor:not-allowed}input{flex:1;min-height:var(--le-input-height);padding:var(--le-input-padding);border:none;background:transparent;color:var(--le-input-color);font-family:inherit;font-size:inherit;outline:none;width:100%}input::placeholder{color:var(--le-input-placeholder-color)}.icon-start,.icon-end{display:flex;align-items:center;justify-content:center;padding:0 8px;color:var(--le-input-desc-color)}.le-input-description{font-size:0.85em;color:var(--le-input-desc-color);margin-top:2px}.le-input-description::has(le-slot>slot[name=description]:empty){display:none}";
272
-
273
- const LeStringInput = /*@__PURE__*/ proxyCustomElement(class LeStringInput extends HTMLElement {
274
- constructor(registerHost) {
275
- super();
276
- if (registerHost !== false) {
277
- this.__registerHost();
278
- }
279
- this.__attachShadow();
280
- this.leChange = createEvent(this, "change", 7);
281
- this.leInput = createEvent(this, "input", 7);
282
- }
283
- get el() { return this; }
284
- /**
285
- * Mode of the popover should be 'default' for internal use
286
- */
287
- mode;
288
- /**
289
- * The value of the input
290
- */
291
- value;
292
- /**
293
- * The name of the input
294
- */
295
- name;
296
- /**
297
- * The type of the input (text, email, password, etc.)
298
- */
299
- type = 'text';
300
- /**
301
- * Label for the input
302
- */
303
- label;
304
- /**
305
- * Icon for the start icon
306
- */
307
- iconStart;
308
- /**
309
- * Icon for the end icon
310
- */
311
- iconEnd;
312
- /**
313
- * Placeholder text
314
- */
315
- placeholder;
316
- /**
317
- * Whether the input is disabled
318
- */
319
- disabled = false;
320
- /**
321
- * Whether the input is read-only
322
- */
323
- readonly = false;
324
- /**
325
- * External ID for linking with external systems
326
- */
327
- externalId;
328
- /**
329
- * Emitted when the value changes (on blur or Enter)
330
- */
331
- leChange;
332
- /**
333
- * Emitted when the input value changes (on keystroke)
334
- */
335
- leInput;
336
- handleInput = (ev) => {
337
- const input = ev.target;
338
- this.value = input.value;
339
- this.leInput.emit({
340
- value: this.value,
341
- name: this.name,
342
- externalId: this.externalId
343
- });
344
- };
345
- handleChange = (ev) => {
346
- const input = ev.target;
347
- this.value = input.value;
348
- this.leChange.emit({
349
- value: this.value,
350
- name: this.name,
351
- externalId: this.externalId
352
- });
353
- };
354
- handleClick = (ev) => {
355
- ev.stopPropagation();
356
- };
357
- render() {
358
- return (h("le-component", { key: 'd0c69370dae2d1fee5700954e4823d2a03a51331', component: "le-string-input", hostClass: classnames({ 'disabled': this.disabled }) }, h("div", { key: '4acae8d3c34da2a86970a616c493ff210d561f5f', class: "le-input-wrapper" }, this.label && (h("label", { key: '609191b45187b6b1a65d05cd594b149760ac6882', class: "le-input-label", htmlFor: this.name }, this.label)), h("div", { key: '36b4caff4468ac7421db03f811cb3ef4a622b001', class: "le-input-container" }, this.iconStart && (h("span", { key: '344f88887fe8270bbef7e26ec1ad5da9fae1f8e4', class: "icon-start" }, this.iconStart)), h("input", { key: '4ba7beeddd7fb3cf23d03e029d11a804764cdd6e', id: this.name, type: this.type, name: this.name, value: this.value, placeholder: this.placeholder, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInput, onChange: this.handleChange, onClick: this.handleClick }), this.iconEnd && (h("span", { key: '7cdd4b52c3e1a1b18b19e697bdb42431941bba01', class: "icon-end" }, this.iconEnd))), h("div", { key: '113a75aa413e4d95300aeaa97d1ce7a75cf68c7a', class: "le-input-description" }, h("le-slot", { key: '0b37fc14e6df68f6c44cf9001d63a70f019e1cc3', name: "description", type: "text", tag: "p", label: "Description" }, h("slot", { key: '2674056dc915fabdb4fcbcaa13294a116b9509a6', name: "description" }))))));
359
- }
360
- static get style() { return leStringInputCss; }
361
- }, [769, "le-string-input", {
362
- "mode": [1537],
363
- "value": [1537],
364
- "name": [1],
365
- "type": [1],
366
- "label": [1],
367
- "iconStart": [1, "icon-start"],
368
- "iconEnd": [1, "icon-end"],
369
- "placeholder": [1],
370
- "disabled": [4],
371
- "readonly": [4],
372
- "externalId": [1, "external-id"]
373
- }]);
374
- function defineCustomElement$4() {
375
- if (typeof customElements === "undefined") {
376
- return;
377
- }
378
- const components = ["le-string-input", "le-button", "le-checkbox", "le-component", "le-popover", "le-slot", "le-string-input"];
379
- components.forEach(tagName => { switch (tagName) {
380
- case "le-string-input":
381
- if (!customElements.get(tagName)) {
382
- customElements.define(tagName, LeStringInput);
383
- }
384
- break;
385
- case "le-button":
386
- if (!customElements.get(tagName)) {
387
- defineCustomElement();
388
- }
389
- break;
390
- case "le-checkbox":
391
- if (!customElements.get(tagName)) {
392
- defineCustomElement$1();
393
- }
394
- break;
395
- case "le-component":
396
- if (!customElements.get(tagName)) {
397
- defineCustomElement$2();
398
- }
399
- break;
400
- case "le-popover":
401
- if (!customElements.get(tagName)) {
402
- defineCustomElement$5();
403
- }
404
- break;
405
- case "le-slot":
406
- if (!customElements.get(tagName)) {
407
- defineCustomElement$3();
408
- }
409
- break;
410
- case "le-string-input":
411
- if (!customElements.get(tagName)) {
412
- defineCustomElement$4();
413
- }
414
- break;
415
- } });
416
- }
417
-
418
- const leSlotDefaultCss = ":host{display:contents;--le-slot-border-color:#0088ff;--le-slot-bg-color:rgba(0, 136, 255, 0.05);--le-slot-header-bg:rgb(218, 238, 255);--le-slot-label-color:#0066cc;--le-slot-description-color:#666;--le-slot-required-color:#e53935;--le-slot-dropzone-min-height:20px;--le-slot-dropzone-border-color:#ccc}.le-slot-container,.le-slot-header,.le-slot-description,.le-slot-dropzone,.le-slot-input{display:none}.hidden-slot{display:none}:host(.admin-mode){display:block;flex:1}:host(.admin-mode) .le-slot-container{position:relative;display:flex;flex-direction:column;border:2px dashed var(--le-slot-border-color);border-radius:4px;background:var(--le-slot-bg-color);margin:4px 0}:host(.admin-mode) .le-slot-header{display:flex;align-items:center;gap:4px;padding:0 0 0 var(--le-spacing-1, 4px);background:var(--le-slot-header-bg);border-bottom:1px solid var(--le-slot-border-color);font-size:var(--le-font-size-xs, 11px);font-weight:400;text-transform:capitalize}:host(.admin-mode) .le-slot-header-no-label{justify-content:flex-end;height:16px;border:none;background-color:transparent}.le-slot-label{color:var(--le-slot-label-color);text-align:start;overflow:hidden;width:0;flex:1 1 0%}.le-slot-required{color:var(--le-slot-required-color);font-weight:bold}:host(.admin-mode) .le-slot-description{display:block;padding:4px 8px;font-size:12px;color:var(--le-slot-description-color);font-style:italic}:host(.admin-mode) .le-slot-description-icon{display:inline-block;font-size:9px;line-height:1;cursor:pointer;color:var(--le-slot-description-color)}:host(.admin-mode) .le-slot-dropzone{display:block;min-height:var(--le-slot-dropzone-min-height);padding:var(--le-spacing-1, 4px);position:relative}:host(.admin-mode) .le-slot-dropzone:empty::before{content:'Drop content here';display:flex;align-items:center;justify-content:center;position:absolute;inset:8px;border:2px dashed var(--le-slot-dropzone-border-color);border-radius:4px;color:#999;font-size:12px;pointer-events:none}:host(.admin-mode.drag-over) .le-slot-container{border-color:#00cc66;background:rgba(0, 204, 102, 0.1)}:host(.admin-mode.drag-over) .le-slot-dropzone:empty::before{border-color:#00cc66;color:#00cc66;content:'Release to drop'}:host(.admin-mode) .le-slot-input{display:block;padding:var(--le-spacing-1, 4px)}:host(.admin-mode) .le-slot-input input,:host(.admin-mode) .le-slot-input textarea{display:block;width:100%;padding:8px 10px;border:1px solid var(--le-slot-dropzone-border-color);border-radius:4px;font-family:inherit;font-size:14px;line-height:1.4;background:#fff;color:#333;box-sizing:border-box;transition:border-color 0.2s, box-shadow 0.2s}:host(.admin-mode) .le-slot-input input:focus,:host(.admin-mode) .le-slot-input textarea:focus{outline:none;border-color:var(--le-slot-border-color);box-shadow:0 0 0 3px rgba(0, 136, 255, 0.15)}:host(.admin-mode) .le-slot-input input::placeholder,:host(.admin-mode) .le-slot-input textarea::placeholder{color:#999}:host(.admin-mode) .le-slot-input textarea{resize:vertical;min-height:60px}:host(.admin-mode) .le-slot-input slot{display:none}.le-slot-invalid{color:var(--le-slot-required-color);font-size:10px;margin-left:auto;font-weight:normal;text-transform:none}:host(.admin-mode) .le-slot-input.has-error input,:host(.admin-mode) .le-slot-input.has-error textarea{border-color:var(--le-slot-required-color);background:rgba(229, 57, 53, 0.05)}:host(.admin-mode) .le-slot-input.has-error input:focus,:host(.admin-mode) .le-slot-input.has-error textarea:focus{border-color:var(--le-slot-required-color);box-shadow:0 0 0 3px rgba(229, 57, 53, 0.15)}.le-slot-add-btn{font-size:24px;line-height:0px;width:12px;height:12px}.le-slot-header-no-label .le-slot-add-btn{font-size:16px}.le-slot-button{width:20px;height:20px}:host(.admin-mode) .le-slot-header-no-label.le-slot-header-text{height:0}";
419
-
420
- const LeSlot = /*@__PURE__*/ proxyCustomElement(class LeSlot extends HTMLElement {
421
- constructor(registerHost) {
422
- super();
423
- if (registerHost !== false) {
424
- this.__registerHost();
425
- }
426
- this.__attachShadow();
427
- this.leSlotChange = createEvent(this, "leSlotChange", 7);
428
- }
429
- get el() { return this; }
430
- /**
431
- * The type of slot content.
432
- * - `slot`: Default, shows a dropzone for components (default)
433
- * - `text`: Shows a single-line text input
434
- * - `textarea`: Shows a multi-line text area
435
- */
436
- type = 'slot';
437
- /**
438
- * The name of the slot this placeholder represents.
439
- * Should match the slot name in the parent component.
440
- */
441
- name = '';
442
- /**
443
- * Label to display in admin mode.
444
- * If not provided, the slot name will be used.
445
- */
446
- label;
447
- /**
448
- * Description of what content this slot accepts.
449
- * Shown in admin mode to guide content editors.
450
- */
451
- description;
452
- /**
453
- * Comma-separated list of allowed component tags for this slot.
454
- * Used by CMS to filter available components.
455
- *
456
- * @example "le-card,le-button,le-text"
457
- */
458
- allowedComponents;
459
- /**
460
- * Whether multiple components can be dropped in this slot.
461
- */
462
- multiple = true;
463
- /**
464
- * Whether this slot is required to have content.
465
- */
466
- required = false;
467
- /**
468
- * Placeholder text for text/textarea inputs in admin mode.
469
- */
470
- placeholder;
471
- /**
472
- * The HTML tag to create when there's no slotted element.
473
- * Used with type="text" or type="textarea" to auto-create elements.
474
- *
475
- * @example "h3" - creates <h3 slot="header">content</h3>
476
- * @example "p" - creates <p slot="content">content</p>
477
- */
478
- tag;
479
- /**
480
- * CSS styles for the slot dropzone container.
481
- * Useful for layouts - e.g., "flex-direction: row" for horizontal stacks.
482
- * Only applies in admin mode for type="slot".
483
- */
484
- slotStyle;
485
- /**
486
- * Internal state to track admin mode
487
- */
488
- adminMode = false;
489
- /**
490
- * Internal state for text input value (synced from slot content)
491
- */
492
- textValue = '';
493
- /**
494
- * Whether the current textValue contains valid HTML
495
- */
496
- isValidHtml = true;
497
- /**
498
- * Available components loaded from Custom Elements Manifest
499
- */
500
- availableComponents = [];
501
- /**
502
- * Whether the component picker popover is open
503
- */
504
- pickerOpen = false;
505
- /**
506
- * Reference to the slot element to access assignedNodes
507
- */
508
- slotRef;
509
- /**
510
- * The original slotted element (e.g., <h3 slot="header">)
511
- */
512
- slottedElement;
513
- /**
514
- * Emitted when text content changes in admin mode.
515
- * The event detail contains the new text value and validity.
516
- */
517
- leSlotChange;
518
- disconnectModeObserver;
519
- connectedCallback() {
520
- this.disconnectModeObserver = observeModeChanges(this.el, (mode) => {
521
- const wasAdmin = this.adminMode;
522
- this.adminMode = mode === 'admin';
523
- // When entering admin mode, read content from slotted elements
524
- if (this.adminMode && !wasAdmin) {
525
- // Need to wait for render to access slot ref
526
- requestAnimationFrame(() => this.readSlottedContent());
527
- // Load available components for the component picker
528
- if (this.type === 'slot') {
529
- this.loadAvailableComponents();
530
- }
531
- }
532
- });
533
- }
534
- disconnectedCallback() {
535
- this.disconnectModeObserver?.();
536
- }
537
- /**
538
- * Flag to prevent re-reading content right after we updated it
539
- */
540
- isUpdating = false;
541
- /**
542
- * Read content from slotted elements via assignedNodes()
543
- */
544
- readSlottedContent() {
545
- if (!this.slotRef)
546
- return;
547
- // Skip if we just updated the content ourselves
548
- if (this.isUpdating) {
549
- this.isUpdating = false;
550
- return;
551
- }
552
- const assignedNodes = this.slotRef.assignedNodes({ flatten: true });
553
- // For text/textarea types, we want to edit the innerHTML of slotted elements
554
- if (this.type === 'text' || this.type === 'textarea') {
555
- // Find the first element node (skip text nodes that are just whitespace)
556
- const elementNode = assignedNodes.find(node => node.nodeType === Node.ELEMENT_NODE);
557
- if (elementNode) {
558
- // Only update textValue if slotted element changed or we don't have one yet
559
- if (this.slottedElement !== elementNode) {
560
- this.slottedElement = elementNode;
561
- this.textValue = elementNode.innerHTML?.trim() || '';
562
- // console.log(`[le-slot "${this.name}"] Read slotted content:`, this.textValue);
563
- }
564
- }
565
- else {
566
- // No element, check for direct text content
567
- const textContent = assignedNodes
568
- .filter(node => node.nodeType === Node.TEXT_NODE)
569
- .map(node => node.textContent)
570
- .join('')
571
- .trim();
572
- if (textContent && !this.textValue) {
573
- this.textValue = textContent;
574
- // console.log(`[le-slot "${this.name}"] Read text content:`, this.textValue);
575
- }
576
- }
577
- }
578
- }
579
- /**
580
- * Validates if a string contains valid HTML
581
- */
582
- validateHtml(html) {
583
- // Empty string is valid
584
- if (!html.trim())
585
- return true;
586
- // Create a template element to parse the HTML
587
- const template = document.createElement('template');
588
- template.innerHTML = html;
589
- // Check that we don't have obviously broken HTML
590
- // Count opening and closing tags for common elements
591
- const openTags = (html.match(/<[a-z][^>]*(?<!\/)>/gi) || []).length;
592
- const closeTags = (html.match(/<\/[a-z][^>]*>/gi) || []).length;
593
- const selfClosing = (html.match(/<[a-z][^>]*\/>/gi) || []).length;
594
- // Simple validation: opening tags (minus self-closing) should roughly match closing tags
595
- // Allow some tolerance for void elements like <br>, <img>, etc.
596
- const voidElements = (html.match(/<(br|hr|img|input|meta|link|area|base|col|embed|param|source|track|wbr)[^>]*>/gi) || []).length;
597
- const effectiveOpenTags = openTags - selfClosing - voidElements;
598
- // If difference is too large, HTML is likely broken
599
- if (Math.abs(effectiveOpenTags - closeTags) > 1) {
600
- return false;
601
- }
602
- return true;
603
- }
604
- handleTextInput = (event) => {
605
- const target = event.target;
606
- this.textValue = target.value;
607
- this.isValidHtml = this.validateHtml(this.textValue);
608
- if (this.isValidHtml) {
609
- // Set flag to prevent slotchange from re-reading what we just wrote
610
- this.isUpdating = true;
611
- console.log('Updating text value:', this.textValue, 'slottedElement:', this.slottedElement);
612
- if (this.slottedElement) {
613
- // Update existing slotted element's innerHTML
614
- this.slottedElement.innerHTML = this.textValue;
615
- }
616
- else if (this.tag && this.textValue) {
617
- // No slotted element exists
618
- // If the slot doesn't have a name, then it's the default slot
619
- // remove the existing non-slotted content (text nodes and elements without slot attribute)
620
- const rootNode = this.el.getRootNode();
621
- if (!this.name && rootNode instanceof ShadowRoot) {
622
- const hostComponent = rootNode.host;
623
- Array.from(hostComponent.childNodes).forEach(node => {
624
- if (node.nodeType === Node.TEXT_NODE ||
625
- (node.nodeType === Node.ELEMENT_NODE && !node.hasAttribute('slot'))) {
626
- node.remove();
627
- }
628
- });
629
- }
630
- // create one using the specified tag
631
- this.createSlottedElement();
632
- }
633
- else if (this.textValue) {
634
- // no tag specified - just replace everything in the host component
635
- const rootNode = this.el.getRootNode();
636
- if (rootNode instanceof ShadowRoot) {
637
- const hostComponent = rootNode.host;
638
- hostComponent.innerHTML = this.textValue;
639
- }
640
- }
641
- }
642
- this.leSlotChange.emit({
643
- name: this.name,
644
- value: this.textValue,
645
- isValid: this.isValidHtml
646
- });
647
- };
648
- /**
649
- * Create a new slotted element when none exists.
650
- * The element is appended to the host component's light DOM.
651
- */
652
- createSlottedElement() {
653
- if (!this.tag)
654
- return;
655
- // Find the host component (le-card, etc.) by traversing up through shadow DOM
656
- // le-slot is inside le-card's shadow DOM, so we need to find le-card's host
657
- const rootNode = this.el.getRootNode();
658
- if (!(rootNode instanceof ShadowRoot))
659
- return;
660
- const hostComponent = rootNode.host;
661
- if (!hostComponent)
662
- return;
663
- // Create the new element
664
- const newElement = document.createElement(this.tag);
665
- newElement.innerHTML = this.textValue;
666
- // Set the slot attribute if this is a named slot
667
- if (this.name) {
668
- newElement.setAttribute('slot', this.name);
669
- }
670
- // Append to the host component's light DOM
671
- hostComponent.appendChild(newElement);
672
- // Store reference to the new element
673
- this.slottedElement = newElement;
674
- // console.log(`[le-slot "${this.name}"] Created new <${this.tag}> element`);
675
- }
676
- /**
677
- * Load available components from Custom Elements Manifest
678
- */
679
- async loadAvailableComponents() {
680
- try {
681
- const response = await fetch('/custom-elements.json');
682
- const manifest = await response.json();
683
- const components = [];
684
- const allowedList = this.allowedComponents?.split(',').map(s => s.trim()) || [];
685
- for (const module of manifest.modules) {
686
- for (const declaration of module.declarations || []) {
687
- if (declaration.tagName && declaration.customElement) {
688
- // Skip internal components (le-slot, le-component, le-popover)
689
- const isInternal = ['le-slot', 'le-component', 'le-popover'].includes(declaration.tagName);
690
- if (isInternal)
691
- continue;
692
- // If allowedComponents is specified, filter by it
693
- if (allowedList.length > 0 && !allowedList.includes(declaration.tagName)) {
694
- continue;
695
- }
696
- components.push({
697
- tagName: declaration.tagName,
698
- name: this.formatComponentName(declaration.tagName),
699
- description: declaration.description || '',
700
- });
701
- }
702
- }
703
- }
704
- this.availableComponents = components;
705
- }
706
- catch (error) {
707
- console.warn('[le-slot] Failed to load component manifest:', error);
708
- }
709
- }
710
- /**
711
- * Format a tag name into a display name
712
- * e.g., 'le-card' -> 'Card'
713
- */
714
- formatComponentName(tagName) {
715
- return tagName
716
- .replace(/^le-/, '')
717
- .split('-')
718
- .map(word => word.charAt(0).toUpperCase() + word.slice(1))
719
- .join(' ');
720
- }
721
- /**
722
- * Add a new component to the slot
723
- */
724
- addComponent(tagName) {
725
- // Find the host component by traversing up through shadow DOM
726
- const rootNode = this.el.getRootNode();
727
- if (!(rootNode instanceof ShadowRoot))
728
- return;
729
- const hostComponent = rootNode.host;
730
- if (!hostComponent)
731
- return;
732
- // Create the new component element
733
- const newElement = document.createElement(tagName);
734
- // Set the slot attribute if this is a named slot
735
- if (this.name) {
736
- newElement.setAttribute('slot', this.name);
737
- }
738
- // Append to the host component's light DOM
739
- hostComponent.appendChild(newElement);
740
- // Emit change event so the page can save
741
- this.leSlotChange.emit({
742
- name: this.name,
743
- value: hostComponent.innerHTML,
744
- isValid: true,
745
- });
746
- }
747
- /**
748
- * Handle slot change event to re-read content when nodes are assigned
749
- */
750
- handleSlotChange = () => {
751
- this.readSlottedContent();
752
- };
753
- render() {
754
- const displayLabel = this.label || this.name;
755
- // Always render the same structure, CSS handles visibility via .admin-mode class
756
- return (h(Host, { key: 'bae03733e0443c10f1abe8b4c846d3eae0723d3d', class: {
757
- 'admin-mode': this.adminMode,
758
- 'invalid-html': !this.isValidHtml
759
- }, role: this.adminMode ? 'region' : undefined, "aria-label": this.adminMode ? `Slot: ${displayLabel}` : undefined, "data-slot-name": this.name, "data-slot-type": this.type, "data-allowed": this.allowedComponents, "data-multiple": this.multiple, "data-required": this.required }, this.adminMode ? (h("div", { class: "le-slot-container" }, h("div", { class: classnames('le-slot-header', {
760
- 'le-slot-header-no-label': !displayLabel,
761
- 'le-slot-header-text': this.type === 'text',
762
- 'le-slot-header-error': !this.isValidHtml
763
- }) }, displayLabel && (h("span", { class: "le-slot-label" }, displayLabel, this.required && h("span", { class: "le-slot-required" }, "*"))), !this.isValidHtml && h("span", { class: "le-slot-invalid" }, "\u26A0 Invalid HTML"), this.type === 'slot' && this.adminMode && (h("le-popover", { mode: "default", showClose: true, align: "start", position: "right", popoverTitle: "Add Component", open: this.pickerOpen, onLePopoverOpen: () => this.pickerOpen = true, onLePopoverClose: () => this.pickerOpen = false }, h("le-button", { type: "button", class: "le-slot-button", slot: "trigger", variant: "clear", size: "small", "aria-label": "Add component", "icon-only": true }, h("span", { class: "le-slot-add-btn", slot: "icon-only" }, "+")), h("div", { class: "le-slot-picker" }, this.availableComponents.length > 0 ? (h("ul", { class: "le-slot-picker-list" }, this.availableComponents.map(component => (h("li", { key: component.tagName }, h("button", { class: "le-slot-picker-item", onClick: () => {
764
- this.addComponent(component.tagName);
765
- this.pickerOpen = false;
766
- } }, h("span", { class: "le-slot-picker-name" }, component.name), component.description && (h("span", { class: "le-slot-picker-desc" }, component.description)))))))) : (h("div", { class: "le-slot-picker-empty" }, "No components available")))))), this.renderContent())) : (
767
- // In default mode, just pass through the slot - slotted content renders naturally
768
- // Note: We use unnamed slot here because named slots from parent component
769
- // are passed as le-slot's light DOM children
770
- h("slot", null))));
771
- }
772
- renderContent() {
773
- // Create the slot element with ref for reading assignedNodes
774
- // Wrap in a hidden div since slot elements can't have style prop in Stencil
775
- // Note: We use unnamed slot here because named slots from parent component
776
- // are passed as le-slot's light DOM children
777
- const slotElement = (h("div", { class: "hidden-slot" }, h("slot", { ref: (el) => this.slotRef = el, onSlotchange: this.handleSlotChange })));
778
- switch (this.type) {
779
- case 'text':
780
- return (h("div", { class: { 'le-slot-input': true, 'has-error': !this.isValidHtml } }, h("le-string-input", { mode: "default", value: this.textValue, placeholder: this.placeholder || `Enter ${this.label || this.name || 'text'}...`, onChange: this.handleTextInput }), slotElement));
781
- case 'textarea':
782
- return (h("div", { class: { 'le-slot-input': true, 'has-error': !this.isValidHtml } }, h("textarea", { value: this.textValue, placeholder: this.placeholder || `Enter ${this.label || this.name || 'text'}...`, onInput: this.handleTextInput, required: this.required, rows: 3 }), slotElement));
783
- case 'slot':
784
- default:
785
- // Parse slotStyle string into style object if provided
786
- const dropzoneStyle = {};
787
- if (this.slotStyle) {
788
- this.slotStyle.split(';').forEach(rule => {
789
- const [prop, value] = rule.split(':').map(s => s.trim());
790
- if (prop && value) {
791
- // Convert kebab-case to camelCase for style object
792
- const camelProp = prop.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
793
- dropzoneStyle[camelProp] = value;
794
- }
795
- });
796
- }
797
- return (h("div", { class: "le-slot-dropzone", style: dropzoneStyle }, h("slot", { ref: (el) => this.slotRef = el, onSlotchange: this.handleSlotChange })));
798
- }
799
- }
800
- static get style() { return leSlotDefaultCss; }
801
- }, [769, "le-slot", {
802
- "type": [1],
803
- "name": [1],
804
- "label": [1],
805
- "description": [1],
806
- "allowedComponents": [1, "allowed-components"],
807
- "multiple": [4],
808
- "required": [4],
809
- "placeholder": [1],
810
- "tag": [1],
811
- "slotStyle": [1, "slot-style"],
812
- "adminMode": [32],
813
- "textValue": [32],
814
- "isValidHtml": [32],
815
- "availableComponents": [32],
816
- "pickerOpen": [32]
817
- }]);
818
- function defineCustomElement$3() {
819
- if (typeof customElements === "undefined") {
820
- return;
821
- }
822
- const components = ["le-slot", "le-button", "le-checkbox", "le-component", "le-popover", "le-slot", "le-string-input"];
823
- components.forEach(tagName => { switch (tagName) {
824
- case "le-slot":
825
- if (!customElements.get(tagName)) {
826
- customElements.define(tagName, LeSlot);
827
- }
828
- break;
829
- case "le-button":
830
- if (!customElements.get(tagName)) {
831
- defineCustomElement();
832
- }
833
- break;
834
- case "le-checkbox":
835
- if (!customElements.get(tagName)) {
836
- defineCustomElement$1();
837
- }
838
- break;
839
- case "le-component":
840
- if (!customElements.get(tagName)) {
841
- defineCustomElement$2();
842
- }
843
- break;
844
- case "le-popover":
845
- if (!customElements.get(tagName)) {
846
- defineCustomElement$5();
847
- }
848
- break;
849
- case "le-slot":
850
- if (!customElements.get(tagName)) {
851
- defineCustomElement$3();
852
- }
853
- break;
854
- case "le-string-input":
855
- if (!customElements.get(tagName)) {
856
- defineCustomElement$4();
857
- }
858
- break;
859
- } });
860
- }
861
-
862
- const leComponentCss = ":host{display:contents}:host(.admin-mode){display:block}.le-component-wrapper{position:relative;border:2px dashed var(--le-admin-border-color, #90caf9);border-radius:var(--le-radius-md, 8px);background:var(--le-admin-bg, rgba(144, 202, 249, 0.05));transition:border-color 0.2s ease, box-shadow 0.2s ease}.le-component-wrapper:hover{border-color:var(--le-admin-border-hover, #42a5f5);box-shadow:0 0 0 2px var(--le-admin-glow, rgba(66, 165, 245, 0.2))}.le-component-header{display:flex;align-items:center;justify-content:space-between;gap:var(--le-spacing-1, 4px);padding:0 0 0 var(--le-spacing-1, 4px);background:var(--le-admin-header-bg, rgba(144, 202, 249, 0.15));border-bottom:1px solid var(--le-admin-border-color, #90caf9);border-radius:var(--le-radius-md, 8px) var(--le-radius-md, 8px) 0 0;font-size:var(--le-font-size-xs, 11px)}.le-component-name{font-weight:var(--le-font-weight-medium, 500);color:var(--le-admin-text, #1976d2);text-transform:capitalize;text-align:start;overflow:hidden;width:0;flex:1 1 0%}.le-component-content{padding:var(--le-space-xs, 4px)}.le-component-trigger{font-size:24px;line-height:0px;width:12px;height:12px}.le-component-button{width:20px}.property-editor{display:flex;flex-direction:column;gap:var(--le-space-sm, 8px);max-width:380px}.property-field{display:flex;flex-direction:column;gap:var(--le-space-xs, 4px)}.property-field label{display:flex;flex-direction:column;gap:2px;font-size:var(--le-font-size-sm, 13px);font-weight:var(--le-font-weight-medium, 500);color:var(--le-color-text, #333)}.property-hint{font-size:var(--le-font-size-xs, 11px);font-weight:normal;color:var(--le-color-text-secondary, #666);line-height:1.3}.property-field input[type=\"text\"],.property-field input[type=\"number\"],.property-field select{padding:var(--le-space-xs, 4px) var(--le-space-sm, 8px);border:1px solid var(--le-color-border, #ddd);border-radius:var(--le-radius-md, 7px);font-size:var(--le-font-size-sm, 13px);font-family:inherit;background:var(--le-color-surface, #fff);color:var(--le-color-text, #333);transition:border-color 0.15s ease, box-shadow 0.15s ease}.property-field input:focus,.property-field select:focus{outline:none;border-color:var(--le-color-primary, #1976d2);box-shadow:0 0 0 2px var(--le-color-primary-light, rgba(25, 118, 210, 0.2))}.property-field--checkbox{flex-direction:column}.property-field--checkbox label{flex-direction:row;align-items:center;gap:var(--le-space-sm, 8px);cursor:pointer}.property-field--checkbox input[type=\"checkbox\"]{width:16px;height:16px;margin:0;cursor:pointer;accent-color:var(--le-color-primary, #1976d2)}.property-field--checkbox .property-hint{margin-left:24px}.no-properties{margin:0;padding:var(--le-space-sm, 8px);font-size:var(--le-font-size-sm, 13px);color:var(--le-color-text-secondary, #666);text-align:center}.property-editor-container{display:flex;flex-direction:column;gap:var(--le-space-md, 12px)}.property-editor-actions{padding-top:var(--le-space-sm, 8px);border-top:1px solid var(--le-color-border, #e5e5e5)}.delete-component-btn{display:flex;align-items:center;justify-content:center;gap:var(--le-space-xs, 4px);width:100%;padding:var(--le-space-sm, 8px) var(--le-space-md, 12px);border:1px solid var(--le-color-danger, #e53935);border-radius:var(--le-radius-md, 6px);background:transparent;color:var(--le-color-danger, #e53935);font-size:var(--le-font-size-sm, 13px);font-weight:500;cursor:pointer;transition:background-color 0.15s, color 0.15s}.delete-component-btn:hover{background:var(--le-color-danger, #e53935);color:white}.delete-component-btn:active{opacity:0.9}";
863
-
864
- const LeComponent = /*@__PURE__*/ proxyCustomElement(class LeComponent extends HTMLElement {
865
- constructor(registerHost) {
866
- super();
867
- if (registerHost !== false) {
868
- this.__registerHost();
869
- }
870
- this.__attachShadow();
871
- }
872
- get el() { return this; }
873
- /**
874
- * The tag name of the component (e.g., 'le-card').
875
- * Used to look up property metadata and display the component name.
876
- */
877
- component;
878
- /**
879
- * Optional display name for the component.
880
- * If not provided, the tag name will be formatted as the display name.
881
- */
882
- displayName;
883
- /**
884
- * Classes to apply to the host element.
885
- * Allows parent components to pass their styling classes.
886
- */
887
- hostClass;
888
- /**
889
- * Inline styles to apply to the host element.
890
- * Allows parent components to pass dynamic styles (e.g., flex properties).
891
- */
892
- hostStyle;
893
- /**
894
- * Reference to the host element (found automatically from parent)
895
- */
896
- hostElement;
897
- /**
898
- * Internal state to track admin mode
899
- */
900
- adminMode = false;
901
- /**
902
- * Component metadata loaded from Custom Elements Manifest
903
- */
904
- componentMeta = null;
905
- /**
906
- * Current property values of the host component
907
- */
908
- propertyValues = {};
909
- disconnectModeObserver;
910
- connectedCallback() {
911
- // Find the host element - le-component is rendered inside the component's shadow DOM,
912
- // so we need to find the shadow root's host element
913
- this.findHostElement();
914
- this.disconnectModeObserver = observeModeChanges(this.el, (mode) => {
915
- this.adminMode = mode === 'admin';
916
- // Load metadata and refresh property values only when entering admin mode
917
- if (this.adminMode) {
918
- if (!this.componentMeta) {
919
- this.loadComponentMetadata();
920
- }
921
- else {
922
- this.readPropertyValues();
923
- }
924
- }
925
- });
926
- }
927
- /**
928
- * Find the host element by traversing up through shadow DOM
929
- */
930
- findHostElement() {
931
- // Get the shadow root that contains this le-component
932
- const rootNode = this.el.getRootNode();
933
- if (rootNode instanceof ShadowRoot) {
934
- // The host of this shadow root is our target component (e.g., le-card)
935
- this.hostElement = rootNode.host;
936
- }
937
- }
938
- componentDidLoad() {
939
- // Read initial property values from the host element
940
- this.readPropertyValues();
941
- }
942
- disconnectedCallback() {
943
- this.disconnectModeObserver?.();
944
- }
945
- /**
946
- * Formats a tag name into a display name
947
- * e.g., 'le-card' -> 'Card'
948
- */
949
- formatDisplayName(tagName) {
950
- return tagName
951
- .replace(/^le-/, '') // Remove 'le-' prefix
952
- .split('-')
953
- .map(word => word.charAt(0).toUpperCase() + word.slice(1))
954
- .join(' ');
955
- }
956
- /**
957
- * Load component metadata from the Custom Elements Manifest
958
- */
959
- async loadComponentMetadata() {
960
- try {
961
- // Fetch the manifest - in production this would be bundled or cached
962
- const response = await fetch('/custom-elements.json');
963
- const manifest = await response.json();
964
- // Find the component definition
965
- for (const module of manifest.modules) {
966
- for (const declaration of module.declarations || []) {
967
- if (declaration.tagName === this.component) {
968
- const attributes = (declaration.attributes || []).filter((attr) => !this.isInternalAttribute(attr.name));
969
- this.componentMeta = {
970
- tagName: declaration.tagName,
971
- description: declaration.description,
972
- attributes,
973
- };
974
- // console.log(`[le-component] Loaded metadata for ${this.component}:`, this.componentMeta);
975
- // Read property values after metadata is loaded
976
- this.readPropertyValues();
977
- return;
978
- }
979
- }
980
- }
981
- // console.warn(`[le-component] No metadata found for component: ${this.component}`);
982
- }
983
- catch (error) {
984
- // console.warn(`[le-component] Failed to load metadata for component: ${this.component}`, error);
985
- }
986
- }
987
- /**
988
- * Check if an attribute is internal (should not be shown in editor)
989
- */
990
- isInternalAttribute(name) {
991
- const internalAttrs = ['mode', 'theme', 'class', 'style', 'id', 'slot'];
992
- return internalAttrs.includes(name);
993
- }
994
- /**
995
- * Read current property values from the host element
996
- */
997
- readPropertyValues() {
998
- if (!this.hostElement || !this.componentMeta)
999
- return;
1000
- const values = {};
1001
- for (const attr of this.componentMeta.attributes) {
1002
- const value = this.hostElement.getAttribute(attr.name);
1003
- values[attr.name] = this.parseAttributeValue(value, attr.type?.text);
1004
- }
1005
- this.propertyValues = values;
1006
- }
1007
- /**
1008
- * Parse an attribute value based on its type
1009
- */
1010
- parseAttributeValue(value, type) {
1011
- if (value === null)
1012
- return undefined;
1013
- if (type === 'boolean') {
1014
- return value !== null && value !== 'false';
1015
- }
1016
- if (type === 'number') {
1017
- return parseFloat(value);
1018
- }
1019
- return value;
1020
- }
1021
- /**
1022
- * Handle property value changes from the editor
1023
- */
1024
- handlePropertyChange(attrName, value, type) {
1025
- if (!this.hostElement)
1026
- return;
1027
- // Update the host element's attribute
1028
- if (type === 'boolean') {
1029
- if (value) {
1030
- this.hostElement.setAttribute(attrName, '');
1031
- }
1032
- else {
1033
- this.hostElement.removeAttribute(attrName);
1034
- }
1035
- }
1036
- else if (value === undefined || value === '') {
1037
- this.hostElement.removeAttribute(attrName);
1038
- }
1039
- else {
1040
- this.hostElement.setAttribute(attrName, String(value));
1041
- }
1042
- // Update local state
1043
- this.propertyValues = { ...this.propertyValues, [attrName]: value };
1044
- }
1045
- /**
1046
- * Delete this component from the DOM
1047
- */
1048
- deleteComponent() {
1049
- if (!this.hostElement)
1050
- return;
1051
- // Confirm deletion
1052
- const name = this.displayName || this.formatDisplayName(this.component);
1053
- if (!confirm(`Delete this ${name}?`))
1054
- return;
1055
- // Remove the host element from its parent
1056
- const parent = this.hostElement.parentElement;
1057
- if (parent) {
1058
- this.hostElement.remove();
1059
- }
1060
- }
1061
- /**
1062
- * Render the property editor form
1063
- */
1064
- renderPropertyEditor() {
1065
- const hasProperties = this.componentMeta && this.componentMeta.attributes.length > 0;
1066
- return (h("div", { class: "property-editor-container" }, hasProperties ? (h("form", { class: "property-editor", onSubmit: (e) => e.preventDefault() }, this.componentMeta.attributes.map(attr => this.renderPropertyField(attr)))) : (h("p", { class: "no-properties" }, "No editable properties")), h("div", { class: "property-editor-actions" }, h("le-button", { type: "button", variant: "outlined", color: "danger", "full-width": true, onClick: () => this.deleteComponent() }, h("span", { slot: "icon-start" }, "\uD83D\uDDD1\uFE0F"), h("span", null, "Delete Component")))));
1067
- }
1068
- /**
1069
- * Render a single property field based on its type
1070
- */
1071
- renderPropertyField(attr) {
1072
- const value = this.propertyValues[attr.name];
1073
- const type = attr.type?.text || 'string';
1074
- // Check if type is a union of string literals (e.g., "'default' | 'outlined' | 'elevated'")
1075
- const enumMatch = type.match(/^'[^']+'/);
1076
- if (enumMatch) {
1077
- const options = type.split('|').map(opt => opt.trim().replace(/'/g, ''));
1078
- return (h("div", { class: "property-field" }, h("label", { htmlFor: `prop-${attr.name}` }, attr.name, attr.description && h("span", { class: "property-hint" }, attr.description)), h("select", { id: `prop-${attr.name}`, onChange: (e) => this.handlePropertyChange(attr.name, e.target.value, type) }, options.map(opt => (h("option", { value: opt, selected: value === opt || (!value && attr.default?.replace(/'/g, '') === opt) }, opt))))));
1079
- }
1080
- // Boolean type
1081
- if (type === 'boolean') {
1082
- return (h("div", { class: "property-field property-field--checkbox" }, h("le-checkbox", { name: `prop-${attr.name}`, checked: value === true || value === '', onChange: (e) => this.handlePropertyChange(attr.name, e.target.checked, type) }, attr.name, attr.description && h("div", { slot: "description" }, attr.description))));
1083
- }
1084
- // Number type
1085
- if (type === 'number') {
1086
- return (h("div", { class: "property-field" }, h("label", { htmlFor: `prop-${attr.name}` }, attr.name, attr.description && h("span", { class: "property-hint" }, attr.description)), h("input", { type: "number", id: `prop-${attr.name}`, value: value ?? '', placeholder: attr.default, onChange: (e) => this.handlePropertyChange(attr.name, e.target.value, type) })));
1087
- }
1088
- // Default: string/text input
1089
- return (h("div", { class: "property-field" }, h("le-string-input", { name: `prop-${attr.name}`, label: attr.name, value: value ?? '', placeholder: attr.default?.replace(/'/g, ''), onChange: (e) => this.handlePropertyChange(attr.name, e.detail.value, type) }, h("span", { slot: "description" }, attr.description))));
1090
- }
1091
- render() {
1092
- const name = this.displayName || this.formatDisplayName(this.component);
1093
- // In default mode, just pass through content with host classes
1094
- if (!this.adminMode) {
1095
- return (h(Host, { class: classnames(this.component, this.hostClass), style: this.hostStyle }, h("slot", null)));
1096
- }
1097
- // In admin mode, show wrapper with header and settings
1098
- return (h(Host, { class: classnames(this.component, this.hostClass, 'admin-mode'), style: this.hostStyle }, h("div", { class: "le-component-wrapper" }, h("div", { class: "le-component-header" }, h("span", { class: "le-component-name" }, name), h("le-popover", { popoverTitle: `${name} Settings`, position: "right", align: "start", "min-width": "300px", mode: "default" }, h("le-button", { type: "button", class: "le-component-button", slot: "trigger", variant: "clear", size: "small", "aria-label": "Edit component properties", "icon-only": true }, h("span", { class: "le-component-trigger", slot: "icon-only" }, "\u2699")), this.renderPropertyEditor())), h("div", { class: "le-component-content" }, h("slot", null)))));
1099
- }
1100
- static get style() { return leComponentCss; }
1101
- }, [769, "le-component", {
1102
- "component": [1],
1103
- "displayName": [1, "display-name"],
1104
- "hostClass": [1, "host-class"],
1105
- "hostStyle": [16],
1106
- "adminMode": [32],
1107
- "componentMeta": [32],
1108
- "propertyValues": [32]
1109
- }]);
1110
- function defineCustomElement$2() {
1111
- if (typeof customElements === "undefined") {
1112
- return;
1113
- }
1114
- const components = ["le-component", "le-button", "le-checkbox", "le-component", "le-popover", "le-slot", "le-string-input"];
1115
- components.forEach(tagName => { switch (tagName) {
1116
- case "le-component":
1117
- if (!customElements.get(tagName)) {
1118
- customElements.define(tagName, LeComponent);
1119
- }
1120
- break;
1121
- case "le-button":
1122
- if (!customElements.get(tagName)) {
1123
- defineCustomElement();
1124
- }
1125
- break;
1126
- case "le-checkbox":
1127
- if (!customElements.get(tagName)) {
1128
- defineCustomElement$1();
1129
- }
1130
- break;
1131
- case "le-component":
1132
- if (!customElements.get(tagName)) {
1133
- defineCustomElement$2();
1134
- }
1135
- break;
1136
- case "le-popover":
1137
- if (!customElements.get(tagName)) {
1138
- defineCustomElement$5();
1139
- }
1140
- break;
1141
- case "le-slot":
1142
- if (!customElements.get(tagName)) {
1143
- defineCustomElement$3();
1144
- }
1145
- break;
1146
- case "le-string-input":
1147
- if (!customElements.get(tagName)) {
1148
- defineCustomElement$4();
1149
- }
1150
- break;
1151
- } });
1152
- }
1153
-
1154
- const leCheckboxCss = ":host{display:block;--le-checkbox-size:18px;--le-checkbox-color:var(--le-color-primary, #007bff);--le-checkbox-label-color:var(--le-color-text-primary, #333);--le-checkbox-desc-color:var(--le-color-text-secondary, #666);--le-checkbox-border-radius:var(--le-radius-sm, 2px);--le-checkbox-marker-color:var(--le-color-surface, #fff)}.le-checkbox-wrapper{display:flex;flex-direction:column;gap:4px}.le-checkbox-label{display:inline-flex;align-items:flex-start;gap:8px;cursor:pointer;user-select:none}:host([disabled]) .le-checkbox-label{cursor:not-allowed;opacity:0.6}.le-checkbox-input{display:flex;align-items:center;justify-content:center;min-height:1.4em}input[type=\"checkbox\"]{appearance:none;-webkit-appearance:none;width:var(--le-checkbox-size);height:var(--le-checkbox-size);border:var(--le-border-width, 2px) solid var(--le-checkbox-color);border-radius:var(--le-checkbox-border-radius);margin:0;margin-top:2px;position:relative;cursor:inherit;background-color:transparent;transition:background-color 0.2s, border-color 0.2s}input[type=\"checkbox\"]:checked{background-color:var(--le-checkbox-color)}input[type=\"checkbox\"]:checked::after{content:'';position:absolute;left:0;top:0;bottom:calc(var(--le-checkbox-size) / 5);right:0;margin:auto;width:calc(var(--le-checkbox-size) / 4);height:calc(var(--le-checkbox-size) / 2);border:solid var(--le-checkbox-marker-color, #fff);border-width:0 calc(var(--le-checkbox-size) / 10) calc(var(--le-checkbox-size) / 10) 0;transform:rotate(45deg)}input[type=\"checkbox\"]:focus-visible{outline:2px solid var(--le-color-focus);outline-offset:2px}.le-checkbox-text{flex:1;flex-wrap:wrap;color:var(--le-checkbox-label-color);line-height:1.5;text-align:start}.le-checkbox-description{margin-left:calc(var(--le-checkbox-size) + 8px);font-size:0.875em;color:var(--le-checkbox-desc-color);line-height:1.4}:host [slot=\"description\"]{margin:0}";
1155
-
1156
- const LeCheckbox = /*@__PURE__*/ proxyCustomElement(class LeCheckbox extends HTMLElement {
1157
- constructor(registerHost) {
1158
- super();
1159
- if (registerHost !== false) {
1160
- this.__registerHost();
1161
- }
1162
- this.__attachShadow();
1163
- this.leChange = createEvent(this, "change", 7);
1164
- }
1165
- get el() { return this; }
1166
- /**
1167
- * Whether the checkbox is checked
1168
- */
1169
- checked = false;
1170
- /**
1171
- * Whether the checkbox is disabled
1172
- */
1173
- disabled = false;
1174
- /**
1175
- * The name of the checkbox input
1176
- */
1177
- name;
1178
- /**
1179
- * The value of the checkbox input
1180
- */
1181
- value;
1182
- /**
1183
- * External ID for linking with external systems (e.g. database ID, PDF form field ID)
1184
- */
1185
- externalId;
1186
- /**
1187
- * Emitted when the checked state changes
1188
- */
1189
- leChange;
1190
- handleChange = (event) => {
1191
- // We stop the internal button click from bubbling up
1192
- event.stopPropagation();
1193
- if (this.disabled) {
1194
- event.preventDefault();
1195
- return;
1196
- }
1197
- const input = event.target;
1198
- this.checked = input.checked;
1199
- this.leChange.emit({
1200
- checked: this.checked,
1201
- value: this.value,
1202
- name: this.name,
1203
- externalId: this.externalId
1204
- });
1205
- };
1206
- render() {
1207
- return (h("le-component", { key: '43399929e07835e0019d509803e50a151921fa72', component: "le-checkbox", hostClass: classnames({ 'disabled': this.disabled }) }, h("div", { key: '7ddbf2ac1690bb09082adfea70b9767c972d007a', class: "le-checkbox-wrapper" }, h("label", { key: '8eec4055c713e8b3b155695751b10bff64c9f903', class: "le-checkbox-label" }, h("span", { key: '2118b1cbe7911ff1674e522d723949d81cade185', class: "le-checkbox-input" }, h("input", { key: 'd0a30af5c14497fa6fa294c07ba74ae2e032481f', type: "checkbox", name: this.name, value: this.value, checked: this.checked, disabled: this.disabled, onChange: this.handleChange })), h("span", { key: '02cf9588431240039a53ee50e02b08ba5d63b974', class: "le-checkbox-text" }, h("le-slot", { key: 'e7d7b253deab72e627164eb72fc06109abfca6a5', name: "", type: "text", tag: "span" }, h("slot", { key: '1d8c443073e48848513a8a6d04cd7805a394e54e' })))), h("div", { key: '16c2c927dc0c0f7844a203a0628bf0e561009bd0', class: "le-checkbox-description" }, h("le-slot", { key: 'c6898ecc8992dce4786e68ab4b136bf5c3a4d3aa', name: "description", type: "text", tag: "div", label: "Description" }, h("slot", { key: '3342add8ed1400ab74681e445163eeb3dd415941', name: "description" }))))));
1208
- }
1209
- static get style() { return leCheckboxCss; }
1210
- }, [769, "le-checkbox", {
1211
- "checked": [1540],
1212
- "disabled": [4],
1213
- "name": [1],
1214
- "value": [1],
1215
- "externalId": [1, "external-id"]
1216
- }]);
1217
- function defineCustomElement$1() {
1218
- if (typeof customElements === "undefined") {
1219
- return;
1220
- }
1221
- const components = ["le-checkbox", "le-button", "le-checkbox", "le-component", "le-popover", "le-slot", "le-string-input"];
1222
- components.forEach(tagName => { switch (tagName) {
1223
- case "le-checkbox":
1224
- if (!customElements.get(tagName)) {
1225
- customElements.define(tagName, LeCheckbox);
1226
- }
1227
- break;
1228
- case "le-button":
1229
- if (!customElements.get(tagName)) {
1230
- defineCustomElement();
1231
- }
1232
- break;
1233
- case "le-checkbox":
1234
- if (!customElements.get(tagName)) {
1235
- defineCustomElement$1();
1236
- }
1237
- break;
1238
- case "le-component":
1239
- if (!customElements.get(tagName)) {
1240
- defineCustomElement$2();
1241
- }
1242
- break;
1243
- case "le-popover":
1244
- if (!customElements.get(tagName)) {
1245
- defineCustomElement$5();
1246
- }
1247
- break;
1248
- case "le-slot":
1249
- if (!customElements.get(tagName)) {
1250
- defineCustomElement$3();
1251
- }
1252
- break;
1253
- case "le-string-input":
1254
- if (!customElements.get(tagName)) {
1255
- defineCustomElement$4();
1256
- }
1257
- break;
1258
- } });
1259
- }
1260
-
1261
- const leButtonDefaultCss = ":host{display:inline-block;--le-button-border-radius:var(--le-radius-md);--le-button-padding-x:0.4rem;--le-button-padding-y:0.4rem;--le-button-small-padding:0.25rem;--le-button-font-size:var(--le-font-size-md);--le-button-font-weight:var(--le-font-weight-medium);--le-button-transition:var(--le-transition-fast);--le-button-icon-aspect-ratio:1;--_btn-bg:var(--le-color-primary);--_btn-bg-hover:var(--le-color-primary-dark);--_btn-bg-system:var(--le-color-black);--_btn-color:var(--le-color-primary-contrast);--_btn-border-color:var(--le-color-primary)}:host([full-width]){display:block;width:100%}.button{display:inline-flex;align-items:center;justify-content:center;gap:var(--le-spacing-3);width:100%;padding:var(--le-button-padding-y) var(--le-button-padding-x);border:1px solid var(--_btn-border-color);border-radius:var(--le-button-border-radius);background:var(--_btn-bg);color:var(--_btn-color);font-family:var(--le-font-family-base);font-size:var(--le-button-font-size);font-weight:var(--le-button-font-weight);line-height:var(--le-line-height-tight);text-decoration:none;cursor:pointer;transition:background-color var(--le-button-transition) var(--le-transition-easing),\n border-color var(--le-button-transition) var(--le-transition-easing),\n box-shadow var(--le-button-transition) var(--le-transition-easing),\n transform var(--le-button-transition) var(--le-transition-easing)}.button:hover:not(:disabled){background:var(--_btn-bg-hover);border-color:var(--_btn-bg-hover)}.button:active:not(:disabled){transform:translateY(1px)}.button:focus-visible{outline:2px solid var(--le-color-focus);outline-offset:2px}.button:disabled{opacity:0.5;cursor:not-allowed}:host>le-component.color-primary{--_btn-bg:var(--le-color-primary);--_btn-bg-hover:var(--le-color-primary-dark);--_btn-color:var(--le-color-primary-contrast);--_btn-border-color:var(--le-color-primary)}:host>le-component.color-secondary{--_btn-bg:var(--le-color-secondary);--_btn-bg-hover:var(--le-color-secondary-dark);--_btn-color:var(--le-color-secondary-contrast);--_btn-border-color:var(--le-color-secondary)}:host>le-component.color-success{--_btn-bg:var(--le-color-success);--_btn-bg-hover:var(--le-color-success-dark);--_btn-color:var(--le-color-success-contrast);--_btn-border-color:var(--le-color-success)}:host>le-component.color-warning{--_btn-bg:var(--le-color-warning);--_btn-bg-hover:var(--le-color-warning-dark);--_btn-color:var(--le-color-warning-contrast);--_btn-border-color:var(--le-color-warning)}:host>le-component.color-danger{--_btn-bg:var(--le-color-danger);--_btn-bg-hover:var(--le-color-danger-dark);--_btn-color:var(--le-color-danger-contrast);--_btn-border-color:var(--le-color-danger)}:host>le-component.color-info{--_btn-bg:var(--le-color-info);--_btn-bg-hover:var(--le-color-info-dark);--_btn-color:var(--le-color-info-contrast);--_btn-border-color:var(--le-color-info)}:host>le-component.variant-solid .button{box-shadow:var(--le-shadow-sm)}:host>le-component.variant-solid .button:hover:not(:disabled){box-shadow:var(--le-shadow-md)}:host>le-component.variant-outlined .button{background:transparent;color:var(--_btn-bg);border-color:var(--_btn-border-color)}:host>le-component.variant-outlined .button:hover:not(:disabled){background:var(--_btn-bg);color:var(--_btn-color)}:host>le-component.variant-clear .button{background:transparent;color:var(--_btn-bg);border-color:transparent}:host>le-component.variant-clear .button:hover:not(:disabled){background:var(--le-color-gray-100);border-color:transparent}:host>le-component.variant-system .button{background:transparent;color:var(--_btn-bg-system);border-color:transparent}:host>le-component.size-small .button{--le-button-padding-x:0.4rem;--le-button-padding-y:0.3rem;--le-button-padding-top:0.35rem;--le-button-font-size:var(--le-button-small-font-size, var(--le-font-size-xs))}:host>le-component.size-large .button{--le-button-padding-x:0.9rem;--le-button-padding-y:0.6rem;--le-button-font-size:var(--le-font-size-xl)}:host>le-component.full-width{display:block;width:100%}:host>le-component.selected .button{box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.2)}:host>le-component.variant-outlined.selected .button,:host>le-component.variant-clear.selected .button{background:var(--_btn-bg);color:var(--_btn-color)}:host>le-component.icon-only .button{padding:0.5rem;padding-bottom:0.6rem;aspect-ratio:var(--le-button-icon-aspect-ratio, 1)}:host>le-component.icon-only.size-small .button{padding:var(--le-button-small-padding, 0.25rem)}:host>le-component.icon-only.size-large .button{padding:0.75rem}:host>le-component.icon-only .content{display:none}.content{display:inline}.content:empty{display:none}.icon-start,.icon-only,.icon-end{display:flex;align-items:center;justify-content:center}.icon-start:empty,.icon-only:empty,.icon-end:empty{display:none}::slotted([slot=\"icon-start\"]),::slotted([slot=\"icon-only\"]),::slotted([slot=\"icon-end\"]){display:flex;align-items:center;justify-content:center;width:1.125em;height:1.125em}";
1262
-
1263
- const LeButton = /*@__PURE__*/ proxyCustomElement(class LeButton extends HTMLElement {
1264
- constructor(registerHost) {
1265
- super();
1266
- if (registerHost !== false) {
1267
- this.__registerHost();
1268
- }
1269
- this.__attachShadow();
1270
- this.leClick = createEvent(this, "click", 7);
1271
- }
1272
- get el() { return this; }
1273
- /**
1274
- * Mode of the popover should be 'default' for internal use
1275
- */
1276
- mode;
1277
- /**
1278
- * Button variant style
1279
- * @allowedValues solid | outlined | clear
1280
- */
1281
- variant = 'solid';
1282
- /**
1283
- * Button color theme (uses theme semantic colors)
1284
- * @allowedValues primary | secondary | success | warning | danger | info
1285
- */
1286
- color = 'primary';
1287
- /**
1288
- * Button size
1289
- * @allowedValues small | medium | large
1290
- */
1291
- size = 'medium';
1292
- /**
1293
- * Whether the button is in a selected/active state
1294
- */
1295
- selected = false;
1296
- /**
1297
- * Whether the button takes full width of its container
1298
- */
1299
- fullWidth = false;
1300
- /**
1301
- * Whether the button displays only an icon (square aspect ratio)
1302
- */
1303
- iconOnly = false;
1304
- /**
1305
- * Whether the button is disabled
1306
- */
1307
- disabled = false;
1308
- /**
1309
- * The button type attribute
1310
- * @allowedValues button | submit | reset
1311
- */
1312
- type = 'button';
1313
- /**
1314
- * Optional href to make the button act as a link
1315
- */
1316
- href;
1317
- /**
1318
- * Link target when href is set
1319
- */
1320
- target;
1321
- /**
1322
- * Emitted when the button is clicked.
1323
- * This is a custom event that wraps the native click but ensures the target is the le-button.
1324
- */
1325
- leClick;
1326
- handleClick = (event) => {
1327
- // We stop the internal button click from bubbling up
1328
- event.stopPropagation();
1329
- if (this.disabled) {
1330
- event.preventDefault();
1331
- return;
1332
- }
1333
- // And emit our own click event from the host element
1334
- this.leClick.emit(event);
1335
- };
1336
- render() {
1337
- const classes = classnames(`variant-${this.variant}`, `color-${this.color}`, `size-${this.size}`, {
1338
- 'selected': this.selected,
1339
- 'full-width': this.fullWidth,
1340
- 'icon-only': this.iconOnly,
1341
- 'disabled': this.disabled,
1342
- });
1343
- const TagType = this.href ? 'a' : 'button';
1344
- const attrs = this.href ? { href: this.href, target: this.target, role: 'button' } : { type: this.type, disabled: this.disabled };
1345
- return (h("le-component", { key: '363dbfddf4a765bfd6f36ed16d0912e281153806', component: "le-button", hostClass: classes }, h(TagType, { key: 'e112acdff4278e976ad767bd1ea7c9ced5e85f43', class: "button", part: "button", ...attrs, onClick: this.handleClick }, this.iconOnly ? (h("span", { class: "icon-start" }, h("slot", { name: "icon-only" }))) : (h(Fragment, null, h("span", { class: "icon-start" }, h("slot", { name: "icon-start" })), h("le-slot", { name: "", description: "Button text", type: "text", class: "content", part: "content" }, h("slot", null)), h("span", { class: "icon-end" }, h("slot", { name: "icon-end" })))))));
1346
- }
1347
- static get style() { return leButtonDefaultCss; }
1348
- }, [769, "le-button", {
1349
- "mode": [1537],
1350
- "variant": [1],
1351
- "color": [1],
1352
- "size": [1],
1353
- "selected": [4],
1354
- "fullWidth": [516, "full-width"],
1355
- "iconOnly": [4, "icon-only"],
1356
- "disabled": [4],
1357
- "type": [1],
1358
- "href": [1],
1359
- "target": [1]
1360
- }]);
1361
- function defineCustomElement() {
1362
- if (typeof customElements === "undefined") {
1363
- return;
1364
- }
1365
- const components = ["le-button", "le-button", "le-checkbox", "le-component", "le-popover", "le-slot", "le-string-input"];
1366
- components.forEach(tagName => { switch (tagName) {
1367
- case "le-button":
1368
- if (!customElements.get(tagName)) {
1369
- customElements.define(tagName, LeButton);
1370
- }
1371
- break;
1372
- case "le-button":
1373
- if (!customElements.get(tagName)) {
1374
- defineCustomElement();
1375
- }
1376
- break;
1377
- case "le-checkbox":
1378
- if (!customElements.get(tagName)) {
1379
- defineCustomElement$1();
1380
- }
1381
- break;
1382
- case "le-component":
1383
- if (!customElements.get(tagName)) {
1384
- defineCustomElement$2();
1385
- }
1386
- break;
1387
- case "le-popover":
1388
- if (!customElements.get(tagName)) {
1389
- defineCustomElement$5();
1390
- }
1391
- break;
1392
- case "le-slot":
1393
- if (!customElements.get(tagName)) {
1394
- defineCustomElement$3();
1395
- }
1396
- break;
1397
- case "le-string-input":
1398
- if (!customElements.get(tagName)) {
1399
- defineCustomElement$4();
1400
- }
1401
- break;
1402
- } });
1403
- }
1404
-
1405
- export { LeButton as L, getMode as a, setGlobalMode as b, getTheme as c, setGlobalTheme as d, classnames as e, defineCustomElement$4 as f, generateId as g, defineCustomElement$3 as h, initializeMode as i, defineCustomElement$2 as j, defineCustomElement$1 as k, defineCustomElement as l, LeCheckbox as m, LeComponent as n, LeSlot as o, parseCommaSeparated as p, LeStringInput as q, observeModeChanges as r, slotHasContent as s };
1406
- //# sourceMappingURL=le-button2.js.map
1407
-
1408
- //# sourceMappingURL=le-button2.js.map