@themarioga/grid-editor 7.2.0 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/README.md +83 -14
- package/UPGRADING.md +31 -0
- package/dist/grideditor.bundle.min.js +2 -2
- package/dist/grideditor.css +102 -0
- package/dist/grideditor.d.ts +18 -0
- package/dist/grideditor.esm.js +291 -31
- package/dist/grideditor.js +291 -31
- package/dist/grideditor.min.css +1 -1
- package/dist/grideditor.min.css.map +1 -1
- package/dist/grideditor.min.js +1 -1
- package/dist/grideditor.min.js.map +3 -3
- package/dist/locales/grideditor.es.esm.js +67 -0
- package/dist/locales/grideditor.es.js +67 -0
- package/dist/locales/grideditor.es.min.js +1 -1
- package/dist/locales/grideditor.es.min.js.map +2 -2
- package/dist/plugins/grideditor.float.esm.js +10 -1
- package/dist/plugins/grideditor.float.js +8 -2
- package/dist/plugins/grideditor.float.min.js +1 -1
- package/dist/plugins/grideditor.float.min.js.map +4 -4
- package/dist/plugins/grideditor.spacing.esm.js +12 -3
- package/dist/plugins/grideditor.spacing.js +9 -3
- package/dist/plugins/grideditor.spacing.min.js +1 -1
- package/dist/plugins/grideditor.spacing.min.js.map +4 -4
- package/dist/plugins/grideditor.style.esm.js +1593 -0
- package/dist/plugins/grideditor.style.js +1592 -0
- package/dist/plugins/grideditor.style.min.js +2 -0
- package/dist/plugins/grideditor.style.min.js.map +7 -0
- package/dist/plugins/grideditor.textalign.esm.js +10 -1
- package/dist/plugins/grideditor.textalign.js +8 -2
- package/dist/plugins/grideditor.textalign.min.js +1 -1
- package/dist/plugins/grideditor.textalign.min.js.map +4 -4
- package/dist/plugins/grideditor.visibility.esm.js +12 -3
- package/dist/plugins/grideditor.visibility.js +9 -3
- package/dist/plugins/grideditor.visibility.min.js +1 -1
- package/dist/plugins/grideditor.visibility.min.js.map +4 -4
- package/docs/locale-keys.md +86 -7
- package/docs/plugins.md +49 -5
- package/example/index.html +14 -0
- package/example/style.html +151 -0
- package/example/utilities.html +15 -11
- package/package.json +1 -1
- package/src/js/grideditor.js +365 -27
- package/src/js/locales/grideditor.es.js +67 -0
- package/src/js/plugins/grideditor.float.js +8 -33
- package/src/js/plugins/grideditor.spacing.js +8 -273
- package/src/js/plugins/grideditor.style.js +179 -0
- package/src/js/plugins/grideditor.textalign.js +8 -39
- package/src/js/plugins/grideditor.visibility.js +8 -147
- package/src/js/style/accordion.js +157 -0
- package/src/js/style/catalog.js +76 -0
- package/src/js/style/custom.js +84 -0
- package/src/js/style/fields.js +382 -0
- package/src/js/style/float.js +46 -0
- package/src/js/style/options.js +75 -0
- package/src/js/style/sections.js +271 -0
- package/src/js/style/spacing.js +286 -0
- package/src/js/style/textalign.js +52 -0
- package/src/js/style/visibility.js +160 -0
- package/src/less/grideditor.less +111 -0
- package/types/grideditor.d.ts +18 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visibility, a part of the style plugin: hiding and showing per breakpoint, with Bootstrap's d-{breakpoint}-none
|
|
3
|
+
* and d-{breakpoint}-block or -flex classes, and the eye in the drawers.
|
|
4
|
+
*
|
|
5
|
+
* The part is what the visibility plugin was up to 7.2 - its families, and
|
|
6
|
+
* whatever it did on the canvas - as a function of the handle and its options.
|
|
7
|
+
* grideditor.style.js puts it in its sections; the deprecated
|
|
8
|
+
* grideditor.visibility.js still registers it on its own, as it always did.
|
|
9
|
+
*/
|
|
10
|
+
import { GridEditor } from '../grideditor.js';
|
|
11
|
+
import * as dom from '../dom.js';
|
|
12
|
+
|
|
13
|
+
Object.assign(GridEditor.locales.en, {
|
|
14
|
+
'utility.visibility': 'Visibility',
|
|
15
|
+
'utility.visibility_hidden': 'Hidden',
|
|
16
|
+
'utility.visibility_shown': 'Shown',
|
|
17
|
+
'tool.hide_in_view': 'Hide in this view',
|
|
18
|
+
'tool.show_in_view': 'Show in this view',
|
|
19
|
+
'badge.hidden_in': 'Hidden at {breakpoints}',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/** A node that carries any class of the family, at any breakpoint. */
|
|
23
|
+
var CLASS_PATTERN = /(?:^|\s)d-(?:(?:sm|md|lg|xl|xxl)-)?(?:none|block|flex)(?:\s|$)/;
|
|
24
|
+
|
|
25
|
+
var NODES = '.row, .column, .ge-content, .ge-element, [data-ge-container]';
|
|
26
|
+
|
|
27
|
+
export function visibilityPart(ge, given) {
|
|
28
|
+
|
|
29
|
+
var options = Object.assign({ drawer: true }, given);
|
|
30
|
+
|
|
31
|
+
/** What "shown" is written as on this kind of node. */
|
|
32
|
+
function shown(kind) {
|
|
33
|
+
return kind === 'row' ? 'flex' : 'block';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function applies(node, kind) {
|
|
37
|
+
return kind === 'row' || kind === 'column' || kind === 'element' || kind === 'text' || kind === 'plain' ||
|
|
38
|
+
dom.is(node, '[data-ge-container]');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function hiddenAt(node, view) {
|
|
42
|
+
return ge.getUtility(node, 'visibility', view) === 'none';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The breakpoints at which the node is hidden, smallest first. */
|
|
46
|
+
function hiddenTiers(node) {
|
|
47
|
+
return ge.breakpoints.filter(function(key) { return hiddenAt(node, key); });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Whether the node is hidden in the view being edited. In the all view
|
|
52
|
+
* that means hidden at every breakpoint, since "hidden at some" is what
|
|
53
|
+
* the badge is for.
|
|
54
|
+
*/
|
|
55
|
+
function hiddenHere(node) {
|
|
56
|
+
return ge.view() === 'all'
|
|
57
|
+
? hiddenTiers(node).length === ge.breakpoints.length
|
|
58
|
+
: hiddenAt(node, ge.view());
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** What the breakpoint below the view shows, which an inherit falls back to. */
|
|
62
|
+
function hiddenBelow(node) {
|
|
63
|
+
var index = ge.breakpoints.indexOf(ge.view());
|
|
64
|
+
|
|
65
|
+
return index > 0 && hiddenAt(node, ge.breakpoints[index - 1]);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Hide or show the node in the view being edited, with as few classes as
|
|
70
|
+
* that takes. In a breakpoint view that is often none at all: showing a
|
|
71
|
+
* node the breakpoint below shows removes this breakpoint's d-*-none
|
|
72
|
+
* rather than writing a d-*-block on top of it. In the all view a node
|
|
73
|
+
* is hidden everywhere or shown everywhere, and shown is no class.
|
|
74
|
+
*/
|
|
75
|
+
function toggle(node, kind) {
|
|
76
|
+
var hide = !hiddenHere(node);
|
|
77
|
+
var value;
|
|
78
|
+
|
|
79
|
+
if (ge.view() === 'all') {
|
|
80
|
+
value = hide ? 'none' : null;
|
|
81
|
+
} else if (hide) {
|
|
82
|
+
value = hiddenBelow(node) ? null : 'none';
|
|
83
|
+
} else {
|
|
84
|
+
value = hiddenBelow(node) ? shown(kind) : null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
ge.setUtility(node, 'visibility', value, { source: 'tool' });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The canvas shows each node as the view sees it. ge-visibility keeps a
|
|
92
|
+
* node Bootstrap would hide on the canvas, ge-hidden-in-view fades it,
|
|
93
|
+
* and data-ge-hidden-in carries the badge text for the all view.
|
|
94
|
+
*/
|
|
95
|
+
function mark(scope) {
|
|
96
|
+
dom.selfAndAll(scope, NODES).forEach(function(node) {
|
|
97
|
+
var kind = ge.kindOf(node);
|
|
98
|
+
var carries = applies(node, kind) && CLASS_PATTERN.test(node.getAttribute('class') || '');
|
|
99
|
+
var tiers = carries ? hiddenTiers(node) : [];
|
|
100
|
+
var here = carries && hiddenHere(node);
|
|
101
|
+
var partly = carries && ge.view() === 'all' && tiers.length > 0 && !here;
|
|
102
|
+
|
|
103
|
+
dom.toggleClass(node, 'ge-visibility', carries);
|
|
104
|
+
dom.toggleClass(node, 'ge-hidden-in-view', here);
|
|
105
|
+
|
|
106
|
+
if (partly) {
|
|
107
|
+
node.setAttribute('data-ge-hidden-in', ge.t('badge.hidden_in', { breakpoints: tiers.join(', ') }));
|
|
108
|
+
} else {
|
|
109
|
+
node.removeAttribute('data-ge-hidden-in');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
dom.children(node, '.ge-tools-drawer').forEach(function(drawer) {
|
|
113
|
+
dom.children(drawer, '.ge-visibility-tool').forEach(function(tool) {
|
|
114
|
+
tool.setAttribute('title', here ? ge.t('tool.show_in_view') : ge.t('tool.hide_in_view'));
|
|
115
|
+
dom.all(tool, 'i').forEach(function(icon) {
|
|
116
|
+
icon.setAttribute('class', here ? 'bi bi-eye-slash' : 'bi bi-eye');
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function unmark() {
|
|
124
|
+
dom.all(ge.canvas, '.ge-visibility, .ge-hidden-in-view, [data-ge-hidden-in]').forEach(function(node) {
|
|
125
|
+
dom.removeClass(node, 'ge-visibility ge-hidden-in-view');
|
|
126
|
+
node.removeAttribute('data-ge-hidden-in');
|
|
127
|
+
dom.dropEmptyClass(node);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
families: [{
|
|
133
|
+
name: 'visibility',
|
|
134
|
+
prefix: 'd',
|
|
135
|
+
values: ['none', 'block', 'flex'],
|
|
136
|
+
appliesTo: ['row', 'column', 'text', 'element', 'container'],
|
|
137
|
+
labelKey: 'utility.visibility',
|
|
138
|
+
|
|
139
|
+
/** Hidden, or shown the way this kind of node is shown. */
|
|
140
|
+
choices: function(node, kind) {
|
|
141
|
+
return ['none', shown(kind)];
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
label: function(value) {
|
|
145
|
+
return value === 'none' ? ge.t('utility.visibility_hidden') : ge.t('utility.visibility_shown');
|
|
146
|
+
},
|
|
147
|
+
}],
|
|
148
|
+
|
|
149
|
+
drawerTools: function(drawer, node, kind) {
|
|
150
|
+
if (!options.drawer || !applies(node, kind)) { return; }
|
|
151
|
+
|
|
152
|
+
ge.createTool(drawer, ge.t('tool.hide_in_view'), 'ge-visibility-tool', 'bi bi-eye', function() {
|
|
153
|
+
toggle(node, kind);
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
onRefresh: mark,
|
|
158
|
+
onDeinit: unmark,
|
|
159
|
+
};
|
|
160
|
+
}
|
package/src/less/grideditor.less
CHANGED
|
@@ -330,6 +330,117 @@
|
|
|
330
330
|
}
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
+
/* A settings panel the dialog was opened from waits under its backdrop:
|
|
334
|
+
Bootstrap's popover would sit over the modal */
|
|
335
|
+
.ge-settings-panel.ge-under-dialog {
|
|
336
|
+
z-index: 1040;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/* What plugins add to a panel, between its general fields and Responsive.
|
|
340
|
+
In a popover or inline, a button that opens it in the dialog. */
|
|
341
|
+
.ge-details .ge-panel-section {
|
|
342
|
+
margin-top: 10px;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/* The style plugin's accordion: in a panel, or in the dialog, which is
|
|
346
|
+
outside any panel, so it carries the look of the fields it shares. */
|
|
347
|
+
.ge-style {
|
|
348
|
+
font-size: 0.8125rem;
|
|
349
|
+
|
|
350
|
+
.accordion-button {
|
|
351
|
+
padding: 6px 10px;
|
|
352
|
+
font-size: 0.8125rem;
|
|
353
|
+
font-weight: 500;
|
|
354
|
+
}
|
|
355
|
+
.accordion-body {
|
|
356
|
+
display: flex;
|
|
357
|
+
flex-direction: column;
|
|
358
|
+
gap: 10px;
|
|
359
|
+
padding: 8px 10px;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.ge-style-label,
|
|
363
|
+
.ge-utility-label,
|
|
364
|
+
.ge-style-shadow-label {
|
|
365
|
+
color: var(--bs-secondary-color, #6c757d);
|
|
366
|
+
font-size: 0.75rem;
|
|
367
|
+
}
|
|
368
|
+
.ge-style-note,
|
|
369
|
+
.ge-utility-note,
|
|
370
|
+
.ge-spacing-gutter {
|
|
371
|
+
color: var(--bs-secondary-color, #666);
|
|
372
|
+
font-size: 0.6875rem;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.ge-style-fields,
|
|
376
|
+
.ge-spacing {
|
|
377
|
+
display: grid;
|
|
378
|
+
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
|
379
|
+
gap: 8px 10px;
|
|
380
|
+
}
|
|
381
|
+
.ge-style-field,
|
|
382
|
+
.ge-utility,
|
|
383
|
+
.ge-spacing-group {
|
|
384
|
+
display: flex;
|
|
385
|
+
flex-direction: column;
|
|
386
|
+
gap: 2px;
|
|
387
|
+
margin: 0;
|
|
388
|
+
}
|
|
389
|
+
.ge-spacing-group .ge-utility > .ge-utility-label {
|
|
390
|
+
display: none;
|
|
391
|
+
}
|
|
392
|
+
.ge-spacing-gutter {
|
|
393
|
+
grid-column: 1 / -1;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.ge-style-color .form-control-color {
|
|
397
|
+
flex: 0 0 2.25rem;
|
|
398
|
+
padding: 2px;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.ge-style-shadow,
|
|
402
|
+
.ge-style-field:has(.ge-style-shadow) {
|
|
403
|
+
grid-column: 1 / -1;
|
|
404
|
+
}
|
|
405
|
+
.ge-style-shadow-builder {
|
|
406
|
+
display: grid;
|
|
407
|
+
grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
|
|
408
|
+
gap: 4px 8px;
|
|
409
|
+
align-items: end;
|
|
410
|
+
}
|
|
411
|
+
.ge-style-shadow-part {
|
|
412
|
+
display: flex;
|
|
413
|
+
flex-direction: column;
|
|
414
|
+
gap: 2px;
|
|
415
|
+
margin: 0;
|
|
416
|
+
}
|
|
417
|
+
.ge-style-shadow-color {
|
|
418
|
+
grid-column: span 2;
|
|
419
|
+
}
|
|
420
|
+
.ge-style-shadow-mode {
|
|
421
|
+
display: inline-block;
|
|
422
|
+
margin-top: 2px;
|
|
423
|
+
font-size: 0.6875rem;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.ge-style-catalog {
|
|
427
|
+
display: flex;
|
|
428
|
+
flex-direction: column;
|
|
429
|
+
gap: 4px;
|
|
430
|
+
}
|
|
431
|
+
.ge-style-chips {
|
|
432
|
+
display: flex;
|
|
433
|
+
flex-wrap: wrap;
|
|
434
|
+
gap: 3px;
|
|
435
|
+
}
|
|
436
|
+
.ge-style-chip {
|
|
437
|
+
--bs-btn-padding-y: 0;
|
|
438
|
+
--bs-btn-padding-x: 6px;
|
|
439
|
+
--bs-btn-font-size: 0.6875rem;
|
|
440
|
+
font-family: var(--bs-font-monospace, monospace);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
333
444
|
/* In a drawer it is part of the drawer, compact */
|
|
334
445
|
.ge-tools-drawer > .ge-details {
|
|
335
446
|
font-size: 11px;
|
package/types/grideditor.d.ts
CHANGED
|
@@ -53,6 +53,22 @@ export interface PresetClass {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/** A content filter: run on init and deinit with the canvas. A string names a function on window. */
|
|
56
|
+
/** A section of the style plugin's accordion. */
|
|
57
|
+
export type StyleSectionKey = 'size' | 'spacing' | 'border' | 'background' | 'text' | 'typography' | 'display' | 'position' | 'custom';
|
|
58
|
+
|
|
59
|
+
/** A section on or off, or on with some of its properties and without its catalog. */
|
|
60
|
+
export type StyleSection = boolean | { properties?: string[]; catalog?: boolean };
|
|
61
|
+
|
|
62
|
+
/** The style plugin's settings. */
|
|
63
|
+
export interface StyleOptions {
|
|
64
|
+
/** Every section is on unless it is turned off here. */
|
|
65
|
+
sections?: Partial<Record<StyleSectionKey, StyleSection>>;
|
|
66
|
+
/** What utilities.spacing was: the values offered, and what 0 to 5 come to. */
|
|
67
|
+
spacing?: { values?: string[]; scale?: string[] };
|
|
68
|
+
/** What utilities.visibility was: false leaves the eye out of the drawers. */
|
|
69
|
+
visibility?: { drawer?: boolean };
|
|
70
|
+
}
|
|
71
|
+
|
|
56
72
|
export type CustomFilter = ((canvas: HTMLElement, isInit: boolean) => void) | string;
|
|
57
73
|
|
|
58
74
|
/** The settings. Every one is optional. */
|
|
@@ -79,6 +95,8 @@ export interface GridEditorOptions {
|
|
|
79
95
|
content_types?: string[];
|
|
80
96
|
row_cols?: boolean;
|
|
81
97
|
utilities?: Record<string, unknown>;
|
|
98
|
+
/** The style plugin's sections, and the options of the utilities it carries. */
|
|
99
|
+
style?: StyleOptions;
|
|
82
100
|
elements?: { enabled?: boolean | 'auto'; selector?: string; auto?: boolean };
|
|
83
101
|
custom_filter?: CustomFilter | CustomFilter[] | '';
|
|
84
102
|
valid_col_sizes?: ColumnSize[];
|