@chromvoid/uikit 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/LICENSE +19 -6
  2. package/README.md +1 -0
  3. package/dist/components/cv-accordion-item.d.ts +1 -1
  4. package/dist/components/cv-accordion.d.ts +1 -1
  5. package/dist/components/cv-accordion.js +2 -1
  6. package/dist/components/cv-alert-dialog.d.ts +1 -1
  7. package/dist/components/cv-alert-dialog.js +17 -2
  8. package/dist/components/cv-alert.d.ts +1 -1
  9. package/dist/components/cv-alert.js +2 -1
  10. package/dist/components/cv-badge.d.ts +1 -1
  11. package/dist/components/cv-badge.js +2 -1
  12. package/dist/components/cv-bottom-sheet.d.ts +127 -0
  13. package/dist/components/cv-bottom-sheet.js +513 -0
  14. package/dist/components/cv-breadcrumb-item.d.ts +1 -1
  15. package/dist/components/cv-breadcrumb-item.js +1 -1
  16. package/dist/components/cv-breadcrumb.d.ts +1 -1
  17. package/dist/components/cv-breadcrumb.js +2 -1
  18. package/dist/components/cv-button.d.ts +23 -1
  19. package/dist/components/cv-button.js +194 -37
  20. package/dist/components/cv-callout.d.ts +8 -1
  21. package/dist/components/cv-callout.js +18 -1
  22. package/dist/components/cv-card.d.ts +1 -1
  23. package/dist/components/cv-card.js +2 -2
  24. package/dist/components/cv-carousel-slide.d.ts +1 -1
  25. package/dist/components/cv-carousel.d.ts +1 -1
  26. package/dist/components/cv-carousel.js +2 -1
  27. package/dist/components/cv-checkbox.d.ts +1 -1
  28. package/dist/components/cv-combobox-group.d.ts +1 -1
  29. package/dist/components/cv-combobox-option.d.ts +1 -1
  30. package/dist/components/cv-combobox-option.js +2 -2
  31. package/dist/components/cv-combobox.d.ts +3 -1
  32. package/dist/components/cv-combobox.js +49 -8
  33. package/dist/components/cv-command-item.d.ts +1 -1
  34. package/dist/components/cv-command-item.js +2 -2
  35. package/dist/components/cv-command-palette.d.ts +1 -1
  36. package/dist/components/cv-command-palette.js +21 -1
  37. package/dist/components/cv-context-menu.d.ts +1 -1
  38. package/dist/components/cv-context-menu.js +2 -1
  39. package/dist/components/cv-copy-button.d.ts +37 -9
  40. package/dist/components/cv-copy-button.js +129 -41
  41. package/dist/components/cv-date-picker.d.ts +1 -1
  42. package/dist/components/cv-date-picker.js +20 -1
  43. package/dist/components/cv-dialog.d.ts +44 -2
  44. package/dist/components/cv-dialog.js +686 -74
  45. package/dist/components/cv-disclosure.d.ts +1 -1
  46. package/dist/components/cv-disclosure.js +2 -1
  47. package/dist/components/cv-drawer.d.ts +29 -1
  48. package/dist/components/cv-drawer.js +229 -4
  49. package/dist/components/cv-feed-article.d.ts +1 -1
  50. package/dist/components/cv-feed-article.js +2 -1
  51. package/dist/components/cv-feed.d.ts +1 -1
  52. package/dist/components/cv-feed.js +2 -1
  53. package/dist/components/cv-grid-cell.d.ts +1 -1
  54. package/dist/components/cv-grid-cell.js +3 -3
  55. package/dist/components/cv-grid-column.d.ts +1 -1
  56. package/dist/components/cv-grid-column.js +1 -1
  57. package/dist/components/cv-grid-row.d.ts +1 -1
  58. package/dist/components/cv-grid.d.ts +1 -1
  59. package/dist/components/cv-grid.js +2 -1
  60. package/dist/components/cv-guidance-anchor.d.ts +47 -0
  61. package/dist/components/cv-guidance-anchor.js +113 -0
  62. package/dist/components/cv-guidance-panel.d.ts +29 -0
  63. package/dist/components/cv-guidance-panel.js +245 -0
  64. package/dist/components/cv-icon.d.ts +2 -1
  65. package/dist/components/cv-icon.js +28 -3
  66. package/dist/components/cv-input.d.ts +7 -1
  67. package/dist/components/cv-input.js +33 -1
  68. package/dist/components/cv-landmark.d.ts +1 -1
  69. package/dist/components/cv-landmark.js +2 -1
  70. package/dist/components/cv-link.d.ts +1 -1
  71. package/dist/components/cv-link.js +2 -1
  72. package/dist/components/cv-listbox-group.d.ts +1 -1
  73. package/dist/components/cv-listbox.d.ts +1 -1
  74. package/dist/components/cv-listbox.js +2 -1
  75. package/dist/components/cv-menu-button.d.ts +24 -1
  76. package/dist/components/cv-menu-button.js +226 -18
  77. package/dist/components/cv-menu-group.d.ts +1 -1
  78. package/dist/components/cv-menu-item.d.ts +1 -1
  79. package/dist/components/cv-menu-item.js +6 -2
  80. package/dist/components/cv-menu.d.ts +1 -1
  81. package/dist/components/cv-menu.js +21 -1
  82. package/dist/components/cv-meter.d.ts +1 -1
  83. package/dist/components/cv-meter.js +6 -22
  84. package/dist/components/cv-number.d.ts +1 -1
  85. package/dist/components/cv-option.d.ts +1 -1
  86. package/dist/components/cv-option.js +3 -9
  87. package/dist/components/cv-popover-positioning.d.ts +22 -0
  88. package/dist/components/cv-popover-positioning.js +112 -0
  89. package/dist/components/cv-popover.d.ts +45 -8
  90. package/dist/components/cv-popover.js +395 -113
  91. package/dist/components/cv-progress-ring.d.ts +1 -1
  92. package/dist/components/cv-progress-ring.js +2 -1
  93. package/dist/components/cv-progress.d.ts +8 -1
  94. package/dist/components/cv-progress.js +41 -10
  95. package/dist/components/cv-radio-group.d.ts +1 -1
  96. package/dist/components/cv-radio.d.ts +1 -1
  97. package/dist/components/cv-radio.js +1 -1
  98. package/dist/components/cv-select-group.d.ts +1 -1
  99. package/dist/components/cv-select-option.d.ts +1 -1
  100. package/dist/components/cv-select-option.js +2 -2
  101. package/dist/components/cv-select.d.ts +1 -1
  102. package/dist/components/cv-select.js +28 -1
  103. package/dist/components/cv-sidebar-item.d.ts +1 -1
  104. package/dist/components/cv-sidebar.d.ts +1 -1
  105. package/dist/components/cv-sidebar.js +3 -2
  106. package/dist/components/cv-slider-multi-thumb.d.ts +1 -1
  107. package/dist/components/cv-slider-multi-thumb.js +2 -1
  108. package/dist/components/cv-slider.d.ts +17 -4
  109. package/dist/components/cv-slider.js +63 -21
  110. package/dist/components/cv-spinbutton.d.ts +1 -1
  111. package/dist/components/cv-spinner.d.ts +1 -1
  112. package/dist/components/cv-spinner.js +2 -1
  113. package/dist/components/cv-switch.d.ts +1 -1
  114. package/dist/components/cv-tab-panel.d.ts +1 -1
  115. package/dist/components/cv-tab.d.ts +1 -1
  116. package/dist/components/cv-table-cell.d.ts +1 -1
  117. package/dist/components/cv-table-cell.js +1 -1
  118. package/dist/components/cv-table-column.d.ts +1 -1
  119. package/dist/components/cv-table-column.js +1 -1
  120. package/dist/components/cv-table-row.d.ts +1 -1
  121. package/dist/components/cv-table-row.js +1 -4
  122. package/dist/components/cv-table.d.ts +1 -3
  123. package/dist/components/cv-table.js +4 -11
  124. package/dist/components/cv-tabs.d.ts +1 -1
  125. package/dist/components/cv-tabs.js +3 -2
  126. package/dist/components/cv-textarea.d.ts +11 -1
  127. package/dist/components/cv-textarea.js +33 -0
  128. package/dist/components/cv-toast-region.d.ts +1 -1
  129. package/dist/components/cv-toast-region.js +2 -1
  130. package/dist/components/cv-toast.d.ts +1 -1
  131. package/dist/components/cv-toast.js +20 -27
  132. package/dist/components/cv-toolbar-item.d.ts +1 -1
  133. package/dist/components/cv-toolbar-separator.d.ts +1 -1
  134. package/dist/components/cv-toolbar.d.ts +1 -1
  135. package/dist/components/cv-toolbar.js +2 -1
  136. package/dist/components/cv-tooltip.d.ts +1 -1
  137. package/dist/components/cv-tooltip.js +2 -1
  138. package/dist/components/cv-treegrid-cell.d.ts +1 -1
  139. package/dist/components/cv-treegrid-cell.js +1 -1
  140. package/dist/components/cv-treegrid-column.d.ts +1 -1
  141. package/dist/components/cv-treegrid-column.js +1 -1
  142. package/dist/components/cv-treegrid-row.d.ts +1 -1
  143. package/dist/components/cv-treegrid-row.js +1 -1
  144. package/dist/components/cv-treegrid.d.ts +1 -1
  145. package/dist/components/cv-treegrid.js +4 -3
  146. package/dist/components/cv-treeitem.d.ts +1 -1
  147. package/dist/components/cv-treeitem.js +2 -2
  148. package/dist/components/cv-treeview.d.ts +1 -1
  149. package/dist/components/cv-treeview.js +2 -1
  150. package/dist/components/cv-window-splitter.d.ts +1 -1
  151. package/dist/components/cv-window-splitter.js +2 -1
  152. package/dist/components/index.d.ts +7 -0
  153. package/dist/components/index.js +3 -0
  154. package/dist/dialog/create-dialog-controller.d.ts +12 -4
  155. package/dist/dialog/create-dialog-controller.js +84 -22
  156. package/dist/dialog/index.d.ts +1 -1
  157. package/dist/index.d.ts +1 -1
  158. package/dist/reatom-lit/ReatomLitElement.d.ts +6 -3
  159. package/dist/reatom-lit/ReatomLitElement.js +18 -8
  160. package/dist/reatom-lit/createAfterRenderScheduler.d.ts +10 -0
  161. package/dist/reatom-lit/createAfterRenderScheduler.js +33 -0
  162. package/dist/reatom-lit/index.d.ts +2 -0
  163. package/dist/reatom-lit/index.js +1 -0
  164. package/dist/reatom-lit/watch.d.ts +1 -1
  165. package/dist/reatom-lit/withReatomElement.js +16 -2
  166. package/dist/register.js +4 -1
  167. package/dist/styles/component-styles.js +4 -0
  168. package/dist/styles/uno-generated.d.ts +2 -0
  169. package/dist/styles/uno-generated.js +1 -0
  170. package/dist/styles/uno-utilities.d.ts +5 -0
  171. package/dist/styles/uno-utilities.js +7 -0
  172. package/dist/theme/cv-theme-provider.d.ts +1 -1
  173. package/dist/theme/cv-theme-provider.js +2 -2
  174. package/dist/theme/tokens.css +619 -162
  175. package/package.json +9 -5
  176. package/specs/components/bottom-sheet.md +93 -0
  177. package/specs/components/button.md +8 -0
  178. package/specs/components/callout.md +8 -0
  179. package/specs/components/copy-button.md +54 -17
  180. package/specs/components/dialog.md +72 -43
  181. package/specs/components/drawer.md +18 -13
  182. package/specs/components/guidance-anchor.md +64 -0
  183. package/specs/components/guidance-panel.md +92 -0
  184. package/specs/components/input.md +7 -0
  185. package/specs/components/menu.md +8 -0
  186. package/specs/components/option.md +9 -9
  187. package/specs/components/progress.md +11 -0
  188. package/specs/components/sidebar.md +12 -12
  189. package/specs/components/table.md +13 -13
  190. package/specs/components/theme.md +13 -13
  191. package/specs/components/treegrid.md +15 -15
  192. package/specs/components/treeview.md +10 -10
@@ -1,10 +1,10 @@
1
1
  import { render } from 'lit';
2
2
  import { CVDialog } from '../components/cv-dialog.js';
3
3
  const sizeMap = {
4
- s: '320px',
5
- m: '480px',
6
- l: '640px',
7
- xl: '800px',
4
+ s: 'var(--cv-dialog-width-s)',
5
+ m: 'var(--cv-dialog-width-m)',
6
+ l: 'var(--cv-dialog-width-l)',
7
+ xl: 'var(--cv-dialog-width-xl)',
8
8
  };
9
9
  const STANDARD_FOCUSABLE_SELECTORS = [
10
10
  'a[href]',
@@ -19,21 +19,21 @@ const STANDARD_FOCUSABLE_SELECTORS = [
19
19
  ].join(',');
20
20
  const INPUT_LIKE_COMPONENTS = ['cv-input', 'cv-number', 'cv-textarea', 'cv-select'];
21
21
  const managedDialogStyles = `
22
- cv-dialog.cv-managed-dialog::part(trigger) {
22
+ :is(cv-dialog, cv-bottom-sheet).cv-managed-dialog::part(trigger) {
23
23
  display: none;
24
24
  }
25
25
 
26
- cv-dialog.cv-managed-dialog::part(content) {
26
+ :is(cv-dialog, cv-bottom-sheet).cv-managed-dialog::part(content) {
27
27
  gap: 0;
28
28
  padding: 0;
29
29
  overflow: hidden;
30
30
  }
31
31
 
32
- cv-dialog.cv-managed-dialog::part(body) {
32
+ :is(cv-dialog, cv-bottom-sheet).cv-managed-dialog::part(body) {
33
33
  padding: 0;
34
34
  }
35
35
 
36
- cv-dialog.cv-managed-dialog::part(footer) {
36
+ :is(cv-dialog, cv-bottom-sheet).cv-managed-dialog::part(footer) {
37
37
  display: block;
38
38
  padding: 0;
39
39
  }
@@ -49,7 +49,7 @@ const managedDialogStyles = `
49
49
  justify-content: flex-end;
50
50
  padding: var(--cv-space-4, 16px);
51
51
  border-top: 1px solid var(--cv-color-border, #2a3245);
52
- background: color-mix(in oklab, var(--cv-color-surface-elevated, #1d2432) 90%, black);
52
+ background: var(--cv-color-surface-glass-strong, var(--cv-color-surface-elevated, #1d2432));
53
53
  }
54
54
 
55
55
  @media (max-width: 640px) {
@@ -65,6 +65,60 @@ const managedDialogStyles = `
65
65
  let stylesInjected = false;
66
66
  let lastDeepFocusedElement = null;
67
67
  let focusTrackerInstalled = false;
68
+ const managedInertStack = [];
69
+ const managedInertElements = new Set();
70
+ function restoreManagedInertElements() {
71
+ for (const element of managedInertElements) {
72
+ element.removeAttribute('inert');
73
+ }
74
+ managedInertElements.clear();
75
+ }
76
+ function removeManagedInertSurface(element) {
77
+ for (let index = managedInertStack.length - 1; index >= 0; index -= 1) {
78
+ if (managedInertStack[index] === element) {
79
+ managedInertStack.splice(index, 1);
80
+ }
81
+ }
82
+ }
83
+ function getTopManagedInertSurface() {
84
+ for (let index = managedInertStack.length - 1; index >= 0; index -= 1) {
85
+ const element = managedInertStack[index];
86
+ if (element?.isConnected) {
87
+ return element;
88
+ }
89
+ managedInertStack.splice(index, 1);
90
+ }
91
+ return null;
92
+ }
93
+ function syncManagedInert() {
94
+ restoreManagedInertElements();
95
+ if (typeof document === 'undefined')
96
+ return;
97
+ const topSurface = getTopManagedInertSurface();
98
+ if (!topSurface)
99
+ return;
100
+ for (const element of Array.from(document.body.children)) {
101
+ if (element === topSurface || element.hasAttribute('inert'))
102
+ continue;
103
+ element.setAttribute('inert', '');
104
+ managedInertElements.add(element);
105
+ }
106
+ }
107
+ function activateManagedInertSurface(element) {
108
+ removeManagedInertSurface(element);
109
+ managedInertStack.push(element);
110
+ syncManagedInert();
111
+ }
112
+ function deactivateManagedInertSurface(element) {
113
+ removeManagedInertSurface(element);
114
+ syncManagedInert();
115
+ }
116
+ function deactivateManagedInertSurfaces(elements) {
117
+ for (const element of elements) {
118
+ removeManagedInertSurface(element);
119
+ }
120
+ syncManagedInert();
121
+ }
68
122
  function injectStyles() {
69
123
  if (stylesInjected || typeof document === 'undefined')
70
124
  return;
@@ -156,28 +210,31 @@ export function createDialogController(adapters = {}) {
156
210
  const activeDialogs = new Map();
157
211
  let zIndexCounter = 1100;
158
212
  const findFirstFocusable = adapters.findFirstFocusable ?? defaultFindFirstFocusable;
213
+ const createCustomDialogElement = adapters.createCustomDialogElement ??
214
+ (() => document.createElement('cv-dialog'));
159
215
  const getNextZIndex = () => zIndexCounter++;
160
216
  const addDialog = (element, closeFn) => {
161
217
  activeDialogs.set(element, closeFn);
162
218
  const zIndex = getNextZIndex().toString();
163
219
  element.style.setProperty('--cv-dialog-z-index', zIndex);
220
+ element.style.setProperty('--cv-bottom-sheet-z-index', zIndex);
164
221
  };
165
222
  const removeDialog = (element) => {
166
223
  activeDialogs.delete(element);
224
+ deactivateManagedInertSurface(element);
167
225
  if (activeDialogs.size === 0) {
168
226
  zIndexCounter = 1100;
169
- adapters.restoreInert?.();
170
227
  }
171
228
  };
172
- const present = async ({ element, title, show, close }) => {
229
+ const present = async ({ element, title, show, close, autoFocus = true, }) => {
173
230
  const focusRestoreTarget = getFocusRestoreTarget();
174
231
  document.body.appendChild(element);
175
232
  addDialog(element, close);
176
233
  element.addEventListener('cv-after-show', () => {
177
234
  if (!activeDialogs.has(element))
178
235
  return;
179
- adapters.setInertExcept?.(element);
180
- const firstFocusable = findFirstFocusable(element);
236
+ activateManagedInertSurface(element);
237
+ const firstFocusable = autoFocus ? findFirstFocusable(element) : null;
181
238
  if (firstFocusable) {
182
239
  setTimeout(() => {
183
240
  if (firstFocusable.isConnected) {
@@ -185,9 +242,6 @@ export function createDialogController(adapters = {}) {
185
242
  }
186
243
  }, 50);
187
244
  }
188
- if (title) {
189
- adapters.announce?.(title, 'assertive');
190
- }
191
245
  }, { once: true });
192
246
  try {
193
247
  return await show();
@@ -212,7 +266,7 @@ export function createDialogController(adapters = {}) {
212
266
  isResolved = true;
213
267
  resolve(result);
214
268
  };
215
- const dialog = document.createElement('cv-dialog');
269
+ const dialog = createCustomDialogElement();
216
270
  dialog.classList.add('cv-managed-dialog');
217
271
  dialog.noHeader = options.noHeader ?? false;
218
272
  dialog.closable = options.closable !== false;
@@ -223,6 +277,7 @@ export function createDialogController(adapters = {}) {
223
277
  dialog.classList.add(...options.className.split(/\s+/).filter(Boolean));
224
278
  }
225
279
  dialog.style.setProperty('--cv-dialog-width', sizeMap[options.size || 'm']);
280
+ dialog.style.setProperty('--cv-bottom-sheet-width', sizeMap[options.size || 'm']);
226
281
  if (!options.noHeader && options.title) {
227
282
  const title = document.createElement('span');
228
283
  title.slot = 'title';
@@ -270,14 +325,11 @@ export function createDialogController(adapters = {}) {
270
325
  if (!activeDialogs.has(dialog))
271
326
  return;
272
327
  hasOpened = true;
273
- adapters.setInertExcept?.(dialog);
328
+ activateManagedInertSurface(dialog);
274
329
  const firstFocusable = findFirstFocusable(dialog);
275
330
  if (firstFocusable) {
276
331
  setTimeout(() => firstFocusable.focus(), 50);
277
332
  }
278
- if (options.title) {
279
- adapters.announce?.(options.title, 'assertive');
280
- }
281
333
  });
282
334
  dialog.addEventListener('cv-change', (event) => {
283
335
  const detail = event.detail;
@@ -306,14 +358,24 @@ export function createDialogController(adapters = {}) {
306
358
  });
307
359
  };
308
360
  const closeAll = () => {
361
+ const dialogs = [...activeDialogs.keys()];
309
362
  activeDialogs.forEach((close) => close());
310
363
  activeDialogs.clear();
311
364
  zIndexCounter = 1100;
312
- adapters.restoreInert?.();
365
+ deactivateManagedInertSurfaces(dialogs);
366
+ };
367
+ const closeTop = () => {
368
+ const close = [...activeDialogs.values()].at(-1);
369
+ if (!close) {
370
+ return false;
371
+ }
372
+ close();
373
+ return true;
313
374
  };
314
375
  return {
315
376
  present,
316
377
  showCustom,
378
+ closeTop,
317
379
  closeAll,
318
380
  getActiveCount: () => activeDialogs.size,
319
381
  };
@@ -1,2 +1,2 @@
1
1
  export { createDialogController } from './create-dialog-controller.js';
2
- export type { CustomDialogOptions, DialogController, DialogControllerAdapters, DialogPriority, ManagedDialogOptions, } from './create-dialog-controller.js';
2
+ export type { CustomDialogOptions, DialogController, DialogControllerAdapters, ManagedDialogOptions, } from './create-dialog-controller.js';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export * from './components/index.js';
2
2
  export { createDialogController } from './dialog/create-dialog-controller.js';
3
- export type { CustomDialogOptions, DialogController, DialogControllerAdapters, DialogPriority, ManagedDialogOptions, } from './dialog/create-dialog-controller.js';
3
+ export type { CustomDialogOptions, DialogController, DialogControllerAdapters, ManagedDialogOptions, } from './dialog/create-dialog-controller.js';
4
4
  export * from './reatom-lit/index.js';
5
5
  export * from './theme/index.js';
6
6
  export * from './toast/index.js';
@@ -3,9 +3,10 @@ import type { CSSResultGroup, CSSResultOrNative, PropertyValues, TemplateResult
3
3
  declare const __aliased_event_dispatch: unique symbol;
4
4
  import { type ComponentHostDisplay } from '../styles/component-styles.js';
5
5
  /**
6
- * Lazily set the shared UnoCSS utility stylesheet.
7
- * Call once at app bootstrap (after `virtual:uno.css` is available):
8
- * import {unoUtilities} from './styles/uno-utilities.js'
6
+ * Override the shared UnoCSS utility stylesheet.
7
+ * By default, ReatomLitElement uses the bundled runtime-generated utilities.
8
+ * Call this only when a host app needs to provide a custom utility sheet:
9
+ * import {unoUtilities} from '../styles/uno-utilities.js'
9
10
  * setUnoUtilities(unoUtilities)
10
11
  */
11
12
  export declare function setUnoUtilities(sheet: CSSResultOrNative): void;
@@ -15,9 +16,11 @@ export declare class ReatomLitElement extends LitElement {
15
16
  private __frame;
16
17
  private __abstractRender?;
17
18
  private __unmount?;
19
+ private __hasRenderedWithReatom;
18
20
  private [__aliased_event_dispatch];
19
21
  constructor();
20
22
  private __initAbstractRender;
23
+ private __mountAbstractRender;
21
24
  protected render(): TemplateResult | unknown;
22
25
  protected update(changedProperties: PropertyValues): void;
23
26
  connectedCallback(): void;
@@ -4,15 +4,17 @@ const __inner_update = Symbol('Inner update');
4
4
  const __aliased_event_dispatch = Symbol('Aliased event dispatch');
5
5
  const CV_EVENT_PREFIX = 'cv-';
6
6
  import { componentResetStyles, getComponentHostDisplayStyles, } from '../styles/component-styles.js';
7
- let _unoUtilities;
7
+ import { unoUtilities as bundledUnoUtilities } from '../styles/uno-utilities.js';
8
+ let _unoUtilitiesOverride;
8
9
  /**
9
- * Lazily set the shared UnoCSS utility stylesheet.
10
- * Call once at app bootstrap (after `virtual:uno.css` is available):
11
- * import {unoUtilities} from './styles/uno-utilities.js'
10
+ * Override the shared UnoCSS utility stylesheet.
11
+ * By default, ReatomLitElement uses the bundled runtime-generated utilities.
12
+ * Call this only when a host app needs to provide a custom utility sheet:
13
+ * import {unoUtilities} from '../styles/uno-utilities.js'
12
14
  * setUnoUtilities(unoUtilities)
13
15
  */
14
16
  export function setUnoUtilities(sheet) {
15
- _unoUtilities = sheet;
17
+ _unoUtilitiesOverride = sheet;
16
18
  }
17
19
  export class ReatomLitElement extends LitElement {
18
20
  static hostDisplay = 'block';
@@ -20,15 +22,15 @@ export class ReatomLitElement extends LitElement {
20
22
  const base = [
21
23
  componentResetStyles,
22
24
  getComponentHostDisplayStyles(this.hostDisplay),
25
+ _unoUtilitiesOverride ?? bundledUnoUtilities,
23
26
  ...super.finalizeStyles(styles),
24
27
  ];
25
- if (_unoUtilities)
26
- base.push(_unoUtilities);
27
28
  return base;
28
29
  }
29
30
  __frame;
30
31
  __abstractRender;
31
32
  __unmount;
33
+ __hasRenderedWithReatom = false;
32
34
  [__aliased_event_dispatch] = false;
33
35
  constructor() {
34
36
  super();
@@ -46,14 +48,21 @@ export class ReatomLitElement extends LitElement {
46
48
  return this.requestUpdate(__inner_update, 1);
47
49
  },
48
50
  name: 'ReatomElement',
51
+ abortOnUnmount: false,
49
52
  });
50
53
  }
54
+ __mountAbstractRender() {
55
+ if (!this.isConnected || this.__unmount || !this.__hasRenderedWithReatom)
56
+ return;
57
+ this.__unmount = this.__abstractRender.mount();
58
+ }
51
59
  render() {
52
60
  return undefined;
53
61
  }
54
62
  update(changedProperties) {
55
63
  this.__initAbstractRender();
56
64
  const { result: value } = this.__abstractRender.render(changedProperties);
65
+ this.__hasRenderedWithReatom = true;
57
66
  const hadOwnRender = Object.prototype.hasOwnProperty.call(this, 'render');
58
67
  const ownRenderDescriptor = hadOwnRender ? Object.getOwnPropertyDescriptor(this, 'render') : undefined;
59
68
  // Keep Lit's native update path intact so SSR hydration support can
@@ -73,11 +82,12 @@ export class ReatomLitElement extends LitElement {
73
82
  delete this.render;
74
83
  }
75
84
  }
85
+ this.__mountAbstractRender();
76
86
  }
77
87
  connectedCallback() {
78
88
  super.connectedCallback();
79
89
  this.__initAbstractRender();
80
- this.__unmount = this.__abstractRender.mount();
90
+ this.__mountAbstractRender();
81
91
  }
82
92
  disconnectedCallback() {
83
93
  super.disconnectedCallback();
@@ -0,0 +1,10 @@
1
+ interface AfterRenderHost {
2
+ readonly isConnected: boolean;
3
+ readonly updateComplete: Promise<unknown>;
4
+ }
5
+ export interface AfterRenderScheduler {
6
+ cancel(): void;
7
+ schedule(task: () => void): void;
8
+ }
9
+ export declare function createAfterRenderScheduler(host: AfterRenderHost): AfterRenderScheduler;
10
+ export {};
@@ -0,0 +1,33 @@
1
+ export function createAfterRenderScheduler(host) {
2
+ let frame = 0;
3
+ let runId = 0;
4
+ const clearFrame = () => {
5
+ if (!frame) {
6
+ return;
7
+ }
8
+ window.cancelAnimationFrame(frame);
9
+ frame = 0;
10
+ };
11
+ return {
12
+ cancel() {
13
+ runId += 1;
14
+ clearFrame();
15
+ },
16
+ schedule(task) {
17
+ const currentRunId = ++runId;
18
+ clearFrame();
19
+ void host.updateComplete.then(() => {
20
+ if (!host.isConnected || currentRunId !== runId) {
21
+ return;
22
+ }
23
+ frame = window.requestAnimationFrame(() => {
24
+ frame = 0;
25
+ if (!host.isConnected || currentRunId !== runId) {
26
+ return;
27
+ }
28
+ task();
29
+ });
30
+ });
31
+ },
32
+ };
33
+ }
@@ -2,3 +2,5 @@ export { ReatomLitElement, setUnoUtilities } from './ReatomLitElement.js';
2
2
  export { withReatomElement } from './withReatomElement.js';
3
3
  export { html, svg } from './html.js';
4
4
  export { watch } from './watch.js';
5
+ export { createAfterRenderScheduler } from './createAfterRenderScheduler.js';
6
+ export type { AfterRenderScheduler } from './createAfterRenderScheduler.js';
@@ -2,3 +2,4 @@ export { ReatomLitElement, setUnoUtilities } from './ReatomLitElement.js';
2
2
  export { withReatomElement } from './withReatomElement.js';
3
3
  export { html, svg } from './html.js';
4
4
  export { watch } from './watch.js';
5
+ export { createAfterRenderScheduler } from './createAfterRenderScheduler.js';
@@ -11,5 +11,5 @@ declare class AtomDirective extends AsyncDirective {
11
11
  subscribe(): void;
12
12
  render(target: AtomLike, frame: Frame): symbol;
13
13
  }
14
- export declare const watch: (target: AtomLike) => import("lit/async-directive.js").DirectiveResult<typeof AtomDirective>;
14
+ export declare const watch: (target: AtomLike) => import("lit-html/directive.js").DirectiveResult<typeof AtomDirective>;
15
15
  export {};
@@ -7,6 +7,8 @@ export const withReatomElement = (superClass) => {
7
7
  __changedProps;
8
8
  __abstractRender;
9
9
  __unmount;
10
+ __hasRenderedWithReatom = false;
11
+ // oxlint-disable-next-line typescript-eslint/no-explicit-any -- TypeScript mixin constructors must use any[].
10
12
  constructor(...args) {
11
13
  super(...args);
12
14
  this.__frame = top();
@@ -25,10 +27,18 @@ export const withReatomElement = (superClass) => {
25
27
  return this.requestUpdate(__inner_update, 1);
26
28
  },
27
29
  name: 'ReatomElement',
30
+ abortOnUnmount: false,
28
31
  });
29
32
  }
33
+ __mountAbstractRender() {
34
+ if (!this.isConnected || this.__unmount || !this.__hasRenderedWithReatom)
35
+ return;
36
+ this.__unmount = this.__abstractRender.mount();
37
+ }
30
38
  render() {
31
- return this.__abstractRender.render(this.__changedProps).result;
39
+ const { result } = this.__abstractRender.render(this.__changedProps);
40
+ this.__hasRenderedWithReatom = true;
41
+ return result;
32
42
  }
33
43
  shouldUpdate(_changedProperties) {
34
44
  if (_changedProperties.size === 1 && _changedProperties.has(__inner_update)) {
@@ -39,7 +49,11 @@ export const withReatomElement = (superClass) => {
39
49
  }
40
50
  connectedCallback() {
41
51
  super.connectedCallback();
42
- this.__unmount = this.__abstractRender.mount();
52
+ this.__mountAbstractRender();
53
+ }
54
+ updated(changedProperties) {
55
+ super.updated(changedProperties);
56
+ this.__mountAbstractRender();
43
57
  }
44
58
  disconnectedCallback() {
45
59
  super.disconnectedCallback();
package/dist/register.js CHANGED
@@ -1,4 +1,4 @@
1
- import { CVAccordion, CVAccordionItem, CVAlertDialog, CVAlert, CVBadge, CVBreadcrumb, CVBreadcrumbItem, CVButton, CVCallout, CVCard, CVCarousel, CVCarouselSlide, CVCheckbox, CVCombobox, CVComboboxGroup, CVComboboxOption, CVCommandItem, CVCommandPalette, CVContextMenu, CVCopyButton, CVDatePicker, CVDialog, CVDisclosure, CVDrawer, CVFeed, CVFeedArticle, CVGrid, CVGridCell, CVGridColumn, CVGridRow, CVIcon, CVInput, CVLandmark, CVLink, CVListbox, CVListboxGroup, CVMenu, CVMenuButton, CVMenuGroup, CVMenuItem, CVMeter, CVNumber, CVOption, CVPopover, CVProgress, CVProgressRing, CVRadio, CVRadioGroup, CVSelect, CVSelectGroup, CVSelectOption, CVSidebar, CVSidebarItem, CVSlider, CVSliderMultiThumb, CVSpinbutton, CVSpinner, CVSwitch, CVTab, CVTabPanel, CVTable, CVTableCell, CVTableColumn, CVTableRow, CVTabs, CVTextarea, CVToast, CVToastRegion, CVToolbar, CVToolbarItem, CVToolbarSeparator, CVTooltip, CVTreegrid, CVTreegridCell, CVTreegridColumn, CVTreegridRow, CVTreeItem, CVTreeview, CVWindowSplitter, } from './components/index.js';
1
+ import { CVAccordion, CVAccordionItem, CVAlertDialog, CVAlert, CVBadge, CVBottomSheet, CVBreadcrumb, CVBreadcrumbItem, CVButton, CVCallout, CVCard, CVCarousel, CVCarouselSlide, CVCheckbox, CVCombobox, CVComboboxGroup, CVComboboxOption, CVCommandItem, CVCommandPalette, CVContextMenu, CVCopyButton, CVDatePicker, CVDialog, CVDisclosure, CVDrawer, CVFeed, CVFeedArticle, CVGrid, CVGridCell, CVGridColumn, CVGridRow, CVGuidanceAnchor, CVGuidancePanel, CVIcon, CVInput, CVLandmark, CVLink, CVListbox, CVListboxGroup, CVMenu, CVMenuButton, CVMenuGroup, CVMenuItem, CVMeter, CVNumber, CVOption, CVPopover, CVProgress, CVProgressRing, CVRadio, CVRadioGroup, CVSelect, CVSelectGroup, CVSelectOption, CVSidebar, CVSidebarItem, CVSlider, CVSliderMultiThumb, CVSpinbutton, CVSpinner, CVSwitch, CVTab, CVTabPanel, CVTable, CVTableCell, CVTableColumn, CVTableRow, CVTabs, CVTextarea, CVToast, CVToastRegion, CVToolbar, CVToolbarItem, CVToolbarSeparator, CVTooltip, CVTreegrid, CVTreegridCell, CVTreegridColumn, CVTreegridRow, CVTreeItem, CVTreeview, CVWindowSplitter, } from './components/index.js';
2
2
  import { CVThemeProvider } from './theme/index.js';
3
3
  export function registerUikit() {
4
4
  CVThemeProvider.define();
@@ -9,6 +9,7 @@ export function registerUikit() {
9
9
  CVBreadcrumbItem.define();
10
10
  CVBreadcrumb.define();
11
11
  CVBadge.define();
12
+ CVBottomSheet.define();
12
13
  CVButton.define();
13
14
  CVCallout.define();
14
15
  CVCard.define();
@@ -32,6 +33,8 @@ export function registerUikit() {
32
33
  CVGridColumn.define();
33
34
  CVGridRow.define();
34
35
  CVGrid.define();
36
+ CVGuidanceAnchor.define();
37
+ CVGuidancePanel.define();
35
38
  CVIcon.define();
36
39
  CVInput.define();
37
40
  CVLandmark.define();
@@ -5,6 +5,10 @@ export const componentResetStyles = css `
5
5
  display: none !important;
6
6
  }
7
7
 
8
+ .cv-u-discrete-presence {
9
+ transition-behavior: allow-discrete;
10
+ }
11
+
8
12
  :host,
9
13
  *,
10
14
  *::before,
@@ -0,0 +1,2 @@
1
+ declare const _default: "/* layer: shortcuts */\n.cv-u-panel-shell{display:grid;overflow:hidden;border-width:1px;border-color:var(--cv-color-border);border-radius:var(--cv-radius-md);background-color:var(--cv-color-surface);--un-shadow:var(--cv-shadow-sm);box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow);}\n.cv-u-fill{min-width:0;flex:1 1 0%;}\n.cv-u-control-shell{display:flex;align-items:center;gap:var(--cv-space-2);}\n.cv-u-row{display:flex;align-items:center;}\n.cv-u-row-between{display:flex;align-items:center;justify-content:space-between;}\n.cv-u-icon-slot{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;}\n.cv-u-inline-center{display:inline-flex;align-items:center;justify-content:center;}\n/* layer: default */\n.b{border-width:1px;}\n.filter{filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}";
2
+ export default _default;
@@ -0,0 +1 @@
1
+ export default "/* layer: shortcuts */\n.cv-u-panel-shell{display:grid;overflow:hidden;border-width:1px;border-color:var(--cv-color-border);border-radius:var(--cv-radius-md);background-color:var(--cv-color-surface);--un-shadow:var(--cv-shadow-sm);box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow);}\n.cv-u-fill{min-width:0;flex:1 1 0%;}\n.cv-u-control-shell{display:flex;align-items:center;gap:var(--cv-space-2);}\n.cv-u-row{display:flex;align-items:center;}\n.cv-u-row-between{display:flex;align-items:center;justify-content:space-between;}\n.cv-u-icon-slot{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;}\n.cv-u-inline-center{display:inline-flex;align-items:center;justify-content:center;}\n/* layer: default */\n.b{border-width:1px;}\n.filter{filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * UnoCSS-generated utility classes as a Lit CSSResult.
3
+ * Only contains utilities actually used in scanned runtime source files.
4
+ */
5
+ export declare const unoUtilities: import("lit").CSSResult;
@@ -0,0 +1,7 @@
1
+ import { unsafeCSS } from 'lit';
2
+ import unoStyles from './uno-generated.js';
3
+ /**
4
+ * UnoCSS-generated utility classes as a Lit CSSResult.
5
+ * Only contains utilities actually used in scanned runtime source files.
6
+ */
7
+ export const unoUtilities = unsafeCSS(unoStyles);
@@ -28,5 +28,5 @@ export declare class CVThemeProvider extends LitElement {
28
28
  private _setupMediaListener;
29
29
  private _removeMediaListener;
30
30
  private _applyCurrentTheme;
31
- protected render(): import("lit").TemplateResult<1>;
31
+ protected render(): import("lit-html").TemplateResult<1>;
32
32
  }
@@ -1,5 +1,5 @@
1
1
  import { LitElement, css, html } from 'lit';
2
- import { applyTheme, getTheme } from './theme-engine.js';
2
+ import { getTheme } from './theme-engine.js';
3
3
  export class CVThemeProvider extends LitElement {
4
4
  static elementName = 'cv-theme-provider';
5
5
  static get properties() {
@@ -93,7 +93,7 @@ export class CVThemeProvider extends LitElement {
93
93
  }
94
94
  const definition = getTheme(this.theme);
95
95
  if (!definition) {
96
- console.warn(`[cv-theme-provider] Theme "${this.theme}" is not registered.`);
96
+ globalThis['console']?.warn?.(`[cv-theme-provider] Theme "${this.theme}" is not registered.`);
97
97
  return;
98
98
  }
99
99
  for (const [key, value] of Object.entries(definition.tokens)) {