@wrrdev/fenix-ui 1.1.14 → 1.1.15

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 (69) hide show
  1. package/README.md +5 -4
  2. package/dist/components/editor/commands.d.ts +27 -0
  3. package/dist/components/editor/commands.d.ts.map +1 -0
  4. package/dist/components/editor/commands.js +235 -0
  5. package/dist/components/editor/commands.js.map +1 -0
  6. package/dist/components/editor/editor.d.ts +83 -0
  7. package/dist/components/editor/editor.d.ts.map +1 -0
  8. package/dist/components/editor/editor.js +1951 -0
  9. package/dist/components/editor/editor.js.map +1 -0
  10. package/dist/components/editor/index.d.ts +12 -0
  11. package/dist/components/editor/index.d.ts.map +1 -0
  12. package/dist/components/editor/index.js +7 -0
  13. package/dist/components/editor/index.js.map +1 -0
  14. package/dist/components/editor/normalize-html.d.ts +33 -0
  15. package/dist/components/editor/normalize-html.d.ts.map +1 -0
  16. package/dist/components/editor/normalize-html.js +316 -0
  17. package/dist/components/editor/normalize-html.js.map +1 -0
  18. package/dist/components/editor/sanitize-html.d.ts +37 -0
  19. package/dist/components/editor/sanitize-html.d.ts.map +1 -0
  20. package/dist/components/editor/sanitize-html.js +247 -0
  21. package/dist/components/editor/sanitize-html.js.map +1 -0
  22. package/dist/components/editor/schema.d.ts +36 -0
  23. package/dist/components/editor/schema.d.ts.map +1 -0
  24. package/dist/components/editor/schema.js +232 -0
  25. package/dist/components/editor/schema.js.map +1 -0
  26. package/dist/components/editor/selection.d.ts +22 -0
  27. package/dist/components/editor/selection.d.ts.map +1 -0
  28. package/dist/components/editor/selection.js +97 -0
  29. package/dist/components/editor/selection.js.map +1 -0
  30. package/dist/components/editor/styles.d.ts +10 -0
  31. package/dist/components/editor/styles.d.ts.map +1 -0
  32. package/dist/components/editor/styles.js +446 -0
  33. package/dist/components/editor/styles.js.map +1 -0
  34. package/dist/components/editor/table-utils.d.ts +33 -0
  35. package/dist/components/editor/table-utils.d.ts.map +1 -0
  36. package/dist/components/editor/table-utils.js +150 -0
  37. package/dist/components/editor/table-utils.js.map +1 -0
  38. package/dist/components/input/input.d.ts +5 -1
  39. package/dist/components/input/input.d.ts.map +1 -1
  40. package/dist/components/input/input.js +15 -1
  41. package/dist/components/input/input.js.map +1 -1
  42. package/dist/components/toast/toast.d.ts +10 -10
  43. package/dist/components/toast/toast.d.ts.map +1 -1
  44. package/dist/components/toast/toast.js +46 -13
  45. package/dist/components/toast/toast.js.map +1 -1
  46. package/dist/core/jsx.d.ts +25 -1
  47. package/dist/core/jsx.d.ts.map +1 -1
  48. package/dist/core/jsx.js.map +1 -1
  49. package/dist/core/vue.d.ts +3 -1
  50. package/dist/core/vue.d.ts.map +1 -1
  51. package/dist/core/vue.js.map +1 -1
  52. package/dist/docs/componentes/editor.doc.d.ts +6 -0
  53. package/dist/docs/componentes/editor.doc.d.ts.map +1 -0
  54. package/dist/docs/componentes/index.d.ts.map +1 -1
  55. package/dist/docs/componentes/input.doc.d.ts.map +1 -1
  56. package/dist/fenix-ui.umd.min.js +748 -254
  57. package/dist/fenix-ui2.esm.js.map +1 -1
  58. package/dist/fenix-ui4.esm.js +3817 -183
  59. package/dist/fenix-ui4.esm.js.map +1 -1
  60. package/dist/fenix-ui5.esm.js +1 -0
  61. package/dist/fenix-ui5.esm.js.map +1 -1
  62. package/dist/index.d.ts +1 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +14 -0
  65. package/dist/index.js.map +1 -1
  66. package/dist/plugins/auto-import.d.ts.map +1 -1
  67. package/dist/plugins/auto-import.js +1 -0
  68. package/dist/plugins/auto-import.js.map +1 -1
  69. package/package.json +5 -1
@@ -0,0 +1,446 @@
1
+ const FX_EDITOR_CONTENT_CSS = `
2
+ .content { line-height: 1.55; color: var(--fx-text-default); }
3
+ .content p { margin: 0 0 0.65em; }
4
+ .content h1, .content h2, .content h3, .content h4, .content h5, .content h6 {
5
+ margin: 0.8em 0 0.4em; line-height: 1.25; font-weight: 600; color: var(--fx-text-default);
6
+ }
7
+ .content h1 { font-size: 1.8em; }
8
+ .content h2 { font-size: 1.5em; }
9
+ .content h3 { font-size: 1.25em; }
10
+ .content h4 { font-size: 1.1em; }
11
+ .content h5, .content h6 { font-size: 1em; }
12
+ .content ul, .content ol { margin: 0 0 0.65em; padding-left: 1.6em; }
13
+ .content li { margin: 0.15em 0; }
14
+ .content blockquote {
15
+ margin: 0.5em 0; padding: 0.25em 0 0.25em 1em;
16
+ border-left: 3px solid var(--fx-color-primary); color: var(--fx-text-muted);
17
+ }
18
+ .content pre {
19
+ margin: 0.6em 0; padding: var(--fx-space-md); overflow: auto;
20
+ background: var(--fx-surface-surface); border-radius: var(--fx-radius-sm);
21
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.9em;
22
+ }
23
+ .content code {
24
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
25
+ font-size: 0.92em; background: var(--fx-surface-surface);
26
+ padding: 0.1em 0.3em; border-radius: 3px;
27
+ }
28
+ .content pre code { background: none; padding: 0; }
29
+ .content hr { border: none; border-top: 1px solid var(--fx-border-default); margin: 1em 0; }
30
+ .content a { color: var(--fx-color-primary); text-decoration: underline; cursor: pointer; }
31
+ .content img { max-width: 100%; height: auto; display: block; }
32
+ .content figure { margin: 1em 0; }
33
+ .content figure.fx-image img { margin: 0 auto; }
34
+ .content figure.fx-image[data-align="left"] { float: left; max-width: 50%; margin: 0 1em 0.5em 0; }
35
+ .content figure.fx-image[data-align="right"] { float: right; max-width: 50%; margin: 0 0 0.5em 1em; }
36
+ .content figure.fx-image[data-align="center"] { margin-left: auto; margin-right: auto; }
37
+ .content figure.fx-video[data-align="left"],
38
+ .content figure.fx-embed[data-align="left"] { float: left; max-width: 50%; margin: 0 1em 0.5em 0; }
39
+ .content figure.fx-video[data-align="right"],
40
+ .content figure.fx-embed[data-align="right"] { float: right; max-width: 50%; margin: 0 0 0.5em 1em; }
41
+ .content figure.fx-video[data-align="center"],
42
+ .content figure.fx-embed[data-align="center"] { margin-left: auto; margin-right: auto; }
43
+ .content figcaption {
44
+ margin-top: 0.4em; color: var(--fx-text-muted);
45
+ font-size: 0.85em; text-align: center;
46
+ }
47
+ .content video { display: block; width: 100%; background: #000; border-radius: var(--fx-radius-sm); }
48
+ .content iframe { display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; }
49
+ .content table { width: 100%; border-collapse: collapse; margin: 1em 0; }
50
+ .content th, .content td { border: 1px solid var(--fx-border-default); padding: var(--fx-space-xs) var(--fx-space-sm); vertical-align: top; }
51
+ .content th { background: var(--fx-surface-surface); text-align: left; font-weight: 600; }
52
+ .content table.fx-grid { border: none; margin: 0.6em 0; }
53
+ .content table.fx-grid > tbody > tr > td {
54
+ border: 1px dashed var(--fx-border-default); padding: var(--fx-space-sm);
55
+ vertical-align: top;
56
+ }
57
+ @media (max-width: 640px) {
58
+ .content table.fx-grid[data-stack] > tbody > tr > td {
59
+ display: block; width: 100% !important; border: none; padding: var(--fx-space-xs) 0;
60
+ }
61
+ }
62
+ `;
63
+ const EDITOR_STYLES = `
64
+ :host {
65
+ display: block;
66
+ width: 100%;
67
+ font-family: var(--fx-font-family);
68
+ font-size: var(--fx-font-size);
69
+ color: var(--fx-text-default);
70
+ --fx-editor-min-height: 240px;
71
+ --fx-editor-max-height: none;
72
+ --fx-editor-radius: var(--fx-radius-md);
73
+ --fx-editor-toolbar-bg: var(--fx-surface-surface);
74
+ --fx-editor-content-padding: var(--fx-space-md) var(--fx-space-lg);
75
+ }
76
+ :host([full]) { width: 100%; }
77
+ .editor {
78
+ display: flex;
79
+ flex-direction: column;
80
+ overflow: hidden;
81
+ background: var(--fx-surface-background);
82
+ border: 1px solid var(--fx-border-default);
83
+ border-radius: var(--fx-editor-radius);
84
+ transition: border-color var(--fx-motion-duration-normal) var(--fx-motion-easing),
85
+ box-shadow var(--fx-motion-duration-normal) var(--fx-motion-easing);
86
+ }
87
+ .editor:focus-within {
88
+ border-color: var(--fx-color-primary);
89
+ box-shadow: var(--fx-effect-focus-ring, none);
90
+ }
91
+ :host([error]) .editor, :host([invalid]) .editor {
92
+ border-color: var(--fx-color-danger, #dc2626);
93
+ box-shadow: var(--fx-effect-error-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent));
94
+ }
95
+ :host([success]) .editor, :host([valid]) .editor {
96
+ border-color: var(--fx-color-success, #16a34a);
97
+ box-shadow: var(--fx-effect-success-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent));
98
+ }
99
+ :host([disabled]) { opacity: 0.55; pointer-events: none; }
100
+ :host([readonly]) .toolbar { display: none; }
101
+
102
+ .toolbar {
103
+ position: relative;
104
+ display: flex;
105
+ flex-wrap: wrap;
106
+ align-items: center;
107
+ gap: 1px;
108
+ padding: var(--fx-space-xs);
109
+ background: var(--fx-editor-toolbar-bg);
110
+ border-bottom: 1px solid var(--fx-border-default);
111
+ user-select: none;
112
+ }
113
+ .toolbar[hidden] { display: none; }
114
+ .tb-group {
115
+ display: flex;
116
+ align-items: center;
117
+ gap: 1px;
118
+ padding: 0 var(--fx-space-xs);
119
+ border-right: 1px solid var(--fx-border-default);
120
+ }
121
+ .tb-group:last-child { border-right: none; }
122
+ .tb-btn {
123
+ display: inline-flex;
124
+ align-items: center;
125
+ justify-content: center;
126
+ width: 30px;
127
+ height: 30px;
128
+ padding: 0;
129
+ border: none;
130
+ border-radius: var(--fx-radius-sm);
131
+ background: transparent;
132
+ color: var(--fx-text-default);
133
+ font-size: 19px;
134
+ cursor: pointer;
135
+ transition: background var(--fx-motion-duration-fast) var(--fx-motion-easing);
136
+ }
137
+ .tb-btn:hover { background: var(--fx-surface-surface-hover, rgba(0, 0, 0, 0.06)); }
138
+ .tb-btn:focus-visible { outline: 2px solid var(--fx-color-primary); outline-offset: -2px; }
139
+ .tb-btn.active {
140
+ background: color-mix(in srgb, var(--fx-color-primary) 14%, transparent);
141
+ color: var(--fx-color-primary);
142
+ }
143
+ .tb-btn:disabled { opacity: 0.4; cursor: not-allowed; }
144
+ .tb-select {
145
+ height: 30px;
146
+ padding: 0 var(--fx-space-xs);
147
+ border: 1px solid var(--fx-border-default);
148
+ border-radius: var(--fx-radius-sm);
149
+ background: var(--fx-surface-background);
150
+ color: var(--fx-text-default);
151
+ font-family: inherit;
152
+ font-size: calc(var(--fx-font-size) - 2px);
153
+ cursor: pointer;
154
+ }
155
+ .tb-color {
156
+ width: 30px;
157
+ height: 30px;
158
+ padding: 2px;
159
+ border: none;
160
+ background: transparent;
161
+ cursor: pointer;
162
+ }
163
+ .tb-color input { width: 26px; height: 26px; padding: 0; border: none; background: none; cursor: pointer; }
164
+ .body { position: relative; display: flex; flex-direction: column; flex: 1 1 auto; }
165
+ .content {
166
+ position: relative;
167
+ min-height: var(--fx-editor-min-height);
168
+ max-height: var(--fx-editor-max-height);
169
+ overflow: auto;
170
+ padding: var(--fx-editor-content-padding);
171
+ outline: none;
172
+ box-sizing: border-box;
173
+ }
174
+ .content[hidden] { display: none; }
175
+ .content.is-empty::before {
176
+ content: attr(data-placeholder);
177
+ color: var(--fx-text-muted);
178
+ pointer-events: none;
179
+ position: absolute;
180
+ }
181
+ .content[contenteditable="false"] { background: var(--fx-surface-surface-hover, rgba(0,0,0,.02)); }
182
+ .content figure.fx-image { touch-action: none; }
183
+
184
+ .media-overlay {
185
+ position: absolute;
186
+ z-index: 5;
187
+ pointer-events: none;
188
+ border: 1px solid var(--fx-color-primary);
189
+ box-shadow: 0 0 0 1px color-mix(in srgb, var(--fx-color-primary) 30%, transparent);
190
+ }
191
+ .media-overlay[hidden] { display: none; }
192
+ .media-handle {
193
+ position: absolute;
194
+ width: 11px;
195
+ height: 11px;
196
+ border: 1px solid #fff;
197
+ border-radius: 50%;
198
+ background: var(--fx-color-primary);
199
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
200
+ pointer-events: auto;
201
+ touch-action: none;
202
+ }
203
+ .media-handle.nw { left: -6px; top: -6px; cursor: nwse-resize; }
204
+ .media-handle.ne { right: -6px; top: -6px; cursor: nesw-resize; }
205
+ .media-handle.sw { left: -6px; bottom: -6px; cursor: nesw-resize; }
206
+ .media-handle.se { right: -6px; bottom: -6px; cursor: nwse-resize; }
207
+ .media-size {
208
+ position: absolute;
209
+ top: -24px;
210
+ left: 0;
211
+ padding: 2px 6px;
212
+ border-radius: var(--fx-radius-sm);
213
+ background: var(--fx-color-primary);
214
+ color: #fff;
215
+ font-size: 11px;
216
+ line-height: 1.4;
217
+ white-space: nowrap;
218
+ }
219
+ .media-delete {
220
+ position: absolute;
221
+ top: -32px;
222
+ right: -1px;
223
+ display: inline-flex;
224
+ align-items: center;
225
+ justify-content: center;
226
+ width: 24px;
227
+ height: 24px;
228
+ padding: 0;
229
+ border: none;
230
+ border-radius: 50%;
231
+ background: var(--fx-color-danger, #dc2626);
232
+ color: #fff;
233
+ font-size: 15px;
234
+ line-height: 1;
235
+ cursor: pointer;
236
+ pointer-events: auto;
237
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
238
+ }
239
+ .media-delete:hover { filter: brightness(0.92); }
240
+ .media-delete:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }
241
+
242
+ .content figure.fx-image,
243
+ .content figure.fx-video,
244
+ .content figure.fx-embed { position: relative; }
245
+ .fx-media-quick {
246
+ position: absolute;
247
+ top: 6px;
248
+ z-index: 4;
249
+ display: inline-flex;
250
+ align-items: center;
251
+ justify-content: center;
252
+ width: 24px;
253
+ height: 24px;
254
+ padding: 0;
255
+ border: 1px solid color-mix(in srgb, var(--fx-color-primary) 35%, transparent);
256
+ border-radius: var(--fx-radius-sm);
257
+ background: var(--fx-surface-background);
258
+ color: var(--fx-text-default);
259
+ cursor: pointer;
260
+ opacity: 0;
261
+ transition: opacity var(--fx-motion-duration-fast) var(--fx-motion-easing), background var(--fx-motion-duration-fast) var(--fx-motion-easing);
262
+ }
263
+ .content figure:hover > .fx-media-quick,
264
+ .content figure:focus-within > .fx-media-quick { opacity: 1; }
265
+ .content figure.fx-video > .fx-media-quick,
266
+ .content figure.fx-embed > .fx-media-quick { opacity: 0.92; }
267
+ .fx-media-quick:hover { background: var(--fx-surface-surface-hover, rgba(0, 0, 0, 0.06)); }
268
+ .fx-media-quick.active { background: var(--fx-color-primary); color: #fff; }
269
+ .fx-media-quick.quick-left { right: 82px; }
270
+ .fx-media-quick.quick-center { right: 56px; }
271
+ .fx-media-quick.quick-right { right: 30px; }
272
+ .fx-media-quick.quick-delete { right: 4px; background: var(--fx-color-danger, #dc2626); color: #fff; border-color: transparent; }
273
+ .fx-media-quick:focus-visible { outline: 2px solid var(--fx-color-primary); outline-offset: 1px; }
274
+
275
+ .link-overlay {
276
+ position: absolute;
277
+ z-index: 6;
278
+ display: flex;
279
+ gap: 2px;
280
+ padding: 3px;
281
+ background: var(--fx-surface-background);
282
+ border: 1px solid var(--fx-border-default);
283
+ border-radius: var(--fx-radius-sm);
284
+ box-shadow: var(--fx-shadow-md, 0 4px 12px rgba(0, 0, 0, 0.16));
285
+ }
286
+ .link-overlay[hidden] { display: none; }
287
+ .link-overlay button {
288
+ border: none;
289
+ background: none;
290
+ color: var(--fx-text-default);
291
+ font: inherit;
292
+ font-size: 12px;
293
+ line-height: 1.4;
294
+ padding: 4px 8px;
295
+ border-radius: var(--fx-radius-sm);
296
+ cursor: pointer;
297
+ }
298
+ .link-overlay button:hover { background: var(--fx-surface-surface-hover, rgba(0, 0, 0, 0.06)); }
299
+ .link-overlay button[data-link-action="remove"] { color: var(--fx-color-danger, #dc2626); }
300
+ .link-overlay button:focus-visible { outline: 2px solid var(--fx-color-primary); outline-offset: 1px; }
301
+
302
+ .source {
303
+ display: block;
304
+ width: 100%;
305
+ min-height: var(--fx-editor-min-height);
306
+ max-height: var(--fx-editor-max-height);
307
+ padding: var(--fx-editor-content-padding);
308
+ border: none;
309
+ outline: none;
310
+ resize: vertical;
311
+ background: var(--fx-surface-background);
312
+ color: var(--fx-text-default);
313
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
314
+ font-size: 13px;
315
+ line-height: 1.55;
316
+ box-sizing: border-box;
317
+ }
318
+ .source[hidden] { display: none; }
319
+
320
+ .statusbar {
321
+ display: flex;
322
+ align-items: center;
323
+ justify-content: space-between;
324
+ gap: var(--fx-space-sm);
325
+ min-height: 28px;
326
+ padding: 2px var(--fx-space-md);
327
+ border-top: 1px solid var(--fx-border-default);
328
+ color: var(--fx-text-muted);
329
+ font-size: calc(var(--fx-font-size) - 3px);
330
+ }
331
+ .statusbar:empty { display: none; }
332
+ .statusbar[hidden] { display: none; }
333
+ .source-actions { display: inline-flex; gap: var(--fx-space-xs); }
334
+ .source-actions[hidden] { display: none; }
335
+
336
+ .backdrop {
337
+ position: fixed;
338
+ inset: 0;
339
+ z-index: var(--fx-z-modal, 1100);
340
+ display: flex;
341
+ align-items: center;
342
+ justify-content: center;
343
+ background: color-mix(in srgb, var(--fx-text-default, #000) 45%, transparent);
344
+ }
345
+ .backdrop[hidden] { display: none; }
346
+ .dialog {
347
+ width: min(460px, calc(100vw - 32px));
348
+ max-height: calc(100vh - 48px);
349
+ overflow: auto;
350
+ background: var(--fx-surface-background);
351
+ border: 1px solid var(--fx-border-default);
352
+ border-radius: var(--fx-radius-lg);
353
+ box-shadow: var(--fx-shadow-xl);
354
+ font-family: var(--fx-font-family);
355
+ font-size: var(--fx-font-size);
356
+ }
357
+ .dialog header {
358
+ display: flex;
359
+ align-items: center;
360
+ justify-content: space-between;
361
+ padding: var(--fx-space-md) var(--fx-space-lg);
362
+ border-bottom: 1px solid var(--fx-border-default);
363
+ }
364
+ .dialog h3 { margin: 0; font-size: 1rem; font-weight: 600; }
365
+ .dialog-close {
366
+ border: none; background: transparent; color: var(--fx-text-muted);
367
+ font-size: 1.4rem; line-height: 1; cursor: pointer;
368
+ }
369
+ .dialog-body { display: flex; flex-direction: column; gap: var(--fx-space-sm); padding: var(--fx-space-lg); }
370
+ .field { display: flex; flex-direction: column; gap: 3px; font-size: calc(var(--fx-font-size) - 2px); color: var(--fx-text-muted); }
371
+ .field input, .field select {
372
+ height: var(--fx-size-md);
373
+ padding: 0 var(--fx-space-sm);
374
+ border: 1px solid var(--fx-border-default);
375
+ border-radius: var(--fx-radius-sm);
376
+ background: var(--fx-surface-background);
377
+ color: var(--fx-text-default);
378
+ font: inherit;
379
+ font-size: var(--fx-font-size);
380
+ }
381
+ .field input:focus, .field select:focus { outline: none; border-color: var(--fx-color-primary); box-shadow: var(--fx-effect-focus-ring, none); }
382
+ .dialog footer {
383
+ display: flex; justify-content: flex-end; gap: var(--fx-space-sm);
384
+ padding: var(--fx-space-md) var(--fx-space-lg);
385
+ border-top: 1px solid var(--fx-border-default);
386
+ }
387
+ .btn {
388
+ min-height: var(--fx-size-sm);
389
+ padding: 0 var(--fx-space-md);
390
+ border: 1px solid var(--fx-border-default);
391
+ border-radius: var(--fx-radius-sm);
392
+ background: var(--fx-surface-background);
393
+ color: var(--fx-text-default);
394
+ font: inherit; font-size: calc(var(--fx-font-size) - 2px);
395
+ cursor: pointer;
396
+ }
397
+ .btn:hover { background: var(--fx-surface-surface-hover, rgba(0,0,0,.05)); }
398
+ .btn.primary { background: var(--fx-color-primary); border-color: transparent; color: #fff; }
399
+ .btn.primary:hover { filter: brightness(0.92); }
400
+
401
+ .panel {
402
+ position: absolute;
403
+ top: calc(100% + 4px);
404
+ left: var(--fx-space-md);
405
+ z-index: 6;
406
+ padding: var(--fx-space-sm);
407
+ background: var(--fx-surface-background);
408
+ border: 1px solid var(--fx-border-default);
409
+ border-radius: var(--fx-radius-md);
410
+ box-shadow: var(--fx-shadow-lg);
411
+ }
412
+ .panel[hidden] { display: none; }
413
+ .grid-picker { display: grid; grid-template-columns: repeat(8, 18px); gap: 3px; }
414
+ .grid-picker button {
415
+ width: 18px; height: 18px; padding: 0;
416
+ border: 1px solid var(--fx-border-default);
417
+ border-radius: 2px; background: var(--fx-surface-background); cursor: pointer;
418
+ }
419
+ .grid-picker button.on { background: var(--fx-color-primary); border-color: var(--fx-color-primary); }
420
+ .panel-title { margin: 0 0 6px; font-size: 11px; color: var(--fx-text-muted); }
421
+ .panel-actions { display: flex; flex-wrap: wrap; gap: 4px; max-width: 210px; }
422
+ .panel-actions .btn { min-height: 26px; padding: 0 6px; font-size: 11px; }
423
+
424
+ :host([fullscreen]) {
425
+ position: fixed;
426
+ inset: 0;
427
+ z-index: var(--fx-z-modal, 1100);
428
+ background: var(--fx-surface-background);
429
+ }
430
+ :host([fullscreen]) .editor { height: 100%; border: none; border-radius: 0; }
431
+ :host([fullscreen]) .content, :host([fullscreen]) .source { flex: 1 1 auto; max-height: none; }
432
+
433
+ @media (max-width: 640px) {
434
+ .toolbar { gap: 0; }
435
+ .tb-group { padding: 0 1px; }
436
+ .tb-btn { width: 28px; height: 28px; }
437
+ }
438
+ ${FX_EDITOR_CONTENT_CSS}
439
+
440
+
441
+ `;
442
+ export {
443
+ EDITOR_STYLES,
444
+ FX_EDITOR_CONTENT_CSS
445
+ };
446
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sources":["../../../src/components/editor/styles.ts"],"sourcesContent":["/**\n * Estilos do <fx-editor>.\n *\n * Tudo isolado no Shadow DOM. A parte de conteúdo também é exportada em\n * `FX_EDITOR_CONTENT_CSS` para quem salva o HTML e precisa renderizá-lo fora\n * do componente.\n */\n\nexport const FX_EDITOR_CONTENT_CSS = `\n.content { line-height: 1.55; color: var(--fx-text-default); }\n.content p { margin: 0 0 0.65em; }\n.content h1, .content h2, .content h3, .content h4, .content h5, .content h6 {\n margin: 0.8em 0 0.4em; line-height: 1.25; font-weight: 600; color: var(--fx-text-default);\n}\n.content h1 { font-size: 1.8em; }\n.content h2 { font-size: 1.5em; }\n.content h3 { font-size: 1.25em; }\n.content h4 { font-size: 1.1em; }\n.content h5, .content h6 { font-size: 1em; }\n.content ul, .content ol { margin: 0 0 0.65em; padding-left: 1.6em; }\n.content li { margin: 0.15em 0; }\n.content blockquote {\n margin: 0.5em 0; padding: 0.25em 0 0.25em 1em;\n border-left: 3px solid var(--fx-color-primary); color: var(--fx-text-muted);\n}\n.content pre {\n margin: 0.6em 0; padding: var(--fx-space-md); overflow: auto;\n background: var(--fx-surface-surface); border-radius: var(--fx-radius-sm);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.9em;\n}\n.content code {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 0.92em; background: var(--fx-surface-surface);\n padding: 0.1em 0.3em; border-radius: 3px;\n}\n.content pre code { background: none; padding: 0; }\n.content hr { border: none; border-top: 1px solid var(--fx-border-default); margin: 1em 0; }\n.content a { color: var(--fx-color-primary); text-decoration: underline; cursor: pointer; }\n.content img { max-width: 100%; height: auto; display: block; }\n.content figure { margin: 1em 0; }\n.content figure.fx-image img { margin: 0 auto; }\n.content figure.fx-image[data-align=\"left\"] { float: left; max-width: 50%; margin: 0 1em 0.5em 0; }\n.content figure.fx-image[data-align=\"right\"] { float: right; max-width: 50%; margin: 0 0 0.5em 1em; }\n.content figure.fx-image[data-align=\"center\"] { margin-left: auto; margin-right: auto; }\n.content figure.fx-video[data-align=\"left\"],\n.content figure.fx-embed[data-align=\"left\"] { float: left; max-width: 50%; margin: 0 1em 0.5em 0; }\n.content figure.fx-video[data-align=\"right\"],\n.content figure.fx-embed[data-align=\"right\"] { float: right; max-width: 50%; margin: 0 0 0.5em 1em; }\n.content figure.fx-video[data-align=\"center\"],\n.content figure.fx-embed[data-align=\"center\"] { margin-left: auto; margin-right: auto; }\n.content figcaption {\n margin-top: 0.4em; color: var(--fx-text-muted);\n font-size: 0.85em; text-align: center;\n}\n.content video { display: block; width: 100%; background: #000; border-radius: var(--fx-radius-sm); }\n.content iframe { display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; }\n.content table { width: 100%; border-collapse: collapse; margin: 1em 0; }\n.content th, .content td { border: 1px solid var(--fx-border-default); padding: var(--fx-space-xs) var(--fx-space-sm); vertical-align: top; }\n.content th { background: var(--fx-surface-surface); text-align: left; font-weight: 600; }\n.content table.fx-grid { border: none; margin: 0.6em 0; }\n.content table.fx-grid > tbody > tr > td {\n border: 1px dashed var(--fx-border-default); padding: var(--fx-space-sm);\n vertical-align: top;\n}\n@media (max-width: 640px) {\n .content table.fx-grid[data-stack] > tbody > tr > td {\n display: block; width: 100% !important; border: none; padding: var(--fx-space-xs) 0;\n }\n}\n`;\n\nexport const EDITOR_STYLES = `\n:host {\n display: block;\n width: 100%;\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n color: var(--fx-text-default);\n --fx-editor-min-height: 240px;\n --fx-editor-max-height: none;\n --fx-editor-radius: var(--fx-radius-md);\n --fx-editor-toolbar-bg: var(--fx-surface-surface);\n --fx-editor-content-padding: var(--fx-space-md) var(--fx-space-lg);\n}\n:host([full]) { width: 100%; }\n.editor {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-editor-radius);\n transition: border-color var(--fx-motion-duration-normal) var(--fx-motion-easing),\n box-shadow var(--fx-motion-duration-normal) var(--fx-motion-easing);\n}\n.editor:focus-within {\n border-color: var(--fx-color-primary);\n box-shadow: var(--fx-effect-focus-ring, none);\n}\n:host([error]) .editor, :host([invalid]) .editor {\n border-color: var(--fx-color-danger, #dc2626);\n box-shadow: var(--fx-effect-error-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent));\n}\n:host([success]) .editor, :host([valid]) .editor {\n border-color: var(--fx-color-success, #16a34a);\n box-shadow: var(--fx-effect-success-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent));\n}\n:host([disabled]) { opacity: 0.55; pointer-events: none; }\n:host([readonly]) .toolbar { display: none; }\n\n.toolbar {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 1px;\n padding: var(--fx-space-xs);\n background: var(--fx-editor-toolbar-bg);\n border-bottom: 1px solid var(--fx-border-default);\n user-select: none;\n}\n.toolbar[hidden] { display: none; }\n.tb-group {\n display: flex;\n align-items: center;\n gap: 1px;\n padding: 0 var(--fx-space-xs);\n border-right: 1px solid var(--fx-border-default);\n}\n.tb-group:last-child { border-right: none; }\n.tb-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n padding: 0;\n border: none;\n border-radius: var(--fx-radius-sm);\n background: transparent;\n color: var(--fx-text-default);\n font-size: 19px;\n cursor: pointer;\n transition: background var(--fx-motion-duration-fast) var(--fx-motion-easing);\n}\n.tb-btn:hover { background: var(--fx-surface-surface-hover, rgba(0, 0, 0, 0.06)); }\n.tb-btn:focus-visible { outline: 2px solid var(--fx-color-primary); outline-offset: -2px; }\n.tb-btn.active {\n background: color-mix(in srgb, var(--fx-color-primary) 14%, transparent);\n color: var(--fx-color-primary);\n}\n.tb-btn:disabled { opacity: 0.4; cursor: not-allowed; }\n.tb-select {\n height: 30px;\n padding: 0 var(--fx-space-xs);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-sm);\n background: var(--fx-surface-background);\n color: var(--fx-text-default);\n font-family: inherit;\n font-size: calc(var(--fx-font-size) - 2px);\n cursor: pointer;\n}\n.tb-color {\n width: 30px;\n height: 30px;\n padding: 2px;\n border: none;\n background: transparent;\n cursor: pointer;\n}\n.tb-color input { width: 26px; height: 26px; padding: 0; border: none; background: none; cursor: pointer; }\n.body { position: relative; display: flex; flex-direction: column; flex: 1 1 auto; }\n.content {\n position: relative;\n min-height: var(--fx-editor-min-height);\n max-height: var(--fx-editor-max-height);\n overflow: auto;\n padding: var(--fx-editor-content-padding);\n outline: none;\n box-sizing: border-box;\n}\n.content[hidden] { display: none; }\n.content.is-empty::before {\n content: attr(data-placeholder);\n color: var(--fx-text-muted);\n pointer-events: none;\n position: absolute;\n}\n.content[contenteditable=\"false\"] { background: var(--fx-surface-surface-hover, rgba(0,0,0,.02)); }\n.content figure.fx-image { touch-action: none; }\n\n.media-overlay {\n position: absolute;\n z-index: 5;\n pointer-events: none;\n border: 1px solid var(--fx-color-primary);\n box-shadow: 0 0 0 1px color-mix(in srgb, var(--fx-color-primary) 30%, transparent);\n}\n.media-overlay[hidden] { display: none; }\n.media-handle {\n position: absolute;\n width: 11px;\n height: 11px;\n border: 1px solid #fff;\n border-radius: 50%;\n background: var(--fx-color-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);\n pointer-events: auto;\n touch-action: none;\n}\n.media-handle.nw { left: -6px; top: -6px; cursor: nwse-resize; }\n.media-handle.ne { right: -6px; top: -6px; cursor: nesw-resize; }\n.media-handle.sw { left: -6px; bottom: -6px; cursor: nesw-resize; }\n.media-handle.se { right: -6px; bottom: -6px; cursor: nwse-resize; }\n.media-size {\n position: absolute;\n top: -24px;\n left: 0;\n padding: 2px 6px;\n border-radius: var(--fx-radius-sm);\n background: var(--fx-color-primary);\n color: #fff;\n font-size: 11px;\n line-height: 1.4;\n white-space: nowrap;\n}\n.media-delete {\n position: absolute;\n top: -32px;\n right: -1px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: var(--fx-color-danger, #dc2626);\n color: #fff;\n font-size: 15px;\n line-height: 1;\n cursor: pointer;\n pointer-events: auto;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);\n}\n.media-delete:hover { filter: brightness(0.92); }\n.media-delete:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }\n\n.content figure.fx-image,\n.content figure.fx-video,\n.content figure.fx-embed { position: relative; }\n.fx-media-quick {\n position: absolute;\n top: 6px;\n z-index: 4;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n border: 1px solid color-mix(in srgb, var(--fx-color-primary) 35%, transparent);\n border-radius: var(--fx-radius-sm);\n background: var(--fx-surface-background);\n color: var(--fx-text-default);\n cursor: pointer;\n opacity: 0;\n transition: opacity var(--fx-motion-duration-fast) var(--fx-motion-easing), background var(--fx-motion-duration-fast) var(--fx-motion-easing);\n}\n.content figure:hover > .fx-media-quick,\n.content figure:focus-within > .fx-media-quick { opacity: 1; }\n.content figure.fx-video > .fx-media-quick,\n.content figure.fx-embed > .fx-media-quick { opacity: 0.92; }\n.fx-media-quick:hover { background: var(--fx-surface-surface-hover, rgba(0, 0, 0, 0.06)); }\n.fx-media-quick.active { background: var(--fx-color-primary); color: #fff; }\n.fx-media-quick.quick-left { right: 82px; }\n.fx-media-quick.quick-center { right: 56px; }\n.fx-media-quick.quick-right { right: 30px; }\n.fx-media-quick.quick-delete { right: 4px; background: var(--fx-color-danger, #dc2626); color: #fff; border-color: transparent; }\n.fx-media-quick:focus-visible { outline: 2px solid var(--fx-color-primary); outline-offset: 1px; }\n\n.link-overlay {\n position: absolute;\n z-index: 6;\n display: flex;\n gap: 2px;\n padding: 3px;\n background: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-sm);\n box-shadow: var(--fx-shadow-md, 0 4px 12px rgba(0, 0, 0, 0.16));\n}\n.link-overlay[hidden] { display: none; }\n.link-overlay button {\n border: none;\n background: none;\n color: var(--fx-text-default);\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n padding: 4px 8px;\n border-radius: var(--fx-radius-sm);\n cursor: pointer;\n}\n.link-overlay button:hover { background: var(--fx-surface-surface-hover, rgba(0, 0, 0, 0.06)); }\n.link-overlay button[data-link-action=\"remove\"] { color: var(--fx-color-danger, #dc2626); }\n.link-overlay button:focus-visible { outline: 2px solid var(--fx-color-primary); outline-offset: 1px; }\n\n.source {\n display: block;\n width: 100%;\n min-height: var(--fx-editor-min-height);\n max-height: var(--fx-editor-max-height);\n padding: var(--fx-editor-content-padding);\n border: none;\n outline: none;\n resize: vertical;\n background: var(--fx-surface-background);\n color: var(--fx-text-default);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 13px;\n line-height: 1.55;\n box-sizing: border-box;\n}\n.source[hidden] { display: none; }\n\n.statusbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--fx-space-sm);\n min-height: 28px;\n padding: 2px var(--fx-space-md);\n border-top: 1px solid var(--fx-border-default);\n color: var(--fx-text-muted);\n font-size: calc(var(--fx-font-size) - 3px);\n}\n.statusbar:empty { display: none; }\n.statusbar[hidden] { display: none; }\n.source-actions { display: inline-flex; gap: var(--fx-space-xs); }\n.source-actions[hidden] { display: none; }\n\n.backdrop {\n position: fixed;\n inset: 0;\n z-index: var(--fx-z-modal, 1100);\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--fx-text-default, #000) 45%, transparent);\n}\n.backdrop[hidden] { display: none; }\n.dialog {\n width: min(460px, calc(100vw - 32px));\n max-height: calc(100vh - 48px);\n overflow: auto;\n background: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-lg);\n box-shadow: var(--fx-shadow-xl);\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n}\n.dialog header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--fx-space-md) var(--fx-space-lg);\n border-bottom: 1px solid var(--fx-border-default);\n}\n.dialog h3 { margin: 0; font-size: 1rem; font-weight: 600; }\n.dialog-close {\n border: none; background: transparent; color: var(--fx-text-muted);\n font-size: 1.4rem; line-height: 1; cursor: pointer;\n}\n.dialog-body { display: flex; flex-direction: column; gap: var(--fx-space-sm); padding: var(--fx-space-lg); }\n.field { display: flex; flex-direction: column; gap: 3px; font-size: calc(var(--fx-font-size) - 2px); color: var(--fx-text-muted); }\n.field input, .field select {\n height: var(--fx-size-md);\n padding: 0 var(--fx-space-sm);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-sm);\n background: var(--fx-surface-background);\n color: var(--fx-text-default);\n font: inherit;\n font-size: var(--fx-font-size);\n}\n.field input:focus, .field select:focus { outline: none; border-color: var(--fx-color-primary); box-shadow: var(--fx-effect-focus-ring, none); }\n.dialog footer {\n display: flex; justify-content: flex-end; gap: var(--fx-space-sm);\n padding: var(--fx-space-md) var(--fx-space-lg);\n border-top: 1px solid var(--fx-border-default);\n}\n.btn {\n min-height: var(--fx-size-sm);\n padding: 0 var(--fx-space-md);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-sm);\n background: var(--fx-surface-background);\n color: var(--fx-text-default);\n font: inherit; font-size: calc(var(--fx-font-size) - 2px);\n cursor: pointer;\n}\n.btn:hover { background: var(--fx-surface-surface-hover, rgba(0,0,0,.05)); }\n.btn.primary { background: var(--fx-color-primary); border-color: transparent; color: #fff; }\n.btn.primary:hover { filter: brightness(0.92); }\n\n.panel {\n position: absolute;\n top: calc(100% + 4px);\n left: var(--fx-space-md);\n z-index: 6;\n padding: var(--fx-space-sm);\n background: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n box-shadow: var(--fx-shadow-lg);\n}\n.panel[hidden] { display: none; }\n.grid-picker { display: grid; grid-template-columns: repeat(8, 18px); gap: 3px; }\n.grid-picker button {\n width: 18px; height: 18px; padding: 0;\n border: 1px solid var(--fx-border-default);\n border-radius: 2px; background: var(--fx-surface-background); cursor: pointer;\n}\n.grid-picker button.on { background: var(--fx-color-primary); border-color: var(--fx-color-primary); }\n.panel-title { margin: 0 0 6px; font-size: 11px; color: var(--fx-text-muted); }\n.panel-actions { display: flex; flex-wrap: wrap; gap: 4px; max-width: 210px; }\n.panel-actions .btn { min-height: 26px; padding: 0 6px; font-size: 11px; }\n\n:host([fullscreen]) {\n position: fixed;\n inset: 0;\n z-index: var(--fx-z-modal, 1100);\n background: var(--fx-surface-background);\n}\n:host([fullscreen]) .editor { height: 100%; border: none; border-radius: 0; }\n:host([fullscreen]) .content, :host([fullscreen]) .source { flex: 1 1 auto; max-height: none; }\n\n@media (max-width: 640px) {\n .toolbar { gap: 0; }\n .tb-group { padding: 0 1px; }\n .tb-btn { width: 28px; height: 28px; }\n}\n${FX_EDITOR_CONTENT_CSS}\n\n\n`;\n"],"names":[],"mappings":"AAQO,MAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+D9B,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuX3B,qBAAqB;AAAA;AAAA;AAAA;"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Utilitários de tabela do <fx-editor>.
3
+ *
4
+ * O editor usa `td/th` com colspan/rowspan; para mesclar/dividir células
5
+ * precisamos de uma matriz lógica que considere os spans. Este módulo é puro
6
+ * (recebe a tabela e o Range) para poder ser testado sem o componente.
7
+ */
8
+ export interface TableCellPosition {
9
+ row: number;
10
+ col: number;
11
+ }
12
+ export interface TableMatrix {
13
+ rows: HTMLTableRowElement[];
14
+ matrix: Array<Array<HTMLTableCellElement | null>>;
15
+ }
16
+ /** Constrói a matriz lógica da tabela respeitando colspan/rowspan. */
17
+ export declare function tableMatrix(table: HTMLTableElement): TableMatrix;
18
+ /** Posição lógica (primeira célula da matriz) de uma célula. */
19
+ export declare function cellPosition(table: HTMLTableElement, cell: HTMLTableCellElement): TableCellPosition | null;
20
+ /** Células tocadas pela seleção atual. */
21
+ export declare function selectedCells(table: HTMLTableElement, range: Range): HTMLTableCellElement[];
22
+ /**
23
+ * Mescla as células selecionadas em uma única célula retangular.
24
+ * Retorna a célula mesclada ou null quando a seleção não forma um retângulo
25
+ * simples (spans que saem da área, seleção em uma única célula etc.).
26
+ */
27
+ export declare function mergeSelectedCells(table: HTMLTableElement, range: Range): HTMLTableCellElement | null;
28
+ /**
29
+ * Divide uma célula mesclada.
30
+ * Retorna as células criadas (sem a original) ou [] se não havia merge.
31
+ */
32
+ export declare function splitCell(table: HTMLTableElement, cell: HTMLTableCellElement): HTMLTableCellElement[];
33
+ //# sourceMappingURL=table-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-utils.d.ts","sourceRoot":"","sources":["../../../src/components/editor/table-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,mBAAmB,EAAE,CAAC;IAC5B,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC,CAAC;CACnD;AAED,sEAAsE;AACtE,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CA0BhE;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,oBAAoB,GAAG,iBAAiB,GAAG,IAAI,CAQ1G;AAED,0CAA0C;AAC1C,wBAAgB,aAAa,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,GAAG,oBAAoB,EAAE,CAQ3F;AASD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,KAAK,GACX,oBAAoB,GAAG,IAAI,CAsD7B;AA8BD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,oBAAoB,GAAG,oBAAoB,EAAE,CA6CrG"}
@@ -0,0 +1,150 @@
1
+ function tableMatrix(table) {
2
+ const rows = Array.from(table.rows);
3
+ const matrix = rows.map(() => []);
4
+ for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
5
+ const row = rows[rowIndex];
6
+ for (const cell of Array.from(row.cells)) {
7
+ let col = 0;
8
+ while (matrix[rowIndex][col]) col++;
9
+ const rowspan = Math.max(1, Math.min(cell.rowSpan || 1, rows.length - rowIndex));
10
+ const colspan = Math.max(1, cell.colSpan || 1);
11
+ for (let r = rowIndex; r < rowIndex + rowspan; r++) {
12
+ if (!matrix[r]) matrix[r] = [];
13
+ for (let c = col; c < col + colspan; c++) matrix[r][c] = cell;
14
+ }
15
+ }
16
+ }
17
+ const width = matrix.reduce((max, row) => Math.max(max, row.length), 0);
18
+ for (const row of matrix) {
19
+ while (row.length < width) row.push(null);
20
+ }
21
+ return { rows, matrix };
22
+ }
23
+ function cellPosition(table, cell) {
24
+ const { matrix } = tableMatrix(table);
25
+ for (let row = 0; row < matrix.length; row++) {
26
+ for (let col = 0; col < matrix[row].length; col++) {
27
+ if (matrix[row][col] === cell) return { row, col };
28
+ }
29
+ }
30
+ return null;
31
+ }
32
+ function selectedCells(table, range) {
33
+ return Array.from(table.querySelectorAll("td,th")).filter((cell) => {
34
+ try {
35
+ return range.intersectsNode(cell);
36
+ } catch {
37
+ return false;
38
+ }
39
+ });
40
+ }
41
+ function copyCellAttributes(from, to) {
42
+ for (const attr of Array.from(from.attributes)) {
43
+ if (attr.name === "colspan" || attr.name === "rowspan") continue;
44
+ to.setAttribute(attr.name, attr.value);
45
+ }
46
+ }
47
+ function mergeSelectedCells(table, range) {
48
+ const cells = selectedCells(table, range);
49
+ if (cells.length < 2) return null;
50
+ const { matrix } = tableMatrix(table);
51
+ const positions = cells.map((cell) => ({ cell, position: cellPosition(table, cell) })).filter((item) => Boolean(item.position));
52
+ if (positions.length !== cells.length) return null;
53
+ const minRow = Math.min(...positions.map((item) => item.position.row));
54
+ const maxRow = Math.max(...positions.map((item) => item.position.row));
55
+ const minCol = Math.min(...positions.map((item) => item.position.col));
56
+ const maxCol = Math.max(...positions.map((item) => item.position.col));
57
+ for (const { cell, position } of positions) {
58
+ if (position.row < minRow || position.col < minCol) return null;
59
+ if (position.row + Math.max(1, cell.rowSpan || 1) - 1 > maxRow) return null;
60
+ if (position.col + Math.max(1, cell.colSpan || 1) - 1 > maxCol) return null;
61
+ }
62
+ const selected = new Set(cells);
63
+ for (let row = minRow; row <= maxRow; row++) {
64
+ for (let col = minCol; col <= maxCol; col++) {
65
+ const cell = matrix[row]?.[col];
66
+ if (!cell || !selected.has(cell)) return null;
67
+ }
68
+ }
69
+ const anchor = matrix[minRow]?.[minCol];
70
+ if (!anchor) return null;
71
+ const tag = cells.every((cell) => cell.tagName.toLowerCase() === "th") ? "th" : "td";
72
+ const merged = document.createElement(tag);
73
+ copyCellAttributes(anchor, merged);
74
+ if (tag === "td") merged.removeAttribute("scope");
75
+ merged.colSpan = maxCol - minCol + 1;
76
+ merged.rowSpan = maxRow - minRow + 1;
77
+ if (merged.colSpan === 1) merged.removeAttribute("colspan");
78
+ if (merged.rowSpan === 1) merged.removeAttribute("rowspan");
79
+ for (const cell of cells) {
80
+ while (cell.firstChild) merged.appendChild(cell.firstChild);
81
+ }
82
+ anchor.replaceWith(merged);
83
+ for (const cell of cells) {
84
+ if (cell !== anchor && cell.parentNode) cell.remove();
85
+ }
86
+ return merged;
87
+ }
88
+ function insertCellAtColumn(table, row, col, cell) {
89
+ const rowIndex = Array.from(table.rows).indexOf(row);
90
+ const { matrix } = tableMatrix(table);
91
+ let before = null;
92
+ for (const existing of Array.from(row.cells)) {
93
+ let start = -1;
94
+ for (let c = 0; c < (matrix[rowIndex]?.length ?? 0); c++) {
95
+ if (matrix[rowIndex][c] === existing) {
96
+ start = c;
97
+ break;
98
+ }
99
+ }
100
+ if (start >= col) {
101
+ before = existing;
102
+ break;
103
+ }
104
+ }
105
+ row.insertBefore(cell, before);
106
+ }
107
+ function splitCell(table, cell) {
108
+ const colspan = Math.max(1, cell.colSpan || 1);
109
+ const rowspan = Math.max(1, cell.rowSpan || 1);
110
+ if (colspan === 1 && rowspan === 1) return [];
111
+ const position = cellPosition(table, cell);
112
+ if (!position) return [];
113
+ const rows = Array.from(table.rows);
114
+ const makeCell = () => {
115
+ const next = document.createElement(cell.tagName.toLowerCase());
116
+ if (next.tagName.toLowerCase() === "th") {
117
+ next.setAttribute("scope", cell.getAttribute("scope") ?? "col");
118
+ }
119
+ next.innerHTML = "<p><br></p>";
120
+ return next;
121
+ };
122
+ const created = [];
123
+ let last = cell;
124
+ for (let index = 1; index < colspan; index++) {
125
+ const next = makeCell();
126
+ last.after(next);
127
+ last = next;
128
+ created.push(next);
129
+ }
130
+ cell.removeAttribute("colspan");
131
+ cell.removeAttribute("rowspan");
132
+ for (let index = 1; index < rowspan; index++) {
133
+ const row = rows[position.row + index];
134
+ if (!row) break;
135
+ for (let offset = 0; offset < colspan; offset++) {
136
+ const next = makeCell();
137
+ insertCellAtColumn(table, row, position.col + offset, next);
138
+ created.push(next);
139
+ }
140
+ }
141
+ return created;
142
+ }
143
+ export {
144
+ cellPosition,
145
+ mergeSelectedCells,
146
+ selectedCells,
147
+ splitCell,
148
+ tableMatrix
149
+ };
150
+ //# sourceMappingURL=table-utils.js.map