@chromvoid/uikit 0.1.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 (246) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +96 -0
  3. package/dist/components/cv-accordion-item.d.ts +69 -0
  4. package/dist/components/cv-accordion-item.js +176 -0
  5. package/dist/components/cv-accordion.d.ts +79 -0
  6. package/dist/components/cv-accordion.js +310 -0
  7. package/dist/components/cv-alert-dialog.d.ts +86 -0
  8. package/dist/components/cv-alert-dialog.js +393 -0
  9. package/dist/components/cv-alert.d.ts +48 -0
  10. package/dist/components/cv-alert.js +156 -0
  11. package/dist/components/cv-badge.d.ts +56 -0
  12. package/dist/components/cv-badge.js +280 -0
  13. package/dist/components/cv-breadcrumb-item.d.ts +35 -0
  14. package/dist/components/cv-breadcrumb-item.js +64 -0
  15. package/dist/components/cv-breadcrumb.d.ts +39 -0
  16. package/dist/components/cv-breadcrumb.js +160 -0
  17. package/dist/components/cv-button.d.ts +83 -0
  18. package/dist/components/cv-button.js +541 -0
  19. package/dist/components/cv-callout.d.ts +32 -0
  20. package/dist/components/cv-callout.js +221 -0
  21. package/dist/components/cv-card.d.ts +48 -0
  22. package/dist/components/cv-card.js +269 -0
  23. package/dist/components/cv-carousel-slide.d.ts +25 -0
  24. package/dist/components/cv-carousel-slide.js +51 -0
  25. package/dist/components/cv-carousel.d.ts +96 -0
  26. package/dist/components/cv-carousel.js +457 -0
  27. package/dist/components/cv-checkbox.d.ts +84 -0
  28. package/dist/components/cv-checkbox.js +274 -0
  29. package/dist/components/cv-combobox-group.d.ts +15 -0
  30. package/dist/components/cv-combobox-group.js +34 -0
  31. package/dist/components/cv-combobox-option.d.ts +30 -0
  32. package/dist/components/cv-combobox-option.js +66 -0
  33. package/dist/components/cv-combobox.d.ts +135 -0
  34. package/dist/components/cv-combobox.js +834 -0
  35. package/dist/components/cv-command-item.d.ts +30 -0
  36. package/dist/components/cv-command-item.js +68 -0
  37. package/dist/components/cv-command-palette.d.ts +105 -0
  38. package/dist/components/cv-command-palette.js +578 -0
  39. package/dist/components/cv-context-menu.d.ts +98 -0
  40. package/dist/components/cv-context-menu.js +515 -0
  41. package/dist/components/cv-copy-button.d.ts +61 -0
  42. package/dist/components/cv-copy-button.js +318 -0
  43. package/dist/components/cv-date-picker.d.ts +161 -0
  44. package/dist/components/cv-date-picker.js +803 -0
  45. package/dist/components/cv-dialog.d.ts +89 -0
  46. package/dist/components/cv-dialog.js +459 -0
  47. package/dist/components/cv-disclosure.d.ts +57 -0
  48. package/dist/components/cv-disclosure.js +241 -0
  49. package/dist/components/cv-drawer.d.ts +102 -0
  50. package/dist/components/cv-drawer.js +595 -0
  51. package/dist/components/cv-feed-article.d.ts +26 -0
  52. package/dist/components/cv-feed-article.js +52 -0
  53. package/dist/components/cv-feed.d.ts +62 -0
  54. package/dist/components/cv-feed.js +310 -0
  55. package/dist/components/cv-grid-cell.d.ts +30 -0
  56. package/dist/components/cv-grid-cell.js +57 -0
  57. package/dist/components/cv-grid-column.d.ts +30 -0
  58. package/dist/components/cv-grid-column.js +43 -0
  59. package/dist/components/cv-grid-row.d.ts +30 -0
  60. package/dist/components/cv-grid-row.js +42 -0
  61. package/dist/components/cv-grid.d.ts +119 -0
  62. package/dist/components/cv-grid.js +567 -0
  63. package/dist/components/cv-icon.d.ts +57 -0
  64. package/dist/components/cv-icon.js +352 -0
  65. package/dist/components/cv-input.d.ts +127 -0
  66. package/dist/components/cv-input.js +482 -0
  67. package/dist/components/cv-landmark.d.ts +32 -0
  68. package/dist/components/cv-landmark.js +62 -0
  69. package/dist/components/cv-link.d.ts +22 -0
  70. package/dist/components/cv-link.js +99 -0
  71. package/dist/components/cv-listbox-group.d.ts +15 -0
  72. package/dist/components/cv-listbox-group.js +42 -0
  73. package/dist/components/cv-listbox.d.ts +81 -0
  74. package/dist/components/cv-listbox.js +388 -0
  75. package/dist/components/cv-menu-button.d.ts +118 -0
  76. package/dist/components/cv-menu-button.js +822 -0
  77. package/dist/components/cv-menu-group.d.ts +20 -0
  78. package/dist/components/cv-menu-group.js +48 -0
  79. package/dist/components/cv-menu-item.d.ts +52 -0
  80. package/dist/components/cv-menu-item.js +105 -0
  81. package/dist/components/cv-menu.d.ts +62 -0
  82. package/dist/components/cv-menu.js +414 -0
  83. package/dist/components/cv-meter.d.ts +66 -0
  84. package/dist/components/cv-meter.js +154 -0
  85. package/dist/components/cv-number.d.ts +139 -0
  86. package/dist/components/cv-number.js +553 -0
  87. package/dist/components/cv-option.d.ts +30 -0
  88. package/dist/components/cv-option.js +84 -0
  89. package/dist/components/cv-popover.d.ts +87 -0
  90. package/dist/components/cv-popover.js +373 -0
  91. package/dist/components/cv-progress-ring.d.ts +45 -0
  92. package/dist/components/cv-progress-ring.js +169 -0
  93. package/dist/components/cv-progress.d.ts +45 -0
  94. package/dist/components/cv-progress.js +148 -0
  95. package/dist/components/cv-radio-group.d.ts +79 -0
  96. package/dist/components/cv-radio-group.js +398 -0
  97. package/dist/components/cv-radio.d.ts +36 -0
  98. package/dist/components/cv-radio.js +123 -0
  99. package/dist/components/cv-select-group.d.ts +15 -0
  100. package/dist/components/cv-select-group.js +44 -0
  101. package/dist/components/cv-select-option.d.ts +30 -0
  102. package/dist/components/cv-select-option.js +66 -0
  103. package/dist/components/cv-select.d.ts +128 -0
  104. package/dist/components/cv-select.js +666 -0
  105. package/dist/components/cv-sidebar-item.d.ts +26 -0
  106. package/dist/components/cv-sidebar-item.js +142 -0
  107. package/dist/components/cv-sidebar.d.ts +171 -0
  108. package/dist/components/cv-sidebar.js +767 -0
  109. package/dist/components/cv-slider-multi-thumb.d.ts +73 -0
  110. package/dist/components/cv-slider-multi-thumb.js +374 -0
  111. package/dist/components/cv-slider.d.ts +84 -0
  112. package/dist/components/cv-slider.js +328 -0
  113. package/dist/components/cv-spinbutton.d.ts +121 -0
  114. package/dist/components/cv-spinbutton.js +486 -0
  115. package/dist/components/cv-spinner.d.ts +18 -0
  116. package/dist/components/cv-spinner.js +95 -0
  117. package/dist/components/cv-switch.d.ts +81 -0
  118. package/dist/components/cv-switch.js +285 -0
  119. package/dist/components/cv-tab-panel.d.ts +20 -0
  120. package/dist/components/cv-tab-panel.js +37 -0
  121. package/dist/components/cv-tab.d.ts +40 -0
  122. package/dist/components/cv-tab.js +132 -0
  123. package/dist/components/cv-table-cell.d.ts +31 -0
  124. package/dist/components/cv-table-cell.js +49 -0
  125. package/dist/components/cv-table-column.d.ts +37 -0
  126. package/dist/components/cv-table-column.js +63 -0
  127. package/dist/components/cv-table-row.d.ts +30 -0
  128. package/dist/components/cv-table-row.js +45 -0
  129. package/dist/components/cv-table.d.ts +147 -0
  130. package/dist/components/cv-table.js +607 -0
  131. package/dist/components/cv-tabs.d.ts +70 -0
  132. package/dist/components/cv-tabs.js +524 -0
  133. package/dist/components/cv-textarea.d.ts +108 -0
  134. package/dist/components/cv-textarea.js +328 -0
  135. package/dist/components/cv-toast-region.d.ts +39 -0
  136. package/dist/components/cv-toast-region.js +162 -0
  137. package/dist/components/cv-toast.d.ts +67 -0
  138. package/dist/components/cv-toast.js +315 -0
  139. package/dist/components/cv-toolbar-item.d.ts +25 -0
  140. package/dist/components/cv-toolbar-item.js +72 -0
  141. package/dist/components/cv-toolbar-separator.d.ts +25 -0
  142. package/dist/components/cv-toolbar-separator.js +45 -0
  143. package/dist/components/cv-toolbar.d.ts +63 -0
  144. package/dist/components/cv-toolbar.js +295 -0
  145. package/dist/components/cv-tooltip.d.ts +83 -0
  146. package/dist/components/cv-tooltip.js +455 -0
  147. package/dist/components/cv-treegrid-cell.d.ts +30 -0
  148. package/dist/components/cv-treegrid-cell.js +57 -0
  149. package/dist/components/cv-treegrid-column.d.ts +37 -0
  150. package/dist/components/cv-treegrid-column.js +53 -0
  151. package/dist/components/cv-treegrid-row.d.ts +55 -0
  152. package/dist/components/cv-treegrid-row.js +90 -0
  153. package/dist/components/cv-treegrid.d.ts +96 -0
  154. package/dist/components/cv-treegrid.js +632 -0
  155. package/dist/components/cv-treeitem.d.ts +58 -0
  156. package/dist/components/cv-treeitem.js +144 -0
  157. package/dist/components/cv-treeview.d.ts +70 -0
  158. package/dist/components/cv-treeview.js +396 -0
  159. package/dist/components/cv-window-splitter.d.ts +79 -0
  160. package/dist/components/cv-window-splitter.js +316 -0
  161. package/dist/components/index.d.ts +94 -0
  162. package/dist/components/index.js +79 -0
  163. package/dist/dialog/create-dialog-controller.d.ts +31 -0
  164. package/dist/dialog/create-dialog-controller.js +320 -0
  165. package/dist/dialog/index.d.ts +2 -0
  166. package/dist/dialog/index.js +1 -0
  167. package/dist/form-associated/FormAssociatedReatomElement.d.ts +25 -0
  168. package/dist/form-associated/FormAssociatedReatomElement.js +70 -0
  169. package/dist/form-associated/withFormAssociated.d.ts +5 -0
  170. package/dist/form-associated/withFormAssociated.js +1 -0
  171. package/dist/index.d.ts +10 -0
  172. package/dist/index.js +9 -0
  173. package/dist/reatom-lit/ReatomLitElement.d.ts +27 -0
  174. package/dist/reatom-lit/ReatomLitElement.js +118 -0
  175. package/dist/reatom-lit/html.d.ts +4 -0
  176. package/dist/reatom-lit/html.js +10 -0
  177. package/dist/reatom-lit/index.d.ts +4 -0
  178. package/dist/reatom-lit/index.js +4 -0
  179. package/dist/reatom-lit/watch.d.ts +15 -0
  180. package/dist/reatom-lit/watch.js +40 -0
  181. package/dist/reatom-lit/withReatomElement.d.ts +4 -0
  182. package/dist/reatom-lit/withReatomElement.js +57 -0
  183. package/dist/register.d.ts +1 -0
  184. package/dist/register.js +84 -0
  185. package/dist/styles/component-styles.d.ts +4 -0
  186. package/dist/styles/component-styles.js +78 -0
  187. package/dist/theme/cv-theme-provider.d.ts +32 -0
  188. package/dist/theme/cv-theme-provider.js +110 -0
  189. package/dist/theme/index.d.ts +4 -0
  190. package/dist/theme/index.js +2 -0
  191. package/dist/theme/theme-engine.d.ts +4 -0
  192. package/dist/theme/theme-engine.js +67 -0
  193. package/dist/theme/tokens.css +265 -0
  194. package/dist/theme/types.d.ts +7 -0
  195. package/dist/theme/types.js +1 -0
  196. package/dist/toast/create-toast-controller.d.ts +12 -0
  197. package/dist/toast/create-toast-controller.js +12 -0
  198. package/dist/toast/index.d.ts +2 -0
  199. package/dist/toast/index.js +1 -0
  200. package/package.json +146 -0
  201. package/specs/_template.md +110 -0
  202. package/specs/components/accordion.md +207 -0
  203. package/specs/components/alert.md +83 -0
  204. package/specs/components/badge.md +183 -0
  205. package/specs/components/breadcrumb.md +152 -0
  206. package/specs/components/button.md +227 -0
  207. package/specs/components/callout.md +153 -0
  208. package/specs/components/card.md +192 -0
  209. package/specs/components/carousel.md +232 -0
  210. package/specs/components/checkbox.md +141 -0
  211. package/specs/components/combobox.md +427 -0
  212. package/specs/components/context-menu.md +375 -0
  213. package/specs/components/copy-button.md +236 -0
  214. package/specs/components/date-picker.md +290 -0
  215. package/specs/components/dialog.md +184 -0
  216. package/specs/components/disclosure.md +151 -0
  217. package/specs/components/drawer.md +216 -0
  218. package/specs/components/feed.md +266 -0
  219. package/specs/components/grid.md +423 -0
  220. package/specs/components/input.md +237 -0
  221. package/specs/components/landmark.md +92 -0
  222. package/specs/components/link.md +117 -0
  223. package/specs/components/listbox.md +327 -0
  224. package/specs/components/menu.md +508 -0
  225. package/specs/components/meter.md +148 -0
  226. package/specs/components/number.md +268 -0
  227. package/specs/components/option.md +167 -0
  228. package/specs/components/popover.md +207 -0
  229. package/specs/components/progress-ring.md +134 -0
  230. package/specs/components/progress.md +110 -0
  231. package/specs/components/radio.md +208 -0
  232. package/specs/components/select.md +305 -0
  233. package/specs/components/sidebar.md +204 -0
  234. package/specs/components/spinbutton.md +157 -0
  235. package/specs/components/spinner.md +83 -0
  236. package/specs/components/switch.md +145 -0
  237. package/specs/components/table.md +372 -0
  238. package/specs/components/tabs.md +242 -0
  239. package/specs/components/textarea.md +166 -0
  240. package/specs/components/theme.md +364 -0
  241. package/specs/components/toast.md +198 -0
  242. package/specs/components/toolbar.md +258 -0
  243. package/specs/components/tooltip.md +152 -0
  244. package/specs/components/treegrid.md +363 -0
  245. package/specs/components/treeview.md +263 -0
  246. package/specs/components/window-splitter.md +225 -0
@@ -0,0 +1,320 @@
1
+ import { render } from 'lit';
2
+ import { CVDialog } from '../components/cv-dialog.js';
3
+ const sizeMap = {
4
+ s: '320px',
5
+ m: '480px',
6
+ l: '640px',
7
+ xl: '800px',
8
+ };
9
+ const STANDARD_FOCUSABLE_SELECTORS = [
10
+ 'a[href]',
11
+ 'area[href]',
12
+ 'input:not([disabled])',
13
+ 'select:not([disabled])',
14
+ 'textarea:not([disabled])',
15
+ 'button:not([disabled])',
16
+ 'iframe',
17
+ '[tabindex]:not([tabindex="-1"])',
18
+ '[contenteditable]',
19
+ ].join(',');
20
+ const INPUT_LIKE_COMPONENTS = ['cv-input', 'cv-number', 'cv-textarea', 'cv-select'];
21
+ const managedDialogStyles = `
22
+ cv-dialog.cv-managed-dialog::part(trigger) {
23
+ display: none;
24
+ }
25
+
26
+ cv-dialog.cv-managed-dialog::part(content) {
27
+ gap: 0;
28
+ padding: 0;
29
+ overflow: hidden;
30
+ }
31
+
32
+ cv-dialog.cv-managed-dialog::part(body) {
33
+ padding: 0;
34
+ }
35
+
36
+ cv-dialog.cv-managed-dialog::part(footer) {
37
+ display: block;
38
+ padding: 0;
39
+ }
40
+
41
+ .cv-dialog-controller-body {
42
+ padding: var(--cv-space-4, 16px);
43
+ line-height: 1.625;
44
+ }
45
+
46
+ .cv-dialog-controller-footer {
47
+ display: flex;
48
+ gap: var(--cv-space-2, 8px);
49
+ justify-content: flex-end;
50
+ padding: var(--cv-space-4, 16px);
51
+ border-top: 1px solid var(--cv-color-border, #2a3245);
52
+ background: color-mix(in oklab, var(--cv-color-surface-elevated, #1d2432) 90%, black);
53
+ }
54
+
55
+ @media (max-width: 640px) {
56
+ .cv-dialog-controller-footer {
57
+ width: 100%;
58
+ }
59
+
60
+ .cv-dialog-controller-footer > * {
61
+ flex: 1 1 0;
62
+ }
63
+ }
64
+ `;
65
+ let stylesInjected = false;
66
+ let lastDeepFocusedElement = null;
67
+ let focusTrackerInstalled = false;
68
+ function injectStyles() {
69
+ if (stylesInjected || typeof document === 'undefined')
70
+ return;
71
+ const style = document.createElement('style');
72
+ style.textContent = managedDialogStyles;
73
+ style.id = 'cv-dialog-controller-styles';
74
+ document.head.appendChild(style);
75
+ stylesInjected = true;
76
+ }
77
+ function installFocusTracker() {
78
+ if (focusTrackerInstalled || typeof document === 'undefined')
79
+ return;
80
+ document.addEventListener('focusin', (event) => {
81
+ const target = event.composedPath?.()[0];
82
+ if (target instanceof HTMLElement) {
83
+ lastDeepFocusedElement = target;
84
+ }
85
+ }, { capture: true });
86
+ focusTrackerInstalled = true;
87
+ }
88
+ function getDeepActiveElement() {
89
+ if (typeof document === 'undefined')
90
+ return null;
91
+ let activeElement = document.activeElement;
92
+ while (activeElement instanceof HTMLElement &&
93
+ activeElement.shadowRoot?.activeElement instanceof HTMLElement) {
94
+ activeElement = activeElement.shadowRoot.activeElement;
95
+ }
96
+ return activeElement instanceof HTMLElement ? activeElement : null;
97
+ }
98
+ function getFocusRestoreTarget() {
99
+ if (typeof document === 'undefined')
100
+ return null;
101
+ const deepActive = getDeepActiveElement();
102
+ if (deepActive && deepActive !== document.body && deepActive !== document.documentElement) {
103
+ return deepActive;
104
+ }
105
+ if (lastDeepFocusedElement &&
106
+ lastDeepFocusedElement !== document.body &&
107
+ lastDeepFocusedElement !== document.documentElement) {
108
+ return lastDeepFocusedElement;
109
+ }
110
+ return null;
111
+ }
112
+ function isElementVisible(element) {
113
+ if (element.offsetWidth === 0 && element.offsetHeight === 0) {
114
+ return false;
115
+ }
116
+ const style = window.getComputedStyle(element);
117
+ return style.visibility !== 'hidden' && style.display !== 'none';
118
+ }
119
+ function defaultFindFirstFocusable(container) {
120
+ const autofocusElement = container.querySelector('[autofocus]');
121
+ if (autofocusElement && isElementVisible(autofocusElement)) {
122
+ return autofocusElement;
123
+ }
124
+ if (container.shadowRoot) {
125
+ const shadowAutofocus = container.shadowRoot.querySelector('[autofocus]');
126
+ if (shadowAutofocus && isElementVisible(shadowAutofocus)) {
127
+ return shadowAutofocus;
128
+ }
129
+ }
130
+ for (const tagName of INPUT_LIKE_COMPONENTS) {
131
+ const component = container.querySelector(tagName);
132
+ if (component && isElementVisible(component)) {
133
+ return component;
134
+ }
135
+ }
136
+ const elements = container.querySelectorAll(STANDARD_FOCUSABLE_SELECTORS);
137
+ for (const element of elements) {
138
+ const htmlElement = element;
139
+ if (isElementVisible(htmlElement)) {
140
+ return htmlElement;
141
+ }
142
+ }
143
+ for (const child of container.children) {
144
+ if (child.shadowRoot) {
145
+ const found = defaultFindFirstFocusable(child);
146
+ if (found)
147
+ return found;
148
+ }
149
+ }
150
+ return null;
151
+ }
152
+ export function createDialogController(adapters = {}) {
153
+ CVDialog.define();
154
+ injectStyles();
155
+ installFocusTracker();
156
+ const activeDialogs = new Map();
157
+ let zIndexCounter = 1100;
158
+ const findFirstFocusable = adapters.findFirstFocusable ?? defaultFindFirstFocusable;
159
+ const getNextZIndex = () => zIndexCounter++;
160
+ const addDialog = (element, closeFn) => {
161
+ activeDialogs.set(element, closeFn);
162
+ const zIndex = getNextZIndex().toString();
163
+ element.style.setProperty('--cv-dialog-z-index', zIndex);
164
+ };
165
+ const removeDialog = (element) => {
166
+ activeDialogs.delete(element);
167
+ if (activeDialogs.size === 0) {
168
+ zIndexCounter = 1100;
169
+ adapters.restoreInert?.();
170
+ }
171
+ };
172
+ const present = async ({ element, title, show, close }) => {
173
+ const focusRestoreTarget = getFocusRestoreTarget();
174
+ document.body.appendChild(element);
175
+ addDialog(element, close);
176
+ element.addEventListener('cv-after-show', () => {
177
+ if (!activeDialogs.has(element))
178
+ return;
179
+ adapters.setInertExcept?.(element);
180
+ const firstFocusable = findFirstFocusable(element);
181
+ if (firstFocusable) {
182
+ setTimeout(() => {
183
+ if (firstFocusable.isConnected) {
184
+ firstFocusable.focus();
185
+ }
186
+ }, 50);
187
+ }
188
+ if (title) {
189
+ adapters.announce?.(title, 'assertive');
190
+ }
191
+ }, { once: true });
192
+ try {
193
+ return await show();
194
+ }
195
+ finally {
196
+ removeDialog(element);
197
+ if (focusRestoreTarget?.isConnected) {
198
+ focusRestoreTarget.focus({ preventScroll: true });
199
+ }
200
+ element.remove();
201
+ }
202
+ };
203
+ const showCustom = (options, resultHandler) => {
204
+ return new Promise((resolve) => {
205
+ const focusRestoreTarget = getFocusRestoreTarget();
206
+ let isResolved = false;
207
+ let hasOpened = false;
208
+ let isCleanedUp = false;
209
+ const resolveOnce = (result) => {
210
+ if (isResolved)
211
+ return;
212
+ isResolved = true;
213
+ resolve(result);
214
+ };
215
+ const dialog = document.createElement('cv-dialog');
216
+ dialog.classList.add('cv-managed-dialog');
217
+ dialog.noHeader = options.noHeader ?? false;
218
+ dialog.closable = options.closable !== false;
219
+ dialog.closeOnEscape = options.closable !== false;
220
+ dialog.closeOnOutsidePointer = options.closable !== false;
221
+ dialog.closeOnOutsideFocus = options.closable !== false;
222
+ if (options.className) {
223
+ dialog.classList.add(...options.className.split(/\s+/).filter(Boolean));
224
+ }
225
+ dialog.style.setProperty('--cv-dialog-width', sizeMap[options.size || 'm']);
226
+ if (!options.noHeader && options.title) {
227
+ const title = document.createElement('span');
228
+ title.slot = 'title';
229
+ title.textContent = options.title;
230
+ dialog.appendChild(title);
231
+ }
232
+ const body = document.createElement('div');
233
+ body.className = 'cv-dialog-controller-body';
234
+ if (typeof options.content === 'string') {
235
+ body.textContent = options.content;
236
+ }
237
+ else {
238
+ render(options.content, body);
239
+ }
240
+ dialog.appendChild(body);
241
+ if (options.footer && !options.noFooter) {
242
+ const footer = document.createElement('div');
243
+ footer.className = 'cv-dialog-controller-footer';
244
+ footer.slot = 'footer';
245
+ render(options.footer, footer);
246
+ dialog.appendChild(footer);
247
+ }
248
+ document.body.appendChild(dialog);
249
+ const cleanup = () => {
250
+ if (isCleanedUp)
251
+ return;
252
+ isCleanedUp = true;
253
+ removeDialog(dialog);
254
+ if (focusRestoreTarget?.isConnected) {
255
+ focusRestoreTarget.focus({ preventScroll: true });
256
+ }
257
+ if (document.body.contains(dialog)) {
258
+ document.body.removeChild(dialog);
259
+ }
260
+ };
261
+ addDialog(dialog, () => {
262
+ dialog.open = false;
263
+ resolveOnce(null);
264
+ if (!hasOpened) {
265
+ cleanup();
266
+ }
267
+ });
268
+ dialog.addEventListener('cv-after-hide', cleanup);
269
+ dialog.addEventListener('cv-after-show', () => {
270
+ if (!activeDialogs.has(dialog))
271
+ return;
272
+ hasOpened = true;
273
+ adapters.setInertExcept?.(dialog);
274
+ const firstFocusable = findFirstFocusable(dialog);
275
+ if (firstFocusable) {
276
+ setTimeout(() => firstFocusable.focus(), 50);
277
+ }
278
+ if (options.title) {
279
+ adapters.announce?.(options.title, 'assertive');
280
+ }
281
+ });
282
+ dialog.addEventListener('cv-change', (event) => {
283
+ const detail = event.detail;
284
+ if (detail?.open === false) {
285
+ resolveOnce(null);
286
+ }
287
+ });
288
+ resultHandler(dialog, (result) => {
289
+ dialog.open = false;
290
+ resolveOnce(result);
291
+ if (!hasOpened) {
292
+ cleanup();
293
+ }
294
+ });
295
+ const openDialog = () => {
296
+ if (isResolved)
297
+ return;
298
+ dialog.open = true;
299
+ };
300
+ if (dialog.updateComplete) {
301
+ dialog.updateComplete.then(openDialog);
302
+ }
303
+ else {
304
+ requestAnimationFrame(openDialog);
305
+ }
306
+ });
307
+ };
308
+ const closeAll = () => {
309
+ activeDialogs.forEach((close) => close());
310
+ activeDialogs.clear();
311
+ zIndexCounter = 1100;
312
+ adapters.restoreInert?.();
313
+ };
314
+ return {
315
+ present,
316
+ showCustom,
317
+ closeAll,
318
+ getActiveCount: () => activeDialogs.size,
319
+ };
320
+ }
@@ -0,0 +1,2 @@
1
+ export { createDialogController } from './create-dialog-controller.js';
2
+ export type { CustomDialogOptions, DialogController, DialogControllerAdapters, DialogPriority, ManagedDialogOptions, } from './create-dialog-controller.js';
@@ -0,0 +1 @@
1
+ export { createDialogController } from './create-dialog-controller.js';
@@ -0,0 +1,25 @@
1
+ import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
2
+ import type { FormAssociatedValidity } from './withFormAssociated.js';
3
+ export declare abstract class FormAssociatedReatomElement extends ReatomLitElement {
4
+ static readonly formAssociated = true;
5
+ protected readonly internals: ElementInternals;
6
+ private _formDisabled;
7
+ constructor();
8
+ protected get formDisabled(): boolean;
9
+ formDisabledCallback(disabled: boolean): void;
10
+ formResetCallback(): void;
11
+ formStateRestoreCallback(state: string | File | FormData | null): void;
12
+ get form(): HTMLFormElement | null;
13
+ get validity(): ValidityState;
14
+ get validationMessage(): string;
15
+ get willValidate(): boolean;
16
+ checkValidity(): boolean;
17
+ reportValidity(): boolean;
18
+ protected syncFormAssociatedState(): void;
19
+ protected onFormDisabledChanged(_disabled: boolean): void;
20
+ protected onFormReset(): void;
21
+ protected onFormStateRestore(_state: string | File | FormData | null): void;
22
+ protected getFormAssociatedValidity(): FormAssociatedValidity;
23
+ protected abstract isFormAssociatedDisabled(): boolean;
24
+ protected abstract getFormAssociatedValue(): string | File | FormData | null;
25
+ }
@@ -0,0 +1,70 @@
1
+ import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
2
+ export class FormAssociatedReatomElement extends ReatomLitElement {
3
+ static formAssociated = true;
4
+ internals;
5
+ _formDisabled = false;
6
+ constructor() {
7
+ super();
8
+ this.internals = this.attachInternals();
9
+ }
10
+ get formDisabled() {
11
+ return this._formDisabled;
12
+ }
13
+ formDisabledCallback(disabled) {
14
+ this._formDisabled = disabled;
15
+ this.onFormDisabledChanged(disabled);
16
+ this.syncFormAssociatedState();
17
+ this.requestUpdate();
18
+ }
19
+ formResetCallback() {
20
+ this.onFormReset();
21
+ this.syncFormAssociatedState();
22
+ this.requestUpdate();
23
+ }
24
+ formStateRestoreCallback(state) {
25
+ this.onFormStateRestore(state);
26
+ this.syncFormAssociatedState();
27
+ this.requestUpdate();
28
+ }
29
+ get form() {
30
+ return this.internals.form;
31
+ }
32
+ get validity() {
33
+ return this.internals.validity;
34
+ }
35
+ get validationMessage() {
36
+ return this.internals.validationMessage;
37
+ }
38
+ get willValidate() {
39
+ return !this.isFormAssociatedDisabled();
40
+ }
41
+ checkValidity() {
42
+ this.syncFormAssociatedState();
43
+ return this.internals.checkValidity();
44
+ }
45
+ reportValidity() {
46
+ this.syncFormAssociatedState();
47
+ return this.internals.reportValidity();
48
+ }
49
+ syncFormAssociatedState() {
50
+ if (this.isFormAssociatedDisabled()) {
51
+ this.internals.setFormValue(null);
52
+ this.internals.setValidity({});
53
+ return;
54
+ }
55
+ this.internals.setFormValue(this.getFormAssociatedValue());
56
+ const validity = this.getFormAssociatedValidity();
57
+ const flags = validity.flags ?? {};
58
+ if (Object.keys(flags).length === 0) {
59
+ this.internals.setValidity({});
60
+ return;
61
+ }
62
+ this.internals.setValidity(flags, validity.message, validity.anchor);
63
+ }
64
+ onFormDisabledChanged(_disabled) { }
65
+ onFormReset() { }
66
+ onFormStateRestore(_state) { }
67
+ getFormAssociatedValidity() {
68
+ return { flags: {} };
69
+ }
70
+ }
@@ -0,0 +1,5 @@
1
+ export interface FormAssociatedValidity {
2
+ flags?: ValidityStateFlags;
3
+ message?: string;
4
+ anchor?: HTMLElement;
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ export * from './components/index.js';
2
+ export { createDialogController } from './dialog/create-dialog-controller.js';
3
+ export type { CustomDialogOptions, DialogController, DialogControllerAdapters, DialogPriority, ManagedDialogOptions, } from './dialog/create-dialog-controller.js';
4
+ export * from './reatom-lit/index.js';
5
+ export * from './theme/index.js';
6
+ export * from './toast/index.js';
7
+ export { getIconBasePath, registerIconCollection, setIconBasePath, unregisterIconCollection, } from './components/cv-icon.js';
8
+ export type { ToastRegionPosition } from './components/cv-toast-region.js';
9
+ export { createAccordion, createAlertDialog, createAlert, createBreadcrumb, createButton, createCarousel, createCheckbox, createCommandPalette, createCombobox, createContextMenu, createDatePicker, createDisclosure, createDialog, createFeed, createGrid, createLandmark, createLink, createListbox, createMenu, createMenuButton, createMeter, createPopover, createProgress, createRadioGroup, createSelect, createSlider, createSpinbutton, createSwitch, createTabs, createToast, createTreeview, createToolbar, createTooltip, createWindowSplitter, type CreateAccordionOptions, type AccordionModel, type CreateAlertDialogOptions, type AlertDialogModel, type CreateAlertOptions, type AlertModel, type CreateBreadcrumbOptions, type BreadcrumbModel, type CreateButtonOptions, type ButtonModel, type CreateCarouselOptions, type CarouselModel, type CarouselSlide, type CreateCheckboxOptions, type CheckboxModel, type CreateCommandPaletteOptions, type CommandPaletteModel, type CreateComboboxOptions, type ComboboxModel, type CreateDatePickerOptions, type DatePickerModel, type CreateContextMenuOptions, type ContextMenuModel, type CreateDisclosureOptions, type DisclosureModel, type CreateDialogOptions, type DialogModel, type CreateFeedOptions, type FeedModel, type CreateGridOptions, type GridCellId, type GridFocusStrategy, type GridModel, type GridSelectionMode, type CreateLandmarkOptions, type LandmarkModel, type LandmarkType, type CreateLinkOptions, type LinkModel, type CreateListboxOptions, type ListboxModel, type CreateMenuOptions, type MenuModel, type CreateMenuButtonOptions, type MenuButtonModel, type CreateMeterOptions, type MeterModel, type CreatePopoverOptions, type PopoverModel, type CreateProgressOptions, type ProgressModel, type CreateRadioGroupOptions, type RadioGroupModel, type CreateSelectOptions, type SelectModel, type CreateSliderOptions, type SliderModel, createSliderMultiThumb, type CreateSliderMultiThumbOptions, type SliderMultiThumbModel, type SliderMultiThumbOrientation, createTable, type CreateTableOptions, type TableModel, type TableSortDirection, type CreateSpinbuttonOptions, type SpinbuttonModel, type CreateSwitchOptions, type SwitchModel, type CreateTabsOptions, type TabsModel, type CreateToastOptions, type ToastModel, type ToastItem, type CreateTreeviewOptions, type TreeNode, type TreeviewModel, createTreegrid, type CreateTreegridOptions, type TreegridCellId, type TreegridModel, type TreegridRow, type TreegridSelectionMode, type TreegridCellRole, type CreateToolbarOptions, type ToolbarModel, type CreateTooltipOptions, type TooltipModel, type CreateWindowSplitterOptions, type WindowSplitterModel, } from '@chromvoid/headless-ui';
10
+ export { registerUikit } from './register.js';
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /// <reference path="./components/global-elements-events.d.ts" />
2
+ export * from './components/index.js';
3
+ export { createDialogController } from './dialog/create-dialog-controller.js';
4
+ export * from './reatom-lit/index.js';
5
+ export * from './theme/index.js';
6
+ export * from './toast/index.js';
7
+ export { getIconBasePath, registerIconCollection, setIconBasePath, unregisterIconCollection, } from './components/cv-icon.js';
8
+ export { createAccordion, createAlertDialog, createAlert, createBreadcrumb, createButton, createCarousel, createCheckbox, createCommandPalette, createCombobox, createContextMenu, createDatePicker, createDisclosure, createDialog, createFeed, createGrid, createLandmark, createLink, createListbox, createMenu, createMenuButton, createMeter, createPopover, createProgress, createRadioGroup, createSelect, createSlider, createSpinbutton, createSwitch, createTabs, createToast, createTreeview, createToolbar, createTooltip, createWindowSplitter, createSliderMultiThumb, createTable, createTreegrid, } from '@chromvoid/headless-ui';
9
+ export { registerUikit } from './register.js';
@@ -0,0 +1,27 @@
1
+ import { LitElement } from 'lit';
2
+ import type { CSSResultGroup, CSSResultOrNative, PropertyValues, TemplateResult } from 'lit';
3
+ declare const __aliased_event_dispatch: unique symbol;
4
+ import { type ComponentHostDisplay } from '../styles/component-styles.js';
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'
9
+ * setUnoUtilities(unoUtilities)
10
+ */
11
+ export declare function setUnoUtilities(sheet: CSSResultOrNative): void;
12
+ export declare class ReatomLitElement extends LitElement {
13
+ protected static hostDisplay: ComponentHostDisplay;
14
+ protected static finalizeStyles(styles?: CSSResultGroup): CSSResultOrNative[];
15
+ private __frame;
16
+ private __abstractRender?;
17
+ private __unmount?;
18
+ private [__aliased_event_dispatch];
19
+ constructor();
20
+ private __initAbstractRender;
21
+ protected render(): TemplateResult | unknown;
22
+ protected update(changedProperties: PropertyValues): void;
23
+ connectedCallback(): void;
24
+ disconnectedCallback(): void;
25
+ dispatchEvent(event: Event): boolean;
26
+ }
27
+ export {};
@@ -0,0 +1,118 @@
1
+ import { reatomAbstractRender, top } from '@reatom/core';
2
+ import { LitElement } from 'lit';
3
+ const __inner_update = Symbol('Inner update');
4
+ const __aliased_event_dispatch = Symbol('Aliased event dispatch');
5
+ const CV_EVENT_PREFIX = 'cv-';
6
+ import { componentResetStyles, getComponentHostDisplayStyles, } from '../styles/component-styles.js';
7
+ let _unoUtilities;
8
+ /**
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'
12
+ * setUnoUtilities(unoUtilities)
13
+ */
14
+ export function setUnoUtilities(sheet) {
15
+ _unoUtilities = sheet;
16
+ }
17
+ export class ReatomLitElement extends LitElement {
18
+ static hostDisplay = 'block';
19
+ static finalizeStyles(styles) {
20
+ const base = [
21
+ componentResetStyles,
22
+ getComponentHostDisplayStyles(this.hostDisplay),
23
+ ...super.finalizeStyles(styles),
24
+ ];
25
+ if (_unoUtilities)
26
+ base.push(_unoUtilities);
27
+ return base;
28
+ }
29
+ __frame;
30
+ __abstractRender;
31
+ __unmount;
32
+ [__aliased_event_dispatch] = false;
33
+ constructor() {
34
+ super();
35
+ this.__frame = top();
36
+ }
37
+ __initAbstractRender() {
38
+ if (this.__abstractRender)
39
+ return;
40
+ this.__abstractRender = reatomAbstractRender({
41
+ frame: this.__frame,
42
+ render: () => {
43
+ return this.render();
44
+ },
45
+ rerender: () => {
46
+ return this.requestUpdate(__inner_update, 1);
47
+ },
48
+ name: 'ReatomElement',
49
+ });
50
+ }
51
+ render() {
52
+ return undefined;
53
+ }
54
+ update(changedProperties) {
55
+ this.__initAbstractRender();
56
+ const { result: value } = this.__abstractRender.render(changedProperties);
57
+ const hadOwnRender = Object.prototype.hasOwnProperty.call(this, 'render');
58
+ const ownRenderDescriptor = hadOwnRender ? Object.getOwnPropertyDescriptor(this, 'render') : undefined;
59
+ // Keep Lit's native update path intact so SSR hydration support can
60
+ // reuse declarative shadow DOM instead of appending a second render.
61
+ Object.defineProperty(this, 'render', {
62
+ configurable: true,
63
+ value: () => value,
64
+ });
65
+ try {
66
+ super.update(changedProperties);
67
+ }
68
+ finally {
69
+ if (hadOwnRender && ownRenderDescriptor) {
70
+ Object.defineProperty(this, 'render', ownRenderDescriptor);
71
+ }
72
+ else {
73
+ delete this.render;
74
+ }
75
+ }
76
+ }
77
+ connectedCallback() {
78
+ super.connectedCallback();
79
+ this.__initAbstractRender();
80
+ this.__unmount = this.__abstractRender.mount();
81
+ }
82
+ disconnectedCallback() {
83
+ super.disconnectedCallback();
84
+ if (this.__unmount) {
85
+ try {
86
+ this.__unmount();
87
+ }
88
+ catch {
89
+ // ignore unmount errors
90
+ }
91
+ this.__unmount = undefined;
92
+ }
93
+ }
94
+ dispatchEvent(event) {
95
+ if (this.localName.startsWith(CV_EVENT_PREFIX) &&
96
+ !this[__aliased_event_dispatch] &&
97
+ event instanceof CustomEvent &&
98
+ !event.type.startsWith(CV_EVENT_PREFIX)) {
99
+ this[__aliased_event_dispatch] = true;
100
+ try {
101
+ const aliasedEvent = new CustomEvent(`${CV_EVENT_PREFIX}${event.type}`, {
102
+ detail: event.detail,
103
+ bubbles: event.bubbles,
104
+ cancelable: event.cancelable,
105
+ composed: event.composed,
106
+ });
107
+ super.dispatchEvent(aliasedEvent);
108
+ if (aliasedEvent.defaultPrevented && event.cancelable) {
109
+ event.preventDefault();
110
+ }
111
+ }
112
+ finally {
113
+ this[__aliased_event_dispatch] = false;
114
+ }
115
+ }
116
+ return super.dispatchEvent(event);
117
+ }
118
+ }
@@ -0,0 +1,4 @@
1
+ import { html as coreHtml, svg as coreSvg, type TemplateResult } from 'lit/html.js';
2
+ export declare const withWatch: (coreTag: typeof coreHtml | typeof coreSvg) => (strings: TemplateStringsArray, ...values: unknown[]) => TemplateResult;
3
+ export declare const html: (strings: TemplateStringsArray, ...values: unknown[]) => TemplateResult;
4
+ export declare const svg: (strings: TemplateStringsArray, ...values: unknown[]) => TemplateResult;
@@ -0,0 +1,10 @@
1
+ import { isAtom } from '@reatom/core';
2
+ import { html as coreHtml, svg as coreSvg } from 'lit/html.js';
3
+ import { watch } from './watch.js';
4
+ export const withWatch = (coreTag) => (strings, ...values) => {
5
+ return coreTag(strings, ...values.map((v) => {
6
+ return isAtom(v) ? watch(v) : v;
7
+ }));
8
+ };
9
+ export const html = withWatch(coreHtml);
10
+ export const svg = withWatch(coreSvg);
@@ -0,0 +1,4 @@
1
+ export { ReatomLitElement, setUnoUtilities } from './ReatomLitElement.js';
2
+ export { withReatomElement } from './withReatomElement.js';
3
+ export { html, svg } from './html.js';
4
+ export { watch } from './watch.js';
@@ -0,0 +1,4 @@
1
+ export { ReatomLitElement, setUnoUtilities } from './ReatomLitElement.js';
2
+ export { withReatomElement } from './withReatomElement.js';
3
+ export { html, svg } from './html.js';
4
+ export { watch } from './watch.js';
@@ -0,0 +1,15 @@
1
+ import type { AtomLike, Frame, Unsubscribe } from '@reatom/core';
2
+ import { AsyncDirective } from 'lit/async-directive.js';
3
+ import type { PartInfo } from 'lit/directive.js';
4
+ declare class AtomDirective extends AsyncDirective {
5
+ target: AtomLike | undefined;
6
+ unsubscribe: Unsubscribe | undefined;
7
+ frame: Frame | undefined;
8
+ constructor(partInfo: PartInfo);
9
+ reconnected(): void;
10
+ disconnected(): void;
11
+ subscribe(): void;
12
+ render(target: AtomLike, frame: Frame): symbol;
13
+ }
14
+ export declare const watch: (target: AtomLike) => import("lit/async-directive.js").DirectiveResult<typeof AtomDirective>;
15
+ export {};