@themarioga/grid-editor 5.3.1 → 6.0.0-beta.2

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 (51) hide show
  1. package/BUILDING.md +2 -4
  2. package/CHANGELOG.md +59 -0
  3. package/README.md +34 -8
  4. package/UPGRADING.md +57 -12
  5. package/dist/grideditor.css +179 -100
  6. package/dist/grideditor.min.css +1 -1
  7. package/dist/grideditor.min.css.map +1 -1
  8. package/dist/jquery.grideditor.bundle.min.js +2 -2
  9. package/dist/jquery.grideditor.js +490 -432
  10. package/dist/jquery.grideditor.min.js +1 -1
  11. package/dist/jquery.grideditor.min.js.map +1 -1
  12. package/dist/locales/grideditor.es.js +12 -0
  13. package/dist/locales/grideditor.es.min.js +1 -1
  14. package/dist/locales/grideditor.es.min.js.map +1 -1
  15. package/dist/plugins/grideditor.ckeditor.js +2 -1
  16. package/dist/plugins/grideditor.ckeditor.min.js.map +1 -1
  17. package/dist/plugins/grideditor.clipboard.js +1 -11
  18. package/dist/plugins/grideditor.clipboard.min.js +1 -1
  19. package/dist/plugins/grideditor.clipboard.min.js.map +1 -1
  20. package/dist/plugins/grideditor.elements.js +66 -38
  21. package/dist/plugins/grideditor.elements.min.js +1 -1
  22. package/dist/plugins/grideditor.elements.min.js.map +1 -1
  23. package/dist/plugins/grideditor.sections.js +2 -2
  24. package/dist/plugins/grideditor.sections.min.js +1 -1
  25. package/dist/plugins/grideditor.sections.min.js.map +1 -1
  26. package/dist/plugins/grideditor.spacing.js +1 -1
  27. package/dist/plugins/grideditor.spacing.min.js +1 -1
  28. package/dist/plugins/grideditor.spacing.min.js.map +1 -1
  29. package/dist/plugins/grideditor.summernote.js +2 -1
  30. package/dist/plugins/grideditor.summernote.min.js.map +1 -1
  31. package/dist/plugins/grideditor.tinymce.js +2 -1
  32. package/dist/plugins/grideditor.tinymce.min.js.map +1 -1
  33. package/docs/events.md +4 -3
  34. package/docs/locale-keys.md +23 -0
  35. package/docs/plugins.md +18 -20
  36. package/example/attributes.html +21 -37
  37. package/example/elements.html +25 -20
  38. package/example/plugins.html +5 -5
  39. package/example/utilities.html +31 -8
  40. package/package.json +1 -1
  41. package/src/js/jquery.grideditor.js +489 -34
  42. package/src/js/locales/grideditor.es.js +12 -0
  43. package/src/js/plugins/grideditor.ckeditor.js +2 -1
  44. package/src/js/plugins/grideditor.clipboard.js +1 -11
  45. package/src/js/plugins/grideditor.elements.js +66 -38
  46. package/src/js/plugins/grideditor.sections.js +2 -2
  47. package/src/js/plugins/grideditor.spacing.js +1 -1
  48. package/src/js/plugins/grideditor.summernote.js +2 -1
  49. package/src/js/plugins/grideditor.tinymce.js +2 -1
  50. package/src/less/grideditor.less +203 -112
  51. package/src/js/compat/bundled-texts.js +0 -14
package/BUILDING.md CHANGED
@@ -22,10 +22,8 @@ the languages and the container plugins it actually wants. See
22
22
  [docs/plugins.md](docs/plugins.md) for what a container plugin is.
23
23
 
24
24
  The text editor plugins - tinyMCE, CKEditor and summernote - are built to
25
- `dist/plugins/` like the others, and up to 6.0 also go into the main bundle,
26
- followed by `src/js/compat/bundled-texts.js`, which marks them as the bundle's
27
- copies so the editor can warn a page that relies on them. 6.0 drops both from
28
- `jsFiles` in the Gruntfile.
25
+ `dist/plugins/` like the others, and like them are not part of the main
26
+ bundle. Up to 5.x the bundle carried a copy of each.
29
27
 
30
28
  One more file comes out of it: `dist/jquery.grideditor.bundle.min.js`, the
31
29
  minified editor concatenated with the copy of SortableJS in `node_modules`,
package/CHANGELOG.md CHANGED
@@ -5,6 +5,65 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
 
8
+ ## [6.0.0-beta.2] - 2026-09-23
9
+ ### Added
10
+ - `settings_panel`: where a gear's settings open - a Bootstrap offcanvas at
11
+ the side, the default; a popover under the gear; a modal; or `'inline'` in
12
+ the drawer, as before. Each is titled after its node, the node is outlined
13
+ while they are open, and Escape closes them. The editor opens and places
14
+ them with Bootstrap's markup and css, and needs neither Popper nor
15
+ Bootstrap's javascript for it. [example/utilities.html](example/utilities.html)
16
+ switches between them.
17
+ - `ge.detailsOf(node)` in the plugin handle: a node's settings panel,
18
+ wherever it is open.
19
+
20
+ ### Changed
21
+ - The settings' fields are Bootstrap 5's own - labelled `form-control-sm`
22
+ inputs and `form-select-sm` selects - and the preset class buttons
23
+ `btn-outline-secondary`, where they carried Bootstrap 3's `btn-default`,
24
+ which Bootstrap 5 has not got.
25
+
26
+ ### Fixed
27
+ - While dragging, the copy that follows the pointer came out unstyled - its
28
+ drawers laid out as plain links, their settings panels open - because it was
29
+ appended to the page's body, outside the canvas the editor's styles apply
30
+ to. It is appended to the list the drag started in, and looks like what it
31
+ copies.
32
+ - With `drag_handle: 'drawer'` a text could not be dragged: its drawer is
33
+ small and made of tools, and a drag never starts on a tool. It has a grip at
34
+ its start now, and an info tool - the text's and an element's - which does
35
+ nothing when clicked, starts a drag too.
36
+
37
+ ## [6.0.0-beta.1] - 2026-09-23
38
+ ### Changed
39
+ - **Elements are blocks of the column.** An element sits in a column beside
40
+ its texts, rows and containers, never inside a content area's text, and
41
+ drags within a column and between columns; the canvas and sections turn one
42
+ away. Markup 5.x saved, with elements in the text, is converted as the editor
43
+ starts: a content area is cut at each element among its own children, the
44
+ text after going into a new content area of the same type. Rows and
45
+ containers inside a content area come out the same way. `getPlainHtml`
46
+ publishes what 5.x published, except that a content area's own id and classes
47
+ stay on its first part. See [UPGRADING.md](UPGRADING.md).
48
+ - **The text editors are not in the main bundle**, nor in the bundle with
49
+ SortableJS: load `dist/plugins/grideditor.<editor>.min.js`.
50
+ - `elements.auto: true` makes every loose node of a column an element.
51
+ - `createElement` into a content area puts the element beside it, and warns.
52
+ - A text dragged between columns is `kind: 'text'`, as when it is added or
53
+ deleted; it was `kind: 'content'`.
54
+ - Elements carry no `contenteditable` and their drawers no `data-mce-bogus`.
55
+ - While a text is being edited its drawer stays faint, so as not to hide the
56
+ end of the line being typed, until the pointer is on the drawer itself; with
57
+ its settings open it stays whole.
58
+
59
+ ### Added
60
+ - A feature plugin's `cuts`: the nodes that are never part of a text, which
61
+ cut the content area they sit in.
62
+
63
+ ### Removed
64
+ - The copies of the text editors in the main bundle, and the warning about
65
+ using them.
66
+
8
67
  ## [5.3.1] - 2026-09-23
9
68
  ### Changed
10
69
  - A text's drawer sits over the text's top right corner instead of in a bar
package/README.md CHANGED
@@ -47,7 +47,7 @@ Installation
47
47
  * If you want to use the tinyMCE integration, include tinyMCE 6 as well, and `dist/plugins/grideditor.tinymce.min.js` after the editor. The tinyMCE jQuery plugin is no longer needed, and no longer exists as of tinyMCE 6.
48
48
  * If you want to use the summernote integration, include summernote and `dist/plugins/grideditor.summernote.min.js`.
49
49
  * If you want to use the CKEditor integration... you get the point: CKEditor and `dist/plugins/grideditor.ckeditor.min.js`.
50
- * Up to 5.x the main bundle still carries a copy of the three, so a page that does not load the plugin keeps working, and the console says, once, to load it. 6.0 leaves the copies out.
50
+ * Up to 5.x the main bundle carried a copy of the three; since 6.0 the plugin of the editor you use has to be loaded, as above. See [UPGRADING.md](UPGRADING.md).
51
51
  * From npm:
52
52
 
53
53
  ```
@@ -362,6 +362,21 @@ $('#myGrid').gridEditor({
362
362
  });
363
363
  ```
364
364
 
365
+ __`settings_panel`:__ Where the settings a gear opens are shown - a node's id, its classes, the presets and the *Responsive* fields. Default `'offcanvas'`.
366
+
367
+ | Value | Where |
368
+ | --- | --- |
369
+ | `'offcanvas'` | A Bootstrap offcanvas at the side of the window, from the bottom on a phone. It does not move the canvas, and has room for every field |
370
+ | `'popover'` | A Bootstrap popover under the gear, or over it when there is more room there; a press anywhere else puts it away |
371
+ | `'modal'` | A Bootstrap modal |
372
+ | `'inline'` | Unfolded in the drawer itself, as up to 5.x |
373
+
374
+ Each is titled after its node ("Column settings"), the node is outlined while its settings are open, and Escape closes them. The editor opens and places them itself, with Bootstrap's markup and css: a page needs neither Popper nor Bootstrap's javascript, and the modal is Bootstrap's own when Bootstrap is there. [example/utilities.html](example/utilities.html) switches between the four.
375
+
376
+ ```javascript
377
+ $('#myGrid').gridEditor({ settings_panel: 'popover' });
378
+ ```
379
+
365
380
  __`confirm_delete`:__ Whether to ask before deleting a row, column, element or container. Default `true`. The question is asked in a Bootstrap modal the editor builds outside your canvas, in the interface language; a page that loaded Bootstrap's css but not its javascript gets the browser's own confirm instead. Set it to `false` if you cancel `before-delete` and ask in your own way.
366
381
 
367
382
  __`drag`:__ How a drag behaves, wherever the editor drags something. Named for the gesture rather than for the library underneath, so it survives a change of library. Every gesture works from a touchscreen, which is what `touch_delay` is for: a touch drag that started instantly would take the page's scrolling with it, so a finger has to rest for a moment before it moves anything. Setting `delay` makes both gestures wait that long.
@@ -413,7 +428,9 @@ The markup does not change: the drawer sits beside the content area in a
413
428
  wrapper that only exists while editing, because inside it the text editor would
414
429
  take it for text. It sits over the text's top right corner and takes no room,
415
430
  showing while the pointer is over the text, while the text is being edited or
416
- holds the focus, and while its settings are open.
431
+ holds the focus, and while its settings are open. While the text is being
432
+ edited it stays faint, not to hide the end of the line being typed, until the
433
+ pointer is on the drawer itself.
417
434
 
418
435
  A column's drawer has an *Add text* tool, and the toolbar a *Text* button, one
419
436
  per editor when `content_types` offers several (*Text (tinyMCE)*, *Text
@@ -433,9 +450,9 @@ __`text_classes`:__ Preset class toggles on a text's settings panel, as `row_cla
433
450
 
434
451
  ### Elements
435
452
 
436
- An element is a node inside a content area that the editor treats as one
437
- movable, deletable thing instead of as rich text. It is a plugin, like the
438
- containers:
453
+ An element is a node the editor treats as one movable, deletable block instead
454
+ of as rich text: a block of the column, beside its texts, rows and containers,
455
+ never part of a text. It is a plugin, like the containers:
439
456
 
440
457
  ```html
441
458
  <script src="grid-editor/dist/plugins/grideditor.elements.min.js"></script>
@@ -444,11 +461,20 @@ containers:
444
461
  You mark the elements themselves:
445
462
 
446
463
  ```html
447
- <div class="ge-content">
464
+ <div class="col-md-6">
465
+ <div class="ge-content"><p>Some text</p></div>
448
466
  <blockquote data-ge-element="quote" data-ge-label="Pull quote">…your markup…</blockquote>
449
467
  </div>
450
468
  ```
451
469
 
470
+ Up to 5.x an element lived inside a content area, among its text. Markup saved
471
+ that way still loads: each element comes out of the text it sits in, into the
472
+ column, and the text is cut there - before it, and after it in a new content
473
+ area of the same type. Only a content area's own children count, as in 5.x;
474
+ a marked node inside a paragraph is text. What `getPlainHtml` publishes is the
475
+ same as before. `createElement` with `appendTo` a content area puts the element
476
+ beside it instead, with a warning.
477
+
452
478
  __`elements`:__ Defaults:
453
479
 
454
480
  ```javascript
@@ -456,7 +482,7 @@ $('#myGrid').gridEditor({
456
482
  elements: {
457
483
  enabled: 'auto', // on when the page has any; true or false to decide yourself
458
484
  selector: '[data-ge-element]', // what counts as an element
459
- auto: false, // true treats every child of a content area as one
485
+ auto: false, // true treats every loose node of a column as one
460
486
  },
461
487
  });
462
488
  ```
@@ -562,7 +588,7 @@ nowhere else:
562
588
  | a section | the canvas, from the toolbar's paste button |
563
589
  | a container (tabs, accordion, popup, card) | a column |
564
590
  | a text | a column |
565
- | an element | a column's content area |
591
+ | an element | a column |
566
592
 
567
593
  The toolbar's paste button is the clipboard icon on the right, beside the
568
594
  source and preview buttons, and shows only while a row or a section is copied.
package/UPGRADING.md CHANGED
@@ -1,25 +1,70 @@
1
- Getting ready for grid-editor `6.*`, from `5.2`
2
- ===============================================
1
+ Upgrading from grid-editor `5.*` to `6.*`
2
+ =========================================
3
3
 
4
- Nothing here breaks in 5.x. It is what 6.0 will need, and 5.2 already
5
- accepts, so a page can make the change at its own pace.
4
+ Two changes make it a major: **elements are blocks of the column**, no longer
5
+ part of a text, and **the text editors are not in the main bundle**. Markup
6
+ 5.x saved loads as it is, and `getPlainHtml` publishes the same from it.
6
7
 
7
- * __Load your text editor as a plugin.__ tinyMCE, CKEditor and summernote
8
- are plugins in `dist/plugins/`, loaded after the editor:
8
+ * __Load your text editor as a plugin.__ tinyMCE, CKEditor and summernote are
9
+ plugins in `dist/plugins/`, loaded after the editor:
9
10
 
10
11
  ```html
11
12
  <script src="grid-editor/dist/jquery.grideditor.min.js"></script>
12
13
  <script src="grid-editor/dist/plugins/grideditor.tinymce.min.js"></script>
13
14
  ```
14
15
 
15
- Up to 5.x the main bundle, and the bundle with SortableJS, still carry a
16
- copy of each, so a page that does not load the plugin keeps working. When a
17
- content area is edited with one of those copies the console says so, once.
18
- 6.0 leaves the copies out.
16
+ Up to 5.x the main bundle, and the bundle with SortableJS, carried a copy of
17
+ each, and since 5.2 editing with one said so in the console. Without the
18
+ plugin a text is still a block, to move and delete, and its drawer says it
19
+ cannot be edited.
20
+
21
+ * __Elements are blocks of the column.__ Up to 5.x an element lived inside a
22
+ content area, among the text a rich text editor edited. Now it sits in the
23
+ column beside the texts, and markup saved the 5.x way is converted as the
24
+ editor starts: each content area is cut at each element among its own
25
+ children - the text before it stays, the element goes into the column, the
26
+ text after goes into a new content area of the same type - and the next
27
+ `getHtml` saves the 6.0 shape.
28
+
29
+ ```html
30
+ <!-- 5.x -->
31
+ <div class="ge-content"><p>Before</p><blockquote data-ge-element="quote">…</blockquote><p>After</p></div>
32
+
33
+ <!-- 6.0 -->
34
+ <div class="ge-content"><p>Before</p></div>
35
+ <blockquote data-ge-element="quote">…</blockquote>
36
+ <div class="ge-content"><p>After</p></div>
37
+ ```
38
+
39
+ What `getPlainHtml` publishes is the same, `div.ge-content` being taken off,
40
+ with one exception: a content area with an id or classes of the host's
41
+ keeps them on its first part only. What to do: nothing, unless you style a
42
+ `div.ge-content` of your own as a whole, or read the saved markup expecting
43
+ elements inside a content area. A marked node inside a paragraph or a list
44
+ was text in 5.x and is text still.
45
+
46
+ Rows and containers found inside a content area come out of it the same way.
47
+
48
+ * __`createElement` into a content area__ - `appendTo` or `prependTo` one - puts
49
+ the element beside it instead, after or before, and warns once. Place it in a
50
+ column.
51
+
52
+ * __`elements.auto: true`__ means every loose node of a column is an element,
53
+ where it meant every child of a content area. A 5.x content area's children
54
+ still come out as elements, so a page that relied on it looks the same.
55
+
56
+ * __A text dragged between columns is `kind: 'text'`__ in `before-move` and
57
+ `after-move`, as it is in its add and delete events since 5.3. It was
58
+ `kind: 'content'`.
59
+
60
+ * __No more `contenteditable="false"` or `data-mce-bogus` on elements__, which
61
+ only existed to live inside a text editor. And a plugin that wrote an
62
+ element's attributes through tinyMCE's `undoManager.transact` can write them
63
+ with a plain `attr()`.
19
64
 
20
65
  * __An integration of your own under `$.fn.gridEditor.RTEs`__ still works,
21
- wrapped by the editor, with a warning that it is deprecated. Register it
22
- under `$.fn.gridEditor.texts` instead; [docs/plugins.md](docs/plugins.md#text-editor-plugins)
66
+ wrapped, with a warning that it is deprecated. Register it under
67
+ `$.fn.gridEditor.texts` instead; [docs/plugins.md](docs/plugins.md#text-editor-plugins)
23
68
  has the contract. `RTEs` goes in 7.0.
24
69
 
25
70
 
@@ -109,6 +109,9 @@
109
109
  /* Dragging by the whole drawer rather than by the move tool */
110
110
  .ge-canvas.ge-editing.ge-drag-drawer {
111
111
  /* The tools in it are still tools, and do not start a drag */
112
+ /* An info tool does nothing when clicked, so it is somewhere to hold */
113
+ /* A text's drawer sits over the text, small, and is mostly tools: a grip
114
+ at its start says where to take hold of it */
112
115
  }
113
116
  .ge-canvas.ge-editing.ge-drag-drawer .ge-tools-drawer {
114
117
  cursor: move;
@@ -120,6 +123,154 @@
120
123
  .ge-canvas.ge-editing.ge-drag-drawer .ge-tools-drawer .ge-details {
121
124
  cursor: auto;
122
125
  }
126
+ .ge-canvas.ge-editing.ge-drag-drawer .ge-tools-drawer > a.ge-text-info,
127
+ .ge-canvas.ge-editing.ge-drag-drawer .ge-tools-drawer > a.ge-element-info {
128
+ cursor: move;
129
+ }
130
+ .ge-canvas.ge-editing.ge-drag-drawer .ge-text-block > .ge-text-drawer {
131
+ padding-left: 14px;
132
+ }
133
+ .ge-canvas.ge-editing.ge-drag-drawer .ge-text-block > .ge-text-drawer::before {
134
+ content: '';
135
+ position: absolute;
136
+ top: 50%;
137
+ left: 4px;
138
+ width: 6px;
139
+ height: 14px;
140
+ transform: translateY(-50%);
141
+ background-image: radial-gradient(circle, #50637b 1px, transparent 1.3px);
142
+ background-size: 3px 3px;
143
+ opacity: 0.7;
144
+ }
145
+ /* A node's settings, wherever settings_panel shows them: in its drawer, or
146
+ in one of Bootstrap's offcanvas, popover or modal, outside the canvas. The
147
+ fields are Bootstrap's own - form-control-sm, form-select-sm,
148
+ btn-outline-secondary - and this only lays them out. */
149
+ .ge-details {
150
+ font-size: 0.8125rem;
151
+ /* The utility plugins' fields, folded under one toggle */
152
+ }
153
+ .ge-details .ge-details-general {
154
+ display: flex;
155
+ flex-direction: column;
156
+ gap: 8px;
157
+ }
158
+ .ge-details .ge-field {
159
+ display: flex;
160
+ flex-direction: column;
161
+ gap: 2px;
162
+ margin: 0;
163
+ }
164
+ .ge-details .ge-field-label,
165
+ .ge-details .ge-utility-label {
166
+ color: var(--bs-secondary-color, #6c757d);
167
+ font-size: 0.75rem;
168
+ }
169
+ .ge-details .ge-presets:empty {
170
+ display: none;
171
+ }
172
+ .ge-details .ge-utilities {
173
+ margin-top: 10px;
174
+ /* The spacing plugin: a side and a value per group */
175
+ }
176
+ .ge-details .ge-utilities > .ge-utilities-toggle {
177
+ display: block;
178
+ color: var(--bs-body-color, #333);
179
+ font-weight: 500;
180
+ cursor: pointer;
181
+ text-decoration: none;
182
+ }
183
+ .ge-details .ge-utilities > .ge-utilities-toggle::before {
184
+ content: '\25B8';
185
+ display: inline-block;
186
+ width: 1em;
187
+ }
188
+ .ge-details .ge-utilities.ge-open > .ge-utilities-toggle::before {
189
+ content: '\25BE';
190
+ }
191
+ .ge-details .ge-utilities > .ge-utilities-body {
192
+ display: none;
193
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
194
+ gap: 8px 10px;
195
+ margin-top: 6px;
196
+ }
197
+ .ge-details .ge-utilities.ge-open > .ge-utilities-body {
198
+ display: grid;
199
+ }
200
+ .ge-details .ge-utilities .ge-utility {
201
+ display: flex;
202
+ flex-direction: column;
203
+ gap: 2px;
204
+ margin: 0;
205
+ }
206
+ .ge-details .ge-utilities .ge-utility-note {
207
+ color: var(--bs-secondary-color, #666);
208
+ font-size: 0.6875rem;
209
+ }
210
+ .ge-details .ge-utilities .ge-spacing {
211
+ display: grid;
212
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
213
+ gap: 8px 10px;
214
+ grid-column: 1 / -1;
215
+ }
216
+ .ge-details .ge-utilities .ge-spacing-group {
217
+ display: flex;
218
+ flex-direction: column;
219
+ gap: 2px;
220
+ /* The group names the field once */
221
+ }
222
+ .ge-details .ge-utilities .ge-spacing-group .ge-utility > .ge-utility-label {
223
+ display: none;
224
+ }
225
+ .ge-details .ge-utilities .ge-spacing-gutter {
226
+ grid-column: 1 / -1;
227
+ color: var(--bs-secondary-color, #666);
228
+ font-size: 0.6875rem;
229
+ }
230
+ /* In a drawer it is part of the drawer, compact */
231
+ .ge-tools-drawer > .ge-details {
232
+ font-size: 11px;
233
+ }
234
+ .ge-tools-drawer > .ge-details .ge-utilities > .ge-utilities-body {
235
+ grid-template-columns: repeat(auto-fill, minmax(120px, 160px));
236
+ }
237
+ /* In one of Bootstrap's, outside the canvas */
238
+ .ge-settings-panel .ge-details {
239
+ display: block;
240
+ }
241
+ .ge-settings-panel .ge-settings-title {
242
+ font-size: 1rem;
243
+ font-weight: 500;
244
+ }
245
+ .ge-settings-offcanvas {
246
+ /* Beside the canvas rather than over most of it */
247
+ --bs-offcanvas-width: 340px;
248
+ --bs-offcanvas-height: 60vh;
249
+ }
250
+ .ge-settings-popover {
251
+ /* Popper would position it; without Popper that is the editor's job */
252
+ position: absolute;
253
+ --bs-popover-max-width: 360px;
254
+ width: 360px;
255
+ max-width: calc(100vw - 16px);
256
+ }
257
+ .ge-settings-popover > .popover-header {
258
+ display: flex;
259
+ align-items: center;
260
+ justify-content: space-between;
261
+ gap: 8px;
262
+ }
263
+ .ge-settings-popover > .popover-header > .btn-close {
264
+ font-size: 0.65rem;
265
+ }
266
+ .ge-settings-popover > .popover-body {
267
+ overflow-y: auto;
268
+ }
269
+ /* The node whose settings are open */
270
+ .ge-canvas.ge-editing .ge-settings-target {
271
+ outline: 2px solid var(--bs-primary, #0d6efd);
272
+ outline-offset: 1px;
273
+ }
123
274
  /* While editing */
124
275
  .ge-canvas.ge-editing {
125
276
  /* Content area */
@@ -175,6 +326,7 @@
175
326
  width: calc(100% + 2 * 5px);
176
327
  /* Its node may align text, and the drawer's tools would follow */
177
328
  text-align: left;
329
+ /* A node's settings, unfolded in its drawer: settings_panel 'inline' */
178
330
  }
179
331
  .ge-canvas.ge-editing .ge-tools-drawer.ge-picker-open {
180
332
  z-index: 200;
@@ -187,102 +339,23 @@
187
339
  background: rgba(255, 255, 255, 0.5);
188
340
  cursor: pointer;
189
341
  }
190
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details {
342
+ .ge-canvas.ge-editing .ge-tools-drawer > .ge-details {
343
+ display: none;
191
344
  padding: 5px;
192
345
  border-top: 1px solid rgba(0, 0, 0, 0.05);
193
- display: none;
194
- /* The utility plugins' fields, folded under one toggle */
195
- }
196
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .btn-group a {
197
- color: #333;
198
- }
199
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .btn-group a.active {
200
- color: white;
346
+ text-align: left;
347
+ cursor: auto;
201
348
  }
202
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .btn-group a:hover {
203
- text-decoration: none;
204
- cursor: pointer;
349
+ .ge-canvas.ge-editing .ge-tools-drawer > .ge-details .ge-details-general {
350
+ flex-direction: row;
351
+ align-items: flex-end;
205
352
  }
206
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details input.ge-id,
207
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details input.ge-classes {
208
- border: 1px solid #7F7F7F;
209
- border-radius: 4px;
210
- font-size: 11px;
211
- padding: 2px 5px;
212
- margin-right: 5px;
213
- width: 80px;
353
+ .ge-canvas.ge-editing .ge-tools-drawer > .ge-details input.ge-id {
354
+ width: 90px;
214
355
  }
215
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details input.ge-classes {
356
+ .ge-canvas.ge-editing .ge-tools-drawer > .ge-details input.ge-classes {
216
357
  width: 200px;
217
358
  }
218
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities {
219
- margin-top: 5px;
220
- font-size: 11px;
221
- /* The spacing plugin: a side and a value per group */
222
- }
223
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities > .ge-utilities-toggle {
224
- color: #333;
225
- cursor: pointer;
226
- text-decoration: none;
227
- }
228
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities > .ge-utilities-toggle::before {
229
- content: '\25B8';
230
- display: inline-block;
231
- width: 1em;
232
- }
233
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities.ge-open > .ge-utilities-toggle::before {
234
- content: '\25BE';
235
- }
236
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities > .ge-utilities-body {
237
- display: none;
238
- flex-wrap: wrap;
239
- gap: 4px 10px;
240
- margin-top: 4px;
241
- }
242
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities.ge-open > .ge-utilities-body {
243
- display: flex;
244
- }
245
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-utility {
246
- display: inline-flex;
247
- flex-direction: column;
248
- margin: 0;
249
- }
250
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-utility select {
251
- border: 1px solid #7F7F7F;
252
- border-radius: 4px;
253
- font-size: 11px;
254
- padding: 1px 2px;
255
- }
256
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-utility-note {
257
- color: #666;
258
- font-size: 10px;
259
- max-width: 160px;
260
- }
261
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-spacing {
262
- display: flex;
263
- flex-wrap: wrap;
264
- gap: 4px 10px;
265
- }
266
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-spacing-group {
267
- display: inline-flex;
268
- flex-direction: column;
269
- /* The group names the field once */
270
- }
271
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-spacing-group > .ge-spacing-side {
272
- border: 1px solid #7F7F7F;
273
- border-radius: 4px;
274
- font-size: 11px;
275
- padding: 1px 2px;
276
- margin-bottom: 2px;
277
- }
278
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-spacing-group .ge-utility > .ge-utility-label {
279
- display: none;
280
- }
281
- .ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-spacing-gutter {
282
- flex-basis: 100%;
283
- color: #666;
284
- font-size: 10px;
285
- }
286
359
  .ge-canvas.ge-editing .row {
287
360
  background-color: #efefef;
288
361
  border: 1px solid #999999;
@@ -488,6 +561,11 @@
488
561
  while it is wanted - the pointer over the text, the text being
489
562
  edited or holding the focus, its settings open, a drag under way -
490
563
  and takes no room either way. */
564
+ /* While the text is being edited it would sit over the end of its
565
+ first line, so it stands back - faint, still there to click - until
566
+ the pointer is on the drawer itself */
567
+ /* Except when something in it is in use: its settings, a choice it
568
+ offers, a drag */
491
569
  /* With its settings open it spans the text, so the panel has room */
492
570
  }
493
571
  .ge-canvas.ge-editing .ge-text-block > .ge-text-drawer {
@@ -525,6 +603,14 @@
525
603
  visibility: visible;
526
604
  transition-delay: 0s;
527
605
  }
606
+ .ge-canvas.ge-editing .ge-text-block:has(> .ge-rte-active) > .ge-text-drawer:not(:hover) {
607
+ opacity: 0.35;
608
+ }
609
+ .ge-canvas.ge-editing .ge-text-block.ge-drag-chosen > .ge-text-drawer:not(:hover),
610
+ .ge-canvas.ge-editing .ge-text-block:has(> .ge-text-drawer.ge-picker-open) > .ge-text-drawer:not(:hover),
611
+ .ge-canvas.ge-editing .ge-text-block:has(> .ge-text-drawer > .ge-details[style*="block"]) > .ge-text-drawer:not(:hover) {
612
+ opacity: 1;
613
+ }
528
614
  .ge-canvas.ge-editing .ge-text-block:has(> .ge-text-drawer > .ge-details[style*="block"]) > .ge-text-drawer {
529
615
  left: 0;
530
616
  border-radius: 0;
@@ -4452,18 +4538,11 @@
4452
4538
  color: #785f33;
4453
4539
  }
4454
4540
  /* The width field, in the section's settings panel beside id and classes */
4455
- .ge-canvas.ge-editing .ge-details .ge-section-width {
4456
- display: inline-flex;
4457
- align-items: center;
4458
- gap: 4px;
4541
+ .ge-details .ge-section-width {
4542
+ display: flex;
4543
+ flex-direction: column;
4544
+ gap: 2px;
4459
4545
  margin: 0;
4460
- font-size: 11px;
4461
- }
4462
- .ge-canvas.ge-editing .ge-details .ge-section-width select {
4463
- border: 1px solid #7F7F7F;
4464
- border-radius: 4px;
4465
- font-size: 11px;
4466
- padding: 1px 2px;
4467
4546
  }
4468
4547
  .ge-canvas.ge-layout-xs > .container {
4469
4548
  max-width: 100%;