@kubex/zinc 1.0.8 → 1.0.10

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 (38) hide show
  1. package/dist/custom-elements.json +229 -10
  2. package/dist/vscode.html-custom-data.json +15 -2
  3. package/dist/web-types.json +64 -5
  4. package/dist/zn.d.ts +40 -2
  5. package/dist/zn.min.css +1 -1
  6. package/dist/zn.min.js +385 -372
  7. package/docs/pages/components/button.md +14 -0
  8. package/docs/pages/components/dropdown.md +6 -1
  9. package/docs/pages/components/table.md +1 -1
  10. package/package.json +1 -1
  11. package/scss/themes/_light.scss +1 -1
  12. package/src/components/button/button.component.ts +12 -20
  13. package/src/components/button/button.scss +3 -33
  14. package/src/components/button-menu/button-menu.component.ts +1 -0
  15. package/src/components/content-block/content-block.scss +54 -0
  16. package/src/components/data-table/data-table.component.ts +22 -3
  17. package/src/components/editor/editor.component.ts +110 -55
  18. package/src/components/editor/editor.scss +0 -1
  19. package/src/components/editor/modules/context-menu/context-menu-component.ts +1 -0
  20. package/src/components/editor/modules/context-menu/context-menu.scss +1 -1
  21. package/src/components/editor/modules/context-menu/context-menu.ts +58 -26
  22. package/src/components/editor/modules/context-menu/quick-action/quick-action.component.ts +1 -0
  23. package/src/components/editor/modules/toolbar/toolbar.component.ts +61 -33
  24. package/src/components/editor/modules/toolbar/toolbar.ts +19 -4
  25. package/src/components/header/header.scss +1 -0
  26. package/src/components/menu/menu.component.ts +2 -1
  27. package/src/components/menu-item/menu-item.component.ts +4 -0
  28. package/src/components/note/note.component.ts +2 -25
  29. package/src/components/note/note.scss +0 -7
  30. package/src/components/order-table/order-table.scss +16 -10
  31. package/src/components/panel/panel.component.ts +9 -3
  32. package/src/components/panel/panel.scss +8 -0
  33. package/src/components/popup/popup.component.ts +11 -21
  34. package/src/components/settings-container/settings-container.component.ts +22 -16
  35. package/src/components/settings-container/settings-container.scss +5 -4
  36. package/src/components/tabs/tabs.component.ts +24 -6
  37. package/src/components/tooltip/tooltip.component.ts +7 -7
  38. package/src/internal/form.ts +41 -3
@@ -4,6 +4,7 @@ import {litToHTML} from "../../../../utilities/lit-to-html";
4
4
  import {type ResultItem} from "./context-menu-component";
5
5
  import Quill, {Delta} from "quill";
6
6
  import ZnEditorQuickAction from "./quick-action";
7
+ import type {EditorFeatureConfig} from "../../editor.component";
7
8
  import type ContextMenuComponent from "./context-menu-component";
8
9
  import type Toolbar from "../toolbar/toolbar";
9
10
 
@@ -14,10 +15,12 @@ class ContextMenu {
14
15
  private _startIndex = -1;
15
16
  private _keydownHandler = (e: KeyboardEvent) => this.onKeydown(e);
16
17
  private _docClickHandler = (e: MouseEvent) => this.onDocumentClick(e);
18
+ private _featureConfig: EditorFeatureConfig = {};
17
19
 
18
- constructor(quill: Quill) {
20
+ constructor(quill: Quill, options: { config: EditorFeatureConfig }) {
19
21
  this._quill = quill;
20
22
  this._toolbarModule = quill.getModule('toolbar') as Toolbar;
23
+ this._featureConfig = options.config || {};
21
24
 
22
25
  this.initComponent();
23
26
  this.attachEvents();
@@ -199,7 +202,7 @@ class ContextMenu {
199
202
  Quill.sources.USER
200
203
  );
201
204
 
202
- setTimeout(() => this._quill.setSelection(insertIndex + contentDelta.length(), 0, Quill.sources.SILENT), 0);
205
+ setTimeout(() => this._quill.setSelection(insertIndex + contentDelta.length() + 1, 0, Quill.sources.SILENT), 0);
203
206
  }
204
207
  this._quill.focus();
205
208
  this.hide();
@@ -225,6 +228,7 @@ class ContextMenu {
225
228
 
226
229
  private _getOptions(): ResultItem[] {
227
230
  const options: ResultItem[] = [];
231
+ let orderCounter = 0;
228
232
 
229
233
  // 1) Quick Actions
230
234
  const root = this._quill.container.getRootNode() as ShadowRoot;
@@ -236,41 +240,69 @@ class ContextMenu {
236
240
 
237
241
  const {label, content, uri, icon, key} = quickAction;
238
242
 
243
+ let order: number;
244
+ if (typeof quickAction.order === 'number') {
245
+ order = quickAction.order!;
246
+ } else {
247
+ order = orderCounter++;
248
+ }
249
+
239
250
  if (label && icon) {
240
251
  if (key) {
241
- options.push({icon, label, format: 'toolbar', key: key});
252
+ options.push({icon, label, format: 'toolbar', key: key, order});
242
253
  } else if (uri) {
243
- options.push({icon, label, format: 'dialog', value: uri});
254
+ options.push({icon, label, format: 'dialog', value: uri, order});
244
255
  } else if (content) {
245
- options.push({icon, label, format: 'insert', value: content});
256
+ options.push({icon, label, format: 'insert', value: content, order});
246
257
  }
247
258
  }
248
259
  });
249
260
  }
250
261
 
251
- // 2) Built-in Actions
262
+ // 2) Built-in Actions (In order they should appear)
252
263
  options.push(
253
- {icon: 'format_bold', label: 'Bold', format: 'bold'},
254
- {icon: 'format_italic', label: 'Italic', format: 'italic'},
255
- {icon: 'format_underlined', label: 'Underline', format: 'underline'},
256
- {icon: 'strikethrough_s', label: 'Strikethrough', format: 'strike'},
257
- {icon: 'format_quote', label: 'Blockquote', format: 'blockquote'},
258
- {icon: 'code', label: 'Inline Code', format: 'code'},
259
- {icon: 'code_blocks', label: 'Code Block', format: 'code-block'},
260
- {icon: 'format_h1', label: 'Heading 1', format: 'header', value: '1'},
261
- {icon: 'format_h2', label: 'Heading 2', format: 'header', value: '2'},
262
- {icon: 'match_case', label: 'Normal Text', format: 'header', value: ''},
263
- {icon: 'format_list_bulleted', label: 'Bulleted List', format: 'list', value: 'bullet'},
264
- {icon: 'format_list_numbered', label: 'Numbered List', format: 'list', value: 'ordered'},
265
- {icon: 'checklist', label: 'Checklist', format: 'list', value: 'checked'},
266
- {icon: 'link', label: 'Link', format: 'link', value: true},
267
- {icon: 'horizontal_rule', label: 'Divider', format: 'divider'},
268
- {icon: 'attachment', label: 'Attachment', format: 'attachment'},
269
- {icon: 'image', label: 'Image', format: 'image'},
270
- {icon: 'video_camera_back', label: 'Video', format: 'video'},
271
- {icon: 'calendar_today', label: 'Date', format: 'date'},
272
- {icon: 'format_clear', label: 'Clear Formatting', format: 'clean'}
264
+ {icon: 'format_bold', label: 'Bold', format: 'bold', order: orderCounter++},
265
+ {icon: 'format_italic', label: 'Italic', format: 'italic', order: orderCounter++},
266
+ {icon: 'format_underlined', label: 'Underline', format: 'underline', order: orderCounter++},
267
+ {icon: 'strikethrough_s', label: 'Strikethrough', format: 'strike', order: orderCounter++},
268
+ {icon: 'format_quote', label: 'Blockquote', format: 'blockquote', order: orderCounter++},
273
269
  );
270
+ if (this._featureConfig.codeEnabled !== false) {
271
+ options.push({icon: 'code', label: 'Inline Code', format: 'code', order: orderCounter++});
272
+ }
273
+ if (this._featureConfig.codeBlocksEnabled !== false) {
274
+ options.push({icon: 'code_blocks', label: 'Code Block', format: 'code-block', order: orderCounter++});
275
+ }
276
+ options.push(
277
+ {icon: 'format_h1', label: 'Heading 1', format: 'header', value: '1', order: orderCounter++},
278
+ {icon: 'format_h2', label: 'Heading 2', format: 'header', value: '2', order: orderCounter++},
279
+ {icon: 'match_case', label: 'Normal Text', format: 'header', value: '', order: orderCounter++},
280
+ {icon: 'format_list_bulleted', label: 'Bulleted List', format: 'list', value: 'bullet', order: orderCounter++},
281
+ {icon: 'format_list_numbered', label: 'Numbered List', format: 'list', value: 'ordered', order: orderCounter++},
282
+ {icon: 'checklist', label: 'Checklist', format: 'list', value: 'checked', order: orderCounter++}
283
+ );
284
+ if (this._featureConfig.linksEnabled !== false) {
285
+ options.push({icon: 'link', label: 'Link', format: 'link', value: true, order: orderCounter++});
286
+ }
287
+ if (this._featureConfig.dividersEnabled !== false) {
288
+ options.push({icon: 'horizontal_rule', label: 'Divider', format: 'divider', order: orderCounter++});
289
+ }
290
+ if (this._featureConfig.attachmentsEnabled !== false) {
291
+ options.push({icon: 'attachment', label: 'Attachment', format: 'attachment', order: orderCounter++});
292
+ }
293
+ if (this._featureConfig.imagesEnabled !== false) {
294
+ options.push({icon: 'image', label: 'Image', format: 'image', order: orderCounter++});
295
+ }
296
+ if (this._featureConfig.videosEnabled !== false) {
297
+ options.push({icon: 'video_camera_back', label: 'Video', format: 'video', order: orderCounter++});
298
+ }
299
+ if (this._featureConfig.datesEnabled !== false) {
300
+ options.push({icon: 'calendar_today', label: 'Date', format: 'date', order: orderCounter++});
301
+ }
302
+ options.push({icon: 'format_clear', label: 'Clear Formatting', format: 'clean', order: orderCounter++});
303
+
304
+ // Sort options by order property
305
+ options.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
274
306
 
275
307
  return options;
276
308
  }
@@ -8,6 +8,7 @@ export default class ZnEditorQuickAction extends ZincElement {
8
8
  @property() content: string;
9
9
  @property() key: string;
10
10
  @property() icon: string;
11
+ @property({type: Number}) order?: number | null;
11
12
 
12
13
  render() {
13
14
  return html`
@@ -6,6 +6,7 @@ import ZnButton from "../../../button";
6
6
  import ZnEditorTool from "./tool";
7
7
  import ZnMenu from "../../../menu";
8
8
  import ZnMenuItem from "../../../menu-item";
9
+ import type {EditorFeatureConfig} from "../../editor.component";
9
10
 
10
11
  import styles from './toolbar.scss';
11
12
 
@@ -22,6 +23,7 @@ export default class ToolbarComponent extends ZincElement {
22
23
  @query('.toolbar__overflow-menu') private _overflowMenu!: HTMLElement;
23
24
  @query('.toolbar__group--overflow') private _overflowGroup!: HTMLElement;
24
25
 
26
+ private _featureConfig: EditorFeatureConfig = {};
25
27
  private _resizeObserver: ResizeObserver | null = null;
26
28
  private _resizeId: number | null = null;
27
29
 
@@ -78,6 +80,10 @@ export default class ToolbarComponent extends ZincElement {
78
80
  });
79
81
  }
80
82
 
83
+ public configureToolbar(config: EditorFeatureConfig) {
84
+ this._featureConfig = config;
85
+ }
86
+
81
87
  private getToolbarWidth() {
82
88
  const host = this as unknown as HTMLElement;
83
89
  let width = host.getBoundingClientRect?.().width || host.offsetWidth || 0;
@@ -456,6 +462,13 @@ export default class ToolbarComponent extends ZincElement {
456
462
  }
457
463
 
458
464
  render() {
465
+ const showInsertOptions = this._featureConfig.dividersEnabled ||
466
+ this._featureConfig.linksEnabled ||
467
+ this._featureConfig.attachmentsEnabled ||
468
+ this._featureConfig.imagesEnabled ||
469
+ this._featureConfig.videosEnabled;
470
+ const showInsertGroup = showInsertOptions || this._featureConfig.datesEnabled || this._featureConfig.emojisEnabled;
471
+
459
472
  return html`
460
473
  <div class="toolbar">
461
474
  <div class="toolbar__group">${this._textOptions()}</div>
@@ -463,11 +476,12 @@ export default class ToolbarComponent extends ZincElement {
463
476
  <div class="toolbar__group">${this._historyOptions()}</div>
464
477
  <div class="toolbar__group">${this._colorOptions()}</div>
465
478
  <div class="toolbar__group">${this._listOptions()}</div>
466
- <div class="toolbar__group">
467
- ${this._insertOptions()}
468
- ${this._dateOption()}
469
- ${this._emojiOptions()}
470
- </div>
479
+ ${showInsertGroup ? html`
480
+ <div class="toolbar__group">
481
+ ${showInsertOptions ? html`${this._insertOptions()}` : ''}
482
+ ${this._featureConfig.datesEnabled ? html`${this._dateOption()}` : ''}
483
+ ${this._featureConfig.emojisEnabled ? html`${this._emojiOptions()}` : ''}
484
+ </div>` : ''}
471
485
  <div class="toolbar__group">
472
486
  <slot></slot>
473
487
  </div>
@@ -550,14 +564,18 @@ export default class ToolbarComponent extends ZincElement {
550
564
  <zn-icon src="format_quote" size="18" slot="prefix"></zn-icon>
551
565
  Quote
552
566
  </zn-menu-item>
553
- <zn-menu-item type="checkbox" checked-position="right" data-format="code">
554
- <zn-icon src="code" size="18" slot="prefix"></zn-icon>
555
- Code
556
- </zn-menu-item>
557
- <zn-menu-item type="checkbox" checked-position="right" data-format="code-block">
558
- <zn-icon src="code_blocks" size="18" slot="prefix"></zn-icon>
559
- Code Block
560
- </zn-menu-item>
567
+ ${this._featureConfig.codeEnabled ? html`
568
+ <zn-menu-item type="checkbox" checked-position="right" data-format="code">
569
+ <zn-icon src="code" size="18" slot="prefix"></zn-icon>
570
+ Code
571
+ </zn-menu-item>
572
+ ` : ''}
573
+ ${this._featureConfig.codeBlocksEnabled ? html`
574
+ <zn-menu-item type="checkbox" checked-position="right" data-format="code-block">
575
+ <zn-icon src="code_blocks" size="18" slot="prefix"></zn-icon>
576
+ Code Block
577
+ </zn-menu-item>
578
+ ` : ''}
561
579
  <zn-menu-item data-format="clean">
562
580
  <zn-icon src="format_clear" size="18" slot="prefix"></zn-icon>
563
581
  Clear Formatting
@@ -680,26 +698,36 @@ export default class ToolbarComponent extends ZincElement {
680
698
  <zn-icon src="add" size="18"></zn-icon>
681
699
  </zn-button>
682
700
  <zn-menu>
683
- <zn-menu-item checked-position="right" data-format="divider">
684
- <zn-icon src="horizontal_rule" size="18" slot="prefix"></zn-icon>
685
- Divider
686
- </zn-menu-item>
687
- <zn-menu-item checked-position="right" data-format="link">
688
- <zn-icon src="link" size="18" slot="prefix"></zn-icon>
689
- Link
690
- </zn-menu-item>
691
- <zn-menu-item checked-position="right" data-format="attachment">
692
- <zn-icon src="attachment" size="18" slot="prefix"></zn-icon>
693
- Attachment
694
- </zn-menu-item>
695
- <zn-menu-item checked-position="right" data-format="image">
696
- <zn-icon src="image" size="18" slot="prefix"></zn-icon>
697
- Image
698
- </zn-menu-item>
699
- <zn-menu-item checked-position="right" data-format="video">
700
- <zn-icon src="video_camera_back" size="18" slot="prefix"></zn-icon>
701
- Video
702
- </zn-menu-item>
701
+ ${this._featureConfig.dividersEnabled ? html`
702
+ <zn-menu-item checked-position="right" data-format="divider">
703
+ <zn-icon src="horizontal_rule" size="18" slot="prefix"></zn-icon>
704
+ Divider
705
+ </zn-menu-item>
706
+ ` : ''}
707
+ ${this._featureConfig.linksEnabled ? html`
708
+ <zn-menu-item checked-position="right" data-format="link">
709
+ <zn-icon src="link" size="18" slot="prefix"></zn-icon>
710
+ Link
711
+ </zn-menu-item>
712
+ ` : ''}
713
+ ${this._featureConfig.attachmentsEnabled ? html`
714
+ <zn-menu-item checked-position="right" data-format="attachment">
715
+ <zn-icon src="attachment" size="18" slot="prefix"></zn-icon>
716
+ Attachment
717
+ </zn-menu-item>
718
+ ` : ''}
719
+ ${this._featureConfig.imagesEnabled ? html`
720
+ <zn-menu-item checked-position="right" data-format="image">
721
+ <zn-icon src="image" size="18" slot="prefix"></zn-icon>
722
+ Image
723
+ </zn-menu-item>
724
+ ` : ''}
725
+ ${this._featureConfig.videosEnabled ? html`
726
+ <zn-menu-item checked-position="right" data-format="video">
727
+ <zn-icon src="video_camera_back" size="18" slot="prefix"></zn-icon>
728
+ Video
729
+ </zn-menu-item>
730
+ ` : ''}
703
731
  </zn-menu>
704
732
  </zn-dropdown>`;
705
733
  }
@@ -1,6 +1,7 @@
1
1
  import './toolbar.component';
2
2
  import Quill from "quill";
3
3
  import QuillToolbar from "quill/modules/toolbar";
4
+ import type {EditorFeatureConfig} from "../../editor.component";
4
5
  import type Attachment from "../attachment/attachment";
5
6
  import type DialogComponent from "../dialog/dialog.component";
6
7
  import type Emoji from "../emoji/emoji";
@@ -17,20 +18,34 @@ class Toolbar extends QuillToolbar {
17
18
  constructor(quill: Quill, options: {
18
19
  container: ToolbarComponent;
19
20
  handlers?: Record<string, (value?: any) => void>;
21
+ config?: EditorFeatureConfig;
20
22
  }) {
21
23
  super(quill, options);
22
24
 
25
+ const featureConfig = options.config;
26
+
23
27
  // Add handlers after parent Toolbar initialization
24
- this.addHandler('attachment', () => null);
25
- this.addHandler('date', () => this._openDatePicker());
26
- this.addHandler('divider', () => this._insertDivider());
28
+ if (featureConfig?.attachmentsEnabled) {
29
+ this.addHandler('attachment', () => null);
30
+ }
31
+ if (featureConfig?.datesEnabled) {
32
+ this.addHandler('date', () => this._openDatePicker());
33
+ }
34
+ if (featureConfig?.dividersEnabled) {
35
+ this.addHandler('divider', () => this._insertDivider());
36
+ }
37
+ if (featureConfig?.imagesEnabled) {
38
+ this.addHandler('image', () => this._addImage());
39
+ }
27
40
  this.addHandler('redo', () => quill.history.redo());
28
41
  this.addHandler('undo', () => quill.history.undo());
29
42
  this.addHandler('dialog', (value: string) => this._openDialog(value));
30
- this.addHandler('image', () => this._addImage());
31
43
 
32
44
  this._quill = quill;
33
45
  this._component = options.container;
46
+ if (featureConfig) {
47
+ this._component.configureToolbar(featureConfig)
48
+ }
34
49
 
35
50
  this._component.updateComplete.then(() => {
36
51
  this._attachToolbarHandlers();
@@ -233,6 +233,7 @@
233
233
  align-items: center;
234
234
  flex-wrap: wrap;
235
235
  gap: var(--zn-spacing-x-small);
236
+ word-break: break-word;
236
237
  }
237
238
 
238
239
  slot[name="nav"] {
@@ -112,7 +112,8 @@ export default class ZnMenu extends ZincElement {
112
112
  action="${item.confirm?.action}"></zn-confirm>
113
113
  <zn-menu-item @mousedown=${this.handleMouseDown}
114
114
  @keydown=${this.handleKeyDown}
115
- id="${item.confirm?.trigger}">
115
+ id="${item.confirm?.trigger}"
116
+ confirm>
116
117
  ${(item.icon) ? html`
117
118
  <zn-icon src="${item.icon}" size="20" slot="prefix"></zn-icon>` : html``}
118
119
  ${item.title}
@@ -76,6 +76,8 @@ export default class ZnMenuItem extends ZincElement {
76
76
 
77
77
  @property({attribute: 'gaid'}) gaid: string;
78
78
 
79
+ @property({type: Boolean, reflect: true}) confirm = false;
80
+
79
81
  private readonly localize = new LocalizeController(this);
80
82
  private readonly hasSlotController = new HasSlotController(this, 'submenu');
81
83
  private submenuController: SubmenuController = new SubmenuController(this, this.hasSlotController, this.localize);
@@ -118,6 +120,8 @@ export default class ZnMenuItem extends ZincElement {
118
120
  if (!this.isSubmenu()) {
119
121
  const composedPath = event.composedPath();
120
122
  const closestMenu: Element | null = composedPath.find((el: Element) => el?.getAttribute?.('role') === 'menu') as Element;
123
+ if (this.confirm) return;
124
+
121
125
  (closestMenu?.closest('zn-dropdown') as ZnDropdown | null)?.hide();
122
126
  this.emit('zn-menu-select', {detail: {value: this.value, element: this}});
123
127
  }
@@ -38,49 +38,26 @@ export default class ZnNote extends ZincElement {
38
38
  // Internal state: whether the body is currently expanded
39
39
  @state() private expanded = false;
40
40
 
41
- // Internal state: whether the content actually overflows the clamp
42
- @state() private _isOverflowing = false;
43
-
44
41
  private _toggleExpand = () => {
45
42
  this.expanded = !this.expanded;
46
- // re-evaluate overflow after toggle (in case of dynamic content)
47
43
  this.updateComplete.then(() => this._measureOverflow());
48
44
  }
49
45
 
50
46
  private _measureOverflow() {
51
- // Only relevant when collapseAtLines is set and not expanded
52
47
  const container = this.shadowRoot?.querySelector('.note__body-container') as HTMLElement | null;
53
- if (!container) {
54
- this._isOverflowing = false;
55
- return;
56
- }
57
-
58
- if (this.collapseAtLines <= 0) {
59
- this._isOverflowing = false;
48
+ if (!container || this.collapseAtLines <= 0) {
60
49
  return;
61
50
  }
62
51
 
63
- // Temporarily ensure clamped styles are applied to measure
64
52
  container.style.setProperty('--note-collapse-lines', String(this.collapseAtLines));
65
53
  container.classList.toggle('note__body--clamped', !this.expanded);
66
-
67
- // element starts hidden, cannot measure
68
- if (container.clientHeight === 0) {
69
- this._isOverflowing = false;
70
- return;
71
- }
72
-
73
- // Measure overflow
74
- this._isOverflowing = container.scrollHeight > container.clientHeight + 1; // +1 for rounding errors
75
54
  }
76
55
 
77
56
  protected firstUpdated() {
78
- // Initial measurement of overflow
79
57
  this._measureOverflow();
80
58
  }
81
59
 
82
60
  protected updated() {
83
- // Re-measure on any update to catch slot/content changes
84
61
  this._measureOverflow();
85
62
  }
86
63
 
@@ -110,7 +87,7 @@ export default class ZnNote extends ZincElement {
110
87
  })}" style="--note-collapse-lines: ${this.collapseAtLines}">
111
88
  <slot class="note__body"></slot>
112
89
  </div>
113
- ${this.collapseAtLines > 0 && this._isOverflowing ? html`
90
+ ${this.collapseAtLines > 0 ? html`
114
91
  <div class="note__toggle">
115
92
  <zn-button color="transparent"
116
93
  size="content"
@@ -51,13 +51,6 @@ $colors: (
51
51
  display: block;
52
52
  }
53
53
 
54
- &__body--clamped {
55
- display: -webkit-box;
56
- -webkit-box-orient: vertical;
57
- -webkit-line-clamp: var(--note-collapse-lines, 0);
58
- overflow: hidden;
59
- }
60
-
61
54
  &__toggle {
62
55
  margin-top: var(--zn-spacing-2x-small);
63
56
  }
@@ -2,13 +2,16 @@
2
2
 
3
3
 
4
4
  .table {
5
- display: table;
5
+ display: flex;
6
+ flex-direction: column;
6
7
  width: 100%;
7
8
  }
8
9
 
9
10
 
10
11
  .header {
11
- display: table-header-group;
12
+ display: flex;
13
+ align-items: center;
14
+ width: 100%;
12
15
  }
13
16
 
14
17
  .header-item, .row-item {
@@ -32,11 +35,17 @@
32
35
  }
33
36
 
34
37
  @include wc.container-query(md) {
35
- display: table-cell;
38
+ flex: 1;
36
39
  border-bottom: 1px solid rgb(var(--zn-border-color));
37
40
 
38
41
  &:first-child {
39
- width: 50%;
42
+ width: 35%;
43
+ flex-basis: 35%;
44
+ align-items: flex-start;
45
+
46
+ &.row-caption {
47
+ text-align: left;
48
+ }
40
49
  }
41
50
 
42
51
  &:last-child {
@@ -66,6 +75,7 @@
66
75
  font-size: 14px;
67
76
  font-weight: 600;
68
77
  color: rgb(var(--zn-text-heading));
78
+ white-space: nowrap;
69
79
  }
70
80
 
71
81
  .row-caption .content {
@@ -78,10 +88,8 @@
78
88
 
79
89
  .rows {
80
90
  width: 100%;
81
-
82
- @include wc.container-query(md) {
83
- display: table-row-group;
84
- }
91
+ display: flex;
92
+ flex-direction: column;
85
93
  }
86
94
 
87
95
  .row {
@@ -91,7 +99,6 @@
91
99
  width: 100%;
92
100
 
93
101
  @include wc.container-query(md) {
94
- display: table-row;
95
102
  border-bottom: none;
96
103
  }
97
104
  }
@@ -111,7 +118,6 @@
111
118
  width: 100%;
112
119
 
113
120
  @include wc.container-query(md) {
114
- display: table-row;
115
121
  border-bottom: none;
116
122
  }
117
123
  }
@@ -31,12 +31,14 @@ export default class ZnPanel extends ZincElement {
31
31
  @property() icon: string;
32
32
  @property() description: string;
33
33
  @property({type: Boolean}) tabbed: boolean;
34
+ @property({attribute: 'header-underline', type: Boolean}) underlineHeader: boolean;
34
35
  @property({type: Boolean}) cosmic: boolean;
35
36
  @property({type: Boolean}) flush: boolean;
36
37
  @property({attribute: 'flush-x', type: Boolean}) flushX: boolean;
37
38
  @property({attribute: 'flush-y', type: Boolean}) flushY: boolean;
38
39
  @property({attribute: 'flush-footer', type: Boolean}) flushFooter: boolean;
39
40
  @property({type: Boolean}) transparent: boolean;
41
+ @property({type: Boolean}) shadow: boolean;
40
42
 
41
43
  protected firstUpdated(_changedProperties: PropertyValues) {
42
44
  super.firstUpdated(_changedProperties);
@@ -78,7 +80,7 @@ export default class ZnPanel extends ZincElement {
78
80
  const hasHeader = this.caption || hasActionSlot;
79
81
 
80
82
  return html`
81
- <div part="base" class="${classMap({
83
+ <div class="${classMap({
82
84
  panel: true,
83
85
  'panel--flush': this.flush || this.tabbed,
84
86
  'panel--flush-x': this.flushX,
@@ -89,12 +91,16 @@ export default class ZnPanel extends ZincElement {
89
91
  'panel--has-actions': hasActionSlot,
90
92
  'panel--has-footer': hasFooterSlot,
91
93
  'panel--has-header': hasHeader,
92
- 'panel--cosmic': this.cosmic
94
+ 'panel--cosmic': this.cosmic,
95
+ 'panel--shadow': this.shadow
93
96
  })}">
94
97
 
95
98
  <div class="panel__inner">
96
99
  ${hasHeader ? html`
97
- <zn-header class="panel__header"
100
+ <zn-header class="${classMap({
101
+ "panel__header": true,
102
+ "panel__header--underline": this.underlineHeader,
103
+ })}"
98
104
  icon="${this.icon}"
99
105
  caption="${this.caption}"
100
106
  description="${ifDefined(this.description)}"
@@ -40,6 +40,10 @@
40
40
  border-bottom: 0;
41
41
  }
42
42
 
43
+ &--underline {
44
+ border-bottom: 1px solid rgb(var(--zn-border-color));
45
+ }
46
+
43
47
  &::part(content) {
44
48
  padding: 0;
45
49
  }
@@ -136,4 +140,8 @@
136
140
  &--cosmic {
137
141
  @include wc.cosmic-border();
138
142
  }
143
+
144
+ &--shadow {
145
+ box-shadow: 0 6px 20px 10px rgba(0, 0, 0, 0.25);
146
+ }
139
147
  }
@@ -1,22 +1,11 @@
1
- import {
2
- arrow,
3
- autoUpdate,
4
- computePosition,
5
- flip,
6
- offset,
7
- platform,
8
- shift,
9
- size
10
- } from '@floating-ui/dom';
1
+ import {arrow, autoUpdate, computePosition, flip, offset, platform, shift, size} from '@floating-ui/dom';
11
2
  import {classMap} from 'lit/directives/class-map.js';
12
3
  import {html, unsafeCSS} from 'lit';
13
4
  import {offsetParent} from 'composed-offset-position';
14
5
  import {property, query} from 'lit/decorators.js';
15
6
  import ZincElement from '../../internal/zinc-element';
16
7
  import type {CSSResultGroup} from 'lit';
17
- import type {
18
- MiddlewareData
19
- } from '@floating-ui/dom';
8
+ import type {MiddlewareData} from '@floating-ui/dom';
20
9
 
21
10
  import styles from './popup.scss';
22
11
 
@@ -210,7 +199,9 @@ export default class ZnPopup extends ZincElement {
210
199
 
211
200
  // Start the positioner after the first update
212
201
  await this.updateComplete;
213
- this.start();
202
+ if (this.active) {
203
+ this.start();
204
+ }
214
205
  }
215
206
 
216
207
  disconnectedCallback() {
@@ -260,7 +251,7 @@ export default class ZnPopup extends ZincElement {
260
251
  }
261
252
 
262
253
  // If the anchor is valid, start it up
263
- if (this.anchorEl) {
254
+ if (this.anchorEl && this.active) {
264
255
  this.start();
265
256
  }
266
257
  }
@@ -270,7 +261,6 @@ export default class ZnPopup extends ZincElement {
270
261
  if (!this.anchorEl) {
271
262
  return;
272
263
  }
273
-
274
264
  this.cleanup = autoUpdate(this.anchorEl, this.popup, () => {
275
265
  this.reposition();
276
266
  });
@@ -527,26 +517,26 @@ export default class ZnPopup extends ZincElement {
527
517
 
528
518
  render() {
529
519
  return html`
530
- <slot class="anchor" name="anchor" @slotchange=${this.handleAnchorChange}></slot>
520
+ <slot class="anchor" name="anchor" @slotchange="${this.handleAnchorChange}"></slot>
531
521
 
532
522
  <span
533
523
  part="hover-bridge"
534
- class=${classMap({
524
+ class="${classMap({
535
525
  'popup-hover-bridge': true,
536
526
  'popup-hover-bridge--visible': this.hoverBridge && this.active
537
- })}
527
+ })}"
538
528
  ></span>
539
529
 
540
530
  <div
541
531
  id="popup"
542
532
  part="popup"
543
533
  popover
544
- class=${classMap({
534
+ class="${classMap({
545
535
  popup: true,
546
536
  'popup--active': this.active,
547
537
  'popup--fixed': this.strategy === 'fixed',
548
538
  'popup--has-arrow': this.arrow
549
- })}
539
+ })}"
550
540
  >
551
541
  <slot></slot>
552
542
  ${this.arrow ? html`