@nys-cui/cui-section 0.2.18 → 0.2.20
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/package.json +1 -1
- package/src/section.js +171 -21
- package/src/section.scss +29 -3
package/package.json
CHANGED
package/src/section.js
CHANGED
|
@@ -29,11 +29,18 @@ export default class CUI_SECTION extends HTMLElement {
|
|
|
29
29
|
this.oPropsToStateNames = {
|
|
30
30
|
"sectiontitle": "sTitle",
|
|
31
31
|
"hideControls": "bHideControls",
|
|
32
|
+
"hideHeader": "bHideHeader",
|
|
32
33
|
"collapsed": "bCollapsed",
|
|
33
34
|
"styles": "asStyles",
|
|
34
35
|
"label": "sTitle",
|
|
35
36
|
"instructions": "oInstructions"
|
|
36
37
|
}
|
|
38
|
+
|
|
39
|
+
this.bSectionMenuDisplayed = false;
|
|
40
|
+
this.dSectionMenu = null;
|
|
41
|
+
this.bMobile = false;
|
|
42
|
+
this.dSectionMenuDialog = null;
|
|
43
|
+
this.fGlobalBodyClick = this.globalBodyClick.bind(this);
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
get style() {
|
|
@@ -42,34 +49,38 @@ export default class CUI_SECTION extends HTMLElement {
|
|
|
42
49
|
|
|
43
50
|
get template() {
|
|
44
51
|
|
|
45
|
-
let sTemplate = `<section part="root-section"><header part="section-header"
|
|
46
|
-
<div class='header-info' part='header-info'><h2 id="section-title" part="section-title"></h2><slot name='section-help-tag'></slot></div>`;
|
|
52
|
+
let sTemplate = `<section part="root-section"><header part="section-header ${this.state.bHideHeader ? `headless" class="headless"` : `"`}>`;
|
|
47
53
|
|
|
48
|
-
if
|
|
54
|
+
if(!this.state.bHideHeader) {
|
|
55
|
+
sTemplate += `<div class='header-info' part='header-info'><h2 id="section-title" part="section-title"></h2><slot name='section-help-tag'></slot></div>`;
|
|
49
56
|
|
|
50
|
-
if (this.
|
|
57
|
+
if (!this.state.bHideControls) {
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
<div class="header-controls" part="header-controls">
|
|
54
|
-
<button type="button" id="collapse-control" aria-controls="container" part="collapse-control">
|
|
55
|
-
<cui-icon src="caret-down" basePath="${this.sIconBasePath}" part="collapse-control-icon"></cui-icon>
|
|
56
|
-
</button>
|
|
57
|
-
</div>`;
|
|
59
|
+
if (this.sIconBasePath) {
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
sTemplate += `
|
|
62
|
+
<div class="header-controls" part="header-controls">
|
|
63
|
+
<button type="button" id="collapse-control" aria-controls="container" part="collapse-control">
|
|
64
|
+
<cui-icon src="caret-down" basePath="${this.sIconBasePath}" part="collapse-control-icon"></cui-icon>
|
|
65
|
+
</button>
|
|
66
|
+
</div>`;
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
|
|
71
|
+
sTemplate += `
|
|
72
|
+
<div class="header-controls" part="header-controls">
|
|
73
|
+
<button type="button" id="collapse-control" aria-controls="container" part="collapse-control">
|
|
74
|
+
<cui-icon src="caret-down" part="collapse-control-icon"></cui-icon>
|
|
75
|
+
</button>
|
|
76
|
+
</div>`;
|
|
77
|
+
}
|
|
69
78
|
|
|
79
|
+
}
|
|
70
80
|
}
|
|
71
81
|
|
|
72
82
|
sTemplate += `</header><div class="container" id="container" part="container">
|
|
83
|
+
<slot name="section-menu"></slot>
|
|
73
84
|
<slot name="section-text"></slot>
|
|
74
85
|
<slot name="section-messages"></slot>
|
|
75
86
|
<slot name="section-contents"></slot>
|
|
@@ -202,11 +213,18 @@ export default class CUI_SECTION extends HTMLElement {
|
|
|
202
213
|
this.state = {
|
|
203
214
|
sTitle: this.state.sTitle || this.getAttribute('sectiontitle') || "SECTION TITLE",
|
|
204
215
|
bHideControls: this.state.bHideControls || this.hasAttribute("hideControls") ? true : false,
|
|
216
|
+
bHideHeader: this.state.bHideHeader || this.hasAttribute("hideHeader") ? true : false,
|
|
205
217
|
bCollapsed: this.state.bCollapsed || (this.getAttribute('collapsed') === "true") ? true : false,
|
|
206
218
|
asStyles: this.state.asStyles || (this.getAttribute('styles')) ? this.getAttribute('styles').split(',') : null,
|
|
207
219
|
oInstructions: this.state.oInstructions || null
|
|
208
220
|
}
|
|
209
221
|
|
|
222
|
+
let match = window.matchMedia || window.msMatchMedia;
|
|
223
|
+
if(match) {
|
|
224
|
+
let mq = match("(pointer:coarse)");
|
|
225
|
+
this.bMobile = mq.matches;
|
|
226
|
+
}
|
|
227
|
+
|
|
210
228
|
this.sIconBasePath = this.getAttribute('iconbase') || null;
|
|
211
229
|
|
|
212
230
|
let dMessageList = this.querySelector(`[slot="section-messages"]`);
|
|
@@ -225,9 +243,11 @@ export default class CUI_SECTION extends HTMLElement {
|
|
|
225
243
|
this.sdSectionTitle = this.shadowRoot.querySelector(`#section-title`);
|
|
226
244
|
this.sdContentsContainer = this.shadowRoot.querySelector(`#container`);
|
|
227
245
|
|
|
228
|
-
|
|
246
|
+
if(!this.state.bHideHeader) {
|
|
247
|
+
this.sdSectionTitle.appendChild(document.createTextNode(this.state.sTitle));
|
|
248
|
+
}
|
|
229
249
|
|
|
230
|
-
if (!this.state.bHideControls) {
|
|
250
|
+
if (!this.state.bHideControls && !this.state.bHideHeader) {
|
|
231
251
|
|
|
232
252
|
this.sdSectionCollapseControl = this.shadowRoot.querySelector(`#collapse-control`);
|
|
233
253
|
|
|
@@ -299,6 +319,136 @@ export default class CUI_SECTION extends HTMLElement {
|
|
|
299
319
|
this.appendChild(dSectionInstructions);
|
|
300
320
|
}
|
|
301
321
|
|
|
322
|
+
let dSectionMenuSlot = this.querySelector('[slot="section-menu"]');
|
|
323
|
+
if(dSectionMenuSlot && dSectionMenuSlot.hasChildNodes()) {
|
|
324
|
+
this.generateSectionMenuButton(dSectionMenuSlot);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
generateSectionMenuButton(dSectionMenuSlot) {
|
|
329
|
+
let dMenuItems = dSectionMenuSlot.querySelectorAll('cui-item');
|
|
330
|
+
|
|
331
|
+
if(dMenuItems) {
|
|
332
|
+
let dHeaderControls = this.shadowRoot.querySelector('.header-controls');
|
|
333
|
+
let dCollapseControl = dHeaderControls.querySelector('#collapse-control');
|
|
334
|
+
|
|
335
|
+
let dMenuButton = document.createElement('button');
|
|
336
|
+
dMenuButton.classList.add('section-menu-btn');
|
|
337
|
+
dMenuButton.setAttribute('part', 'section-menu-btn');
|
|
338
|
+
dMenuButton.setAttribute('id', 'section-menu-btn');
|
|
339
|
+
dMenuButton.addEventListener('click', this.sectionMenuClick.bind(this, dMenuItems));
|
|
340
|
+
|
|
341
|
+
let dMenuIcon = document.createElement('cui-icon');
|
|
342
|
+
dMenuIcon.setAttribute('src', 'ellipsis-vertical');
|
|
343
|
+
dMenuIcon.setAttribute('part', 'section-menu-icon');
|
|
344
|
+
|
|
345
|
+
dMenuButton.appendChild(dMenuIcon);
|
|
346
|
+
dCollapseControl.before(dMenuButton);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
sectionMenuClick(dMenuItems, evt) {
|
|
351
|
+
evt.stopImmediatePropagation();
|
|
352
|
+
let dActiveBody = this.closest('body, dialog, modal');
|
|
353
|
+
if(this.bSectionMenuDisplayed) {
|
|
354
|
+
this.hideSectionMenu();
|
|
355
|
+
dActiveBody.removeEventListener('click', this.fGlobalBodyClick, false);
|
|
356
|
+
dActiveBody.removeEventListener('screenUnloadComplete', this.fGlobalBodyClick, false);
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
this.displaySectionMenu(dMenuItems, dActiveBody);
|
|
360
|
+
dActiveBody.addEventListener('click', this.fGlobalBodyClick, false);
|
|
361
|
+
dActiveBody.addEventListener('screenUnloadComplete', this.fGlobalBodyClick, false);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
displaySectionMenu(dMenuItems) {
|
|
366
|
+
if(this.dSectionMenu) {
|
|
367
|
+
if(this.bMobile) {
|
|
368
|
+
this.dSectionMenuDialog.showModal();
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
this.shadowRoot.appendChild(this.dSectionMenu);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
let dMenu = document.createElement('div');
|
|
376
|
+
dMenu.classList.add('section-menu-popover');
|
|
377
|
+
dMenu.setAttribute('part', 'section-menu-popover');
|
|
378
|
+
let bFirstMenuItem = true;
|
|
379
|
+
for(let dMenuItem of dMenuItems) {
|
|
380
|
+
let dMenuOption = document.createElement('button');
|
|
381
|
+
dMenuOption.innerHTML = dMenuItem.getAttribute('text');
|
|
382
|
+
if(bFirstMenuItem) {
|
|
383
|
+
dMenuOption.classList.add('section-menu-item');
|
|
384
|
+
dMenuOption.setAttribute('part', 'section-menu-item');
|
|
385
|
+
bFirstMenuItem = false;
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
dMenuOption.classList.add(['section-menu-item', 'not-first']);
|
|
389
|
+
dMenuOption.setAttribute('part', 'section-menu-item not-first');
|
|
390
|
+
}
|
|
391
|
+
dMenuOption.addEventListener('click', this.emitActionEvent.bind(this, dMenuItem.getAttribute('action')));
|
|
392
|
+
dMenu.appendChild(dMenuOption);
|
|
393
|
+
}
|
|
394
|
+
this.dSectionMenu = dMenu;
|
|
395
|
+
if(this.bMobile) {
|
|
396
|
+
let dMenuDialog = document.createElement('dialog');
|
|
397
|
+
dMenuDialog.setAttribute('id', 'section-menu-dialog');
|
|
398
|
+
dMenuDialog.classList.add('section-menu-dialog');
|
|
399
|
+
dMenuDialog.setAttribute('part', 'section-menu-dialog');
|
|
400
|
+
dMenuDialog.setAttribute('closedby', 'any');
|
|
401
|
+
|
|
402
|
+
dMenu.classList.add('dialog');
|
|
403
|
+
dMenu.setAttribute('part', dMenu.getAttribute('part') + ' dialog');
|
|
404
|
+
|
|
405
|
+
dMenuDialog.appendChild(dMenu);
|
|
406
|
+
this.shadowRoot.appendChild(dMenuDialog);
|
|
407
|
+
dMenuDialog.showModal();
|
|
408
|
+
this.dSectionMenuDialog = dMenuDialog;
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
this.shadowRoot.appendChild(dMenu);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
this.bSectionMenuDisplayed = true;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
emitActionEvent(sAction) {
|
|
418
|
+
const E_CONTROL_EVENT = new CustomEvent("eventAction", {
|
|
419
|
+
bubbles: true,
|
|
420
|
+
composed: true,
|
|
421
|
+
detail: {
|
|
422
|
+
target: this,
|
|
423
|
+
name: sAction
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
this.dispatchEvent(E_CONTROL_EVENT);
|
|
428
|
+
this.hideSectionMenu();
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
hideSectionMenu() {
|
|
432
|
+
if(this.bSectionMenuDisplayed === false) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if(this.bMobile) {
|
|
437
|
+
this.dSectionMenuDialog.close();
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
this.shadowRoot.removeChild(this.dSectionMenu);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
this.bSectionMenuDisplayed = false;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
globalBodyClick(evt) {
|
|
447
|
+
if(this.bSectionMenuDisplayed && !this.dSectionMenu.contains(evt.target)) {
|
|
448
|
+
this.hideSectionMenu();
|
|
449
|
+
evt.currentTarget.removeEventListener('click', this.fGlobalBodyClick, false);
|
|
450
|
+
evt.currentTarget.removeEventListener('screenUnloadComplete', this.fGlobalBodyClick, false);
|
|
451
|
+
}
|
|
302
452
|
}
|
|
303
453
|
|
|
304
454
|
get messages() {
|
package/src/section.scss
CHANGED
|
@@ -33,16 +33,16 @@
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
.header-controls {
|
|
36
|
-
flex: 0 1
|
|
36
|
+
flex: 0 1 auto;
|
|
37
37
|
margin: 10px 0 3px;
|
|
38
38
|
|
|
39
|
-
button
|
|
39
|
+
button#collapse-control,
|
|
40
|
+
button#section-menu-btn {
|
|
40
41
|
background: transparent;
|
|
41
42
|
border: 0;
|
|
42
43
|
border-radius: 32px;
|
|
43
44
|
cursor: pointer;
|
|
44
45
|
height: 32px;
|
|
45
|
-
margin-left: 0.5em;
|
|
46
46
|
margin-top: -7px;
|
|
47
47
|
transform: rotate(180deg);
|
|
48
48
|
width: 32px;
|
|
@@ -66,6 +66,19 @@
|
|
|
66
66
|
transform: rotate(0);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
|
|
70
|
+
button#collapse-control {
|
|
71
|
+
margin-left: 0.5em;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
button#section-menu-btn {
|
|
75
|
+
anchor-name: --section-menu;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&.headless {
|
|
80
|
+
border-bottom: none;
|
|
81
|
+
margin: 0.75em 0.75em;
|
|
69
82
|
}
|
|
70
83
|
|
|
71
84
|
}
|
|
@@ -91,6 +104,19 @@
|
|
|
91
104
|
}
|
|
92
105
|
}
|
|
93
106
|
|
|
107
|
+
.section-menu-popover {
|
|
108
|
+
display: flex;
|
|
109
|
+
flex-direction: column;
|
|
110
|
+
align-items: flex-end;
|
|
111
|
+
|
|
112
|
+
&:not(.dialog) {
|
|
113
|
+
position: fixed;
|
|
114
|
+
position-anchor: --section-menu;
|
|
115
|
+
top: anchor(bottom);
|
|
116
|
+
right: anchor(right);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
94
120
|
}
|
|
95
121
|
|
|
96
122
|
:host([subsection]) {
|