@threadlabs/looma 0.1.5 → 0.1.7

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 (62) hide show
  1. package/README.md +5 -4
  2. package/dist/{chunk-3PASQ7DE.js → chunk-UMFO4QNN.js} +26 -26
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/looma.cjs.js +1 -1
  5. package/dist/cjs/ui-dialog.cjs.entry.js +3 -1
  6. package/dist/collection/components/ui-dialog/ui-dialog.js +22 -1
  7. package/dist/components/ui-dialog.js +1 -1
  8. package/dist/esm/loader.js +1 -1
  9. package/dist/esm/looma.js +1 -1
  10. package/dist/esm/ui-dialog.entry.js +3 -1
  11. package/dist/index.cjs +4 -2
  12. package/dist/index.js +2 -2
  13. package/dist/looma/looma.esm.js +1 -1
  14. package/dist/looma/p-5df568d8.entry.js +1 -0
  15. package/dist/types/components/ui-dialog/ui-dialog.d.ts +2 -0
  16. package/dist/types/components.d.ts +9 -0
  17. package/dist/{ui-avatar-group.entry-DBVLQ4KB.js → ui-avatar-group.entry-S6DFXYB7.js} +1 -1
  18. package/dist/{ui-avatar.entry-2WTBM2EC.js → ui-avatar.entry-MDRGXLWQ.js} +1 -1
  19. package/dist/{ui-badge.entry-XKIGBK5V.js → ui-badge.entry-RLL4YKPD.js} +1 -1
  20. package/dist/{ui-button.entry-PWT56MPD.js → ui-button.entry-IYMYLBFY.js} +1 -1
  21. package/dist/{ui-checkbox.entry-QT5S7EEL.js → ui-checkbox.entry-K5FGWDG2.js} +1 -1
  22. package/dist/{ui-context-menu.entry-NGWR3LOZ.js → ui-context-menu.entry-KWXXJ3ZV.js} +1 -1
  23. package/dist/{ui-dialog.entry-PEDDIALQ.js → ui-dialog.entry-RKHLQLQM.js} +4 -2
  24. package/dist/{ui-disclosure.entry-UKO7MAZM.js → ui-disclosure.entry-FRZKGEJP.js} +1 -1
  25. package/dist/{ui-floating-action-button.entry-SSGHRMCO.js → ui-floating-action-button.entry-BH4FDSTL.js} +1 -1
  26. package/dist/{ui-form-field.entry-6TZCWPYL.js → ui-form-field.entry-3CR2KSUH.js} +1 -1
  27. package/dist/{ui-icon-button.entry-WMCYMK2H.js → ui-icon-button.entry-LB54U25M.js} +1 -1
  28. package/dist/{ui-input.entry-AZ5BGQNA.js → ui-input.entry-5PQR37HS.js} +1 -1
  29. package/dist/{ui-menu-item.entry-L4NJDBKF.js → ui-menu-item.entry-2T3QWHLK.js} +1 -1
  30. package/dist/{ui-menu.entry-DGUYAE3Q.js → ui-menu.entry-Q5Z5YO5P.js} +1 -1
  31. package/dist/{ui-popover.entry-A54EKVZG.js → ui-popover.entry-4P2NWWAY.js} +1 -1
  32. package/dist/{ui-radio-group.entry-6YP4LY4N.js → ui-radio-group.entry-QKPRNV26.js} +1 -1
  33. package/dist/{ui-radio.entry-CGYNK7PN.js → ui-radio.entry-O4DOMFNU.js} +1 -1
  34. package/dist/{ui-search-result-row.entry-DGKSI2QM.js → ui-search-result-row.entry-BR5O3UCH.js} +1 -1
  35. package/dist/{ui-search-shell.entry-3F5ASGTW.js → ui-search-shell.entry-2ZBP7SA3.js} +1 -1
  36. package/dist/{ui-select.entry-SXSZPVXA.js → ui-select.entry-L75HQY72.js} +1 -1
  37. package/dist/{ui-switch.entry-AD4EVUWM.js → ui-switch.entry-L5QWD3BT.js} +1 -1
  38. package/dist/{ui-tabs.entry-WLKO5G5N.js → ui-tabs.entry-KWRD6Y7J.js} +1 -1
  39. package/dist/{ui-textarea.entry-IHPC7Q4R.js → ui-textarea.entry-JC3HPEBS.js} +1 -1
  40. package/dist/{ui-toast-region.entry-GCW2LJAC.js → ui-toast-region.entry-C6KK4OM4.js} +1 -1
  41. package/dist/{ui-tooltip.entry-EU2G6BH5.js → ui-tooltip.entry-G5EOCWP4.js} +1 -1
  42. package/dist/{ui-top-bar.entry-NMAFXVET.js → ui-top-bar.entry-YLKVAQFH.js} +1 -1
  43. package/editor/chunk-CX4QDKSV.js +22 -0
  44. package/editor/{chunk-YGJLGDQC.js → chunk-NJ2KAMS2.js} +2203 -17
  45. package/editor/{chunk-CWCXYQMT.js → chunk-OK5NARJI.js} +59 -28
  46. package/editor/extensions/index.d.ts +74 -20
  47. package/editor/extensions/index.js +22 -4
  48. package/editor/index.d.ts +3 -3
  49. package/editor/index.js +25 -5
  50. package/editor/table-overlay-Bq0F5xPg.d.ts +64 -0
  51. package/editor/ui.d.ts +2 -12
  52. package/editor/ui.js +9 -1
  53. package/editor.css +375 -4
  54. package/package.json +9 -2
  55. package/tokens.css +17 -0
  56. package/vue/chunk-KDA4RFLQ.js +203 -0
  57. package/vue/editor/index.d.ts +93 -3
  58. package/vue/editor/index.js +565 -30
  59. package/vue/index.js +38 -82
  60. package/dist/looma/p-a7be33fd.entry.js +0 -1
  61. package/editor/table-overlay-DTr3KC9e.d.ts +0 -12
  62. package/vue/chunk-P72L3GWE.js +0 -84
package/editor.css CHANGED
@@ -3,6 +3,335 @@
3
3
  * Tables, context menu, insert-table grid, slash menu. Use with ProseMirror/Tiptap content.
4
4
  */
5
5
 
6
+ /* Turnkey editor */
7
+ .looma-editor {
8
+ position: relative;
9
+ min-width: 0;
10
+ color: var(--ui-text-primary);
11
+ font-family: var(--ui-font-family-sans);
12
+ }
13
+
14
+ .looma-editor .ProseMirror {
15
+ min-height: var(--ui-editor-content-min-height, 300px);
16
+ padding:
17
+ var(--ui-editor-content-padding-block, var(--ui-space-4))
18
+ var(--ui-editor-content-padding-inline, var(--ui-space-6));
19
+ outline: none;
20
+ color: var(--ui-editor-content-color, var(--ui-text-primary));
21
+ caret-color: var(--ui-editor-caret-color, var(--ui-accent-solid));
22
+ font-family: var(--ui-editor-font-family, var(--ui-font-family-sans));
23
+ font-size: var(--ui-editor-font-size, var(--ui-font-size-md));
24
+ line-height: var(--ui-editor-line-height, var(--ui-line-height-relaxed));
25
+ }
26
+
27
+ @media (max-width: 767px) {
28
+ .looma-editor .ProseMirror {
29
+ padding-bottom: var(--ui-editor-mobile-bottom-space, 80px);
30
+ }
31
+ }
32
+
33
+ .looma-editor .ProseMirror p {
34
+ margin: 0 0 var(--ui-editor-paragraph-gap, var(--ui-space-3));
35
+ }
36
+
37
+ .looma-editor .ProseMirror h1,
38
+ .looma-editor .ProseMirror h2,
39
+ .looma-editor .ProseMirror h3 {
40
+ color: inherit;
41
+ line-height: var(--ui-line-height-tight);
42
+ }
43
+
44
+ .looma-editor .ProseMirror h1 {
45
+ margin: var(--ui-space-6) 0 var(--ui-space-3);
46
+ font-size: var(--ui-font-size-2xl);
47
+ font-weight: var(--ui-font-bold);
48
+ }
49
+
50
+ .looma-editor .ProseMirror h2 {
51
+ margin: var(--ui-space-5) 0 var(--ui-space-2);
52
+ font-size: var(--ui-font-size-xl);
53
+ font-weight: var(--ui-font-semibold);
54
+ }
55
+
56
+ .looma-editor .ProseMirror h3 {
57
+ margin: var(--ui-space-4) 0 var(--ui-space-2);
58
+ font-size: var(--ui-font-size-lg);
59
+ font-weight: var(--ui-font-semibold);
60
+ }
61
+
62
+ .looma-editor .ProseMirror ul,
63
+ .looma-editor .ProseMirror ol {
64
+ margin: 0 0 var(--ui-space-3);
65
+ padding-left: var(--ui-space-6);
66
+ }
67
+
68
+ .looma-editor .ProseMirror li {
69
+ margin-bottom: var(--ui-space-1);
70
+ }
71
+
72
+ .looma-editor .ProseMirror blockquote {
73
+ margin: var(--ui-space-4) 0;
74
+ padding-left: var(--ui-space-4);
75
+ border-left: 3px solid var(--ui-accent-solid);
76
+ color: var(--ui-text-secondary);
77
+ font-style: italic;
78
+ }
79
+
80
+ .looma-editor .ProseMirror pre {
81
+ margin: var(--ui-space-4) 0;
82
+ padding: var(--ui-space-4);
83
+ overflow-x: auto;
84
+ border: 1px solid var(--ui-border-default);
85
+ border-radius: var(--ui-radius-2);
86
+ background: var(--ui-surface-muted);
87
+ font-family: var(--ui-font-family-mono, ui-monospace, monospace);
88
+ font-size: var(--ui-font-size-sm);
89
+ }
90
+
91
+ .looma-editor .ProseMirror code {
92
+ padding: 0.1em 0.3em;
93
+ border-radius: var(--ui-radius-1);
94
+ background: var(--ui-surface-subtle);
95
+ font-family: var(--ui-font-family-mono, ui-monospace, monospace);
96
+ font-size: 0.9em;
97
+ }
98
+
99
+ .looma-editor .ProseMirror pre code {
100
+ padding: 0;
101
+ background: none;
102
+ }
103
+
104
+ .looma-editor .ProseMirror hr {
105
+ margin: var(--ui-space-6) 0;
106
+ border: 0;
107
+ border-top: 1px solid var(--ui-border-default);
108
+ }
109
+
110
+ .looma-editor .ProseMirror mark {
111
+ border-radius: var(--ui-radius-1);
112
+ background: var(--ui-editor-highlight-bg, var(--ui-warning-soft));
113
+ }
114
+
115
+ .looma-editor .ProseMirror a {
116
+ color: var(--ui-editor-link-color, var(--ui-accent-solid));
117
+ text-decoration: underline;
118
+ }
119
+
120
+ .looma-editor .ProseMirror ul[data-type="taskList"] {
121
+ padding-left: var(--ui-space-2);
122
+ list-style: none;
123
+ }
124
+
125
+ .looma-editor .ProseMirror ul[data-type="taskList"] li {
126
+ display: flex;
127
+ align-items: flex-start;
128
+ gap: var(--ui-space-2);
129
+ }
130
+
131
+ .looma-editor .ProseMirror ul[data-type="taskList"] li > label {
132
+ margin-top: 3px;
133
+ }
134
+
135
+ .looma-editor .ProseMirror ul[data-type="taskList"] input[type="checkbox"] {
136
+ width: 16px;
137
+ height: 16px;
138
+ accent-color: var(--ui-accent-solid);
139
+ cursor: pointer;
140
+ }
141
+
142
+ .looma-editor .ProseMirror .is-editor-empty:first-child::before {
143
+ float: left;
144
+ height: 0;
145
+ color: var(--ui-text-muted);
146
+ content: attr(data-placeholder);
147
+ pointer-events: none;
148
+ }
149
+
150
+ .looma-editor .ProseMirror img {
151
+ max-width: 100%;
152
+ margin: var(--ui-space-3) 0;
153
+ border-radius: var(--ui-radius-2);
154
+ }
155
+
156
+ .looma-editor__file-input {
157
+ position: absolute;
158
+ width: 0;
159
+ height: 0;
160
+ opacity: 0;
161
+ pointer-events: none;
162
+ }
163
+
164
+ .looma-editor__drop-overlay {
165
+ position: absolute;
166
+ z-index: var(--ui-editor-drop-overlay-z-index, 10);
167
+ inset: 0;
168
+ display: flex;
169
+ flex-direction: column;
170
+ align-items: center;
171
+ justify-content: center;
172
+ gap: var(--ui-space-3);
173
+ border: 2px dashed var(--ui-accent-solid);
174
+ border-radius: var(--ui-radius-2);
175
+ background: color-mix(in srgb, var(--ui-accent-soft) 92%, transparent);
176
+ color: var(--ui-accent-active);
177
+ font-size: var(--ui-font-size-sm);
178
+ font-weight: var(--ui-font-semibold);
179
+ pointer-events: none;
180
+ }
181
+
182
+ .looma-editor__drop-glyph {
183
+ font-size: var(--ui-font-size-2xl);
184
+ }
185
+
186
+ .looma-editor__toolbar-button {
187
+ --ui-icon-button-size-sm: var(--ui-editor-toolbar-button-size, 2rem);
188
+ --ui-icon-button-radius: var(--ui-editor-toolbar-button-radius, var(--ui-radius-1));
189
+ --ui-icon-button-icon-size: var(--ui-editor-toolbar-icon-size, 1rem);
190
+ }
191
+
192
+ .looma-editor__toolbar-glyph {
193
+ display: inline-flex;
194
+ align-items: center;
195
+ justify-content: center;
196
+ min-width: 1em;
197
+ color: inherit;
198
+ font-family: var(--ui-font-family-sans);
199
+ font-size: var(--ui-editor-toolbar-glyph-size, 0.75rem);
200
+ font-weight: var(--ui-font-semibold);
201
+ line-height: 1;
202
+ }
203
+
204
+ .looma-editor__table-picker-anchor {
205
+ display: inline-flex;
206
+ }
207
+
208
+ .looma-editor__table-picker-popover,
209
+ .looma-editor__table-toolbar-shell,
210
+ .looma-editor__table-menu-shell {
211
+ z-index: var(--ui-editor-popover-z-index, 300);
212
+ }
213
+
214
+ .looma-editor__table-picker-popover {
215
+ min-width: 220px;
216
+ }
217
+
218
+ .looma-editor__table-toolbar-shell,
219
+ .looma-editor__table-menu-shell,
220
+ .looma-editor__table-overlay-shell {
221
+ position: fixed;
222
+ }
223
+
224
+ .looma-editor__mobile-toolbar-shell {
225
+ position: fixed;
226
+ z-index: var(--ui-editor-mobile-toolbar-z-index, var(--ui-editor-popover-z-index, 300));
227
+ display: flex;
228
+ align-items: stretch;
229
+ min-height: var(--ui-editor-toolbar-mobile-min-height, 56px);
230
+ padding:
231
+ var(--ui-editor-mobile-toolbar-padding-block, 4px)
232
+ max(var(--ui-editor-mobile-toolbar-padding-inline, 8px), env(safe-area-inset-left));
233
+ overflow-x: auto;
234
+ overflow-y: hidden;
235
+ overscroll-behavior-inline: contain;
236
+ -webkit-overflow-scrolling: touch;
237
+ scroll-snap-type: x mandatory;
238
+ scrollbar-width: none;
239
+ background: var(--ui-editor-toolbar-bg, var(--ui-surface, #fff));
240
+ border-top: 1px solid var(--ui-editor-toolbar-border, var(--ui-border, #e5e7eb));
241
+ box-shadow: var(--ui-editor-toolbar-mobile-shadow, 0 -2px 8px rgb(0 0 0 / 0.06));
242
+ }
243
+
244
+ .looma-editor__mobile-toolbar-shell::-webkit-scrollbar {
245
+ display: none;
246
+ }
247
+
248
+ .looma-editor__mobile-toolbar-shell > *,
249
+ .looma-editor__mobile-toolbar-shell button,
250
+ .looma-editor__mobile-toolbar-shell ui-icon-button {
251
+ flex: 0 0 auto;
252
+ scroll-snap-align: start;
253
+ }
254
+
255
+ .looma-editor__mobile-toolbar-shell ui-editor-toolbar[floating] {
256
+ width: 100%;
257
+ max-width: none;
258
+ min-height: 100%;
259
+ padding: 0;
260
+ overflow-x: auto;
261
+ overflow-y: hidden;
262
+ overscroll-behavior-inline: contain;
263
+ -webkit-overflow-scrolling: touch;
264
+ scroll-snap-type: x mandatory;
265
+ scrollbar-width: none;
266
+ background: transparent;
267
+ border: 0;
268
+ border-radius: 0;
269
+ box-shadow: none;
270
+ backdrop-filter: none;
271
+ }
272
+
273
+ .looma-editor__mobile-toolbar-shell ui-editor-toolbar[floating]::-webkit-scrollbar {
274
+ display: none;
275
+ }
276
+
277
+ .looma-editor__mobile-toolbar-shell .looma-editor__toolbar-button {
278
+ --ui-icon-button-size-sm: var(--ui-editor-toolbar-mobile-button-size, 44px);
279
+ }
280
+
281
+ .looma-editor__mobile-toolbar-back {
282
+ min-width: 44px;
283
+ min-height: 44px;
284
+ padding: 0 var(--ui-space-3, 12px);
285
+ border: 0;
286
+ border-radius: var(--ui-radius-md, 6px);
287
+ background: transparent;
288
+ color: var(--ui-text-secondary, #4b5563);
289
+ cursor: pointer;
290
+ font: inherit;
291
+ white-space: nowrap;
292
+ }
293
+
294
+ .looma-editor__mobile-toolbar-back:is(:hover, :focus-visible) {
295
+ background: var(--ui-surface-hover, #f3f4f6);
296
+ color: var(--ui-text-primary, #111827);
297
+ }
298
+
299
+ .looma-editor__mobile-toolbar-shell .ui-editor-table-toolbar {
300
+ min-width: max-content;
301
+ min-height: 100%;
302
+ padding: 0;
303
+ background: transparent;
304
+ border: 0;
305
+ border-radius: 0;
306
+ box-shadow: none;
307
+ backdrop-filter: none;
308
+ }
309
+
310
+ .looma-editor__mobile-toolbar-shell .ui-editor-table-toolbar button {
311
+ min-height: 44px;
312
+ background: transparent;
313
+ }
314
+
315
+ .looma-editor__mobile-toolbar-shell .ui-editor-table-toolbar button[data-active="true"],
316
+ .looma-editor__mobile-toolbar-shell .ui-editor-table-toolbar button[data-selected="true"] {
317
+ background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
318
+ }
319
+
320
+ .looma-editor__mobile-toolbar-shell .ui-editor-table-toolbar__menu {
321
+ top: auto;
322
+ right: 0;
323
+ bottom: calc(100% + var(--ui-space-2, 8px));
324
+ max-height: min(50dvh, 22rem);
325
+ overflow-y: auto;
326
+ overscroll-behavior: contain;
327
+ }
328
+
329
+ .looma-editor__table-overlay-shell {
330
+ z-index: var(--ui-editor-overlay-z-index, 299);
331
+ overflow: visible;
332
+ pointer-events: none;
333
+ }
334
+
6
335
  /* Slash menu */
7
336
  ui-editor-slash-menu {
8
337
  user-select: none;
@@ -458,6 +787,36 @@ ui-editor-toolbar[floating] {
458
787
  text-align: left;
459
788
  }
460
789
 
790
+ .ui-editor-table-toolbar__swatches {
791
+ display: grid;
792
+ grid-template-columns: repeat(3, minmax(0, 1fr));
793
+ gap: 2px;
794
+ }
795
+
796
+ .ui-editor-table-toolbar__swatch-button {
797
+ gap: var(--ui-space-1, 4px);
798
+ justify-content: flex-start !important;
799
+ }
800
+
801
+ .ui-editor-table-toolbar__swatch {
802
+ width: 14px;
803
+ height: 14px;
804
+ flex: 0 0 14px;
805
+ border: 1px solid color-mix(in srgb, var(--ui-border, #e5e7eb) 80%, #000);
806
+ border-radius: 3px;
807
+ background: var(--ui-editor-table-toolbar-swatch);
808
+ }
809
+
810
+ .ui-editor-table-toolbar__swatch--default {
811
+ background:
812
+ linear-gradient(135deg, transparent 44%, var(--ui-danger, #dc2626) 46% 54%, transparent 56%),
813
+ var(--ui-surface, #fff);
814
+ }
815
+
816
+ .ui-editor-table-toolbar__swatch-button[data-selected="true"] {
817
+ background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
818
+ }
819
+
461
820
  /* Insert table grid */
462
821
  .ui-editor-insert-table-grid {
463
822
  padding: var(--ui-space-3, 12px);
@@ -584,6 +943,7 @@ ui-editor-toolbar[floating] {
584
943
  }
585
944
 
586
945
  .ui-editor-table-overlay__control--row {
946
+ pointer-events: auto;
587
947
  left: 0;
588
948
  right: 0;
589
949
  top: calc(var(--ui-editor-table-overlay-boundary-index) * 100% / var(--ui-editor-table-overlay-segments));
@@ -657,17 +1017,24 @@ ui-editor-toolbar[floating] {
657
1017
 
658
1018
  .ProseMirror .tableWrapper {
659
1019
  max-width: 100%;
660
- overflow-x: hidden;
1020
+ overflow-x: auto;
661
1021
  overflow-y: visible;
1022
+ overscroll-behavior-inline: contain;
1023
+ -webkit-overflow-scrolling: touch;
662
1024
  }
663
1025
 
664
1026
  /* ProseMirror table (for when Looma editor content is rendered) */
1027
+ .ProseMirror:focus-visible {
1028
+ outline: none;
1029
+ box-shadow: none;
1030
+ }
1031
+
665
1032
  .ProseMirror table {
666
1033
  border-collapse: collapse;
667
1034
  margin: 0;
668
- width: 100% !important;
1035
+ width: max-content !important;
669
1036
  min-width: 100%;
670
- max-width: 100% !important;
1037
+ max-width: none !important;
671
1038
  table-layout: fixed;
672
1039
  }
673
1040
 
@@ -681,11 +1048,15 @@ ui-editor-toolbar[floating] {
681
1048
  border: 1px solid var(--ui-border, #e5e7eb);
682
1049
  padding: var(--ui-space-2, 8px) var(--ui-space-3, 12px);
683
1050
  vertical-align: top;
684
- min-width: 80px;
1051
+ min-width: var(--ui-editor-table-cell-min-width, 112px);
685
1052
  text-align: left;
686
1053
  overflow-wrap: anywhere;
687
1054
  }
688
1055
 
1056
+ .ProseMirror :is(th, td) > p:last-child {
1057
+ margin-bottom: 0;
1058
+ }
1059
+
689
1060
  .ProseMirror th {
690
1061
  font-weight: 600;
691
1062
  background: var(--ui-surface-hover, #f3f4f6);
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "type": "module",
5
- "description": "Looma web components, layout primitives, editor UI, and supported Vue adapters.",
5
+ "description": "Looma web components, responsive layout primitives, a complete editor, and supported Vue adapters.",
6
6
  "license": "MIT",
7
7
  "author": "Threadlabs Studio",
8
8
  "repository": {
@@ -93,9 +93,13 @@
93
93
  "./vue/editor/*.js",
94
94
  "./*.css"
95
95
  ],
96
+ "dependencies": {
97
+ "lowlight": "^3.3.0"
98
+ },
96
99
  "peerDependencies": {
97
100
  "@tiptap/core": ">=2 <3",
98
101
  "@tiptap/pm": ">=2 <3",
102
+ "@tiptap/vue-3": ">=2 <3",
99
103
  "vue": "^3.5.0"
100
104
  },
101
105
  "peerDependenciesMeta": {
@@ -105,6 +109,9 @@
105
109
  "@tiptap/pm": {
106
110
  "optional": true
107
111
  },
112
+ "@tiptap/vue-3": {
113
+ "optional": true
114
+ },
108
115
  "vue": {
109
116
  "optional": true
110
117
  }
package/tokens.css CHANGED
@@ -102,6 +102,23 @@
102
102
  --ui-warning-soft: #fdf7e6;
103
103
  --ui-info-solid: #0066cc;
104
104
  --ui-info-soft: #e8f0fb;
105
+
106
+ /* Compatibility aliases used by the editor's public styling surface.
107
+ Each alias resolves through the canonical semantic token so an app only
108
+ needs to override the canonical Looma theme contract. */
109
+ --ui-surface: var(--ui-surface-elevated);
110
+ --ui-surface-hover: var(--ui-surface-muted);
111
+ --ui-text: var(--ui-text-primary);
112
+ --ui-border: var(--ui-border-default);
113
+ --ui-accent: var(--ui-accent-solid);
114
+ --ui-accent-subtle: var(--ui-accent-soft);
115
+ --ui-accent-contrast: var(--ui-text-on-accent);
116
+ --ui-danger: var(--ui-danger-solid);
117
+ --ui-radius-sm: var(--ui-radius-1);
118
+ --ui-radius-md: var(--ui-radius-2);
119
+ --ui-radius-lg: var(--ui-radius-3);
120
+ --ui-radius-xl: var(--ui-radius-4);
121
+ --ui-text-sm: var(--ui-font-size-sm);
105
122
  }
106
123
 
107
124
  @supports (color: oklch(0.5 0.1 240)) {
@@ -0,0 +1,203 @@
1
+ // src/index.ts
2
+ import "@threadlabs/looma/layout";
3
+ import "@threadlabs/looma/core";
4
+
5
+ // src/adapter.ts
6
+ import {
7
+ cloneVNode,
8
+ defineComponent,
9
+ h,
10
+ isVNode,
11
+ shallowRef,
12
+ watchEffect
13
+ } from "vue";
14
+ var BASE_EVENT_BINDINGS = [
15
+ ["open", "onOpen"],
16
+ ["close", "onClose"],
17
+ ["select", "onSelect"],
18
+ ["change", "onChange"],
19
+ ["input", "onInput"],
20
+ ["dismiss", "onDismiss"]
21
+ ];
22
+ function toHTMLElement(value) {
23
+ if (!value) return null;
24
+ if (value instanceof HTMLElement) return value;
25
+ return null;
26
+ }
27
+ function createAdapterComponent(tagName, displayName, additionalEventBindings = []) {
28
+ const eventBindings = [...BASE_EVENT_BINDINGS, ...additionalEventBindings];
29
+ const callbackAttrs = new Set(eventBindings.map(([, callbackAttr]) => callbackAttr));
30
+ return defineComponent({
31
+ name: displayName,
32
+ inheritAttrs: false,
33
+ setup(_props, { attrs, slots }) {
34
+ const elementRef = shallowRef(null);
35
+ watchEffect((onCleanup) => {
36
+ const element = elementRef.value;
37
+ if (!element) return;
38
+ const adapterAttrs = attrs;
39
+ const handlers = eventBindings.map(
40
+ ([eventName, callbackAttr]) => {
41
+ const callback = adapterAttrs[callbackAttr];
42
+ return [
43
+ eventName,
44
+ typeof callback === "function" ? (event) => callback(event.detail) : void 0
45
+ ];
46
+ }
47
+ );
48
+ for (const [eventName, handler] of handlers) {
49
+ if (handler) element.addEventListener(eventName, handler);
50
+ }
51
+ onCleanup(() => {
52
+ for (const [eventName, handler] of handlers) {
53
+ if (handler) element.removeEventListener(eventName, handler);
54
+ }
55
+ });
56
+ });
57
+ return () => {
58
+ const forwardedAttrs = Object.fromEntries(
59
+ Object.entries(attrs).filter(([name]) => !callbackAttrs.has(name))
60
+ );
61
+ const children = Object.entries(slots).flatMap(([slotName, slotFn]) => {
62
+ if (!slotFn) return [];
63
+ return slotFn().map((node) => {
64
+ if (slotName === "default") return node;
65
+ if (isVNode(node)) return cloneVNode(node, { slot: slotName });
66
+ return h("span", { slot: slotName }, node);
67
+ });
68
+ });
69
+ return h(
70
+ tagName,
71
+ {
72
+ "data-allow-mismatch": forwardedAttrs["data-allow-mismatch"] ?? "class",
73
+ ...forwardedAttrs,
74
+ ref: (value) => {
75
+ elementRef.value = toHTMLElement(value);
76
+ }
77
+ },
78
+ children.length > 0 ? children : void 0
79
+ );
80
+ };
81
+ }
82
+ });
83
+ }
84
+
85
+ // src/index.ts
86
+ var Stack = createAdapterComponent("ui-stack", "Stack");
87
+ var Inline = createAdapterComponent("ui-inline", "Inline");
88
+ var Cluster = createAdapterComponent("ui-cluster", "Cluster");
89
+ var Grid = createAdapterComponent("ui-grid", "Grid");
90
+ var Center = createAdapterComponent("ui-center", "Center");
91
+ var Switcher = createAdapterComponent("ui-switcher", "Switcher");
92
+ var Sidebar = createAdapterComponent("ui-sidebar", "Sidebar");
93
+ var Reel = createAdapterComponent("ui-reel", "Reel");
94
+ var Separator = createAdapterComponent("ui-separator", "Separator");
95
+ var Disclosure = createAdapterComponent("ui-disclosure", "Disclosure");
96
+ var Tabs = createAdapterComponent("ui-tabs", "Tabs");
97
+ var Dialog = createAdapterComponent("ui-dialog", "Dialog");
98
+ var Popover = createAdapterComponent("ui-popover", "Popover");
99
+ var Menu = createAdapterComponent("ui-menu", "Menu");
100
+ var MenuItem = createAdapterComponent("ui-menu-item", "MenuItem");
101
+ var ContextMenu = createAdapterComponent("ui-context-menu", "ContextMenu");
102
+ var Button = createAdapterComponent("ui-button", "Button");
103
+ var IconButton = createAdapterComponent("ui-icon-button", "IconButton");
104
+ var Input = createAdapterComponent("ui-input", "Input");
105
+ var Select = createAdapterComponent("ui-select", "Select");
106
+ var Textarea = createAdapterComponent("ui-textarea", "Textarea");
107
+ var FormField = createAdapterComponent("ui-form-field", "FormField");
108
+ var Tooltip = createAdapterComponent("ui-tooltip", "Tooltip");
109
+ var ToastRegion = createAdapterComponent("ui-toast-region", "ToastRegion");
110
+ var Checkbox = createAdapterComponent("ui-checkbox", "Checkbox");
111
+ var Switch = createAdapterComponent("ui-switch", "Switch");
112
+ var RadioGroup = createAdapterComponent("ui-radio-group", "RadioGroup");
113
+ var Radio = createAdapterComponent("ui-radio", "Radio");
114
+ var Badge = createAdapterComponent("ui-badge", "Badge");
115
+ var Avatar = createAdapterComponent("ui-avatar", "Avatar");
116
+ var AvatarGroup = createAdapterComponent("ui-avatar-group", "AvatarGroup");
117
+ var FloatingActionButton = createAdapterComponent(
118
+ "ui-floating-action-button",
119
+ "FloatingActionButton"
120
+ );
121
+ var SearchShell = createAdapterComponent("ui-search-shell", "SearchShell");
122
+ var SearchResultRow = createAdapterComponent("ui-search-result-row", "SearchResultRow");
123
+ var TopBar = createAdapterComponent("ui-top-bar", "TopBar");
124
+ var ADAPTER_COMPONENT_TAG_MAP = {
125
+ Stack: "ui-stack",
126
+ Inline: "ui-inline",
127
+ Cluster: "ui-cluster",
128
+ Grid: "ui-grid",
129
+ Center: "ui-center",
130
+ Switcher: "ui-switcher",
131
+ Sidebar: "ui-sidebar",
132
+ Reel: "ui-reel",
133
+ Separator: "ui-separator",
134
+ Disclosure: "ui-disclosure",
135
+ Tabs: "ui-tabs",
136
+ Dialog: "ui-dialog",
137
+ Popover: "ui-popover",
138
+ Menu: "ui-menu",
139
+ MenuItem: "ui-menu-item",
140
+ ContextMenu: "ui-context-menu",
141
+ Button: "ui-button",
142
+ IconButton: "ui-icon-button",
143
+ Input: "ui-input",
144
+ Select: "ui-select",
145
+ Textarea: "ui-textarea",
146
+ FormField: "ui-form-field",
147
+ Tooltip: "ui-tooltip",
148
+ ToastRegion: "ui-toast-region",
149
+ Checkbox: "ui-checkbox",
150
+ Switch: "ui-switch",
151
+ RadioGroup: "ui-radio-group",
152
+ Radio: "ui-radio",
153
+ Badge: "ui-badge",
154
+ Avatar: "ui-avatar",
155
+ AvatarGroup: "ui-avatar-group",
156
+ FloatingActionButton: "ui-floating-action-button",
157
+ SearchShell: "ui-search-shell",
158
+ SearchResultRow: "ui-search-result-row",
159
+ TopBar: "ui-top-bar"
160
+ };
161
+ var VUE_ADAPTER_NOTE = "Thin adapter only: attrs and slots pass through to custom elements and DOM events map to typed callbacks.";
162
+
163
+ export {
164
+ toHTMLElement,
165
+ createAdapterComponent,
166
+ Stack,
167
+ Inline,
168
+ Cluster,
169
+ Grid,
170
+ Center,
171
+ Switcher,
172
+ Sidebar,
173
+ Reel,
174
+ Separator,
175
+ Disclosure,
176
+ Tabs,
177
+ Dialog,
178
+ Popover,
179
+ Menu,
180
+ MenuItem,
181
+ ContextMenu,
182
+ Button,
183
+ IconButton,
184
+ Input,
185
+ Select,
186
+ Textarea,
187
+ FormField,
188
+ Tooltip,
189
+ ToastRegion,
190
+ Checkbox,
191
+ Switch,
192
+ RadioGroup,
193
+ Radio,
194
+ Badge,
195
+ Avatar,
196
+ AvatarGroup,
197
+ FloatingActionButton,
198
+ SearchShell,
199
+ SearchResultRow,
200
+ TopBar,
201
+ ADAPTER_COMPONENT_TAG_MAP,
202
+ VUE_ADAPTER_NOTE
203
+ };