@kubex/zinc 1.1.141 → 1.1.142
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/dist/custom-elements.json +313 -80
- package/dist/vscode.html-custom-data.json +44 -14
- package/dist/web-types.json +101 -28
- package/dist/zn.d.ts +555 -530
- package/dist/zn.min.js +894 -866
- package/package.json +1 -1
- package/src/components/form-group/form-group.scss +11 -1
- package/src/components/form-group/form-group.test.ts +16 -0
- package/src/components/linked-select/linked-select.component.ts +37 -5
- package/src/components/linked-select/linked-select.test.ts +95 -9
- package/src/components/page-builder/page-builder.component.ts +56 -2
- package/src/components/page-builder/page-builder.scss +41 -0
- package/src/components/page-builder/page-builder.test.ts +210 -0
- package/src/components/remarkd-editor/remarkd-editor.component.ts +2 -0
- package/src/components/remarkd-editor/remarkd-editor.test.ts +35 -7
- package/src/components/sp/sp.scss +6 -0
- package/src/components/sp/sp.test.ts +31 -0
- package/src/components/translations/translations.component.ts +33 -2
- package/src/components/translations/translations.test.ts +41 -0
|
@@ -331,7 +331,7 @@ Second"></zn-remarkd-editor>`);
|
|
|
331
331
|
|
|
332
332
|
it('should group the toolbar buttons', async () => {
|
|
333
333
|
const el = await fixture<ZnRemarkdEditor>(html`
|
|
334
|
-
<zn-remarkd-editor include-url="/includes" link-url="/links"></zn-remarkd-editor>`);
|
|
334
|
+
<zn-remarkd-editor attachment-url="/attachments" include-url="/includes" link-url="/links"></zn-remarkd-editor>`);
|
|
335
335
|
const groups = el.shadowRoot!.querySelectorAll('.remarkd-editor__toolbar .toolbar__group');
|
|
336
336
|
|
|
337
337
|
expect(groups.length).to.be.greaterThan(5);
|
|
@@ -343,7 +343,7 @@ Second"></zn-remarkd-editor>`);
|
|
|
343
343
|
|
|
344
344
|
it('should move toolbar groups into an overflow menu when narrow', async () => {
|
|
345
345
|
const el = await fixture<ZnRemarkdEditor>(html`
|
|
346
|
-
<zn-remarkd-editor style="width: 240px"></zn-remarkd-editor>`);
|
|
346
|
+
<zn-remarkd-editor attachment-url="/attachments" style="width: 240px"></zn-remarkd-editor>`);
|
|
347
347
|
await el.updateComplete;
|
|
348
348
|
await waitUntil(() => el.shadowRoot!.querySelector('.remarkd-editor__toolbar-more'),
|
|
349
349
|
'the overflow trigger never appeared');
|
|
@@ -748,7 +748,7 @@ Second"></zn-remarkd-editor>`);
|
|
|
748
748
|
|
|
749
749
|
it('should list every action in the slash menu under its group', async () => {
|
|
750
750
|
const el = await fixture<ZnRemarkdEditor>(html`
|
|
751
|
-
<zn-remarkd-editor value="Hello" include-url="/includes" link-url="/links"></zn-remarkd-editor>`);
|
|
751
|
+
<zn-remarkd-editor value="Hello" attachment-url="/attachments" include-url="/includes" link-url="/links"></zn-remarkd-editor>`);
|
|
752
752
|
el.shadowRoot!.querySelector<HTMLElement>('.remarkd-editor__rendered')!.click();
|
|
753
753
|
await el.updateComplete;
|
|
754
754
|
typeInBlock(el, '/');
|
|
@@ -761,20 +761,32 @@ Second"></zn-remarkd-editor>`);
|
|
|
761
761
|
|
|
762
762
|
it('should omit the Include action from the slash menu without an include-url', async () => {
|
|
763
763
|
const el = await fixture<ZnRemarkdEditor>(html`
|
|
764
|
-
<zn-remarkd-editor value="Hello"></zn-remarkd-editor>`);
|
|
764
|
+
<zn-remarkd-editor value="Hello" attachment-url="/attachments" link-url="/links"></zn-remarkd-editor>`);
|
|
765
765
|
el.shadowRoot!.querySelector<HTMLElement>('.remarkd-editor__rendered')!.click();
|
|
766
766
|
await el.updateComplete;
|
|
767
767
|
typeInBlock(el, '/');
|
|
768
768
|
await waitUntil(() => el.shadowRoot!.querySelector('zn-slash-menu[open]'), 'the slash menu never opened');
|
|
769
769
|
|
|
770
770
|
const menu = el.shadowRoot!.querySelector<ZnSlashMenu>('zn-slash-menu')!;
|
|
771
|
-
expect(menu.items.length).to.equal(EDITOR_ACTIONS.length -
|
|
771
|
+
expect(menu.items.length).to.equal(EDITOR_ACTIONS.length - 1);
|
|
772
772
|
expect(menu.items.every(item => item.action !== 'include')).to.be.true;
|
|
773
773
|
});
|
|
774
774
|
|
|
775
|
+
it('should omit the Image action from the slash menu without an attachment-url', async () => {
|
|
776
|
+
const el = await fixture<ZnRemarkdEditor>(html`
|
|
777
|
+
<zn-remarkd-editor value="Hello" include-url="/includes" link-url="/links"></zn-remarkd-editor>`);
|
|
778
|
+
el.shadowRoot!.querySelector<HTMLElement>('.remarkd-editor__rendered')!.click();
|
|
779
|
+
await el.updateComplete;
|
|
780
|
+
typeInBlock(el, '/');
|
|
781
|
+
await waitUntil(() => el.shadowRoot!.querySelector('zn-slash-menu[open]'), 'the slash menu never opened');
|
|
782
|
+
|
|
783
|
+
const menu = el.shadowRoot!.querySelector<ZnSlashMenu>('zn-slash-menu')!;
|
|
784
|
+
expect(menu.items.every(item => item.action !== 'image')).to.be.true;
|
|
785
|
+
});
|
|
786
|
+
|
|
775
787
|
it('should omit the article link action without a link-url', async () => {
|
|
776
788
|
const el = await fixture<ZnRemarkdEditor>(html`
|
|
777
|
-
<zn-remarkd-editor value="Hello" include-url="/includes"></zn-remarkd-editor>`);
|
|
789
|
+
<zn-remarkd-editor value="Hello" attachment-url="/attachments" include-url="/includes"></zn-remarkd-editor>`);
|
|
778
790
|
el.shadowRoot!.querySelector<HTMLElement>('.remarkd-editor__rendered')!.click();
|
|
779
791
|
await el.updateComplete;
|
|
780
792
|
typeInBlock(el, '/');
|
|
@@ -787,7 +799,7 @@ Second"></zn-remarkd-editor>`);
|
|
|
787
799
|
|
|
788
800
|
it('should offer the article link action with a link-url', async () => {
|
|
789
801
|
const el = await fixture<ZnRemarkdEditor>(html`
|
|
790
|
-
<zn-remarkd-editor value="Hello" include-url="/includes" link-url="/links"></zn-remarkd-editor>`);
|
|
802
|
+
<zn-remarkd-editor value="Hello" attachment-url="/attachments" include-url="/includes" link-url="/links"></zn-remarkd-editor>`);
|
|
791
803
|
el.shadowRoot!.querySelector<HTMLElement>('.remarkd-editor__rendered')!.click();
|
|
792
804
|
await el.updateComplete;
|
|
793
805
|
typeInBlock(el, '/');
|
|
@@ -1179,6 +1191,22 @@ include::inc-1[Payment Terms]"></zn-remarkd-editor>`);
|
|
|
1179
1191
|
expect(options[0].textContent).to.contain('Refund Policy');
|
|
1180
1192
|
});
|
|
1181
1193
|
|
|
1194
|
+
it('should offer no image entry points without an attachment-url', async () => {
|
|
1195
|
+
const el = await fixture<ZnRemarkdEditor>(html`
|
|
1196
|
+
<zn-remarkd-editor value="# Title"></zn-remarkd-editor>`);
|
|
1197
|
+
const tooltips = Array.from(el.shadowRoot!.querySelectorAll('.remarkd-editor__toolbar zn-button'))
|
|
1198
|
+
.map(button => button.getAttribute('tooltip'));
|
|
1199
|
+
expect(tooltips).to.not.contain('Image');
|
|
1200
|
+
});
|
|
1201
|
+
|
|
1202
|
+
it('should offer the Image action with an attachment-url', async () => {
|
|
1203
|
+
const el = await fixture<ZnRemarkdEditor>(html`
|
|
1204
|
+
<zn-remarkd-editor value="# Title" attachment-url="/attachments"></zn-remarkd-editor>`);
|
|
1205
|
+
const tooltips = Array.from(el.shadowRoot!.querySelectorAll('.remarkd-editor__toolbar zn-button'))
|
|
1206
|
+
.map(button => button.getAttribute('tooltip'));
|
|
1207
|
+
expect(tooltips).to.contain('Image');
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1182
1210
|
it('should offer no include entry points without an include-url', async () => {
|
|
1183
1211
|
const el = await fixture<ZnRemarkdEditor>(html`
|
|
1184
1212
|
<zn-remarkd-editor value="# Title"></zn-remarkd-editor>`);
|
|
@@ -15,6 +15,12 @@
|
|
|
15
15
|
height: 100%;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
// A form wrapping the whole panel is there to submit it, not to lay it out —
|
|
19
|
+
// leaving it in the box tree floors the panel at the form's content height.
|
|
20
|
+
:host([grow]) ::slotted(form:only-child) {
|
|
21
|
+
display: contents;
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
:host([max-full]) {
|
|
19
25
|
max-height: 100%;
|
|
20
26
|
overflow: hidden;
|
|
@@ -8,6 +8,37 @@ describe('<zn-sp>', () => {
|
|
|
8
8
|
expect(el).to.exist;
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
+
it('should lay out through a form that wraps the whole panel', async () => {
|
|
12
|
+
const parent = await fixture(html`
|
|
13
|
+
<div style="display: flex; flex-direction: column; height: 400px; width: 600px;">
|
|
14
|
+
<zn-sp grow flush>
|
|
15
|
+
<form>
|
|
16
|
+
<div id="panel" style="height: 100%;">Content</div>
|
|
17
|
+
</form>
|
|
18
|
+
</zn-sp>
|
|
19
|
+
</div>
|
|
20
|
+
`);
|
|
21
|
+
|
|
22
|
+
const form = parent.querySelector('form')!;
|
|
23
|
+
expect(getComputedStyle(form).display).to.equal('contents');
|
|
24
|
+
expect(parent.querySelector<HTMLElement>('#panel')!.getBoundingClientRect().height).to.equal(400);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should leave a form that shares the panel with siblings alone', async () => {
|
|
28
|
+
const parent = await fixture(html`
|
|
29
|
+
<div style="display: flex; flex-direction: column; height: 400px;">
|
|
30
|
+
<zn-sp grow>
|
|
31
|
+
<h2>Heading</h2>
|
|
32
|
+
<form>
|
|
33
|
+
<div>Content</div>
|
|
34
|
+
</form>
|
|
35
|
+
</zn-sp>
|
|
36
|
+
</div>
|
|
37
|
+
`);
|
|
38
|
+
|
|
39
|
+
expect(getComputedStyle(parent.querySelector('form')!).display).to.equal('block');
|
|
40
|
+
});
|
|
41
|
+
|
|
11
42
|
it('should fill its parent container height', async () => {
|
|
12
43
|
const parent = await fixture(html`
|
|
13
44
|
<div style="height: 300px;">
|
|
@@ -13,6 +13,7 @@ import ZnChip from '../chip';
|
|
|
13
13
|
import ZnInlineEdit from '../inline-edit';
|
|
14
14
|
import ZnInput from '../input';
|
|
15
15
|
import ZnOption from '../option';
|
|
16
|
+
import ZnRemarkdEditor from '../remarkd-editor';
|
|
16
17
|
import ZnSelect from '../select';
|
|
17
18
|
import ZnTextarea from '../textarea';
|
|
18
19
|
import type {PropertyValues} from 'lit';
|
|
@@ -64,6 +65,7 @@ export default class ZnTranslations extends ZincElement implements ZincFormContr
|
|
|
64
65
|
'zn-inline-edit': ZnInlineEdit,
|
|
65
66
|
'zn-input': ZnInput,
|
|
66
67
|
'zn-option': ZnOption,
|
|
68
|
+
'zn-remarkd-editor': ZnRemarkdEditor,
|
|
67
69
|
'zn-select': ZnSelect,
|
|
68
70
|
'zn-textarea': ZnTextarea
|
|
69
71
|
};
|
|
@@ -96,11 +98,23 @@ export default class ZnTranslations extends ZincElement implements ZincFormContr
|
|
|
96
98
|
@property({type: Boolean, reflect: true}) flush = false;
|
|
97
99
|
|
|
98
100
|
/** The control each translation is edited through. */
|
|
99
|
-
@property({attribute: "input-type"}) inputType: 'text' | 'number' | 'textarea' = 'text';
|
|
101
|
+
@property({attribute: "input-type"}) inputType: 'text' | 'number' | 'textarea' | 'remarkd' = 'text';
|
|
100
102
|
|
|
101
103
|
/** Rows of the textarea, when `input-type` is `textarea`. */
|
|
102
104
|
@property({attribute: "textarea-rows", type: Number}) textareaRows: number | undefined;
|
|
103
105
|
|
|
106
|
+
/** Allows raw HTML blocks, when `input-type` is `remarkd`. */
|
|
107
|
+
@property({type: Boolean, attribute: 'allow-raw'}) allowRaw = false;
|
|
108
|
+
|
|
109
|
+
/** Where the remarkd editor uploads images, when `input-type` is `remarkd`. */
|
|
110
|
+
@property({attribute: 'attachment-url'}) attachmentUrl = '';
|
|
111
|
+
|
|
112
|
+
/** Where the remarkd editor lists embeddable includes, when `input-type` is `remarkd`. */
|
|
113
|
+
@property({attribute: 'include-url'}) includeUrl = '';
|
|
114
|
+
|
|
115
|
+
/** Where the remarkd editor searches link targets, when `input-type` is `remarkd`. */
|
|
116
|
+
@property({attribute: 'link-url'}) linkUrl = '';
|
|
117
|
+
|
|
104
118
|
/**
|
|
105
119
|
* Edits the translation through a `zn-inline-edit` — the value reads as text until it is clicked — rather than a
|
|
106
120
|
* plain input or textarea.
|
|
@@ -325,7 +339,7 @@ export default class ZnTranslations extends ZincElement implements ZincFormContr
|
|
|
325
339
|
};
|
|
326
340
|
|
|
327
341
|
private handleValueUpdate = (e: CustomEvent) => {
|
|
328
|
-
const target = e.target as (ZnInput | ZnInlineEdit | ZnTextarea);
|
|
342
|
+
const target = e.target as (ZnInput | ZnInlineEdit | ZnRemarkdEditor | ZnTextarea);
|
|
329
343
|
if (this._activeLanguage) {
|
|
330
344
|
const newValue: string = target.value as string;
|
|
331
345
|
if (newValue !== this.values[this._activeLanguage]) {
|
|
@@ -387,6 +401,23 @@ export default class ZnTranslations extends ZincElement implements ZincFormContr
|
|
|
387
401
|
></zn-inline-edit>`;
|
|
388
402
|
}
|
|
389
403
|
|
|
404
|
+
if (this.inputType === 'remarkd') {
|
|
405
|
+
return html`
|
|
406
|
+
<zn-remarkd-editor
|
|
407
|
+
.value=${live(value)}
|
|
408
|
+
name="${this.name}"
|
|
409
|
+
placeholder="${placeholder}"
|
|
410
|
+
dir="${dir}"
|
|
411
|
+
?disabled="${this.disabled}"
|
|
412
|
+
?allow-raw="${this.allowRaw}"
|
|
413
|
+
attachment-url="${this.attachmentUrl}"
|
|
414
|
+
include-url="${this.includeUrl}"
|
|
415
|
+
link-url="${this.linkUrl}"
|
|
416
|
+
@zn-change="${this.handleValueUpdate}"
|
|
417
|
+
@zn-input="${this.handleValueUpdate}"
|
|
418
|
+
></zn-remarkd-editor>`;
|
|
419
|
+
}
|
|
420
|
+
|
|
390
421
|
if (this.inputType === 'textarea') {
|
|
391
422
|
return html`
|
|
392
423
|
<zn-textarea
|
|
@@ -219,6 +219,47 @@ describe('<zn-translations>', () => {
|
|
|
219
219
|
expect(el.shadowRoot!.querySelector('zn-input')).to.be.null;
|
|
220
220
|
});
|
|
221
221
|
|
|
222
|
+
it('renders a remarkd editor for input-type="remarkd"', async () => {
|
|
223
|
+
const el = await fixture<ZnTranslations>(html`
|
|
224
|
+
<zn-translations input-type="remarkd" values='{"en":"= Hello"}'></zn-translations>`);
|
|
225
|
+
await el.updateComplete;
|
|
226
|
+
|
|
227
|
+
const editor = el.shadowRoot!.querySelector<HTMLElement & { value: string }>('zn-remarkd-editor');
|
|
228
|
+
expect(editor).to.exist;
|
|
229
|
+
expect(editor!.value).to.equal('= Hello');
|
|
230
|
+
expect(el.shadowRoot!.querySelector('zn-input')).to.be.null;
|
|
231
|
+
expect(el.shadowRoot!.querySelector('zn-textarea')).to.be.null;
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('passes its editor endpoints through to the remarkd editor', async () => {
|
|
235
|
+
const el = await fixture<ZnTranslations>(html`
|
|
236
|
+
<zn-translations input-type="remarkd"
|
|
237
|
+
allow-raw
|
|
238
|
+
attachment-url="/a"
|
|
239
|
+
include-url="/i"
|
|
240
|
+
link-url="/l"></zn-translations>`);
|
|
241
|
+
await el.updateComplete;
|
|
242
|
+
|
|
243
|
+
const editor = el.shadowRoot!.querySelector('zn-remarkd-editor')!;
|
|
244
|
+
expect(editor.getAttribute('attachment-url')).to.equal('/a');
|
|
245
|
+
expect(editor.getAttribute('include-url')).to.equal('/i');
|
|
246
|
+
expect(editor.getAttribute('link-url')).to.equal('/l');
|
|
247
|
+
expect(editor.hasAttribute('allow-raw')).to.be.true;
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it('writes a remarkd edit back to the active language', async () => {
|
|
251
|
+
const el = await fixture<ZnTranslations>(html`
|
|
252
|
+
<zn-translations input-type="remarkd" values='{"en":"one"}'></zn-translations>`);
|
|
253
|
+
await el.updateComplete;
|
|
254
|
+
|
|
255
|
+
const editor = el.shadowRoot!.querySelector<HTMLElement & { value: string }>('zn-remarkd-editor')!;
|
|
256
|
+
editor.value = 'two';
|
|
257
|
+
editor.dispatchEvent(new CustomEvent('zn-change', {bubbles: true, composed: true}));
|
|
258
|
+
await el.updateComplete;
|
|
259
|
+
|
|
260
|
+
expect(el.values.en).to.equal('two');
|
|
261
|
+
});
|
|
262
|
+
|
|
222
263
|
it('renders an inline edit when asked for one', async () => {
|
|
223
264
|
const el = await fixture<ZnTranslations>(html`
|
|
224
265
|
<zn-translations inline-edit values='{"en":"Hello"}'></zn-translations>`);
|