@themarioga/grid-editor 4.1.0 → 5.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +131 -10
  3. package/UPGRADING.md +55 -0
  4. package/dist/grideditor.css +466 -0
  5. package/dist/grideditor.min.css +1 -1
  6. package/dist/grideditor.min.css.map +1 -1
  7. package/dist/jquery.grideditor.bundle.min.js +2 -2
  8. package/dist/jquery.grideditor.js +741 -126
  9. package/dist/jquery.grideditor.min.js +1 -1
  10. package/dist/jquery.grideditor.min.js.map +1 -1
  11. package/dist/locales/grideditor.es.js +30 -0
  12. package/dist/locales/grideditor.es.min.js +1 -1
  13. package/dist/locales/grideditor.es.min.js.map +1 -1
  14. package/dist/plugins/grideditor.clipboard.js +274 -0
  15. package/dist/plugins/grideditor.clipboard.min.js +2 -0
  16. package/dist/plugins/grideditor.clipboard.min.js.map +1 -0
  17. package/dist/plugins/grideditor.float.js +56 -0
  18. package/dist/plugins/grideditor.float.min.js +2 -0
  19. package/dist/plugins/grideditor.float.min.js.map +1 -0
  20. package/dist/plugins/grideditor.sections.js +199 -0
  21. package/dist/plugins/grideditor.sections.min.js +2 -0
  22. package/dist/plugins/grideditor.sections.min.js.map +1 -0
  23. package/dist/plugins/grideditor.textalign.js +60 -0
  24. package/dist/plugins/grideditor.textalign.min.js +2 -0
  25. package/dist/plugins/grideditor.textalign.min.js.map +1 -0
  26. package/docs/events.md +17 -3
  27. package/docs/locale-keys.md +49 -1
  28. package/docs/plugins.md +45 -3
  29. package/example/autocols.html +137 -0
  30. package/example/breakpoints.html +7 -5
  31. package/example/clipboard.html +99 -0
  32. package/example/index.html +24 -2
  33. package/example/utilities.html +22 -1
  34. package/example/wrap_content.html +66 -16
  35. package/package.json +1 -1
  36. package/src/js/jquery.grideditor.js +742 -127
  37. package/src/js/locales/grideditor.es.js +30 -0
  38. package/src/js/plugins/grideditor.clipboard.js +274 -0
  39. package/src/js/plugins/grideditor.float.js +56 -0
  40. package/src/js/plugins/grideditor.sections.js +199 -0
  41. package/src/js/plugins/grideditor.textalign.js +60 -0
  42. package/src/less/grideditor.less +138 -0
package/docs/events.md CHANGED
@@ -59,6 +59,7 @@ about every insertion can bind `grideditor:before-add` and switch on
59
59
  | `grideditor:before-utility` | — | yes | before a utility class is written, from the panel, a plugin's tool or `setUtility` |
60
60
  | `grideditor:after-utility` | — | no | after the class is written and the preview redrawn, only if something changed |
61
61
  | `grideditor:view-change` | — | no | after the view changes, only if it actually changed |
62
+ | `grideditor:after-copy` | — | no | with the clipboard plugin, after a node is copied |
62
63
 
63
64
  Two things here are not in the 3.0 specification's catalogue. The indent pair,
64
65
  because the indent tools are an operation like any other and announce
@@ -73,19 +74,24 @@ The payload
73
74
  {
74
75
  kind: 'row', // row | column | content | element
75
76
  // tabs | accordion | popup | tab | accordion-item
77
+ // section, with the sections plugin
76
78
  node: jQuery, // the node added, deleted, moved or resized
77
79
  parent: jQuery, // where it is going, or where it came from on a delete
78
80
  canvas: jQuery,
79
81
  breakpoint: 'lg', // the view at the time: a breakpoint key, or 'all'
80
- source: 'tool', // tool | api | dragdrop | panel
82
+ source: 'tool', // tool | api | dragdrop | panel (a width chosen in the panel)
81
83
 
82
84
  // move only
83
85
  from: { parent: jQuery, index: 2 },
84
86
  to: { parent: jQuery, index: 0 },
85
87
 
86
- // resize and indent only: units, not pixels
88
+ // resize and indent only: units, not pixels. A size can also be
89
+ // 'equal' or 'auto', and null when the width field chose "inherit"
87
90
  from: 6,
88
91
  to: 7,
92
+ cleared: [ // the all view only: the breakpoints' own sizes or
93
+ { breakpoint: 'md', value: 4 }, // offsets, which the write took off
94
+ ],
89
95
 
90
96
  // a pane inside a container
91
97
  container: jQuery,
@@ -104,6 +110,12 @@ The payload
104
110
  }
105
111
  ```
106
112
 
113
+ A section's width change is announced as a utility change too, with
114
+ `family: 'section'`, `breakpoint: 'all'` and the widths - `'fixed'`, `'fluid'`,
115
+ `'md'` - as `from` and `to`: a section has one container class, whatever the
116
+ breakpoint. Adding a section fires `before-add-section` and `after-add-section`,
117
+ with the generic pair.
118
+
107
119
  `view-change` carries no node: its payload is `canvas`, `breakpoint` (the new
108
120
  view), `from` and `to`. A utility's `breakpoint` is the view it was written
109
121
  in, which `setUtility` can be asked to make a different one from the view on
@@ -111,7 +123,9 @@ screen, and its `source` is `panel`, `tool` or `api`.
111
123
 
112
124
  `source` matters to a host that both drives the editor from its own palette and
113
125
  listens for what the user does: `api` is your own call coming back to you,
114
- `tool` is a click in the editor, `dragdrop` is a gesture.
126
+ `tool` is a click in the editor, `dragdrop` is a gesture, and `paste` is a node
127
+ the clipboard plugin put in, from a paste tool or the toolbar. A paste is an add
128
+ like any other, so canceling its `before-add-*` turns it away.
115
129
 
116
130
  `kind: 'content'` appears when a content area itself is dragged between
117
131
  columns. The kinds for containers are the container's own type, so a listener
@@ -30,6 +30,8 @@ The tools in a drawer, and the buttons in the toolbar above the canvas.
30
30
  | `tool.add_row` | Add row | Column drawer, adds a nested row |
31
31
  | `tool.add_column` | Add column\n(hold to choose the width) | Row drawer. A click adds a column, holding the tool offers the widths. Two lines |
32
32
  | `tool.column_size` | {size} of 12 | Tooltip of a width in that picker |
33
+ | `tool.column_equal` | Equal: shares what the row has left | The `equal` choice in that picker, which adds a `col` |
34
+ | `tool.column_auto` | Auto: as wide as its content | The `auto` choice in that picker, which adds a `col-auto` |
33
35
  | `tool.delete_row` | Remove row | Row drawer |
34
36
  | `tool.delete_column` | Remove col | Column drawer |
35
37
  | `tool.delete_element` | Remove element | Element drawer |
@@ -57,6 +59,7 @@ row.*
57
59
  | Key | English | Where |
58
60
  | --- | --- | --- |
59
61
  | `row.add` | Add row {layout} | Tooltip of each toolbar add-row button. `{layout}` is the column layout, as in `6-6` |
62
+ | `row.add_row_cols` | Add a row of {columns} columns, {counts} per row | Tooltip of a toolbar button for a `{ row_cols, columns }` layout. `{counts}` reads like `1, md: 3` |
60
63
 
61
64
 
62
65
  container.*
@@ -80,6 +83,36 @@ The containers: tabs, accordions and popups, and the panes inside them.
80
83
  | `container.card_footer` | Card footer | Text of a new card's footer, when it has one |
81
84
 
82
85
 
86
+ section.*
87
+ ---------
88
+
89
+ The sections plugin: Bootstrap's `.container` and its kin, on the canvas.
90
+
91
+ | Key | English | Where |
92
+ | --- | --- | --- |
93
+ | `section.add` | Section | Toolbar button that adds a section |
94
+ | `section.width` | Width | Label of a section's width field, in its settings panel |
95
+ | `section.fixed` | Fixed | Its choice for `container` |
96
+ | `section.fluid` | Full width | Its choice for `container-fluid` |
97
+ | `section.from` | Fixed from {breakpoint} | Its choice for `container-{bp}`. `{breakpoint}` is the key |
98
+ | `tool.add_row_to_section` | Add row | Section drawer, adds a row to the section |
99
+ | `tool.delete_section` | Remove section | Section drawer |
100
+ | `confirm.delete_section` | Delete this section and everything in it? | Asked before a section is deleted |
101
+
102
+
103
+ clipboard.*
104
+ -----------
105
+
106
+ The clipboard plugin: copy and paste.
107
+
108
+ | Key | English | Where |
109
+ | --- | --- | --- |
110
+ | `tool.copy` | Copy | Row, column, section, container and element drawers |
111
+ | `tool.paste` | Paste | Column, row and section drawers, while something that fits there is copied |
112
+ | `clipboard.paste_row` | Paste row | Toolbar button, while a row is copied |
113
+ | `clipboard.paste_section` | Paste section | Toolbar button, while a section is copied |
114
+
115
+
83
116
  confirm.*
84
117
  ---------
85
118
 
@@ -113,7 +146,7 @@ key, so a locale covers a new breakpoint by adding `view.<key>`. Short strings
113
146
 
114
147
  | Key | English | Where |
115
148
  | --- | --- | --- |
116
- | `view.all` | All sizes | The default view, which writes every breakpoint at once |
149
+ | `view.all` | All sizes | The default view, which writes one class for every breakpoint |
117
150
  | `view.xs` | Phone | Layout mode writing `col-*` and `offset-*` |
118
151
  | `view.sm` | Tablet | Layout mode writing `col-sm-*` and `offset-sm-*` |
119
152
  | `view.md` | Small desktop | Layout mode writing `col-md-*` and `offset-md-*` |
@@ -131,6 +164,11 @@ The labels of each utility and its values are the plugins' own keys.
131
164
  | Key | English | Where |
132
165
  | --- | --- | --- |
133
166
  | `utility.section` | Responsive: {view} | The section's fold toggle. `{view}` is the label of the view being edited |
167
+ | `utility.col_width` | Width | The column width field, in a column's Responsive section |
168
+ | `utility.col_equal` | Equal | Its choice for `col` / `col-{bp}` |
169
+ | `utility.col_auto` | Auto | Its choice for `col-auto` / `col-{bp}-auto` |
170
+ | `utility.col_from_row` | From the row: {count} | The width field's empty choice when the row's row-cols sizes the column. `{count}` is `badge.row_cols` |
171
+ | `utility.row_cols` | Columns per row | The row-cols field, in a row's Responsive section |
134
172
  | `utility.default` | Default | The empty choice of a field when nothing below the view sets the utility, and always in the all view |
135
173
  | `utility.inherit` | Inherit: {value} (from {breakpoint}) | The empty choice in a breakpoint view when a smaller breakpoint sets the utility. `{breakpoint}` is its key, `sm` |
136
174
  | `utility.varies` | Changes at {breakpoints}; choosing here replaces that | Note under a field in the all view when breakpoints set their own value. `{breakpoints}` is a list of keys |
@@ -159,6 +197,14 @@ The labels of each utility and its values are the plugins' own keys.
159
197
  | `utility.side_b` | Bottom | The side of `pb-*` and `mb-*` |
160
198
  | `utility.side_s` | Start | The side of `ps-*` and `ms-*` |
161
199
  | `utility.side_e` | End | The side of `pe-*` and `me-*` |
200
+ | `utility.text_align` | Text alignment | Label of the textalign plugin's field |
201
+ | `utility.text_start` | Start | Its choice for `text-*-start` |
202
+ | `utility.text_center` | Center | Its choice for `text-*-center` |
203
+ | `utility.text_end` | End | Its choice for `text-*-end` |
204
+ | `utility.float` | Float | Label of the float plugin's field, on an element |
205
+ | `utility.float_start` | Start | Its choice for `float-*-start` |
206
+ | `utility.float_end` | End | Its choice for `float-*-end` |
207
+ | `utility.float_none` | None | Its choice for `float-*-none` |
162
208
  | `utility.spacing_gutter` | A column's side padding is its gutter: changing it changes the gutter | Note in a column's spacing group while it carries side padding |
163
209
 
164
210
 
@@ -171,6 +217,8 @@ markup `getHtml` returns.
171
217
  | Key | English | Where |
172
218
  | --- | --- | --- |
173
219
  | `badge.hidden_in` | Hidden at {breakpoints} | Corner of a node hidden at some breakpoints, in the all view. `{breakpoints}` is a list of keys |
220
+ | `badge.row_cols` | {count} per row | Corner of a row whose row-cols sizes its columns in the view being edited |
221
+ | `badge.row_cols_auto` | As wide as their content | The same, for `row-cols-auto` |
174
222
  | `badge.order` | Order: {value} | Corner of a column ordered by class in the view being edited |
175
223
 
176
224
 
package/docs/plugins.md CHANGED
@@ -107,7 +107,7 @@ not change without a major version.
107
107
  | `ge.createMoveTool(drawer)` | The drag handle, unless `drag_handle` says the whole drawer is one |
108
108
  | `ge.addSettingsTool(drawer, node, presets)` | The gear, and the id and class panel it opens |
109
109
  | `ge.deleteNode(kind, node, confirmText, animate)` | Remove a node: ask, animate, announce |
110
- | `ge.place(node, kind, options)` | Put a created node where `appendTo` and friends say, through the add events |
110
+ | `ge.place(node, kind, options)` | Put a created node where `appendTo` and friends say, through the add events. `options.source` is the payload's `source`, `api` by default |
111
111
  | `ge.createPaneControls(pane, kind, hostTools, confirmText, remove)` | The drawer a pane gets: move, the host's tools, delete |
112
112
  | `ge.makeLabelEditable(label)` | Rename in place, with the Bootstrap toggle suspended while typing |
113
113
  | `ge.labelIn(button)` | The label span inside a button, wrapped if it is not already |
@@ -118,11 +118,15 @@ not change without a major version.
118
118
  | `ge.operate(body)` | Run `body` as one operation, so a handler calling back in is queued |
119
119
  | `ge.kindOf(node)` | What an event calls a node: `row`, `column`, `element`, a container's type… |
120
120
  | `ge.view()` | The view being edited: a breakpoint key, or `'all'` |
121
- | `ge.viewTiers()` | The breakpoint keys that view writes: one, or all six |
121
+ | `ge.viewTiers()` | The breakpoint key that view writes: the one being edited, or `xs` - the class with no breakpoint - in the all view |
122
122
  | `ge.breakpoints` | Every breakpoint key, smallest first |
123
123
  | `ge.getUtility(node, family, view?)` | A utility's value, as in the public method |
124
124
  | `ge.setUtility(node, family, value, options?)` | Write one through the events. `options` is a view key or `{ view, source }` |
125
125
  | `ge.utilityField(node, family)` | A panel field for one family, for a plugin that builds its own panel |
126
+ | `ge.rowFromLayout(layout)` | A detached row from a layout: `[8, 4]`, `['auto', 'equal']` or `{ row_cols, columns }` |
127
+ | `ge.nodeHtml(node)` | One node's markup as `getHtml` would give it. The canvas leaves editing to read it and comes back, as it does for `getHtml` |
128
+ | `ge.toolbarItems(name)` | The toolbar buttons the feature plugin `name` declared, for showing and hiding them |
129
+ | `ge.bareStyle(node, family, property)` | A css property's value on the node with none of the family's classes: what a preview shows when no class applies and that is not a constant |
126
130
 
127
131
  The add, delete and move events for a container and its panes are fired by the
128
132
  editor, not by the plugin: `createPaneControls` handles a pane's delete, and
@@ -143,10 +147,36 @@ $.fn.gridEditor.features.elements = function(ge) {
143
147
  onDeinit: function() { … }, // every deinit: take it out again
144
148
  onContentReady: function(area) { … }, // a rich text editor just took over
145
149
  onSortable: function(sortable) { … }, // declare your own sortable lists
150
+ blocks: '.ge-section', // more blocks the canvas and the columns move
151
+ regions: '.ge-section', // more lists those blocks move in
152
+ accepts: function(region, node) { … }, // false turns a block away from a region
153
+ toolbar: [{ labelKey: …, kind: …, create: function() { … } }], // buttons beside the containers'
154
+ drawerTools: function(drawer, node, kind) { … }, // tools beside the gear, in every drawer
146
155
  };
147
156
  };
148
157
  ```
149
158
 
159
+ The last four are what the sections plugin is made of, and what a plugin
160
+ needs to put a new kind of block on the canvas:
161
+
162
+ - **`blocks`** is a selector added to what the canvas and every column move -
163
+ rows, content areas and containers, the editor's own blocks.
164
+ - **`regions`** is a selector for more lists those blocks move in, in the same
165
+ group, so a row dragged from the canvas can land in one.
166
+ - **`accepts(region, node)`** can turn a block away from a list: `false` and the
167
+ drag will not drop it there, whoever's block and whoever's list. With none of
168
+ these hooks, every block goes everywhere, as before.
169
+ - **`toolbar`** adds buttons beside the containers'. A click appends what
170
+ `create()` returns to the canvas, announced as `kind`; a drop puts it where it
171
+ was dropped, or, when that region will not have it, on the canvas just after
172
+ the block it was dropped in.
173
+
174
+ - **`drawerTools(drawer, node, kind)`** runs for every drawer that has a gear,
175
+ as a utility plugin's does, so a tool can go on any node. The clipboard
176
+ plugin puts its copy and paste tools in with it.
177
+ - A **`toolbar`** item can also have an `iconClass`, `bi bi-plus` otherwise,
178
+ and a `source` for the add events, `tool` or `dragdrop` otherwise.
179
+
150
180
  - **`onSortable(sortable)`** is handed the function the editor makes all of its
151
181
  own lists with. A plugin describes a list; it never touches the drag toolkit
152
182
  itself, which is what keeps `drag_handle`, the cancel selector and the move
@@ -208,6 +238,8 @@ $.fn.gridEditor.utilities.order = function(ge) {
208
238
  label: function(value) { … }, // an option's text, optional: the value itself otherwise
209
239
  choices: function(node, kind) { … }, // what to offer this node, optional: every value otherwise
210
240
  panel: false, // optional: no field of its own, see "A panel of your own"
241
+ className: function(breakpoint, value) { … }, // optional, for classes not spelled {prefix}-{bp}-{value}
242
+ write: function(node, value, view, source) { … }, // optional, a write that is some other operation
211
243
  preview: function(value, node, kind) { // what the value looks like, see below
212
244
  return { order: value === null ? 0 : value };
213
245
  },
@@ -239,7 +271,10 @@ What the editor does with a family:
239
271
  breakpoint view each node that carries a family's class gets
240
272
  `preview(value)` — the value that applies there, or `null` — as inline
241
273
  `!important` styles. Return what `null` looks like too: a wider breakpoint's
242
- class is still live in a wide window and has to be overruled. The all view
274
+ class is still live in a wide window and has to be overruled. When what
275
+ `null` looks like depends on the page — `text-align` inherits, the host's
276
+ css may float an element — `ge.bareStyle(node, family, property)` asks the
277
+ browser. Parents are previewed before their children. The all view
243
278
  previews nothing, since every breakpoint there is live and what Bootstrap
244
279
  shows is the truth. The styles come off on `deinit`, leaving the host's own
245
280
  `style` as it was, so `getHtml` never sees them.
@@ -275,6 +310,13 @@ set the top padding. A plugin-level `preview(node, kind, breakpoint)` is called
275
310
  for every node in a breakpoint view, after the families' own, and returns the
276
311
  styles for the node or an empty object.
277
312
 
313
+ Two escape hatches, which the column width uses: `className(breakpoint,
314
+ value)` spells the classes of a family that does not follow the pattern
315
+ (`col`, `col-md`, `col-md-auto`), and `write(node, value, view, source)` does a
316
+ write some other way than a utility change - the width field's writes are
317
+ resizes, through the resize events. The editor still checks the value and the
318
+ node before it calls `write`.
319
+
278
320
  Two plugins cannot declare the same family name: the second one is ignored,
279
321
  with a warning.
280
322
 
@@ -0,0 +1,137 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+
6
+ <!-- CSS dependencies -->
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.css">
9
+
10
+ <!-- Javascript dependencies -->
11
+ <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
13
+
14
+ <!-- Grid editor CSS -->
15
+ <link rel="stylesheet" type="text/css" href="../dist/grideditor.css" />
16
+
17
+ <!-- The editor, and the sections plugin: equal and auto sizes and
18
+ columns per row are the editor's own, sections are a plugin -->
19
+ <script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.6/Sortable.min.js"></script>
20
+ <script src="../dist/jquery.grideditor.min.js"></script>
21
+ <script src="../dist/plugins/grideditor.sections.min.js"></script>
22
+
23
+ <script>
24
+ $(function() {
25
+ $('#myGrid').gridEditor({
26
+ content_types: [],
27
+
28
+ // Sizes are numbers, 'equal' (col) or 'auto' (col-auto), and a
29
+ // layout can be a row with columns per row
30
+ new_row_layouts: [
31
+ [12], [6, 6], ['auto', 'equal'], ['equal', 'equal', 'equal'],
32
+ { row_cols: { xs: 1, sm: 2, lg: 4 }, columns: 4 },
33
+ ],
34
+
35
+ default_view: 'lg',
36
+ });
37
+
38
+ // A width chosen anywhere - tools, edge, panel - is a resize
39
+ $('#myGrid').on('grideditor:after-resize', function(e, payload) {
40
+ $('#last').text('width at ' + payload.breakpoint + ': ' +
41
+ (payload.from === null ? 'from the row' : payload.from) + ' → ' +
42
+ (payload.to === null ? 'inherit' : payload.to) +
43
+ (payload.cleared && payload.cleared.length ? ' (took off ' + payload.cleared.map(function(entry) {
44
+ return entry.breakpoint;
45
+ }).join(', ') + ')' : ''));
46
+ });
47
+
48
+ $('#output').on('click', function() {
49
+ $('#html').text($('#myGrid').gridEditor('getHtml'));
50
+ });
51
+ });
52
+ </script>
53
+
54
+ <title>Grid Editor column sizes and sections example</title>
55
+ </head>
56
+ <body>
57
+ <!-- Back to the demo index -->
58
+ <div class="container pt-3">
59
+ <a class="link-secondary" href="index.html"><i class="bi bi-arrow-left"></i> All demos</a>
60
+ </div>
61
+
62
+
63
+ <div class="container-fluid px-4">
64
+
65
+ <div class="row my-3">
66
+ <div class="col-lg-8">
67
+ <h1 class="h4">Column sizes, columns per row, and sections</h1>
68
+ <p class="form-text">
69
+ <strong>Equal and auto.</strong> A column is a number of
70
+ twelfths, <em>equal</em> (<code>col</code>: an equal share
71
+ of what the row has left) or <em>auto</em>
72
+ (<code>col-auto</code>: as wide as its content), at each
73
+ breakpoint. Every size is in the <em>Width</em> field of a
74
+ column's settings, under Responsive; the width tools and
75
+ dragging an edge turn an equal or auto column into a
76
+ number, starting from the width it has.
77
+ </p>
78
+ <p class="form-text">
79
+ <strong>Columns per row.</strong> A row's
80
+ <em>Columns per row</em> field shares the line out among
81
+ the columns that have no size of their own. The second
82
+ section's cards are one per line on phones, two on
83
+ tablets, four on desktops.
84
+ </p>
85
+ <p class="form-text">
86
+ <strong>Sections.</strong> Bootstrap's containers, grouping
87
+ rows. Drag rows in and out of them, choose their width in
88
+ their settings, and switch views to see each one as wide
89
+ as its container would be. <strong>All sizes</strong>
90
+ writes one class for every size.
91
+ </p>
92
+ <p class="form-text">Last width change: <span id="last">none yet</span></p>
93
+ <button class="btn btn-sm btn-secondary" id="output" type="button">Show the html this produces</button>
94
+ <pre id="html" class="form-text"></pre>
95
+ </div>
96
+ </div>
97
+
98
+ <div id="myGrid">
99
+
100
+ <div class="container">
101
+ <div class="row">
102
+ <div class="col-auto">
103
+ <h2 class="h5">Auto</h2>
104
+ <p>As wide as this.</p>
105
+ </div>
106
+ <div class="col">
107
+ <h2 class="h5">Equal</h2>
108
+ <p>Takes what the auto column leaves.</p>
109
+ </div>
110
+ <div class="col-3">
111
+ <h2 class="h5">Three</h2>
112
+ <p>A fixed quarter.</p>
113
+ </div>
114
+ </div>
115
+ </div>
116
+
117
+ <div class="container-lg">
118
+ <div class="row row-cols-1 row-cols-sm-2 row-cols-lg-4">
119
+ <div class="col"><h2 class="h6">Card one</h2><p>Shared out by the row.</p></div>
120
+ <div class="col"><h2 class="h6">Card two</h2><p>Shared out by the row.</p></div>
121
+ <div class="col"><h2 class="h6">Card three</h2><p>Shared out by the row.</p></div>
122
+ <div class="col"><h2 class="h6">Card four</h2><p>Shared out by the row.</p></div>
123
+ </div>
124
+ </div>
125
+
126
+ <div class="row">
127
+ <div class="col-12">
128
+ <h2 class="h5">A row outside any section</h2>
129
+ <p>Full width of the canvas. Drag it into one of the sections above.</p>
130
+ </div>
131
+ </div>
132
+
133
+ </div> <!-- /#myGrid -->
134
+ </div> <!-- /.container-fluid -->
135
+
136
+ </body>
137
+ </html>
@@ -23,9 +23,10 @@
23
23
  new_row_layouts: [[12], [6,6], [4,4,4], [8,4]],
24
24
  content_types: [],
25
25
 
26
- // The default: every size and offset change is written to all
27
- // six breakpoints at once. Switch the dropdown to a single
28
- // breakpoint to tune that one on its own.
26
+ // The default: a size or offset change is written once, as the
27
+ // class with no breakpoint, and replaces what the breakpoints
28
+ // said. Switch the dropdown to a single breakpoint to tune
29
+ // that one on its own.
29
30
  default_view: 'all',
30
31
 
31
32
  // A host that wants the old three-mode feel can offer three
@@ -55,8 +56,9 @@
55
56
  <p class="form-text">
56
57
  The dropdown on the right of the toolbar picks the layout
57
58
  mode. In <strong>All sizes</strong> the canvas renders as
58
- the browser would, and the width and indent tools write
59
- every breakpoint at once. Pick a single breakpoint and the
59
+ the browser would, and the width and indent tools write one
60
+ class for every size (<code>col-4</code>), replacing what
61
+ the breakpoints had. Pick a single breakpoint and the
60
62
  canvas narrows to that tier's width, that tier's classes
61
63
  become the effective ones whatever your window is doing,
62
64
  and the tools write only that tier.
@@ -0,0 +1,99 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+
6
+ <!-- CSS dependencies -->
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.css">
9
+
10
+ <!-- Javascript dependencies -->
11
+ <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
13
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.6/tinymce.min.js"></script>
14
+
15
+ <!-- Grid editor CSS -->
16
+ <link rel="stylesheet" type="text/css" href="../dist/grideditor.css" />
17
+ <!-- Grid editor javascript -->
18
+ <script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.6/Sortable.min.js"></script>
19
+ <script src="../dist/jquery.grideditor.min.js"></script>
20
+ <!-- Copy and paste is a plugin of its own. The others are here so there
21
+ is a bit of everything to copy. -->
22
+ <script src="../dist/plugins/grideditor.clipboard.min.js"></script>
23
+ <script src="../dist/plugins/grideditor.sections.min.js"></script>
24
+ <script src="../dist/plugins/grideditor.tabs.min.js"></script>
25
+ <script src="../dist/plugins/grideditor.accordion.min.js"></script>
26
+ <script src="../dist/plugins/grideditor.elements.min.js"></script>
27
+
28
+ <script>
29
+ $(function() {
30
+ var settings = {
31
+ new_row_layouts: [[12], [6, 6], [4, 4, 4]],
32
+ content_types: ['tinymce'],
33
+ };
34
+
35
+ $('#myGrid').gridEditor(settings);
36
+ $('#otherGrid').gridEditor(settings);
37
+
38
+ // A paste is an add like any other, with source 'paste'
39
+ $('#myGrid, #otherGrid').on('grideditor:after-add', function(e, payload) {
40
+ if (payload.source === 'paste') {
41
+ $('#log').text('Pasted a ' + payload.kind + ' into ' + e.currentTarget.id);
42
+ }
43
+ });
44
+ });
45
+ </script>
46
+
47
+ <title>Grid Editor example - copy and paste</title>
48
+ </head>
49
+ <body>
50
+ <!-- Back to the demo index -->
51
+ <div class="container pt-3">
52
+ <a class="link-secondary" href="index.html"><i class="bi bi-arrow-left"></i> All demos</a>
53
+ </div>
54
+
55
+ <div class="container py-3">
56
+ <h2>Copy and paste</h2>
57
+ <p class="text-body-secondary">
58
+ Every row, column, section, container and element has a
59
+ <i class="bi bi-copy"></i> copy tool in its drawer. Once something
60
+ is copied, a <i class="bi bi-clipboard-plus"></i> paste tool shows
61
+ wherever it can go: a row into a column or a section, a column into
62
+ a row, a container or an element into a column. Rows and sections
63
+ also get a <em>Paste</em> button in the toolbar, which can be
64
+ clicked or dragged to where the copy should land.
65
+ </p>
66
+ <p class="text-body-secondary">
67
+ What is copied is kept in the browser, so it can be pasted in the
68
+ other editor, after a reload, or in this page open in another tab.
69
+ <span id="log" class="fw-semibold"></span>
70
+ </p>
71
+
72
+ <h5 class="mt-4">One editor</h5>
73
+ <div id="myGrid">
74
+ <div class="row" id="intro">
75
+ <div class="col-lg-6">
76
+ <h3>Copy this row</h3>
77
+ <p>Then paste it into a column below, or into the other editor. Its id is renamed in the copy, so <a href="#intro">links to it</a> keep working.</p>
78
+ </div>
79
+ <div class="col-lg-6">
80
+ <blockquote data-ge-element="quote">An element: copy it into another column.</blockquote>
81
+ </div>
82
+ </div>
83
+ <div class="row">
84
+ <div class="col-lg-4"><p>A column to paste into.</p></div>
85
+ <div class="col-lg-4"><p>Another one.</p></div>
86
+ <div class="col-lg-4"><p>And a third.</p></div>
87
+ </div>
88
+ </div>
89
+
90
+ <h5 class="mt-4">Another editor</h5>
91
+ <div id="otherGrid">
92
+ <div class="row">
93
+ <div class="col-lg-12"><p>Paste here what you copied above.</p></div>
94
+ </div>
95
+ </div>
96
+ </div>
97
+
98
+ </body>
99
+ </html>
@@ -31,7 +31,13 @@
31
31
  editor and SortableJS in one file.
32
32
  </p>
33
33
  <p class="text-body-secondary">
34
- New in 4.1: utility plugins, which edit Bootstrap's responsive
34
+ New in 5.0: equal and auto columns, columns per row, and sections
35
+ for Bootstrap's containers &mdash; see
36
+ <a href="autocols.html">Column sizes and sections</a>. The
37
+ <em>All sizes</em> view now writes one class for every size.
38
+ </p>
39
+ <p class="text-body-secondary">
40
+ Since 4.1: utility plugins, which edit Bootstrap's responsive
35
41
  utility classes &mdash; visibility, column order, alignment,
36
42
  gutters and spacing &mdash; per breakpoint. See
37
43
  <a href="utilities.html">Responsive utilities</a>.
@@ -79,12 +85,20 @@
79
85
  <span class="text-body-secondary">The six breakpoints, the &ldquo;all sizes&rdquo; view, and resizing by dragging</span>
80
86
  </a>
81
87
 
88
+ <a class="list-group-item list-group-item-action" href="autocols.html">
89
+ <div class="d-flex justify-content-between">
90
+ <strong>Column sizes and sections</strong>
91
+ <code class="text-body-secondary">autocols.html</code>
92
+ </div>
93
+ <span class="text-body-secondary">Equal and auto columns, columns per row, and Bootstrap's containers as sections</span>
94
+ </a>
95
+
82
96
  <a class="list-group-item list-group-item-action" href="utilities.html">
83
97
  <div class="d-flex justify-content-between">
84
98
  <strong>Responsive utilities</strong>
85
99
  <code class="text-body-secondary">utilities.html</code>
86
100
  </div>
87
- <span class="text-body-secondary">Bootstrap's utility classes edited per breakpoint: visibility, column order, alignment, gutters and spacing</span>
101
+ <span class="text-body-secondary">Bootstrap's utility classes edited per breakpoint: visibility, column order, alignment, gutters, spacing, text alignment and float</span>
88
102
  </a>
89
103
 
90
104
  <a class="list-group-item list-group-item-action" href="locale.html">
@@ -111,6 +125,14 @@
111
125
  <span class="text-body-secondary">The same, with summernote</span>
112
126
  </a>
113
127
 
128
+ <a class="list-group-item list-group-item-action" href="clipboard.html">
129
+ <div class="d-flex justify-content-between">
130
+ <strong>Copy and paste</strong>
131
+ <code class="text-body-secondary">clipboard.html</code>
132
+ </div>
133
+ <span class="text-body-secondary">Copying a row, a column or a container and pasting it somewhere else, in this editor or another</span>
134
+ </a>
135
+
114
136
  <a class="list-group-item list-group-item-action" href="wrap_content.html">
115
137
  <div class="d-flex justify-content-between">
116
138
  <strong>Wrapped content</strong>
@@ -23,6 +23,10 @@
23
23
  <script src="../dist/plugins/grideditor.alignment.min.js"></script>
24
24
  <script src="../dist/plugins/grideditor.gutters.min.js"></script>
25
25
  <script src="../dist/plugins/grideditor.spacing.min.js"></script>
26
+ <script src="../dist/plugins/grideditor.textalign.min.js"></script>
27
+ <!-- Float works on elements, so the elements plugin comes first -->
28
+ <script src="../dist/plugins/grideditor.elements.min.js"></script>
29
+ <script src="../dist/plugins/grideditor.float.min.js"></script>
26
30
 
27
31
  <script>
28
32
  $(function() {
@@ -101,6 +105,13 @@
101
105
  every panel, each a side and a value. The centred column
102
106
  below gets more padding from small desktop up.
103
107
  </p>
108
+ <p class="form-text">
109
+ <strong>Text alignment:</strong> a field in every panel.
110
+ The centred column's text is centred from small desktop
111
+ up. <strong>Float:</strong> a field in an element's panel;
112
+ the quote in the last row floats to the end from tablet up,
113
+ with the text flowing round it.
114
+ </p>
104
115
  <p class="form-text">Last change: <span id="last">none yet</span></p>
105
116
  <button class="btn btn-sm btn-secondary" id="output" type="button">Show the html this produces</button>
106
117
  <pre id="html" class="form-text"></pre>
@@ -132,12 +143,22 @@
132
143
  </div>
133
144
 
134
145
  <div class="row justify-content-md-center">
135
- <div class="col-12 col-md-6 py-2 py-md-4">
146
+ <div class="col-12 col-md-6 py-2 py-md-4 text-md-center">
136
147
  <h2 class="h5">Centred</h2>
137
148
  <p>Its row has <code>justify-content-md-center</code>, and it has <code>py-2 py-md-4</code>.</p>
138
149
  </div>
139
150
  </div>
140
151
 
152
+ <div class="row">
153
+ <div class="col-12">
154
+ <blockquote data-ge-element="quote" data-ge-label="Pull quote" class="float-sm-end ms-sm-3 p-3 border-start border-4">
155
+ A floated element, <code>float-sm-end</code>.
156
+ </blockquote>
157
+ <p>The text of the content area flows round the quote from tablet up, and runs under it on phones, where it does not float. Switch between Phone and Tablet in the dropdown to see it move, or choose another float in the element's panel.</p>
158
+ <p>A second paragraph, so there is enough text to flow.</p>
159
+ </div>
160
+ </div>
161
+
141
162
  </div> <!-- /#myGrid -->
142
163
  </div> <!-- /.container -->
143
164