@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
@@ -21,6 +21,8 @@
21
21
  'tool.add_row': 'Añadir fila',
22
22
  'tool.add_column': 'Añadir columna\n(mantén pulsado para elegir el ancho)',
23
23
  'tool.column_size': '{size} de 12',
24
+ 'tool.column_equal': 'Igual: reparte lo que queda de la fila',
25
+ 'tool.column_auto': 'Auto: tan ancha como su contenido',
24
26
  'tool.delete_row': 'Borrar fila',
25
27
  'tool.delete_column': 'Borrar columna',
26
28
  'tool.delete_element': 'Borrar elemento',
@@ -41,6 +43,7 @@
41
43
  'tool.classes_title': 'Clases css, separadas por espacios',
42
44
  'tool.toggle_class': 'Aplicar o quitar el estilo "{label}"',
43
45
  'row.add': 'Añadir fila {layout}',
46
+ 'row.add_row_cols': 'Añadir una fila de {columns} columnas, {counts} por fila',
44
47
  'container.add_tabs': 'Pestañas',
45
48
  'container.add_tab': 'Añadir pestaña',
46
49
  'container.tab_label': 'Pestaña {number}',
@@ -70,6 +73,21 @@
70
73
  'view.xl': 'Escritorio grande',
71
74
  'view.xxl': 'Pantalla panorámica',
72
75
  'utility.section': 'Responsive: {view}',
76
+ 'utility.col_width': 'Ancho',
77
+ 'utility.col_equal': 'Igual',
78
+ 'utility.col_auto': 'Auto',
79
+ 'section.add': 'Sección',
80
+ 'section.width': 'Ancho',
81
+ 'section.fixed': 'Fijo',
82
+ 'section.fluid': 'Ancho completo',
83
+ 'section.from': 'Fijo desde {breakpoint}',
84
+ 'tool.add_row_to_section': 'Añadir fila',
85
+ 'tool.delete_section': 'Quitar sección',
86
+ 'confirm.delete_section': '¿Seguro que quieres borrar esta sección y todo su contenido?',
87
+ 'utility.col_from_row': 'De la fila: {count}',
88
+ 'utility.row_cols': 'Columnas por fila',
89
+ 'badge.row_cols': '{count} por fila',
90
+ 'badge.row_cols_auto': 'Tan anchas como su contenido',
73
91
  'utility.default': 'Por defecto',
74
92
  'utility.inherit': 'Hereda: {value} (de {breakpoint})',
75
93
  'utility.varies': 'Cambia en {breakpoints}; elegir aquí lo sustituye',
@@ -100,6 +118,14 @@
100
118
  'utility.side_b': 'Abajo',
101
119
  'utility.side_s': 'Inicio',
102
120
  'utility.side_e': 'Fin',
121
+ 'utility.text_align': 'Alineación del texto',
122
+ 'utility.text_start': 'Inicio',
123
+ 'utility.text_center': 'Centro',
124
+ 'utility.text_end': 'Fin',
125
+ 'utility.float': 'Flotar',
126
+ 'utility.float_start': 'Inicio',
127
+ 'utility.float_end': 'Fin',
128
+ 'utility.float_none': 'Ninguno',
103
129
  'utility.spacing_gutter': 'El relleno lateral de una columna es su espaciado: cambiarlo cambia el espacio entre columnas',
104
130
  'error.sortable_missing': '¡SortableJS no está disponible! Asegúrate de haber cargado el archivo js de Sortable; sin él no se puede arrastrar.',
105
131
  'warning.setting_removed': 'El ajuste {setting} se eliminó en la 4.0. Usa {replacement} en su lugar.',
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Floating elements for grid-editor.
3
+ *
4
+ * A utility plugin: load this file after the editor and after the elements
5
+ * plugin, and an element can float to the start or the end of its content
6
+ * area per breakpoint, with the text around it, using Bootstrap's
7
+ * float-{breakpoint}-start, -end and -none classes. What it can ask the
8
+ * editor for is the handle its factory is called with, described in
9
+ * docs/plugins.md.
10
+ *
11
+ * <script src="dist/jquery.grideditor.min.js"></script>
12
+ * <script src="dist/plugins/grideditor.elements.min.js"></script>
13
+ * <script src="dist/plugins/grideditor.float.min.js"></script>
14
+ *
15
+ * Elements only. A floated row or column stops being part of the grid, and a
16
+ * container sits beside the content areas rather than in their text.
17
+ */
18
+ (function($) {
19
+
20
+ $.extend($.fn.gridEditor.locales.en, {
21
+ 'utility.float': 'Float',
22
+ 'utility.float_start': 'Start',
23
+ 'utility.float_end': 'End',
24
+ 'utility.float_none': 'None',
25
+ });
26
+
27
+ /** Start and end are left and right: Bootstrap's css is left to right. */
28
+ var CSS = { start: 'left', end: 'right', none: 'none' };
29
+
30
+ $.fn.gridEditor.utilities.float = function(ge) {
31
+
32
+ function label(value) {
33
+ if (value === 'start') { return ge.t('utility.float_start'); }
34
+ if (value === 'end') { return ge.t('utility.float_end'); }
35
+
36
+ return ge.t('utility.float_none');
37
+ }
38
+
39
+ return {
40
+ families: [{
41
+ name: 'float',
42
+ prefix: 'float',
43
+ values: ['start', 'end', 'none'],
44
+ appliesTo: ['element'],
45
+ labelKey: 'utility.float',
46
+ label: label,
47
+
48
+ /** With no class applying here, whatever the host's css floats it as. */
49
+ preview: function(value, node) {
50
+ return { float: value === null ? ge.bareStyle(node, 'float', 'float') : CSS[value] };
51
+ },
52
+ }],
53
+ };
54
+ };
55
+
56
+ })(jQuery);
@@ -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,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);
@@ -44,6 +44,8 @@
44
44
 
45
45
  .ge-row-icon {
46
46
  width: 48px;
47
+ /* A button shrinks to its content, and an equal column has none */
48
+ flex: 0 0 48px;
47
49
  margin: 0;
48
50
 
49
51
  .column {
@@ -52,6 +54,10 @@
52
54
  padding: 0;
53
55
  border-left: 2px solid #f4f4f4;
54
56
  }
57
+ /* Nothing inside to be as wide as */
58
+ .col-auto {
59
+ min-width: 8px;
60
+ }
55
61
  }
56
62
  }
57
63
 
@@ -167,6 +173,8 @@
167
173
  margin: 0 -@editGutter @editGutter;
168
174
  display: block;
169
175
  width: calc(~"100% +" 2 * @editGutter);
176
+ /* Its node may align text, and the drawer's tools would follow */
177
+ text-align: left;
170
178
 
171
179
  > a {
172
180
  display: inline-block;
@@ -314,6 +322,10 @@
314
322
  position: relative;
315
323
 
316
324
  > .ge-tools-drawer {
325
+ /* The drawer is not content: an auto column is as wide as what
326
+ it holds, and its tools would make it as wide as a drawer */
327
+ contain: inline-size;
328
+
317
329
  a {
318
330
  color: @colTextColor;
319
331
  }
@@ -370,6 +382,13 @@
370
382
  color: #fff;
371
383
  }
372
384
 
385
+ /* col and col-auto: a word, not a number */
386
+ &.ge-size-flex {
387
+ width: auto;
388
+ padding-left: 5px;
389
+ padding-right: 5px;
390
+ }
391
+
373
392
  /* Wider than what is left of the row: allowed, but said so */
374
393
  &.ge-size-tight {
375
394
  color: #999;
@@ -644,16 +663,43 @@
644
663
  /* this tier applies at the active one, so it is written by the pass below */
645
664
  }
646
665
  .ge-tier-above-off(@j, @active) when (@j > @active) {
666
+ .ge-flex-columns-off(extract(@ge-col-prefixes, @j));
647
667
  .ge-columns-off(extract(@ge-col-prefixes, @j));
648
668
  .ge-offsets-off(extract(@ge-offset-prefixes, @j));
649
669
  }
650
670
 
651
671
  .ge-tiers-upto-on(@active, @j: 1) when (@j =< @active) {
672
+ .ge-flex-columns-on(extract(@ge-col-prefixes, @j));
652
673
  .ge-columns-on(extract(@ge-col-prefixes, @j));
653
674
  .ge-offsets-on(extract(@ge-offset-prefixes, @j));
654
675
  .ge-tiers-upto-on(@active, @j + 1);
655
676
  }
656
677
 
678
+ /*
679
+ * col and col-auto, in the order Bootstrap writes them: before the numbered
680
+ * sizes, so that of two classes for one tier the number wins, as it does on
681
+ * the real page.
682
+ */
683
+ .ge-flex-columns-on(@prefix) {
684
+ .@{prefix} {
685
+ flex: 1 0 0%;
686
+ max-width: 100%;
687
+ }
688
+ .@{prefix}-auto {
689
+ flex: 0 0 auto;
690
+ width: auto;
691
+ max-width: 100%;
692
+ }
693
+ }
694
+ .ge-flex-columns-off(@prefix) {
695
+ .@{prefix},
696
+ .@{prefix}-auto {
697
+ flex: 0 0 auto;
698
+ width: 100%;
699
+ max-width: 100%;
700
+ }
701
+ }
702
+
657
703
  .ge-columns-on(@prefix, @i: 1) when (@i =< @ge-columns) {
658
704
  .@{prefix}-@{i} {
659
705
  flex: 0 0 auto;
@@ -784,3 +830,89 @@
784
830
  }
785
831
  }
786
832
  }
833
+
834
+ /* A row whose row-cols sizes its columns in this view says how many */
835
+ .ge-canvas.ge-editing .row[data-ge-row-cols] {
836
+ position: relative;
837
+
838
+ &::before {
839
+ content: attr(data-ge-row-cols);
840
+ position: absolute;
841
+ left: 2px;
842
+ bottom: 2px;
843
+ z-index: 1;
844
+ padding: 0 4px;
845
+ border-radius: 3px;
846
+ background: rgba(0, 0, 0, .55);
847
+ color: #fff;
848
+ font-size: 10px;
849
+ line-height: 16px;
850
+ pointer-events: none;
851
+ }
852
+ }
853
+
854
+ /*
855
+ * The sections plugin: Bootstrap's containers on the canvas. A section is
856
+ * framed while editing, and in a breakpoint view each container class gets
857
+ * the max-width it has at that breakpoint - Bootstrap sets it for the
858
+ * window, and the window is not what a breakpoint view narrows.
859
+ */
860
+ @ge-section-color: #8a6d3b;
861
+
862
+ .ge-canvas.ge-editing > .ge-section {
863
+ border: 1px dashed @ge-section-color;
864
+ margin-bottom: @editGutter;
865
+ padding-bottom: @editGutter;
866
+
867
+ > .ge-section-drawer {
868
+ background: fadeout(@ge-section-color, 85%);
869
+ margin-left: 0;
870
+ margin-right: 0;
871
+ width: 100%;
872
+
873
+ > a {
874
+ color: darken(@ge-section-color, 5%);
875
+ }
876
+ }
877
+ }
878
+
879
+ /* The width field, in the section's settings panel beside id and classes */
880
+ .ge-canvas.ge-editing .ge-details .ge-section-width {
881
+ display: inline-flex;
882
+ align-items: center;
883
+ gap: 4px;
884
+ margin: 0;
885
+ font-size: 11px;
886
+
887
+ select {
888
+ border: 1px solid #7F7F7F;
889
+ border-radius: 4px;
890
+ font-size: 11px;
891
+ padding: 1px 2px;
892
+ }
893
+ }
894
+
895
+ @ge-section-classes: container, container-sm, container-md, container-lg, container-xl, container-xxl;
896
+ @ge-section-from: 2, 2, 3, 4, 5, 6;
897
+ @ge-section-widths: 100%, 540px, 720px, 960px, 1140px, 1320px;
898
+
899
+ .ge-section-modes(@i: 1) when (@i =< length(@ge-tiers)) {
900
+ @tier: extract(@ge-tiers, @i);
901
+ .ge-section-classes(@i, @tier);
902
+ .ge-section-modes(@i + 1);
903
+ }
904
+ .ge-section-classes(@i, @tier, @k: 1) when (@k =< length(@ge-section-classes)) {
905
+ .ge-section-width(@i, @tier, extract(@ge-section-classes, @k), extract(@ge-section-from, @k));
906
+ .ge-section-classes(@i, @tier, @k + 1);
907
+ }
908
+ .ge-section-width(@i, @tier, @class, @from) when (@i >= @from) {
909
+ .ge-canvas.ge-layout-@{tier} > .@{class} {
910
+ max-width: extract(@ge-section-widths, @i);
911
+ }
912
+ }
913
+ .ge-section-width(@i, @tier, @class, @from) when (@i < @from) {
914
+ .ge-canvas.ge-layout-@{tier} > .@{class} {
915
+ max-width: 100%;
916
+ }
917
+ }
918
+ .ge-section-modes();