@themarioga/grid-editor 4.1.0 → 5.0.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 (36) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +68 -8
  3. package/UPGRADING.md +55 -0
  4. package/dist/grideditor.css +461 -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 +634 -109
  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 +26 -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.float.js +56 -0
  15. package/dist/plugins/grideditor.float.min.js +2 -0
  16. package/dist/plugins/grideditor.float.min.js.map +1 -0
  17. package/dist/plugins/grideditor.sections.js +199 -0
  18. package/dist/plugins/grideditor.sections.min.js +2 -0
  19. package/dist/plugins/grideditor.sections.min.js.map +1 -0
  20. package/dist/plugins/grideditor.textalign.js +60 -0
  21. package/dist/plugins/grideditor.textalign.min.js +2 -0
  22. package/dist/plugins/grideditor.textalign.min.js.map +1 -0
  23. package/docs/events.md +13 -2
  24. package/docs/locale-keys.md +36 -1
  25. package/docs/plugins.md +35 -2
  26. package/example/autocols.html +137 -0
  27. package/example/breakpoints.html +7 -5
  28. package/example/index.html +16 -2
  29. package/example/utilities.html +22 -1
  30. package/package.json +1 -1
  31. package/src/js/jquery.grideditor.js +635 -110
  32. package/src/js/locales/grideditor.es.js +26 -0
  33. package/src/js/plugins/grideditor.float.js +56 -0
  34. package/src/js/plugins/grideditor.sections.js +199 -0
  35. package/src/js/plugins/grideditor.textalign.js +60 -0
  36. package/src/less/grideditor.less +132 -0
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Sections for grid-editor.
3
+ *
4
+ * A feature plugin: load this file after the editor and the canvas can hold
5
+ * sections - Bootstrap's .container, .container-fluid and .container-{bp} -
6
+ * each grouping rows at a width of its own. What it can ask the editor for is
7
+ * the handle its factory is called with, described in docs/plugins.md.
8
+ *
9
+ * <script src="dist/jquery.grideditor.min.js"></script>
10
+ * <script src="dist/plugins/grideditor.sections.min.js"></script>
11
+ *
12
+ * Called sections, not containers, because a container is what the tabs,
13
+ * accordion, popup and card plugins make. A section is recognised by its
14
+ * Bootstrap class alone, and only as a child of the canvas: a .container
15
+ * somewhere inside an element's markup is that element's business.
16
+ *
17
+ * sections.widths narrows the widths the field offers.
18
+ */
19
+ (function($) {
20
+
21
+ $.extend($.fn.gridEditor.locales.en, {
22
+ 'section.add': 'Section',
23
+ 'section.width': 'Width',
24
+ 'section.fixed': 'Fixed',
25
+ 'section.fluid': 'Full width',
26
+ 'section.from': 'Fixed from {breakpoint}',
27
+ 'tool.add_row_to_section': 'Add row',
28
+ 'tool.delete_section': 'Remove section',
29
+ 'confirm.delete_section': 'Delete this section and everything in it?',
30
+ });
31
+
32
+ /** Each width, and the class that gives it. */
33
+ var WIDTHS = {
34
+ fixed: 'container',
35
+ fluid: 'container-fluid',
36
+ sm: 'container-sm',
37
+ md: 'container-md',
38
+ lg: 'container-lg',
39
+ xl: 'container-xl',
40
+ xxl: 'container-xxl',
41
+ };
42
+
43
+ var ORDER = ['fixed', 'sm', 'md', 'lg', 'xl', 'xxl', 'fluid'];
44
+
45
+ $.fn.gridEditor.features.sections = function(ge) {
46
+
47
+ var options = $.extend({ widths: ORDER }, ge.settings.sections);
48
+
49
+ function widthOf(section) {
50
+ var found = null;
51
+
52
+ $.each(WIDTHS, function(width, className) {
53
+ if (!found && section.hasClass(className)) { found = width; }
54
+ });
55
+
56
+ return found;
57
+ }
58
+
59
+ function isSection(node) {
60
+ return node.parent()[0] === ge.canvas[0] && widthOf(node) !== null;
61
+ }
62
+
63
+ function sections() {
64
+ return ge.canvas.children().filter(function() { return isSection($(this)); });
65
+ }
66
+
67
+ function label(width) {
68
+ if (width === 'fixed') { return ge.t('section.fixed'); }
69
+ if (width === 'fluid') { return ge.t('section.fluid'); }
70
+
71
+ return ge.t('section.from', { breakpoint: width });
72
+ }
73
+
74
+ /**
75
+ * Change a section's width, announced like a utility: the width is its
76
+ * one container class, the same at every breakpoint.
77
+ */
78
+ function setWidth(section, width, source) {
79
+ var from = widthOf(section);
80
+ if (from === width || !WIDTHS[width]) { return false; }
81
+
82
+ return ge.operate(function() {
83
+ var payload = ge.payloadFor('section', section, {
84
+ family: 'section',
85
+ breakpoint: 'all',
86
+ tiers: [],
87
+ from: from,
88
+ to: width,
89
+ source: source || 'api',
90
+ });
91
+
92
+ if (!ge.emit('before-utility', payload)) {
93
+ section.find('> .ge-tools-drawer .ge-section-width select').val(from);
94
+ return false;
95
+ }
96
+
97
+ section.removeClass(WIDTHS[from]).addClass(WIDTHS[width]);
98
+ ge.emit('after-utility', payload);
99
+
100
+ return true;
101
+ });
102
+ }
103
+
104
+ function widthField(section) {
105
+ var select = $('<select />');
106
+ var current = widthOf(section);
107
+ var offered = options.widths.indexOf(current) === -1 ? options.widths.concat([current]) : options.widths;
108
+
109
+ ORDER.forEach(function(width) {
110
+ if (offered.indexOf(width) === -1) { return; }
111
+ $('<option />').attr('value', width).text(label(width)).appendTo(select);
112
+ });
113
+
114
+ select.val(current).on('change', function() { setWidth(section, this.value, 'panel'); });
115
+
116
+ return $('<label class="ge-utility ge-section-width" />')
117
+ .append($('<span class="ge-utility-label" />').text(ge.t('section.width')))
118
+ .append(select);
119
+ }
120
+
121
+ function createControls(section) {
122
+ var drawer = $('<div class="ge-tools-drawer ge-section-drawer" />').prependTo(section);
123
+
124
+ ge.createMoveTool(drawer);
125
+ ge.addSettingsTool(drawer, section, ge.settings.section_classes || []).append(widthField(section));
126
+
127
+ ge.createTool(drawer, ge.t('tool.add_row_to_section'), 'ge-add-row', 'bi bi-plus-circle', function() {
128
+ ge.place(ge.rowFromLayout([12]), 'row', { appendTo: section });
129
+ });
130
+
131
+ ge.createTool(drawer, ge.t('tool.delete_section'), 'ge-delete-section', 'bi bi-trash', function() {
132
+ ge.deleteNode('section', section, ge.t('confirm.delete_section'), function(removed) {
133
+ section.slideUp(removed);
134
+ });
135
+ });
136
+ }
137
+
138
+ function mark() {
139
+ sections().each(function() {
140
+ var section = $(this).addClass('ge-section');
141
+ if (!section.children('.ge-tools-drawer').length) { createControls(section); }
142
+ });
143
+ }
144
+
145
+ function unmark() {
146
+ ge.canvas.children('.ge-section').removeClass('ge-section');
147
+ }
148
+
149
+ /** createSection(options): a section, detached unless a placement is given. */
150
+ function createSection(settings) {
151
+ settings = settings || {};
152
+
153
+ var section = $('<div />').addClass(WIDTHS[settings.width] || WIDTHS.fixed);
154
+
155
+ (settings.rows || [[12]]).forEach(function(layout) {
156
+ ge.rowFromLayout(layout).appendTo(section);
157
+ });
158
+
159
+ return ge.place(section, 'section', settings);
160
+ }
161
+
162
+ return {
163
+ methods: {
164
+ createSection: createSection,
165
+ },
166
+
167
+ kindOf: function(node) {
168
+ return node.hasClass('ge-section') ? 'section' : null;
169
+ },
170
+
171
+ // A section is a block the canvas moves, and a region rows move in
172
+ blocks: '.ge-section',
173
+ regions: '.ge-section',
174
+
175
+ /** A section goes on the canvas and nowhere else, and holds rows and nothing else. */
176
+ accepts: function(region, node) {
177
+ if (node.hasClass('ge-section') || isSectionMade(node)) { return region[0] === ge.canvas[0]; }
178
+ if (region.hasClass('ge-section')) { return node.hasClass('row'); }
179
+
180
+ return true;
181
+ },
182
+
183
+ toolbar: [{
184
+ labelKey: 'section.add',
185
+ kind: 'section',
186
+ create: function() { return createSection(); },
187
+ }],
188
+
189
+ onInit: mark,
190
+ onDeinit: unmark,
191
+ };
192
+
193
+ /** A section the toolbar just made, before init has marked it. */
194
+ function isSectionMade(node) {
195
+ return !node.parent().length && widthOf(node) !== null;
196
+ }
197
+ };
198
+
199
+ })(jQuery);
@@ -0,0 +1,2 @@
1
+ (c=>{c.extend(c.fn.gridEditor.locales.en,{"section.add":"Section","section.width":"Width","section.fixed":"Fixed","section.fluid":"Full width","section.from":"Fixed from {breakpoint}","tool.add_row_to_section":"Add row","tool.delete_section":"Remove section","confirm.delete_section":"Delete this section and everything in it?"});var r={fixed:"container",fluid:"container-fluid",sm:"container-sm",md:"container-md",lg:"container-lg",xl:"container-xl",xxl:"container-xxl"},l=["fixed","sm","md","lg","xl","xxl","fluid"];c.fn.gridEditor.features.sections=function(s){var o=c.extend({widths:l},s.settings.sections);function a(n){var i=null;return c.each(r,function(e,t){!i&&n.hasClass(t)&&(i=e)}),i}function e(){return s.canvas.children().filter(function(){return(e=c(this)).parent()[0]===s.canvas[0]&&null!==a(e);var e})}function n(e){var t=c("<select />"),n=a(e),i=-1===o.widths.indexOf(n)?o.widths.concat([n]):o.widths;return l.forEach(function(e){-1!==i.indexOf(e)&&c("<option />").attr("value",e).text("fixed"===(e=e)?s.t("section.fixed"):"fluid"===e?s.t("section.fluid"):s.t("section.from",{breakpoint:e})).appendTo(t)}),t.val(n).on("change",function(){var t,n,i,o;t=e,n=this.value,i="panel",(o=a(t))!==n&&r[n]&&s.operate(function(){var e=s.payloadFor("section",t,{family:"section",breakpoint:"all",tiers:[],from:o,to:n,source:i||"api"});return s.emit("before-utility",e)?(t.removeClass(r[o]).addClass(r[n]),s.emit("after-utility",e),!0):(t.find("> .ge-tools-drawer .ge-section-width select").val(o),!1)})}),c('<label class="ge-utility ge-section-width" />').append(c('<span class="ge-utility-label" />').text(s.t("section.width"))).append(t)}function t(e){e=e||{};var t=c("<div />").addClass(r[e.width]||r.fixed);return(e.rows||[[12]]).forEach(function(e){s.rowFromLayout(e).appendTo(t)}),s.place(t,"section",e)}return{methods:{createSection:t},kindOf:function(e){return e.hasClass("ge-section")?"section":null},blocks:".ge-section",regions:".ge-section",accepts:function(e,t){var n;return t.hasClass("ge-section")||!(n=t).parent().length&&null!==a(n)?e[0]===s.canvas[0]:!e.hasClass("ge-section")||t.hasClass("row")},toolbar:[{labelKey:"section.add",kind:"section",create:function(){return t()}}],onInit:function(){e().each(function(){var t,e=c(this).addClass("ge-section");e.children(".ge-tools-drawer").length||(t=e,e=c('<div class="ge-tools-drawer ge-section-drawer" />').prependTo(t),s.createMoveTool(e),s.addSettingsTool(e,t,s.settings.section_classes||[]).append(n(t)),s.createTool(e,s.t("tool.add_row_to_section"),"ge-add-row","bi bi-plus-circle",function(){s.place(s.rowFromLayout([12]),"row",{appendTo:t})}),s.createTool(e,s.t("tool.delete_section"),"ge-delete-section","bi bi-trash",function(){s.deleteNode("section",t,s.t("confirm.delete_section"),function(e){t.slideUp(e)})}))})},onDeinit:function(){s.canvas.children(".ge-section").removeClass("ge-section")}}}})(jQuery);
2
+ //# sourceMappingURL=grideditor.sections.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grideditor.sections.min.js","sources":["../../src/js/plugins/grideditor.sections.js"],"names":["$","extend","fn","gridEditor","locales","en","section.add","section.width","section.fixed","section.fluid","section.from","tool.add_row_to_section","tool.delete_section","confirm.delete_section","WIDTHS","fixed","fluid","sm","md","lg","xl","xxl","ORDER","features","sections","ge","options","widths","settings","widthOf","section","found","each","width","className","hasClass","canvas","children","filter","node","this","parent","widthField","select","current","offered","indexOf","concat","forEach","attr","text","t","breakpoint","appendTo","val","on","source","from","value","operate","payload","payloadFor","family","tiers","to","emit","removeClass","addClass","find","append","createSection","rows","layout","rowFromLayout","place","methods","kindOf","blocks","regions","accepts","region","length","toolbar","labelKey","kind","create","onInit","drawer","prependTo","createMoveTool","addSettingsTool","section_classes","createTool","deleteNode","removed","slideUp","onDeinit","jQuery"],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Text alignment for grid-editor.
3
+ *
4
+ * A utility plugin: load this file after the editor and a row, column,
5
+ * element or container can align its text per breakpoint, with Bootstrap's
6
+ * text-{breakpoint}-start, -center and -end classes. What it can ask the
7
+ * editor for is the handle its factory is called with, described in
8
+ * docs/plugins.md.
9
+ *
10
+ * <script src="dist/jquery.grideditor.min.js"></script>
11
+ * <script src="dist/plugins/grideditor.textalign.min.js"></script>
12
+ *
13
+ * The class aligns everything inside the node that does not align itself: a
14
+ * paragraph the rich text editor gave its own text-align keeps it.
15
+ */
16
+ (function($) {
17
+
18
+ $.extend($.fn.gridEditor.locales.en, {
19
+ 'utility.text_align': 'Text alignment',
20
+ 'utility.text_start': 'Start',
21
+ 'utility.text_center': 'Center',
22
+ 'utility.text_end': 'End',
23
+ });
24
+
25
+ /** Start and end are left and right: Bootstrap's css is left to right. */
26
+ var CSS = { start: 'left', center: 'center', end: 'right' };
27
+
28
+ $.fn.gridEditor.utilities.textalign = function(ge) {
29
+
30
+ function label(value) {
31
+ if (value === 'start') { return ge.t('utility.text_start'); }
32
+ if (value === 'center') { return ge.t('utility.text_center'); }
33
+
34
+ return ge.t('utility.text_end');
35
+ }
36
+
37
+ return {
38
+ families: [{
39
+ name: 'text-align',
40
+ prefix: 'text',
41
+ values: ['start', 'center', 'end'],
42
+ appliesTo: ['row', 'column', 'element', 'container'],
43
+ labelKey: 'utility.text_align',
44
+ label: label,
45
+
46
+ /**
47
+ * With no class applying here, the node aligns as its parent
48
+ * does - or as the host's css says - which only the browser can
49
+ * tell, so it is asked with the classes out of the way. Parents
50
+ * are previewed before their children, so the parent's answer is
51
+ * already the view's.
52
+ */
53
+ preview: function(value, node) {
54
+ return { 'text-align': value === null ? ge.bareStyle(node, 'text-align', 'text-align') : CSS[value] };
55
+ },
56
+ }],
57
+ };
58
+ };
59
+
60
+ })(jQuery);
@@ -0,0 +1,2 @@
1
+ (t=>{t.extend(t.fn.gridEditor.locales.en,{"utility.text_align":"Text alignment","utility.text_start":"Start","utility.text_center":"Center","utility.text_end":"End"});var n={start:"left",center:"center",end:"right"};t.fn.gridEditor.utilities.textalign=function(i){return{families:[{name:"text-align",prefix:"text",values:["start","center","end"],appliesTo:["row","column","element","container"],labelKey:"utility.text_align",label:function(t){return"start"===t?i.t("utility.text_start"):"center"===t?i.t("utility.text_center"):i.t("utility.text_end")},preview:function(t,e){return{"text-align":null===t?i.bareStyle(e,"text-align","text-align"):n[t]}}}]}}})(jQuery);
2
+ //# sourceMappingURL=grideditor.textalign.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grideditor.textalign.min.js","sources":["../../src/js/plugins/grideditor.textalign.js"],"names":["$","extend","fn","gridEditor","locales","en","utility.text_align","utility.text_start","utility.text_center","utility.text_end","CSS","start","center","end","utilities","textalign","ge","families","name","prefix","values","appliesTo","labelKey","label","value","t","preview","node","text-align","bareStyle","jQuery"],"mappings":"CAeUA,IAEVA,EAAEC,OAAOD,EAAEE,GAAGC,WAAWC,QAAQC,GAAI,CACjCC,qBAAsB,iBACtBC,qBAAsB,QACtBC,sBAAuB,SACvBC,mBAAoB,KACxB,CAAC,EAGD,IAAIC,EAAM,CAAEC,MAAO,OAAQC,OAAQ,SAAUC,IAAK,OAAQ,EAE1Db,EAAEE,GAAGC,WAAWW,UAAUC,UAAY,SAASC,GAS3C,MAAO,CACHC,SAAU,CAAC,CACPC,KAAM,aACNC,OAAQ,OACRC,OAAQ,CAAC,QAAS,SAAU,OAC5BC,UAAW,CAAC,MAAO,SAAU,UAAW,aACxCC,SAAU,qBACVC,MAdR,SAAeC,GACX,MAAc,UAAVA,EAA4BR,EAAGS,EAAE,oBAAoB,EAC3C,WAAVD,EAA6BR,EAAGS,EAAE,qBAAqB,EAEpDT,EAAGS,EAAE,kBAAkB,CAClC,EAkBQC,QAAS,SAASF,EAAOG,GACrB,MAAO,CAAEC,aAAwB,OAAVJ,EAAiBR,EAAGa,UAAUF,EAAM,aAAc,YAAY,EAAIjB,EAAIc,EAAO,CACxG,CACJ,EACJ,CACJ,CAEC,GAAEM,MAAM"}
package/docs/events.md CHANGED
@@ -73,19 +73,24 @@ The payload
73
73
  {
74
74
  kind: 'row', // row | column | content | element
75
75
  // tabs | accordion | popup | tab | accordion-item
76
+ // section, with the sections plugin
76
77
  node: jQuery, // the node added, deleted, moved or resized
77
78
  parent: jQuery, // where it is going, or where it came from on a delete
78
79
  canvas: jQuery,
79
80
  breakpoint: 'lg', // the view at the time: a breakpoint key, or 'all'
80
- source: 'tool', // tool | api | dragdrop | panel
81
+ source: 'tool', // tool | api | dragdrop | panel (a width chosen in the panel)
81
82
 
82
83
  // move only
83
84
  from: { parent: jQuery, index: 2 },
84
85
  to: { parent: jQuery, index: 0 },
85
86
 
86
- // resize and indent only: units, not pixels
87
+ // resize and indent only: units, not pixels. A size can also be
88
+ // 'equal' or 'auto', and null when the width field chose "inherit"
87
89
  from: 6,
88
90
  to: 7,
91
+ cleared: [ // the all view only: the breakpoints' own sizes or
92
+ { breakpoint: 'md', value: 4 }, // offsets, which the write took off
93
+ ],
89
94
 
90
95
  // a pane inside a container
91
96
  container: jQuery,
@@ -104,6 +109,12 @@ The payload
104
109
  }
105
110
  ```
106
111
 
112
+ A section's width change is announced as a utility change too, with
113
+ `family: 'section'`, `breakpoint: 'all'` and the widths - `'fixed'`, `'fluid'`,
114
+ `'md'` - as `from` and `to`: a section has one container class, whatever the
115
+ breakpoint. Adding a section fires `before-add-section` and `after-add-section`,
116
+ with the generic pair.
117
+
107
118
  `view-change` carries no node: its payload is `canvas`, `breakpoint` (the new
108
119
  view), `from` and `to`. A utility's `breakpoint` is the view it was written
109
120
  in, which `setUtility` can be asked to make a different one from the view on
@@ -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,23 @@ 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
+
83
103
  confirm.*
84
104
  ---------
85
105
 
@@ -113,7 +133,7 @@ key, so a locale covers a new breakpoint by adding `view.<key>`. Short strings
113
133
 
114
134
  | Key | English | Where |
115
135
  | --- | --- | --- |
116
- | `view.all` | All sizes | The default view, which writes every breakpoint at once |
136
+ | `view.all` | All sizes | The default view, which writes one class for every breakpoint |
117
137
  | `view.xs` | Phone | Layout mode writing `col-*` and `offset-*` |
118
138
  | `view.sm` | Tablet | Layout mode writing `col-sm-*` and `offset-sm-*` |
119
139
  | `view.md` | Small desktop | Layout mode writing `col-md-*` and `offset-md-*` |
@@ -131,6 +151,11 @@ The labels of each utility and its values are the plugins' own keys.
131
151
  | Key | English | Where |
132
152
  | --- | --- | --- |
133
153
  | `utility.section` | Responsive: {view} | The section's fold toggle. `{view}` is the label of the view being edited |
154
+ | `utility.col_width` | Width | The column width field, in a column's Responsive section |
155
+ | `utility.col_equal` | Equal | Its choice for `col` / `col-{bp}` |
156
+ | `utility.col_auto` | Auto | Its choice for `col-auto` / `col-{bp}-auto` |
157
+ | `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` |
158
+ | `utility.row_cols` | Columns per row | The row-cols field, in a row's Responsive section |
134
159
  | `utility.default` | Default | The empty choice of a field when nothing below the view sets the utility, and always in the all view |
135
160
  | `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
161
  | `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 +184,14 @@ The labels of each utility and its values are the plugins' own keys.
159
184
  | `utility.side_b` | Bottom | The side of `pb-*` and `mb-*` |
160
185
  | `utility.side_s` | Start | The side of `ps-*` and `ms-*` |
161
186
  | `utility.side_e` | End | The side of `pe-*` and `me-*` |
187
+ | `utility.text_align` | Text alignment | Label of the textalign plugin's field |
188
+ | `utility.text_start` | Start | Its choice for `text-*-start` |
189
+ | `utility.text_center` | Center | Its choice for `text-*-center` |
190
+ | `utility.text_end` | End | Its choice for `text-*-end` |
191
+ | `utility.float` | Float | Label of the float plugin's field, on an element |
192
+ | `utility.float_start` | Start | Its choice for `float-*-start` |
193
+ | `utility.float_end` | End | Its choice for `float-*-end` |
194
+ | `utility.float_none` | None | Its choice for `float-*-none` |
162
195
  | `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
196
 
164
197
 
@@ -171,6 +204,8 @@ markup `getHtml` returns.
171
204
  | Key | English | Where |
172
205
  | --- | --- | --- |
173
206
  | `badge.hidden_in` | Hidden at {breakpoints} | Corner of a node hidden at some breakpoints, in the all view. `{breakpoints}` is a list of keys |
207
+ | `badge.row_cols` | {count} per row | Corner of a row whose row-cols sizes its columns in the view being edited |
208
+ | `badge.row_cols_auto` | As wide as their content | The same, for `row-cols-auto` |
174
209
  | `badge.order` | Order: {value} | Corner of a column ordered by class in the view being edited |
175
210
 
176
211
 
package/docs/plugins.md CHANGED
@@ -118,11 +118,13 @@ 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.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
128
 
127
129
  The add, delete and move events for a container and its panes are fired by the
128
130
  editor, not by the plugin: `createPaneControls` handles a pane's delete, and
@@ -143,10 +145,29 @@ $.fn.gridEditor.features.elements = function(ge) {
143
145
  onDeinit: function() { … }, // every deinit: take it out again
144
146
  onContentReady: function(area) { … }, // a rich text editor just took over
145
147
  onSortable: function(sortable) { … }, // declare your own sortable lists
148
+ blocks: '.ge-section', // more blocks the canvas and the columns move
149
+ regions: '.ge-section', // more lists those blocks move in
150
+ accepts: function(region, node) { … }, // false turns a block away from a region
151
+ toolbar: [{ labelKey: …, kind: …, create: function() { … } }], // buttons beside the containers'
146
152
  };
147
153
  };
148
154
  ```
149
155
 
156
+ The last four are what the sections plugin is made of, and what a plugin
157
+ needs to put a new kind of block on the canvas:
158
+
159
+ - **`blocks`** is a selector added to what the canvas and every column move -
160
+ rows, content areas and containers, the editor's own blocks.
161
+ - **`regions`** is a selector for more lists those blocks move in, in the same
162
+ group, so a row dragged from the canvas can land in one.
163
+ - **`accepts(region, node)`** can turn a block away from a list: `false` and the
164
+ drag will not drop it there, whoever's block and whoever's list. With none of
165
+ these hooks, every block goes everywhere, as before.
166
+ - **`toolbar`** adds buttons beside the containers'. A click appends what
167
+ `create()` returns to the canvas, announced as `kind`; a drop puts it where it
168
+ was dropped, or, when that region will not have it, on the canvas just after
169
+ the block it was dropped in.
170
+
150
171
  - **`onSortable(sortable)`** is handed the function the editor makes all of its
151
172
  own lists with. A plugin describes a list; it never touches the drag toolkit
152
173
  itself, which is what keeps `drag_handle`, the cancel selector and the move
@@ -208,6 +229,8 @@ $.fn.gridEditor.utilities.order = function(ge) {
208
229
  label: function(value) { … }, // an option's text, optional: the value itself otherwise
209
230
  choices: function(node, kind) { … }, // what to offer this node, optional: every value otherwise
210
231
  panel: false, // optional: no field of its own, see "A panel of your own"
232
+ className: function(breakpoint, value) { … }, // optional, for classes not spelled {prefix}-{bp}-{value}
233
+ write: function(node, value, view, source) { … }, // optional, a write that is some other operation
211
234
  preview: function(value, node, kind) { // what the value looks like, see below
212
235
  return { order: value === null ? 0 : value };
213
236
  },
@@ -239,7 +262,10 @@ What the editor does with a family:
239
262
  breakpoint view each node that carries a family's class gets
240
263
  `preview(value)` — the value that applies there, or `null` — as inline
241
264
  `!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
265
+ class is still live in a wide window and has to be overruled. When what
266
+ `null` looks like depends on the page — `text-align` inherits, the host's
267
+ css may float an element — `ge.bareStyle(node, family, property)` asks the
268
+ browser. Parents are previewed before their children. The all view
243
269
  previews nothing, since every breakpoint there is live and what Bootstrap
244
270
  shows is the truth. The styles come off on `deinit`, leaving the host's own
245
271
  `style` as it was, so `getHtml` never sees them.
@@ -275,6 +301,13 @@ set the top padding. A plugin-level `preview(node, kind, breakpoint)` is called
275
301
  for every node in a breakpoint view, after the families' own, and returns the
276
302
  styles for the node or an empty object.
277
303
 
304
+ Two escape hatches, which the column width uses: `className(breakpoint,
305
+ value)` spells the classes of a family that does not follow the pattern
306
+ (`col`, `col-md`, `col-md-auto`), and `write(node, value, view, source)` does a
307
+ write some other way than a utility change - the width field's writes are
308
+ resizes, through the resize events. The editor still checks the value and the
309
+ node before it calls `write`.
310
+
278
311
  Two plugins cannot declare the same family name: the second one is ignored,
279
312
  with a warning.
280
313
 
@@ -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>