@wrrdev/fenix-ui 1.1.13 → 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 (161) hide show
  1. package/README.md +6 -5
  2. package/dist/components/autocomplete/autocomplete.d.ts +11 -5
  3. package/dist/components/autocomplete/autocomplete.d.ts.map +1 -1
  4. package/dist/components/autocomplete/autocomplete.js +18 -2
  5. package/dist/components/autocomplete/autocomplete.js.map +1 -1
  6. package/dist/components/button/button.d.ts +15 -0
  7. package/dist/components/button/button.d.ts.map +1 -1
  8. package/dist/components/button/button.js +20 -1
  9. package/dist/components/button/button.js.map +1 -1
  10. package/dist/components/checkbox/checkbox.d.ts +20 -4
  11. package/dist/components/checkbox/checkbox.d.ts.map +1 -1
  12. package/dist/components/checkbox/checkbox.js +39 -2
  13. package/dist/components/checkbox/checkbox.js.map +1 -1
  14. package/dist/components/datepicker/datepicker.d.ts +16 -2
  15. package/dist/components/datepicker/datepicker.d.ts.map +1 -1
  16. package/dist/components/datepicker/datepicker.js +46 -2
  17. package/dist/components/datepicker/datepicker.js.map +1 -1
  18. package/dist/components/editor/commands.d.ts +27 -0
  19. package/dist/components/editor/commands.d.ts.map +1 -0
  20. package/dist/components/editor/commands.js +235 -0
  21. package/dist/components/editor/commands.js.map +1 -0
  22. package/dist/components/editor/editor.d.ts +83 -0
  23. package/dist/components/editor/editor.d.ts.map +1 -0
  24. package/dist/components/editor/editor.js +1951 -0
  25. package/dist/components/editor/editor.js.map +1 -0
  26. package/dist/components/editor/index.d.ts +12 -0
  27. package/dist/components/editor/index.d.ts.map +1 -0
  28. package/dist/components/editor/index.js +7 -0
  29. package/dist/components/editor/index.js.map +1 -0
  30. package/dist/components/editor/normalize-html.d.ts +33 -0
  31. package/dist/components/editor/normalize-html.d.ts.map +1 -0
  32. package/dist/components/editor/normalize-html.js +316 -0
  33. package/dist/components/editor/normalize-html.js.map +1 -0
  34. package/dist/components/editor/sanitize-html.d.ts +37 -0
  35. package/dist/components/editor/sanitize-html.d.ts.map +1 -0
  36. package/dist/components/editor/sanitize-html.js +247 -0
  37. package/dist/components/editor/sanitize-html.js.map +1 -0
  38. package/dist/components/editor/schema.d.ts +36 -0
  39. package/dist/components/editor/schema.d.ts.map +1 -0
  40. package/dist/components/editor/schema.js +232 -0
  41. package/dist/components/editor/schema.js.map +1 -0
  42. package/dist/components/editor/selection.d.ts +22 -0
  43. package/dist/components/editor/selection.d.ts.map +1 -0
  44. package/dist/components/editor/selection.js +97 -0
  45. package/dist/components/editor/selection.js.map +1 -0
  46. package/dist/components/editor/styles.d.ts +10 -0
  47. package/dist/components/editor/styles.d.ts.map +1 -0
  48. package/dist/components/editor/styles.js +446 -0
  49. package/dist/components/editor/styles.js.map +1 -0
  50. package/dist/components/editor/table-utils.d.ts +33 -0
  51. package/dist/components/editor/table-utils.d.ts.map +1 -0
  52. package/dist/components/editor/table-utils.js +150 -0
  53. package/dist/components/editor/table-utils.js.map +1 -0
  54. package/dist/components/fileupload/fileupload.d.ts +10 -2
  55. package/dist/components/fileupload/fileupload.d.ts.map +1 -1
  56. package/dist/components/fileupload/fileupload.js +17 -2
  57. package/dist/components/fileupload/fileupload.js.map +1 -1
  58. package/dist/components/floatlabel/floatlabel.d.ts +9 -3
  59. package/dist/components/floatlabel/floatlabel.d.ts.map +1 -1
  60. package/dist/components/floatlabel/floatlabel.js +22 -7
  61. package/dist/components/floatlabel/floatlabel.js.map +1 -1
  62. package/dist/components/input/input.d.ts +18 -7
  63. package/dist/components/input/input.d.ts.map +1 -1
  64. package/dist/components/input/input.js +33 -3
  65. package/dist/components/input/input.js.map +1 -1
  66. package/dist/components/knob/knob.d.ts +7 -3
  67. package/dist/components/knob/knob.d.ts.map +1 -1
  68. package/dist/components/knob/knob.js +4 -2
  69. package/dist/components/knob/knob.js.map +1 -1
  70. package/dist/components/multiselect/multiselect.d.ts +13 -3
  71. package/dist/components/multiselect/multiselect.d.ts.map +1 -1
  72. package/dist/components/multiselect/multiselect.js +27 -2
  73. package/dist/components/multiselect/multiselect.js.map +1 -1
  74. package/dist/components/radio/radio.d.ts +27 -4
  75. package/dist/components/radio/radio.d.ts.map +1 -1
  76. package/dist/components/radio/radio.js +67 -8
  77. package/dist/components/radio/radio.js.map +1 -1
  78. package/dist/components/rating/rating.d.ts +8 -4
  79. package/dist/components/rating/rating.d.ts.map +1 -1
  80. package/dist/components/rating/rating.js +5 -2
  81. package/dist/components/rating/rating.js.map +1 -1
  82. package/dist/components/select/select.d.ts +9 -3
  83. package/dist/components/select/select.d.ts.map +1 -1
  84. package/dist/components/select/select.js +11 -2
  85. package/dist/components/select/select.js.map +1 -1
  86. package/dist/components/slider/slider.d.ts +12 -6
  87. package/dist/components/slider/slider.d.ts.map +1 -1
  88. package/dist/components/slider/slider.js +10 -2
  89. package/dist/components/slider/slider.js.map +1 -1
  90. package/dist/components/switch/switch.d.ts +20 -4
  91. package/dist/components/switch/switch.d.ts.map +1 -1
  92. package/dist/components/switch/switch.js +40 -2
  93. package/dist/components/switch/switch.js.map +1 -1
  94. package/dist/components/textarea/textarea.d.ts +12 -5
  95. package/dist/components/textarea/textarea.d.ts.map +1 -1
  96. package/dist/components/textarea/textarea.js +12 -2
  97. package/dist/components/textarea/textarea.js.map +1 -1
  98. package/dist/components/toast/toast.d.ts +27 -15
  99. package/dist/components/toast/toast.d.ts.map +1 -1
  100. package/dist/components/toast/toast.js +205 -32
  101. package/dist/components/toast/toast.js.map +1 -1
  102. package/dist/components/toggle-button-group/toggle-button-group.d.ts +13 -5
  103. package/dist/components/toggle-button-group/toggle-button-group.d.ts.map +1 -1
  104. package/dist/components/toggle-button-group/toggle-button-group.js +19 -2
  105. package/dist/components/toggle-button-group/toggle-button-group.js.map +1 -1
  106. package/dist/core/base.d.ts +7 -0
  107. package/dist/core/base.d.ts.map +1 -1
  108. package/dist/core/base.js +4 -1
  109. package/dist/core/base.js.map +1 -1
  110. package/dist/core/form-element.d.ts +81 -0
  111. package/dist/core/form-element.d.ts.map +1 -0
  112. package/dist/core/form-element.js +129 -0
  113. package/dist/core/form-element.js.map +1 -0
  114. package/dist/core/jsx.d.ts +25 -1
  115. package/dist/core/jsx.d.ts.map +1 -1
  116. package/dist/core/jsx.js.map +1 -1
  117. package/dist/core/presets.d.ts +8 -3
  118. package/dist/core/presets.d.ts.map +1 -1
  119. package/dist/core/presets.js +6 -17
  120. package/dist/core/presets.js.map +1 -1
  121. package/dist/core/types.d.ts +4 -0
  122. package/dist/core/types.d.ts.map +1 -1
  123. package/dist/core/vue.d.ts +3 -1
  124. package/dist/core/vue.d.ts.map +1 -1
  125. package/dist/core/vue.js.map +1 -1
  126. package/dist/docs/app.d.ts.map +1 -1
  127. package/dist/docs/componentes/autocomplete.doc.d.ts.map +1 -1
  128. package/dist/docs/componentes/checkbox.doc.d.ts.map +1 -1
  129. package/dist/docs/componentes/datepicker.doc.d.ts.map +1 -1
  130. package/dist/docs/componentes/editor.doc.d.ts +6 -0
  131. package/dist/docs/componentes/editor.doc.d.ts.map +1 -0
  132. package/dist/docs/componentes/fileupload.doc.d.ts.map +1 -1
  133. package/dist/docs/componentes/index.d.ts.map +1 -1
  134. package/dist/docs/componentes/input.doc.d.ts.map +1 -1
  135. package/dist/docs/componentes/knob.doc.d.ts.map +1 -1
  136. package/dist/docs/componentes/multiselect.doc.d.ts.map +1 -1
  137. package/dist/docs/componentes/rating.doc.d.ts.map +1 -1
  138. package/dist/docs/componentes/select.doc.d.ts.map +1 -1
  139. package/dist/docs/componentes/slider.doc.d.ts.map +1 -1
  140. package/dist/docs/componentes/switch.doc.d.ts.map +1 -1
  141. package/dist/docs/componentes/textarea.doc.d.ts.map +1 -1
  142. package/dist/docs/componentes/toast.doc.d.ts.map +1 -1
  143. package/dist/docs/componentes/toggle-button-group.doc.d.ts.map +1 -1
  144. package/dist/docs/frameworks.d.ts +75 -0
  145. package/dist/docs/frameworks.d.ts.map +1 -0
  146. package/dist/docs/ui/code.d.ts +4 -0
  147. package/dist/docs/ui/code.d.ts.map +1 -1
  148. package/dist/fenix-ui.umd.min.js +786 -254
  149. package/dist/fenix-ui2.esm.js.map +1 -1
  150. package/dist/fenix-ui4.esm.js +4396 -172
  151. package/dist/fenix-ui4.esm.js.map +1 -1
  152. package/dist/fenix-ui5.esm.js +1 -0
  153. package/dist/fenix-ui5.esm.js.map +1 -1
  154. package/dist/index.d.ts +2 -0
  155. package/dist/index.d.ts.map +1 -1
  156. package/dist/index.js +18 -1
  157. package/dist/index.js.map +1 -1
  158. package/dist/plugins/auto-import.d.ts.map +1 -1
  159. package/dist/plugins/auto-import.js +1 -0
  160. package/dist/plugins/auto-import.js.map +1 -1
  161. 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