@themarioga/grid-editor 3.2.1 → 4.1.0
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/BUILDING.md +12 -3
- package/CHANGELOG.md +87 -0
- package/README.md +79 -7
- package/UPGRADING.md +79 -0
- package/dist/grideditor.css +188 -20
- package/dist/grideditor.min.css +1 -1
- package/dist/grideditor.min.css.map +1 -1
- package/dist/jquery.grideditor.bundle.min.js +10 -0
- package/dist/jquery.grideditor.js +924 -174
- package/dist/jquery.grideditor.min.js +1 -1
- package/dist/jquery.grideditor.min.js.map +1 -1
- package/dist/locales/grideditor.es.js +34 -0
- package/dist/locales/grideditor.es.min.js +1 -1
- package/dist/locales/grideditor.es.min.js.map +1 -1
- package/dist/plugins/grideditor.accordion.js +8 -0
- package/dist/plugins/grideditor.accordion.min.js +1 -1
- package/dist/plugins/grideditor.accordion.min.js.map +1 -1
- package/dist/plugins/grideditor.alignment.js +81 -0
- package/dist/plugins/grideditor.alignment.min.js +2 -0
- package/dist/plugins/grideditor.alignment.min.js.map +1 -0
- package/dist/plugins/grideditor.elements.js +5 -5
- package/dist/plugins/grideditor.elements.min.js +1 -1
- package/dist/plugins/grideditor.elements.min.js.map +1 -1
- package/dist/plugins/grideditor.gutters.js +145 -0
- package/dist/plugins/grideditor.gutters.min.js +2 -0
- package/dist/plugins/grideditor.gutters.min.js.map +1 -0
- package/dist/plugins/grideditor.order.js +206 -0
- package/dist/plugins/grideditor.order.min.js +2 -0
- package/dist/plugins/grideditor.order.min.js.map +1 -0
- package/dist/plugins/grideditor.spacing.js +299 -0
- package/dist/plugins/grideditor.spacing.min.js +2 -0
- package/dist/plugins/grideditor.spacing.min.js.map +1 -0
- package/dist/plugins/grideditor.tabs.js +8 -0
- package/dist/plugins/grideditor.tabs.min.js +1 -1
- package/dist/plugins/grideditor.tabs.min.js.map +1 -1
- package/dist/plugins/grideditor.visibility.js +172 -0
- package/dist/plugins/grideditor.visibility.min.js +2 -0
- package/dist/plugins/grideditor.visibility.min.js.map +1 -0
- package/docs/events.md +26 -8
- package/docs/locale-keys.md +54 -0
- package/docs/plugins.md +129 -10
- package/example/autosave.html +6 -1
- package/example/basic.html +8 -2
- package/example/breakpoints.html +6 -1
- package/example/ckeditor.html +6 -1
- package/example/containers.html +5 -1
- package/example/elements.html +6 -1
- package/example/index.html +24 -1
- package/example/locale.html +6 -1
- package/example/plugins.html +6 -1
- package/example/summernote.html +6 -1
- package/example/utilities.html +145 -0
- package/example/wrap_content.html +6 -1
- package/package.json +3 -2
- package/src/js/jquery.grideditor.js +924 -174
- package/src/js/locales/grideditor.es.js +34 -0
- package/src/js/plugins/grideditor.accordion.js +8 -0
- package/src/js/plugins/grideditor.alignment.js +81 -0
- package/src/js/plugins/grideditor.elements.js +5 -5
- package/src/js/plugins/grideditor.gutters.js +145 -0
- package/src/js/plugins/grideditor.order.js +206 -0
- package/src/js/plugins/grideditor.spacing.js +299 -0
- package/src/js/plugins/grideditor.tabs.js +8 -0
- package/src/js/plugins/grideditor.visibility.js +172 -0
- package/src/less/grideditor.less +210 -18
package/BUILDING.md
CHANGED
|
@@ -19,8 +19,17 @@ and the files in `src/js/locales/` and `src/js/plugins/` one by one under
|
|
|
19
19
|
`dist/locales/` and `dist/plugins/`. Neither of those two directories is part
|
|
20
20
|
of the main bundle: the `src/js/*.js` glob does not descend, so a page loads
|
|
21
21
|
the languages and the container plugins it actually wants. See
|
|
22
|
-
[docs/plugins.md](docs/plugins.md) for what a container plugin is.
|
|
23
|
-
|
|
22
|
+
[docs/plugins.md](docs/plugins.md) for what a container plugin is.
|
|
23
|
+
|
|
24
|
+
One more file comes out of it: `dist/jquery.grideditor.bundle.min.js`, the
|
|
25
|
+
minified editor concatenated with the copy of SortableJS in `node_modules`,
|
|
26
|
+
for pages that would rather load one file than two. It carries both MIT
|
|
27
|
+
notices, it is built after the minified editor because it is made of it, and a
|
|
28
|
+
page loads it *or* the editor and SortableJS separately, never both. The
|
|
29
|
+
version is pinned in `package.json`, so refreshing it is an `npm update
|
|
30
|
+
sortablejs` and a rebuild.
|
|
31
|
+
|
|
32
|
+
Locale files are deliberately not part of the main bundle: a page loads only the languages it
|
|
24
33
|
offers. English is the exception and lives in the bundle, because it is the
|
|
25
34
|
fallback every string lookup ends at. See `docs/locale-keys.md` for the keys,
|
|
26
35
|
and `src/js/locales/grideditor.es.js` for what a locale file looks like.
|
|
@@ -44,7 +53,7 @@ suite, pass part of its name:
|
|
|
44
53
|
|
|
45
54
|
A suite can also be run on its own with `node test/rte.js`.
|
|
46
55
|
|
|
47
|
-
The fixture pages in `test/fixtures` load jQuery,
|
|
56
|
+
The fixture pages in `test/fixtures` load jQuery, SortableJS and Bootstrap from
|
|
48
57
|
`test/vendor` rather than from a CDN, so most of the suite runs offline. The
|
|
49
58
|
rich text editor suite is the exception: it loads tinyMCE, CKEditor and
|
|
50
59
|
Summernote from their CDNs to test against the real editors, and the runner
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,93 @@ 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
|
+
## [4.1.0] - 2026-09-22
|
|
9
|
+
### Added
|
|
10
|
+
- Utility plugins, a third kind beside containers and features:
|
|
11
|
+
`$.fn.gridEditor.utilities`. A plugin declares families of Bootstrap's
|
|
12
|
+
responsive utility classes and the editor reads them through the cascade,
|
|
13
|
+
writes them per breakpoint (the all view writes the class with no infix and
|
|
14
|
+
clears the rest), shows them in a folded *Responsive* section of the settings
|
|
15
|
+
panel, and previews them in each breakpoint view. See docs/plugins.md.
|
|
16
|
+
- `getUtility` and `setUtility` methods, and the `utilities` setting for the
|
|
17
|
+
plugins' options.
|
|
18
|
+
- `before-utility`, `after-utility` and `view-change` events. `view-change` is
|
|
19
|
+
new for every host, not only for utility plugins.
|
|
20
|
+
- The plugin handle gains `kindOf`, `view`, `viewTiers`, `breakpoints`,
|
|
21
|
+
`getUtility` and `setUtility`, and a utility plugin may add tools beside any
|
|
22
|
+
drawer's gear and mark the canvas in `onRefresh`.
|
|
23
|
+
- The `visibility` utility plugin: hide a row, column, element or container at
|
|
24
|
+
some breakpoints with `d-{bp}-none` and show it at others. An eye in each
|
|
25
|
+
drawer toggles the view being edited with as few classes as that takes. A
|
|
26
|
+
hidden node stays on the canvas, faded, and in the all view a badge says at
|
|
27
|
+
which breakpoints it is hidden.
|
|
28
|
+
- The `order` utility plugin: a column's place in its row per breakpoint,
|
|
29
|
+
with `order-{bp}-*`. Two arrows in each column drawer move it one place
|
|
30
|
+
earlier or later in the view being edited without moving the markup, and
|
|
31
|
+
take the classes off again once the row is back in the markup's order. A
|
|
32
|
+
column ordered by class says so in a corner of the canvas.
|
|
33
|
+
- The `alignment` utility plugin: `justify-content-{bp}-*` and
|
|
34
|
+
`align-items-{bp}-*` on rows, `align-self-{bp}-*` on columns, as fields in
|
|
35
|
+
the settings panel.
|
|
36
|
+
- The `gutters` utility plugin: `g-{bp}-*`, `gx-{bp}-*` and `gy-{bp}-*` on
|
|
37
|
+
rows. A row with gutter classes is drawn with its real gutters instead of the
|
|
38
|
+
editor's frame, the preview settles `g` against `gx`/`gy` the way Bootstrap's
|
|
39
|
+
css does, and choosing `g` takes that breakpoint's `gx` and `gy` off.
|
|
40
|
+
`utilities.gutters.scale` follows a page that changed `$spacers`.
|
|
41
|
+
- The `spacing` utility plugin: padding and margin on rows, columns, elements
|
|
42
|
+
and containers, `{p,m}{,x,y,t,b,s,e}-{bp}-*`. The panel has a padding and a
|
|
43
|
+
margin group, each a side and a value, and the preview settles the fourteen
|
|
44
|
+
families the way Bootstrap's css does. `utilities.spacing.values` and
|
|
45
|
+
`.scale` narrow the steps and follow a changed `$spacers`.
|
|
46
|
+
- A utility plugin can build its own panel (`panel`, `ge.utilityField`,
|
|
47
|
+
families with `panel: false`) and preview a node as a whole (`preview`).
|
|
48
|
+
- `example/utilities.html`.
|
|
49
|
+
|
|
50
|
+
## [4.0.0] - 2026-09-22
|
|
51
|
+
### Added
|
|
52
|
+
- Editing from a touchscreen. Sorting, resizing a column and carrying a toolbar
|
|
53
|
+
button onto the canvas all work with a finger; a touch rests for
|
|
54
|
+
`drag.touch_delay` before it moves anything, so the page can still be
|
|
55
|
+
scrolled. `test/touch.js` holds every gesture to it, and none of them worked
|
|
56
|
+
in 3.x.
|
|
57
|
+
- `dist/jquery.grideditor.bundle.min.js`: the editor with SortableJS inside it,
|
|
58
|
+
for pages that would rather load one file than two. A page loads it or the
|
|
59
|
+
pair, never both.
|
|
60
|
+
- A `drag` setting: `delay`, `touch_delay`, `threshold`, `animation` and
|
|
61
|
+
`scroll`, named for the gesture rather than for the library underneath.
|
|
62
|
+
- A whole container can be dragged. Its move tool used to be a handle for a
|
|
63
|
+
list that did not accept containers, so dragging one did nothing.
|
|
64
|
+
|
|
65
|
+
### Removed
|
|
66
|
+
- jQuery UI is no longer a dependency. A page loads jQuery, SortableJS and the
|
|
67
|
+
editor, which comes to 81.6 kB gzip against 132.8 kB before: 51 kB less, 39%
|
|
68
|
+
of the page.
|
|
69
|
+
- `sortable_options` and `resizable_options`. Both handed out the drag
|
|
70
|
+
library's own options; `drag` and `resize` replace them, and passing either
|
|
71
|
+
warns once naming the replacement.
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
- Resizing a column and dragging a toolbar button onto the canvas are the
|
|
75
|
+
editor's own pointer code, so jQuery UI is no longer used at all. A refused
|
|
76
|
+
`before-resize` now stops the gesture before it starts instead of refusing
|
|
77
|
+
every step of it, and the pointer is captured, so a fast drag that leaves the
|
|
78
|
+
column behind keeps resizing it. `.ui-resizable-*` become `.ge-resize-*` and
|
|
79
|
+
`.ge-resizing`; a palette button carries `.ge-palette-button`.
|
|
80
|
+
- Sorting is SortableJS instead of jQuery UI: rows, columns, blocks, tabs,
|
|
81
|
+
accordion items and elements all move through it, with touch support that
|
|
82
|
+
jQuery UI sortable never had. `.ui-sortable-helper` and
|
|
83
|
+
`.ui-sortable-placeholder` become `.ge-drag-helper` and
|
|
84
|
+
`.ge-drag-placeholder`.
|
|
85
|
+
- Every sortable list the editor makes, core's and a plugin's, goes through one
|
|
86
|
+
internal seam that names the drag toolkit in one place. Groundwork for 4.0,
|
|
87
|
+
which replaces jQuery UI with SortableJS.
|
|
88
|
+
- A plugin's `onSortable` hook receives that function instead of a jQuery UI
|
|
89
|
+
options object, and describes a list rather than making one. See
|
|
90
|
+
`UPGRADING.md`.
|
|
91
|
+
- Sortable groups are scoped to the editor instance, so two editors on one page
|
|
92
|
+
no longer drag into each other.
|
|
93
|
+
|
|
94
|
+
|
|
8
95
|
## [3.2.1] - 2026-09-22
|
|
9
96
|
### Changed
|
|
10
97
|
- `example/containers.html` shows a card too: its own row, with two columns
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Grid Editor
|
|
2
2
|
===========
|
|
3
3
|
|
|
4
|
-
Grid Editor is a visual javascript editor for the [bootstrap 5 grid system](https://getbootstrap.com/docs/5.3/layout/grid/), written as a [jQuery](http://jquery.com/) plugin. You can create, drag, resize and delete rows and columns, indent them, and give each of bootstrap's six breakpoints its own layout — or edit them all at once. It also edits tabs, accordions, popups and cards, and any markup you mark as an element, and it tells your application about every change it makes.
|
|
4
|
+
Grid Editor is a visual javascript editor for the [bootstrap 5 grid system](https://getbootstrap.com/docs/5.3/layout/grid/), written as a [jQuery](http://jquery.com/) plugin. You can create, drag, resize and delete rows and columns, indent them, and give each of bootstrap's six breakpoints its own layout — or edit them all at once, with a mouse or with a finger. It also edits tabs, accordions, popups and cards, and any markup you mark as an element, and it tells your application about every change it makes.
|
|
5
5
|
|
|
6
6
|
This is a fork of [Friendly-Pixel/grid-editor](https://github.com/Friendly-Pixel/grid-editor)
|
|
7
7
|
by Simon Epskamp, carrying it on from 2.x. It is published as
|
|
@@ -30,6 +30,7 @@ from any web server, or from GitHub Pages, with no build step.
|
|
|
30
30
|
| [example/plugins.html](example/plugins.html) | The plugin model, with one written in the page itself | [live](https://themarioga.github.io/grid-editor/example/plugins.html) |
|
|
31
31
|
| [example/containers.html](example/containers.html) | Tabs, accordions, popups and cards, two levels deep | [live](https://themarioga.github.io/grid-editor/example/containers.html) |
|
|
32
32
|
| [example/elements.html](example/elements.html) | Element level controls, including an element with no visual output | [live](https://themarioga.github.io/grid-editor/example/elements.html) |
|
|
33
|
+
| [example/utilities.html](example/utilities.html) | Bootstrap's responsive utilities, edited per breakpoint | [live](https://themarioga.github.io/grid-editor/example/utilities.html) |
|
|
33
34
|
| [example/locale.html](example/locale.html) | The interface in Spanish, with a language switcher | [live](https://themarioga.github.io/grid-editor/example/locale.html) |
|
|
34
35
|
| [example/ckeditor.html](example/ckeditor.html) | CKEditor instead of tinyMCE | [live](https://themarioga.github.io/grid-editor/example/ckeditor.html) |
|
|
35
36
|
| [example/summernote.html](example/summernote.html) | Summernote instead of tinyMCE | [live](https://themarioga.github.io/grid-editor/example/summernote.html) |
|
|
@@ -39,7 +40,7 @@ from any web server, or from GitHub Pages, with no build step.
|
|
|
39
40
|
Installation
|
|
40
41
|
------------
|
|
41
42
|
|
|
42
|
-
* __Dependencies:__ Grid Editor depends on jQuery,
|
|
43
|
+
* __Dependencies:__ Grid Editor depends on jQuery, [SortableJS](https://sortablejs.github.io/Sortable/), Bootstrap Icons, and Bootstrap 5, so make sure you have included those in the page.
|
|
43
44
|
* If you want to use the tinyMCE integration, include tinyMCE 6 as well. The tinyMCE jQuery plugin is no longer needed, and no longer exists as of tinyMCE 6.
|
|
44
45
|
* If you want to use the summernote integration, include summernote as well.
|
|
45
46
|
* If you want to use the CKEditor integration... you get the point.
|
|
@@ -52,11 +53,20 @@ npm install @themarioga/grid-editor
|
|
|
52
53
|
* Or [download the latest version of Grid Editor](https://github.com/themarioga/grid-editor/archive/master.zip) and include it in your page:
|
|
53
54
|
|
|
54
55
|
```html
|
|
55
|
-
<!-- Make sure jQuery,
|
|
56
|
+
<!-- Make sure jQuery, SortableJS, bootstrap icons, and bootstrap 5 are included. TinyMCE is optional. -->
|
|
56
57
|
<link rel="stylesheet" type="text/css" href="grid-editor/dist/grideditor.min.css" />
|
|
58
|
+
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.6/Sortable.min.js"></script>
|
|
57
59
|
<script src="grid-editor/dist/jquery.grideditor.min.js"></script>
|
|
58
60
|
```
|
|
59
61
|
|
|
62
|
+
Or, for a page that would rather load one file, the editor with SortableJS
|
|
63
|
+
inside it — one or the other, never both:
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<link rel="stylesheet" type="text/css" href="grid-editor/dist/grideditor.min.css" />
|
|
67
|
+
<script src="grid-editor/dist/jquery.grideditor.bundle.min.js"></script>
|
|
68
|
+
```
|
|
69
|
+
|
|
60
70
|
Usage
|
|
61
71
|
-----
|
|
62
72
|
```javascript
|
|
@@ -91,6 +101,8 @@ $('#myGrid').gridEditor('method', argument);
|
|
|
91
101
|
| `createContainer` | `type`, `options?` | `jQuery` | `'tabs'`, `'accordion'` or `'popup'` |
|
|
92
102
|
| `addTab` | `container`, `options?` | `jQuery` | Appends a tab, returns its pane |
|
|
93
103
|
| `addAccordionItem` | `container`, `options?` | `jQuery` | Appends an item, returns its body |
|
|
104
|
+
| `getUtility` | `node`, `family`, `view?` | `String` | A utility plugin's value on a node in a view (the current one by default), or `null` |
|
|
105
|
+
| `setUtility` | `node`, `family`, `value`, `view?` | `Boolean` | Write it through the events; `null` is inherit. `false` if canceled or nothing changed |
|
|
94
106
|
|
|
95
107
|
A method called on an element with no editor on it is a no-op that returns the
|
|
96
108
|
set, so host code does not have to check first. `getHtml` is the exception: it
|
|
@@ -295,7 +307,19 @@ $('#myGrid').gridEditor({
|
|
|
295
307
|
|
|
296
308
|
__`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.
|
|
297
309
|
|
|
298
|
-
__`
|
|
310
|
+
__`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.
|
|
311
|
+
|
|
312
|
+
```javascript
|
|
313
|
+
$('#myGrid').gridEditor({
|
|
314
|
+
drag: {
|
|
315
|
+
delay: 0, // ms to hold before a drag starts
|
|
316
|
+
touch_delay: 100, // the same for touch, where 0 eats the page's scrolling
|
|
317
|
+
threshold: 3, // px of movement before a gesture counts as a drag
|
|
318
|
+
animation: 150, // ms of reordering animation, 0 for none
|
|
319
|
+
scroll: true, // scroll the page when a drag reaches its edge
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
```
|
|
299
323
|
|
|
300
324
|
### Breakpoints and sizing
|
|
301
325
|
|
|
@@ -315,13 +339,12 @@ __`resize`:__ Resizing a column by dragging its edge. Defaults:
|
|
|
315
339
|
$('#myGrid').gridEditor({
|
|
316
340
|
resize: {
|
|
317
341
|
enabled: true,
|
|
318
|
-
handles: 'e', //
|
|
342
|
+
handles: 'e', // 'w' for a right to left page, 'e, w' for both
|
|
319
343
|
balance: 'next', // the following column absorbs the change; false lets the row wrap
|
|
320
344
|
},
|
|
321
345
|
});
|
|
322
346
|
```
|
|
323
347
|
|
|
324
|
-
__`resizable_options`:__ Merged into every jQuery UI resizable.
|
|
325
348
|
|
|
326
349
|
### Elements
|
|
327
350
|
|
|
@@ -358,6 +381,55 @@ __`element_tools`:__ Extra tools on every element drawer, same shape as `row_too
|
|
|
358
381
|
See [example/elements.html](example/elements.html), which also shows the
|
|
359
382
|
pattern for an element with no visual output of its own.
|
|
360
383
|
|
|
384
|
+
### Responsive utilities
|
|
385
|
+
|
|
386
|
+
Bootstrap's responsive utility classes, edited per breakpoint. Each family is
|
|
387
|
+
a plugin in a file of its own:
|
|
388
|
+
|
|
389
|
+
```html
|
|
390
|
+
<script src="grid-editor/dist/plugins/grideditor.visibility.min.js"></script>
|
|
391
|
+
<script src="grid-editor/dist/plugins/grideditor.order.min.js"></script>
|
|
392
|
+
<script src="grid-editor/dist/plugins/grideditor.alignment.min.js"></script>
|
|
393
|
+
<script src="grid-editor/dist/plugins/grideditor.gutters.min.js"></script>
|
|
394
|
+
<script src="grid-editor/dist/plugins/grideditor.spacing.min.js"></script>
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
| Plugin | Classes | On |
|
|
398
|
+
| --- | --- | --- |
|
|
399
|
+
| `visibility` | `d-{bp}-none`, `d-{bp}-block`, `d-{bp}-flex` | rows, columns, elements, containers |
|
|
400
|
+
| `order` | `order-{bp}-{first,0–5,last}` | columns |
|
|
401
|
+
| `alignment` | `justify-content-{bp}-*`, `align-items-{bp}-*`; `align-self-{bp}-*` | rows; columns |
|
|
402
|
+
| `gutters` | `g-{bp}-{0–5}`, `gx-{bp}-*`, `gy-{bp}-*` | rows |
|
|
403
|
+
| `spacing` | `{p,m}{,x,y,t,b,s,e}-{bp}-{0–5}`, and `auto` for margin | rows, columns, elements, containers |
|
|
404
|
+
|
|
405
|
+
A plugin puts a field in the *Responsive* section of each drawer's settings
|
|
406
|
+
panel, and some add a tool to the drawer. In a breakpoint view a change is
|
|
407
|
+
written for that breakpoint alone, and the field says what it inherits and from
|
|
408
|
+
where. In the all view it is written once, as the class with no breakpoint, and
|
|
409
|
+
replaces what the breakpoints said. While you edit, the canvas shows what the
|
|
410
|
+
classes mean in the view you are in; `getHtml` returns only the classes.
|
|
411
|
+
|
|
412
|
+
```javascript
|
|
413
|
+
$('#myGrid').gridEditor('setUtility', column, 'visibility', 'none', 'md'); // d-md-none
|
|
414
|
+
$('#myGrid').gridEditor('getUtility', column, 'visibility', 'lg'); // 'none', inherited
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
__`utilities`:__ Options for each plugin, under its name.
|
|
418
|
+
|
|
419
|
+
```javascript
|
|
420
|
+
$('#myGrid').gridEditor({
|
|
421
|
+
utilities: {
|
|
422
|
+
visibility: { drawer: false }, // no eye in the drawers, the field only
|
|
423
|
+
order: { drawer: false }, // no arrows in the column drawers
|
|
424
|
+
gutters: { scale: ['0', '.25rem', '.5rem', '1rem', '1.5rem', '3rem'] }, // if you changed $spacers
|
|
425
|
+
spacing: { values: ['0', '2', '4'], scale: [/* the same */] }, // offer fewer steps
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
See [example/utilities.html](example/utilities.html), and
|
|
431
|
+
[docs/plugins.md](docs/plugins.md#utility-plugins) for writing one.
|
|
432
|
+
|
|
361
433
|
### Containers
|
|
362
434
|
|
|
363
435
|
Tabs, accordions, popups and cards. A tabs, accordion or popup container holds
|
|
@@ -379,7 +451,7 @@ it available:
|
|
|
379
451
|
The toolbar offers a button per loaded plugin. See [docs/plugins.md](docs/plugins.md)
|
|
380
452
|
for the contract, and for writing one of your own.
|
|
381
453
|
|
|
382
|
-
__`plugins`:__ Which of the loaded plugins to use, containers and
|
|
454
|
+
__`plugins`:__ Which of the loaded plugins to use, containers, features and utilities alike. Every one by default; name them to use fewer than the page loaded.
|
|
383
455
|
|
|
384
456
|
```javascript
|
|
385
457
|
$('#myGrid').gridEditor({ plugins: ['tabs', 'elements'] });
|
package/UPGRADING.md
CHANGED
|
@@ -1,3 +1,82 @@
|
|
|
1
|
+
Upgrading from grid-editor `3.*` to `4.*`
|
|
2
|
+
=========================================
|
|
3
|
+
|
|
4
|
+
One change, and it is worth the major: jQuery UI is gone. The editor is 51 kB
|
|
5
|
+
lighter on the page and works from a touchscreen, which it never did. Four
|
|
6
|
+
things to do:
|
|
7
|
+
|
|
8
|
+
* __A plugin's `onSortable` takes a function, not an options object.__ It used
|
|
9
|
+
to receive the editor's shared jQuery UI options and call `.sortable()`
|
|
10
|
+
itself; it now receives `sortable(lists, { draggable, group })` and describes
|
|
11
|
+
the list instead. See [docs/plugins.md](docs/plugins.md). Nothing else in the
|
|
12
|
+
plugin handle changed.
|
|
13
|
+
|
|
14
|
+
```javascript
|
|
15
|
+
// 3.x
|
|
16
|
+
onSortable: function(shared) {
|
|
17
|
+
ge.canvas.find('.ge-content').sortable($.extend({
|
|
18
|
+
items: '> .ge-element',
|
|
19
|
+
connectWith: '.ge-canvas .ge-content',
|
|
20
|
+
}, shared, ge.settings.sortable_options));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 4.x
|
|
24
|
+
onSortable: function(sortable) {
|
|
25
|
+
sortable(ge.canvas.find('.ge-content'), {
|
|
26
|
+
draggable: '> .ge-element',
|
|
27
|
+
group: 'element',
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
* __`sortable_options` and `resizable_options` are gone.__ They existed to hand
|
|
33
|
+
you the drag library's own options, and 4.0 stops promising there is one: the
|
|
34
|
+
group names, the handle, the filter and the callbacks are the editor's, and
|
|
35
|
+
overwriting them breaks the canvas rather than tuning it. What they were used
|
|
36
|
+
for is now `drag` — `delay`, `touch_delay`, `threshold`, `animation`,
|
|
37
|
+
`scroll` — and the `resize` block you already have. Passing either warns once
|
|
38
|
+
and names the replacement.
|
|
39
|
+
|
|
40
|
+
* __jQuery UI is not a dependency.__ Drop its `<script>` and add SortableJS;
|
|
41
|
+
resizing a column and carrying a toolbar button onto the canvas are the
|
|
42
|
+
editor's own pointer code now. A page that would rather load one file can
|
|
43
|
+
load `dist/jquery.grideditor.bundle.min.js`, the editor with SortableJS
|
|
44
|
+
inside it, instead of the two.
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
<!-- 3.x -->
|
|
48
|
+
<script src="jquery-ui.min.js"></script>
|
|
49
|
+
<script src="dist/jquery.grideditor.min.js"></script>
|
|
50
|
+
|
|
51
|
+
<!-- 4.x -->
|
|
52
|
+
<script src="Sortable.min.js"></script>
|
|
53
|
+
<script src="dist/jquery.grideditor.min.js"></script>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Classes you may have styled:
|
|
57
|
+
|
|
58
|
+
| 3.x | 4.0 |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `.ui-sortable-helper` | `.ge-drag-helper` |
|
|
61
|
+
| `.ui-sortable-placeholder` | `.ge-drag-placeholder` |
|
|
62
|
+
| `.ui-resizable-handle` | `.ge-resize-handle` |
|
|
63
|
+
| `.ui-resizable-e`, `.ui-resizable-w` | `.ge-resize-e`, `.ge-resize-w` |
|
|
64
|
+
| `.ui-resizable-resizing` | `.ge-resizing` |
|
|
65
|
+
| `.ui-draggable` on a toolbar button | `.ge-palette-button` |
|
|
66
|
+
|
|
67
|
+
* __A whole container can be dragged now.__ Its move tool was a handle for a
|
|
68
|
+
list that did not accept containers, so in 3.x dragging one did nothing. It
|
|
69
|
+
moves like a row does, and fires the same `before-move`/`after-move` with the
|
|
70
|
+
container's kind.
|
|
71
|
+
|
|
72
|
+
* __Two editors on one page no longer drag into each other.__ Lists were
|
|
73
|
+
connected by selector — `.ge-canvas .row` matches every canvas on the page —
|
|
74
|
+
so a column could be dragged from one editor into another, carrying the first
|
|
75
|
+
editor's furniture and firing its events in the wrong place. Lists are now
|
|
76
|
+
connected per instance. If you were relying on that, you were relying on a
|
|
77
|
+
bug.
|
|
78
|
+
|
|
79
|
+
|
|
1
80
|
Upgrading from grid-editor `2.*` to `3.*`
|
|
2
81
|
=========================================
|
|
3
82
|
|
package/dist/grideditor.css
CHANGED
|
@@ -76,7 +76,21 @@
|
|
|
76
76
|
background: #2FA4E7;
|
|
77
77
|
}
|
|
78
78
|
/* The button following the pointer must not be what the pointer is over */
|
|
79
|
+
.ge-drag-helper {
|
|
80
|
+
opacity: 0.85;
|
|
81
|
+
pointer-events: none;
|
|
82
|
+
}
|
|
83
|
+
.ge-drag-helper .ge-tools-drawer {
|
|
84
|
+
pointer-events: none;
|
|
85
|
+
}
|
|
86
|
+
/* A toolbar button that can be carried onto the canvas */
|
|
87
|
+
.ge-palette-button {
|
|
88
|
+
cursor: move;
|
|
89
|
+
touch-action: none;
|
|
90
|
+
}
|
|
79
91
|
.ge-toolbar-helper {
|
|
92
|
+
position: absolute;
|
|
93
|
+
z-index: 1000;
|
|
80
94
|
pointer-events: none;
|
|
81
95
|
opacity: 0.85;
|
|
82
96
|
}
|
|
@@ -114,21 +128,21 @@
|
|
|
114
128
|
/* A trigger pointing at a popup that is not there any more */
|
|
115
129
|
/* Elements: the level below a column, inside a content area. Dashed
|
|
116
130
|
rather than solid, so a page full of them still reads as content */
|
|
117
|
-
/* Sorting
|
|
131
|
+
/* Sorting. The dragged node stays in the list and shows where it would
|
|
132
|
+
land - that is the placeholder - while a copy of it follows the
|
|
133
|
+
pointer. */
|
|
118
134
|
/* A size change should read as a movement rather than a jump, but not
|
|
119
135
|
while the pointer is dragging the edge: there the column follows the
|
|
120
136
|
pointer and a transition only lags behind it */
|
|
121
|
-
/* Resizing
|
|
122
|
-
|
|
123
|
-
is what keeps the resize gesture and the sort gesture apart */
|
|
137
|
+
/* Resizing: a grip on the column's edge, clear of the drawer, which is
|
|
138
|
+
what keeps the resize gesture and the sort gesture apart */
|
|
124
139
|
/* The units the column would land on, shown in its drawer while dragging */
|
|
125
140
|
}
|
|
126
141
|
.ge-canvas.ge-editing .ge-tools-drawer {
|
|
127
142
|
/* Positioned, so a tool can hang a picker off itself. Deliberately
|
|
128
|
-
not stacked above anything the rest of the time:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
the handle. */
|
|
143
|
+
not stacked above anything the rest of the time: the resize handle
|
|
144
|
+
runs down the column's edge, and a drawer sitting over it would take
|
|
145
|
+
the clicks meant for the handle. */
|
|
132
146
|
position: relative;
|
|
133
147
|
-webkit-touch-callout: none;
|
|
134
148
|
/* While one of its tools is offering a choice, this drawer is the one
|
|
@@ -157,6 +171,7 @@
|
|
|
157
171
|
padding: 5px;
|
|
158
172
|
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
|
159
173
|
display: none;
|
|
174
|
+
/* The utility plugins' fields, folded under one toggle */
|
|
160
175
|
}
|
|
161
176
|
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .btn-group a {
|
|
162
177
|
color: #333;
|
|
@@ -180,6 +195,74 @@
|
|
|
180
195
|
.ge-canvas.ge-editing .ge-tools-drawer .ge-details input.ge-classes {
|
|
181
196
|
width: 200px;
|
|
182
197
|
}
|
|
198
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities {
|
|
199
|
+
margin-top: 5px;
|
|
200
|
+
font-size: 11px;
|
|
201
|
+
/* The spacing plugin: a side and a value per group */
|
|
202
|
+
}
|
|
203
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities > .ge-utilities-toggle {
|
|
204
|
+
color: #333;
|
|
205
|
+
cursor: pointer;
|
|
206
|
+
text-decoration: none;
|
|
207
|
+
}
|
|
208
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities > .ge-utilities-toggle::before {
|
|
209
|
+
content: '\25B8';
|
|
210
|
+
display: inline-block;
|
|
211
|
+
width: 1em;
|
|
212
|
+
}
|
|
213
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities.ge-open > .ge-utilities-toggle::before {
|
|
214
|
+
content: '\25BE';
|
|
215
|
+
}
|
|
216
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities > .ge-utilities-body {
|
|
217
|
+
display: none;
|
|
218
|
+
flex-wrap: wrap;
|
|
219
|
+
gap: 4px 10px;
|
|
220
|
+
margin-top: 4px;
|
|
221
|
+
}
|
|
222
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities.ge-open > .ge-utilities-body {
|
|
223
|
+
display: flex;
|
|
224
|
+
}
|
|
225
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-utility {
|
|
226
|
+
display: inline-flex;
|
|
227
|
+
flex-direction: column;
|
|
228
|
+
margin: 0;
|
|
229
|
+
}
|
|
230
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-utility select {
|
|
231
|
+
border: 1px solid #7F7F7F;
|
|
232
|
+
border-radius: 4px;
|
|
233
|
+
font-size: 11px;
|
|
234
|
+
padding: 1px 2px;
|
|
235
|
+
}
|
|
236
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-utility-note {
|
|
237
|
+
color: #666;
|
|
238
|
+
font-size: 10px;
|
|
239
|
+
max-width: 160px;
|
|
240
|
+
}
|
|
241
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-spacing {
|
|
242
|
+
display: flex;
|
|
243
|
+
flex-wrap: wrap;
|
|
244
|
+
gap: 4px 10px;
|
|
245
|
+
}
|
|
246
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-spacing-group {
|
|
247
|
+
display: inline-flex;
|
|
248
|
+
flex-direction: column;
|
|
249
|
+
/* The group names the field once */
|
|
250
|
+
}
|
|
251
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-spacing-group > .ge-spacing-side {
|
|
252
|
+
border: 1px solid #7F7F7F;
|
|
253
|
+
border-radius: 4px;
|
|
254
|
+
font-size: 11px;
|
|
255
|
+
padding: 1px 2px;
|
|
256
|
+
margin-bottom: 2px;
|
|
257
|
+
}
|
|
258
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-spacing-group .ge-utility > .ge-utility-label {
|
|
259
|
+
display: none;
|
|
260
|
+
}
|
|
261
|
+
.ge-canvas.ge-editing .ge-tools-drawer .ge-details .ge-utilities .ge-spacing-gutter {
|
|
262
|
+
flex-basis: 100%;
|
|
263
|
+
color: #666;
|
|
264
|
+
font-size: 10px;
|
|
265
|
+
}
|
|
183
266
|
.ge-canvas.ge-editing .row {
|
|
184
267
|
background-color: #efefef;
|
|
185
268
|
border: 1px solid #999999;
|
|
@@ -364,42 +447,48 @@
|
|
|
364
447
|
.ge-canvas.ge-editing .ge-element > .ge-element-drawer > a.ge-element-info {
|
|
365
448
|
cursor: default;
|
|
366
449
|
}
|
|
367
|
-
.ge-canvas.ge-editing .
|
|
450
|
+
.ge-canvas.ge-editing .ge-drag-placeholder {
|
|
368
451
|
background: rgba(255, 255, 0, 0.2);
|
|
369
|
-
|
|
452
|
+
opacity: 1;
|
|
370
453
|
min-height: 50px;
|
|
371
454
|
max-height: 100px;
|
|
372
455
|
}
|
|
456
|
+
.ge-canvas.ge-editing .ge-drag-placeholder > * {
|
|
457
|
+
visibility: hidden;
|
|
458
|
+
}
|
|
373
459
|
.ge-canvas.ge-editing .column {
|
|
374
460
|
transition: width 120ms ease, margin-left 120ms ease;
|
|
375
461
|
}
|
|
376
|
-
.ge-canvas.ge-editing .column.
|
|
462
|
+
.ge-canvas.ge-editing .column.ge-resizing {
|
|
377
463
|
transition: none;
|
|
378
464
|
/* Follow the pointer in pixels: the layout mode's max-width is what
|
|
379
465
|
the column will snap back into once the drag lands */
|
|
380
466
|
max-width: none;
|
|
381
467
|
}
|
|
382
|
-
.ge-canvas.ge-editing .column > .
|
|
468
|
+
.ge-canvas.ge-editing .column > .ge-resize-handle {
|
|
383
469
|
position: absolute;
|
|
384
470
|
display: block;
|
|
385
471
|
z-index: 10;
|
|
472
|
+
/* The gesture is the editor's, not the page's: without this a touch
|
|
473
|
+
drag on the handle scrolls instead of resizing */
|
|
474
|
+
touch-action: none;
|
|
386
475
|
}
|
|
387
|
-
.ge-canvas.ge-editing .column > .
|
|
388
|
-
.ge-canvas.ge-editing .column > .
|
|
476
|
+
.ge-canvas.ge-editing .column > .ge-resize-e,
|
|
477
|
+
.ge-canvas.ge-editing .column > .ge-resize-w {
|
|
389
478
|
top: 0;
|
|
390
479
|
bottom: 0;
|
|
391
480
|
width: 8px;
|
|
392
481
|
cursor: ew-resize;
|
|
393
482
|
background: rgba(47, 164, 231, 0.3);
|
|
394
483
|
}
|
|
395
|
-
.ge-canvas.ge-editing .column > .
|
|
396
|
-
.ge-canvas.ge-editing .column > .
|
|
484
|
+
.ge-canvas.ge-editing .column > .ge-resize-e:hover,
|
|
485
|
+
.ge-canvas.ge-editing .column > .ge-resize-w:hover {
|
|
397
486
|
background: #2FA4E7;
|
|
398
487
|
}
|
|
399
|
-
.ge-canvas.ge-editing .column > .
|
|
488
|
+
.ge-canvas.ge-editing .column > .ge-resize-e {
|
|
400
489
|
right: -1px;
|
|
401
490
|
}
|
|
402
|
-
.ge-canvas.ge-editing .column > .
|
|
491
|
+
.ge-canvas.ge-editing .column > .ge-resize-w {
|
|
403
492
|
left: -1px;
|
|
404
493
|
}
|
|
405
494
|
.ge-canvas.ge-editing .ge-tools-drawer > .ge-resize-size {
|
|
@@ -409,11 +498,11 @@
|
|
|
409
498
|
font-size: 11px;
|
|
410
499
|
color: #178acc;
|
|
411
500
|
}
|
|
412
|
-
.ge-canvas.ge-editing .column.
|
|
501
|
+
.ge-canvas.ge-editing .column.ge-resizing > .ge-tools-drawer > .ge-resize-size {
|
|
413
502
|
display: block;
|
|
414
503
|
}
|
|
415
504
|
/* The handle belongs to editing, and never to the output */
|
|
416
|
-
.ge-canvas:not(.ge-editing) .
|
|
505
|
+
.ge-canvas:not(.ge-editing) .ge-resize-handle {
|
|
417
506
|
display: none;
|
|
418
507
|
}
|
|
419
508
|
/* Layout modes */
|
|
@@ -3873,3 +3962,82 @@
|
|
|
3873
3962
|
.ge-canvas.ge-layout-xxl .offset-xxl-11 {
|
|
3874
3963
|
margin-left: 91.66666667%;
|
|
3875
3964
|
}
|
|
3965
|
+
/*
|
|
3966
|
+
* The visibility plugin. A node Bootstrap would hide is kept on the canvas -
|
|
3967
|
+
* there would be nothing left to click to show it again - and shown the way
|
|
3968
|
+
* the view sees it instead. The selectors outweigh Bootstrap's d-* classes,
|
|
3969
|
+
* which are !important too.
|
|
3970
|
+
*/
|
|
3971
|
+
.ge-canvas.ge-editing {
|
|
3972
|
+
/* The all view: hidden at some breakpoints, said in a corner */
|
|
3973
|
+
}
|
|
3974
|
+
.ge-canvas.ge-editing .ge-visibility {
|
|
3975
|
+
display: block !important;
|
|
3976
|
+
}
|
|
3977
|
+
.ge-canvas.ge-editing .row.ge-visibility {
|
|
3978
|
+
display: flex !important;
|
|
3979
|
+
}
|
|
3980
|
+
.ge-canvas.ge-editing .ge-hidden-in-view {
|
|
3981
|
+
opacity: 0.45;
|
|
3982
|
+
background-image: repeating-linear-gradient(-45deg, transparent 0, transparent 6px, rgba(0, 0, 0, 0.07) 6px, rgba(0, 0, 0, 0.07) 12px);
|
|
3983
|
+
}
|
|
3984
|
+
.ge-canvas.ge-editing [data-ge-hidden-in] {
|
|
3985
|
+
position: relative;
|
|
3986
|
+
}
|
|
3987
|
+
.ge-canvas.ge-editing [data-ge-hidden-in]::after {
|
|
3988
|
+
content: attr(data-ge-hidden-in);
|
|
3989
|
+
position: absolute;
|
|
3990
|
+
right: 2px;
|
|
3991
|
+
bottom: 2px;
|
|
3992
|
+
z-index: 1;
|
|
3993
|
+
padding: 0 4px;
|
|
3994
|
+
border-radius: 3px;
|
|
3995
|
+
background: rgba(0, 0, 0, 0.6);
|
|
3996
|
+
color: #fff;
|
|
3997
|
+
font-size: 10px;
|
|
3998
|
+
line-height: 16px;
|
|
3999
|
+
pointer-events: none;
|
|
4000
|
+
}
|
|
4001
|
+
/* The order plugin: a column ordered by class in this view says where */
|
|
4002
|
+
.ge-canvas.ge-editing .column[data-ge-order]::before {
|
|
4003
|
+
content: attr(data-ge-order);
|
|
4004
|
+
position: absolute;
|
|
4005
|
+
left: 2px;
|
|
4006
|
+
bottom: 2px;
|
|
4007
|
+
z-index: 1;
|
|
4008
|
+
padding: 0 4px;
|
|
4009
|
+
border-radius: 3px;
|
|
4010
|
+
background: rgba(23, 138, 204, 0.85);
|
|
4011
|
+
color: #fff;
|
|
4012
|
+
font-size: 10px;
|
|
4013
|
+
line-height: 16px;
|
|
4014
|
+
pointer-events: none;
|
|
4015
|
+
}
|
|
4016
|
+
/*
|
|
4017
|
+
* The gutters plugin. A row with gutter classes is drawn with its real
|
|
4018
|
+
* gutters rather than the editor's frame: each column padded by half the
|
|
4019
|
+
* horizontal gutter, and the vertical gutter above each column. Bootstrap
|
|
4020
|
+
* takes the first line's back with a negative top margin on the row, which
|
|
4021
|
+
* here would pull it over the row above, so the row's drawer takes it back
|
|
4022
|
+
* instead and the gap shows between lines of columns only.
|
|
4023
|
+
*/
|
|
4024
|
+
.ge-canvas.ge-editing .row.ge-gutters {
|
|
4025
|
+
margin-top: 0;
|
|
4026
|
+
}
|
|
4027
|
+
.ge-canvas.ge-editing .row.ge-gutters > .ge-tools-drawer {
|
|
4028
|
+
margin-top: 0;
|
|
4029
|
+
margin-bottom: calc(5px - var(--bs-gutter-y));
|
|
4030
|
+
/* Bootstrap pads every child of a row by half its gutter, the drawer
|
|
4031
|
+
too; it keeps the padding a row with no gutter class gives it */
|
|
4032
|
+
padding-left: 0.75rem;
|
|
4033
|
+
padding-right: 0.75rem;
|
|
4034
|
+
}
|
|
4035
|
+
.ge-canvas.ge-editing .row.ge-gutters > .column {
|
|
4036
|
+
padding-left: calc(var(--bs-gutter-x) * 0.5);
|
|
4037
|
+
padding-right: calc(var(--bs-gutter-x) * 0.5);
|
|
4038
|
+
}
|
|
4039
|
+
.ge-canvas.ge-editing .row.ge-gutters > .column > .ge-tools-drawer {
|
|
4040
|
+
margin-left: calc(var(--bs-gutter-x) * -0.5);
|
|
4041
|
+
margin-right: calc(var(--bs-gutter-x) * -0.5);
|
|
4042
|
+
width: calc(100% + var(--bs-gutter-x));
|
|
4043
|
+
}
|