@kubex/zinc 1.0.104 → 1.0.105

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubex/zinc",
3
- "version": "1.0.104",
3
+ "version": "1.0.105",
4
4
  "description": "A collection of web components for building web applications based off of @shoelace-style/Shoelace",
5
5
  "keywords": [
6
6
  "web components",
@@ -3,18 +3,19 @@ import {type CSSResultGroup, html, type PropertyValues, unsafeCSS} from 'lit';
3
3
  import {defaultValue} from "../../internal/default-value";
4
4
  import {FormControlController} from "../../internal/form";
5
5
  import {HasSlotController} from "../../internal/slot";
6
+ import {ifDefined} from "lit/directives/if-defined.js";
6
7
  import {marked} from "marked";
7
- import {property, query, state} from 'lit/decorators.js';
8
+ import {property, query} from 'lit/decorators.js';
8
9
  import {watch} from "../../internal/watch";
9
- import ZincElement from '../../internal/zinc-element';
10
10
  import type {ZincFormControl} from '../../internal/zinc-element';
11
11
  import type ZnTextarea from "../textarea";
12
12
 
13
13
  import styles from './markdown-editor.scss';
14
+ import ZnPanel from "../panel/panel.component";
14
15
 
15
16
  type ViewMode = 'editor' | 'split' | 'preview';
16
17
 
17
- const VIEW_MODES: {mode: ViewMode; icon: string; label: string}[] = [
18
+ const VIEW_MODES: { mode: ViewMode; icon: string; label: string }[] = [
18
19
  {mode: 'editor', icon: 'edit_note', label: 'Editor'},
19
20
  {mode: 'split', icon: 'vertical_split', label: 'Split'},
20
21
  {mode: 'preview', icon: 'visibility', label: 'Preview'},
@@ -42,13 +43,13 @@ const VIEW_MODES: {mode: ViewMode; icon: string; label: string}[] = [
42
43
  * @csspart editor - The textarea wrapper.
43
44
  * @csspart preview - The rendered markdown preview.
44
45
  */
45
- export default class ZnMarkdownEditor extends ZincElement implements ZincFormControl {
46
- static styles: CSSResultGroup = unsafeCSS(styles);
46
+ export default class ZnMarkdownEditor extends ZnPanel implements ZincFormControl {
47
+ static styles: CSSResultGroup = [ZnPanel.styles as CSSResultGroup, unsafeCSS(styles)];
47
48
 
48
49
  private readonly formControlController = new FormControlController(this, {
49
50
  assumeInteractionOn: ['zn-input', 'zn-change'],
50
51
  });
51
- private readonly hasSlotController = new HasSlotController(this, 'label', 'help-text');
52
+ private readonly markdownSlotController = new HasSlotController(this, 'label', 'help-text', 'actions', 'footer');
52
53
 
53
54
  private debounceTimer: ReturnType<typeof setTimeout> | null = null;
54
55
 
@@ -95,7 +96,7 @@ export default class ZnMarkdownEditor extends ZincElement implements ZincFormCon
95
96
  @property({type: Boolean, reflect: true}) disabled = false;
96
97
 
97
98
  /** Whether the editor is currently expanded to cover its containing positioned ancestor. */
98
- @state() expanded = false;
99
+ @property({type: Boolean, reflect: true}) expanded = false;
99
100
 
100
101
  get validity(): ValidityState {
101
102
  return this.textarea?.validity;
@@ -151,15 +152,18 @@ export default class ZnMarkdownEditor extends ZincElement implements ZincFormCon
151
152
 
152
153
  const stored = this.readStoredViewMode();
153
154
  if (stored) this.viewMode = stored;
155
+
156
+ this.addEventListener('toggle', this.handleExpandToggle as EventListener);
154
157
  }
155
158
 
156
159
  disconnectedCallback() {
157
160
  super.disconnectedCallback();
158
161
  if (this.debounceTimer) clearTimeout(this.debounceTimer);
162
+ this.removeEventListener('toggle', this.handleExpandToggle as EventListener);
159
163
  }
160
164
 
161
165
  protected firstUpdated(_changedProperties: PropertyValues) {
162
- void _changedProperties;
166
+ super.firstUpdated(_changedProperties);
163
167
  this.formControlController.updateValidity();
164
168
  if (this.viewMode !== 'editor') this.renderPreview();
165
169
  }
@@ -240,70 +244,109 @@ export default class ZnMarkdownEditor extends ZincElement implements ZincFormCon
240
244
  }
241
245
 
242
246
  render() {
243
- const hasLabelSlot = this.hasSlotController.test('label');
244
- const hasHelpSlot = this.hasSlotController.test('help-text');
247
+ const hasLabelSlot = this.markdownSlotController.test('label');
248
+ const hasHelpSlot = this.markdownSlotController.test('help-text');
249
+ const hasActionSlot = this.markdownSlotController.test('actions');
250
+ const hasFooterSlot = this.markdownSlotController.test('footer');
245
251
  const hasLabel = !!this.label || hasLabelSlot;
246
252
  const hasHelpText = !!this.helpText || hasHelpSlot;
253
+ const hasHeader = !!this.caption || hasActionSlot;
247
254
  const showEditor = this.viewMode === 'editor' || this.viewMode === 'split';
248
255
  const showPreview = this.viewMode === 'preview' || this.viewMode === 'split';
249
256
 
250
257
  return html`
251
- <div part="base"
252
- class=${classMap({
253
- 'markdown-editor': true,
254
- 'markdown-editor--expanded': this.expanded,
255
- 'markdown-editor--split': this.viewMode === 'split',
256
- 'markdown-editor--preview-only': this.viewMode === 'preview',
257
- })}>
258
- ${hasLabel ? html`
259
- <label class="markdown-editor__label">
260
- <slot name="label">${this.label}</slot>
261
- </label>` : ''}
262
-
263
- <div part="toolbar" class="markdown-editor__toolbar">
264
- <zn-button-group class="markdown-editor__view-toggle" @click=${this.handleViewToggle}>
265
- ${VIEW_MODES.map(v => this.renderViewButton(v.mode, v.icon, v.label))}
266
- </zn-button-group>
267
- <zn-button
268
- class="markdown-editor__expand-btn"
269
- type="button"
270
- size="medium"
271
- color="secondary"
272
- icon=${this.expanded ? 'close_fullscreen' : 'open_in_full'}
273
- icon-size="18"
274
- tooltip=${this.expanded ? 'Collapse' : 'Expand'}
275
- @click=${this.handleExpandToggle}
276
- ></zn-button>
277
- </div>
278
-
279
- <div class="markdown-editor__body">
280
- <div part="editor"
281
- class="markdown-editor__editor"
282
- ?hidden=${!showEditor}>
283
- <zn-textarea
284
- .value=${this.value}
285
- name=${this.name || ''}
286
- placeholder=${this.placeholder}
287
- rows=${this.rows}
288
- resize="auto"
289
- ?required=${this.required}
290
- ?readonly=${this.readonly}
291
- ?disabled=${this.disabled}
292
- @zn-input=${this.handleInput}
293
- @zn-change=${this.handleChange}
294
- ></zn-textarea>
258
+ <div part="base" class=${classMap({
259
+ panel: true,
260
+ 'panel--flush': this.flush || this.tabbed,
261
+ 'panel--flush-x': this.flushX,
262
+ 'panel--flush-y': this.flushY,
263
+ 'panel--flush-footer': this.flushFooter,
264
+ 'panel--tabbed': this.tabbed,
265
+ 'panel--transparent': this.transparent,
266
+ 'panel--has-actions': hasActionSlot,
267
+ 'panel--has-footer': hasFooterSlot,
268
+ 'panel--has-header': hasHeader,
269
+ 'panel--cosmic': this.cosmic,
270
+ 'panel--shadow': this.shadow,
271
+ })}>
272
+ <div class="panel__inner">
273
+ ${hasHeader ? html`
274
+ <zn-header class=${classMap({
275
+ panel__header: true,
276
+ 'panel__header--underline': this.underlineHeader,
277
+ })}
278
+ icon=${this.icon}
279
+ caption=${this.caption}
280
+ description=${ifDefined(this.description)}
281
+ transparent>
282
+ ${hasActionSlot ? html`
283
+ <slot name="actions" slot="actions" class="panel__header__actions"></slot>` : null}
284
+ </zn-header>` : null}
285
+
286
+ <div class="panel__content">
287
+ <div class="panel__body">
288
+ <div class=${classMap({
289
+ 'markdown-editor': true,
290
+ 'markdown-editor--split': this.viewMode === 'split',
291
+ 'markdown-editor--preview-only': this.viewMode === 'preview',
292
+ 'markdown-editor--expanded': this.expanded,
293
+ })}>
294
+ ${hasLabel ? html`
295
+ <label class="markdown-editor__label">
296
+ <slot name="label">${this.label}</slot>
297
+ </label>` : ''}
298
+
299
+ <div part="toolbar" class="markdown-editor__toolbar">
300
+ <zn-button-group class="markdown-editor__view-toggle" @click=${this.handleViewToggle}>
301
+ ${VIEW_MODES.map(v => this.renderViewButton(v.mode, v.icon, v.label))}
302
+ </zn-button-group>
303
+ <zn-button
304
+ class="markdown-editor__expand-btn"
305
+ type="button"
306
+ size="medium"
307
+ color="secondary"
308
+ icon=${this.expanded ? 'close_fullscreen' : 'open_in_full'}
309
+ icon-size="18"
310
+ tooltip=${this.expanded ? 'Collapse' : 'Expand'}
311
+ @click=${this.handleExpandToggle}
312
+ ></zn-button>
313
+ </div>
314
+
315
+ <div class="markdown-editor__body">
316
+ <div part="editor"
317
+ class="markdown-editor__editor"
318
+ ?hidden=${!showEditor}>
319
+ <zn-textarea
320
+ .value=${this.value}
321
+ name=${this.name || ''}
322
+ placeholder=${this.placeholder}
323
+ rows=${this.rows}
324
+ resize="auto"
325
+ ?required=${this.required}
326
+ ?readonly=${this.readonly}
327
+ ?disabled=${this.disabled}
328
+ @zn-input=${this.handleInput}
329
+ @zn-change=${this.handleChange}
330
+ ></zn-textarea>
331
+ </div>
332
+ <div part="preview"
333
+ class="markdown-editor__preview-wrapper"
334
+ ?hidden=${!showPreview}>
335
+ <div class="markdown-editor__preview"></div>
336
+ </div>
337
+ </div>
338
+
339
+ ${hasHelpText ? html`
340
+ <div class="markdown-editor__help-text">
341
+ <slot name="help-text">${this.helpText}</slot>
342
+ </div>` : ''}
343
+ </div>
344
+ </div>
295
345
  </div>
296
- <div part="preview"
297
- class="markdown-editor__preview-wrapper"
298
- ?hidden=${!showPreview}>
299
- <div class="markdown-editor__preview"></div>
300
- </div>
301
- </div>
302
346
 
303
- ${hasHelpText ? html`
304
- <div class="markdown-editor__help-text">
305
- <slot name="help-text">${this.helpText}</slot>
306
- </div>` : ''}
347
+ ${hasFooterSlot ? html`
348
+ <slot name="footer" class="panel__footer"></slot>` : null}
349
+ </div>
307
350
  </div>
308
351
  `;
309
352
  }
@@ -1,10 +1,9 @@
1
1
  @use "../../wc";
2
2
 
3
- :host {
4
- display: flex;
5
- flex-direction: column;
6
- width: 100%;
7
- min-height: 0;
3
+ .panel {
4
+ border: 1px solid rgb(var(--zn-border-color));
5
+ background-color: rgba(var(--zn-panel), var(--zn-panel-opacity));
6
+ border-radius: var(--zn-border-radius-large);
8
7
  }
9
8
 
10
9
  .markdown-editor {
@@ -16,15 +15,25 @@
16
15
  min-height: 0;
17
16
  }
18
17
 
19
- .markdown-editor--expanded {
20
- position: fixed;
21
- inset: 10px;
22
- z-index: 9999;
23
- background: var(--zn-panel-background-color, var(--zn-color-neutral-0, #fff));
24
- border: 1px solid var(--zn-color-neutral-300);
25
- border-radius: var(--zn-border-radius-medium);
26
- padding: var(--zn-spacing-medium);
27
- box-shadow: var(--zn-shadow-large);
18
+ :host([expanded]) {
19
+ position: absolute;
20
+ top: 10px;
21
+ bottom: 10px;
22
+ left: var(--zn-sp-padding);
23
+ right: var(--zn-sp-padding);
24
+ z-index: var(--zn-z-index-editor-action, 1000000);
25
+ }
26
+
27
+ :host([expanded]) .panel,
28
+ :host([expanded]) .panel__inner,
29
+ :host([expanded]) .panel__content,
30
+ :host([expanded]) .panel__body {
31
+ height: 100%;
32
+ max-height: 100%;
33
+ }
34
+
35
+ :host([expanded]) .markdown-editor {
36
+ height: 100%;
28
37
  }
29
38
 
30
39
  .markdown-editor__label {
@@ -200,13 +209,3 @@
200
209
  font-size: var(--zn-input-help-text-font-size-medium);
201
210
  color: var(--zn-input-help-text-color);
202
211
  }
203
-
204
- .markdown-editor--expanded .markdown-editor__body {
205
- min-height: 0;
206
- flex: 1;
207
- }
208
-
209
- .markdown-editor--expanded .markdown-editor__editor zn-textarea,
210
- .markdown-editor--expanded .markdown-editor__preview {
211
- min-height: calc(100vh - 200px);
212
- }