@themarioga/grid-editor 6.0.0-beta.1 → 6.0.0-beta.3

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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,43 @@ 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.3] - 2026-09-23
9
+ ### Changed
10
+ - Which editor edits a text is shown first in its settings, as a read-only
11
+ `Editor` field (`panel.editor`), where it was an info tool in its drawer.
12
+ The `tool.text_info` locale key is gone. A text whose editor is not loaded
13
+ still says so in its drawer.
14
+
15
+
16
+ ## [6.0.0-beta.2] - 2026-09-23
17
+ ### Added
18
+ - `settings_panel`: where a gear's settings open - a Bootstrap offcanvas at
19
+ the side, the default; a popover under the gear; a modal; or `'inline'` in
20
+ the drawer, as before. Each is titled after its node, the node is outlined
21
+ while they are open, and Escape closes them. The editor opens and places
22
+ them with Bootstrap's markup and css, and needs neither Popper nor
23
+ Bootstrap's javascript for it. [example/utilities.html](example/utilities.html)
24
+ switches between them.
25
+ - `ge.detailsOf(node)` in the plugin handle: a node's settings panel,
26
+ wherever it is open.
27
+
28
+ ### Changed
29
+ - The settings' fields are Bootstrap 5's own - labelled `form-control-sm`
30
+ inputs and `form-select-sm` selects - and the preset class buttons
31
+ `btn-outline-secondary`, where they carried Bootstrap 3's `btn-default`,
32
+ which Bootstrap 5 has not got.
33
+
34
+ ### Fixed
35
+ - While dragging, the copy that follows the pointer came out unstyled - its
36
+ drawers laid out as plain links, their settings panels open - because it was
37
+ appended to the page's body, outside the canvas the editor's styles apply
38
+ to. It is appended to the list the drag started in, and looks like what it
39
+ copies.
40
+ - With `drag_handle: 'drawer'` a text could not be dragged: its drawer is
41
+ small and made of tools, and a drag never starts on a tool. It has a grip at
42
+ its start now, and an info tool - the text's and an element's - which does
43
+ nothing when clicked, starts a drag too.
44
+
8
45
  ## [6.0.0-beta.1] - 2026-09-23
9
46
  ### Changed
10
47
  - **Elements are blocks of the column.** An element sits in a column beside
package/README.md CHANGED
@@ -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.
@@ -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;
@@ -4465,18 +4538,11 @@
4465
4538
  color: #785f33;
4466
4539
  }
4467
4540
  /* The width field, in the section's settings panel beside id and classes */
4468
- .ge-canvas.ge-editing .ge-details .ge-section-width {
4469
- display: inline-flex;
4470
- align-items: center;
4471
- gap: 4px;
4541
+ .ge-details .ge-section-width {
4542
+ display: flex;
4543
+ flex-direction: column;
4544
+ gap: 2px;
4472
4545
  margin: 0;
4473
- font-size: 11px;
4474
- }
4475
- .ge-canvas.ge-editing .ge-details .ge-section-width select {
4476
- border: 1px solid #7F7F7F;
4477
- border-radius: 4px;
4478
- font-size: 11px;
4479
- padding: 1px 2px;
4480
4546
  }
4481
4547
  .ge-canvas.ge-layout-xs > .container {
4482
4548
  max-width: 100%;