@kubex/zinc 1.1.61 → 1.1.63
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 +337 -6
- package/dist/vscode.html-custom-data.json +55 -3
- package/dist/web-types.json +116 -6
- package/dist/zn.d.ts +83 -0
- package/dist/zn.min.js +529 -518
- package/docs/data/preview-frame-payload-error.json +4 -0
- package/docs/data/preview-frame-payload.json +6 -0
- package/docs/pages/components/form-group.md +12 -0
- package/docs/pages/components/preview-frame-demo.njk +138 -0
- package/docs/pages/components/preview-frame.md +105 -0
- package/docs/pages/components/toggle.md +2 -2
- package/package.json +1 -1
- package/src/components/form-group/form-group.component.ts +24 -12
- package/src/components/form-group/form-group.scss +10 -0
- package/src/components/form-group/form-group.test.ts +19 -0
- package/src/components/preview-frame/index.ts +12 -0
- package/src/components/preview-frame/preview-frame.component.ts +246 -0
- package/src/components/preview-frame/preview-frame.scss +27 -0
- package/src/components/preview-frame/preview-frame.test.ts +268 -0
- package/src/components/query-builder/query-builder.component.ts +1 -1
- package/src/components/select/select.component.ts +4 -0
- package/src/components/select/select.test.ts +29 -0
- package/src/components/sp/sp.scss +5 -1
- package/src/components/tile/tile.scss +5 -1
- package/src/components/toggle/toggle.component.ts +3 -12
- package/src/components/toggle/toggle.test.ts +29 -0
- package/src/events/zn-error.ts +1 -1
- package/src/zinc.ts +1 -0
|
@@ -48,6 +48,18 @@ Add descriptive help text to a form group with the `help-text` attribute. For he
|
|
|
48
48
|
</zn-form-group>
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
### Chip
|
|
52
|
+
|
|
53
|
+
Use the `chip` slot to display a chip under the form group's help text.
|
|
54
|
+
|
|
55
|
+
```html:preview
|
|
56
|
+
<zn-form-group label="Team Members" help-text="Manage who has access to this project">
|
|
57
|
+
<zn-chip slot="chip" type="success">Pro Plan</zn-chip>
|
|
58
|
+
<zn-input label="Name" placeholder="Team member name"></zn-input>
|
|
59
|
+
<zn-input label="Email" type="email" placeholder="email@example.com"></zn-input>
|
|
60
|
+
</zn-form-group>
|
|
61
|
+
```
|
|
62
|
+
|
|
51
63
|
### Label with Tooltip
|
|
52
64
|
|
|
53
65
|
Use the `label-tooltip` attribute to add text that appears in a tooltip triggered by an info icon next to the label.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
meta:
|
|
3
|
+
title: Preview Frame — Demo Embed
|
|
4
|
+
description: A demo embed page implementing the hp-preview postMessage protocol, for iframing into zn-preview-frame examples.
|
|
5
|
+
layout: full-page
|
|
6
|
+
toc: false
|
|
7
|
+
eleventyExcludeFromCollections: true
|
|
8
|
+
permalink: /components/preview-frame-demo/index.html
|
|
9
|
+
---
|
|
10
|
+
{% raw %}
|
|
11
|
+
<div class="shell">
|
|
12
|
+
<p id="waiting">Waiting for hp-preview:config…</p>
|
|
13
|
+
|
|
14
|
+
<div class="card" id="card" hidden>
|
|
15
|
+
<div class="card__accent"></div>
|
|
16
|
+
<h2 id="merchant"></h2>
|
|
17
|
+
<p class="card__amount" id="amount"></p>
|
|
18
|
+
<label>Card number
|
|
19
|
+
<input type="text" placeholder="4242 4242 4242 4242" disabled>
|
|
20
|
+
</label>
|
|
21
|
+
<div class="card__row">
|
|
22
|
+
<label>Expiry
|
|
23
|
+
<input type="text" placeholder="12/28" disabled>
|
|
24
|
+
</label>
|
|
25
|
+
<label>CVC
|
|
26
|
+
<input type="text" placeholder="123" disabled>
|
|
27
|
+
</label>
|
|
28
|
+
</div>
|
|
29
|
+
<button id="pay" type="button"></button>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<style>
|
|
34
|
+
.shell {
|
|
35
|
+
height: 100%;
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#waiting {
|
|
42
|
+
color: rgb(var(--zn-color-muted-text));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.card {
|
|
46
|
+
--accent: #6936f5;
|
|
47
|
+
width: 320px;
|
|
48
|
+
padding: 24px;
|
|
49
|
+
border: 1px solid rgb(var(--zn-border-color));
|
|
50
|
+
border-radius: 12px;
|
|
51
|
+
background: rgb(var(--zn-panel));
|
|
52
|
+
display: flex;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
gap: 12px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.card__accent {
|
|
58
|
+
height: 6px;
|
|
59
|
+
border-radius: 3px;
|
|
60
|
+
background: var(--accent);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.card h2 {
|
|
64
|
+
margin: 0;
|
|
65
|
+
font-size: 1.125rem;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.card__amount {
|
|
69
|
+
margin: 0;
|
|
70
|
+
font-size: 1.75rem;
|
|
71
|
+
font-weight: 700;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.card label {
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-direction: column;
|
|
77
|
+
gap: 4px;
|
|
78
|
+
font-size: 0.75rem;
|
|
79
|
+
font-weight: 600;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.card input {
|
|
83
|
+
padding: 8px 10px;
|
|
84
|
+
border: 1px solid rgb(var(--zn-border-color));
|
|
85
|
+
border-radius: 6px;
|
|
86
|
+
font: inherit;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.card__row {
|
|
90
|
+
display: flex;
|
|
91
|
+
gap: 12px;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.card__row label {
|
|
95
|
+
flex: 1;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* id selector: zn.min.css targets native buttons at higher specificity */
|
|
99
|
+
.card #pay {
|
|
100
|
+
padding: 10px;
|
|
101
|
+
border: 0;
|
|
102
|
+
border-radius: 6px;
|
|
103
|
+
background: var(--accent);
|
|
104
|
+
color: #fff;
|
|
105
|
+
font: inherit;
|
|
106
|
+
font-weight: 600;
|
|
107
|
+
cursor: pointer;
|
|
108
|
+
}
|
|
109
|
+
</style>
|
|
110
|
+
|
|
111
|
+
<script>
|
|
112
|
+
// The embed side of the hp-preview protocol: announce readiness, wait for the
|
|
113
|
+
// config payload, render it, then report rendered (or error). A real embed
|
|
114
|
+
// should use the host's origin instead of '*'.
|
|
115
|
+
const post = message => window.parent.postMessage(message, '*');
|
|
116
|
+
|
|
117
|
+
window.addEventListener('message', e => {
|
|
118
|
+
const data = e.data;
|
|
119
|
+
if (data?.type !== 'hp-preview:config') return;
|
|
120
|
+
|
|
121
|
+
if (data.fail) {
|
|
122
|
+
post({type: 'hp-preview:error', message: data.message || 'Preview failed to render'});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
document.getElementById('waiting').hidden = true;
|
|
127
|
+
const card = document.getElementById('card');
|
|
128
|
+
card.hidden = false;
|
|
129
|
+
card.style.setProperty('--accent', data.accent || '#6936f5');
|
|
130
|
+
document.getElementById('merchant').textContent = data.merchant || 'Merchant';
|
|
131
|
+
document.getElementById('amount').textContent = data.amount || '';
|
|
132
|
+
document.getElementById('pay').textContent = data.buttonLabel || 'Pay now';
|
|
133
|
+
post({type: 'hp-preview:rendered'});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
post({type: 'hp-preview:ready'});
|
|
137
|
+
</script>
|
|
138
|
+
{% endraw %}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
meta:
|
|
3
|
+
title: Preview Frame
|
|
4
|
+
description: Embeds a live preview iframe and keeps it in sync with surrounding forms via the hp-preview postMessage protocol.
|
|
5
|
+
layout: component
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
The frame loads the embed page from `src`, waits for it to post `hp-preview:ready`, fetches the JSON payload from `data-uri` and posts it back into the frame as `hp-preview:config`. The embed then reports `hp-preview:rendered` or `hp-preview:error`.
|
|
9
|
+
|
|
10
|
+
The example below embeds the [demo embed page](/components/preview-frame-demo/), which implements the embed side of the protocol. `frame-origin` must match the embed's origin exactly — messages from any other origin are ignored — so the example sets it at runtime since the docs demo is same-origin.
|
|
11
|
+
|
|
12
|
+
```html:preview
|
|
13
|
+
<zn-preview-frame
|
|
14
|
+
id="preview-frame-demo"
|
|
15
|
+
src="/components/preview-frame-demo/"
|
|
16
|
+
data-uri="/data/preview-frame-payload.json"
|
|
17
|
+
watch="#preview-frame-demo-form"></zn-preview-frame>
|
|
18
|
+
|
|
19
|
+
<script>
|
|
20
|
+
document.getElementById('preview-frame-demo').frameOrigin = location.origin;
|
|
21
|
+
</script>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
:::tip
|
|
25
|
+
`watch` defaults to `form[data-auto-save]`, so only forms explicitly opted in via a `data-auto-save` attribute are watched — unmarked forms keep normal submit behavior and are never intercepted. Override `watch` with your own selector to widen or change the scope — the examples here point it at a form that doesn't exist. Watched forms are auto-saved via a POST to their `action` on change, which needs a real endpoint, so it isn't demonstrated here.
|
|
26
|
+
:::
|
|
27
|
+
|
|
28
|
+
The frame always fills the panel; `zoom` (0–1, default `1`) zooms the previewed page out browser-style — e.g. `zoom="0.4"` renders the content at 40% size with correspondingly more of the page visible. `min-height` (default `480`) sets the visible panel height in pixels.
|
|
29
|
+
|
|
30
|
+
## Live Form Updates
|
|
31
|
+
|
|
32
|
+
In a real deployment, editing a watched form auto-saves it and the preview refreshes with the newly saved config. This docs site is static, so the example simulates the save: form changes are encoded into a `data:` payload URI and `refresh()` re-runs the fetch → `hp-preview:config` cycle — the same path a real save triggers.
|
|
33
|
+
|
|
34
|
+
```html:preview
|
|
35
|
+
<form id="preview-frame-live-form" class="preview-frame-live-form">
|
|
36
|
+
<zn-input name="merchant" label="Merchant" value="Acme Donuts"></zn-input>
|
|
37
|
+
<zn-input name="amount" label="Amount" value="£24.99"></zn-input>
|
|
38
|
+
<zn-input name="buttonLabel" label="Button label" value="Pay £24.99"></zn-input>
|
|
39
|
+
<label class="preview-frame-live-form__color">Accent
|
|
40
|
+
<input type="color" name="accent" value="#6936f5">
|
|
41
|
+
</label>
|
|
42
|
+
</form>
|
|
43
|
+
|
|
44
|
+
<zn-preview-frame
|
|
45
|
+
id="preview-frame-live"
|
|
46
|
+
src="/components/preview-frame-demo/"
|
|
47
|
+
watch="#preview-frame-live-none"></zn-preview-frame>
|
|
48
|
+
|
|
49
|
+
<script>
|
|
50
|
+
customElements.whenDefined('zn-preview-frame').then(() => {
|
|
51
|
+
const frame = document.getElementById('preview-frame-live');
|
|
52
|
+
const form = document.getElementById('preview-frame-live-form');
|
|
53
|
+
frame.frameOrigin = location.origin;
|
|
54
|
+
|
|
55
|
+
const update = () => {
|
|
56
|
+
const payload = Object.fromEntries(new FormData(form));
|
|
57
|
+
frame.dataUri = 'data:application/json,' + encodeURIComponent(JSON.stringify(payload));
|
|
58
|
+
frame.refresh();
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
form.addEventListener('zn-input', update);
|
|
62
|
+
form.addEventListener('input', update);
|
|
63
|
+
update();
|
|
64
|
+
});
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<style>
|
|
68
|
+
.preview-frame-live-form {
|
|
69
|
+
display: flex;
|
|
70
|
+
flex-wrap: wrap;
|
|
71
|
+
gap: 16px;
|
|
72
|
+
align-items: flex-end;
|
|
73
|
+
margin-bottom: 16px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.preview-frame-live-form zn-input {
|
|
77
|
+
flex: 1;
|
|
78
|
+
min-width: 140px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.preview-frame-live-form__color {
|
|
82
|
+
display: flex;
|
|
83
|
+
flex-direction: column;
|
|
84
|
+
gap: 4px;
|
|
85
|
+
font-size: 0.875rem;
|
|
86
|
+
font-weight: 500;
|
|
87
|
+
}
|
|
88
|
+
</style>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Error Overlay
|
|
92
|
+
|
|
93
|
+
When the embed reports `hp-preview:error` (or fetching the payload fails), the message is shown in an overlay and `zn-error` is emitted. This example uses a payload that asks the demo embed to fail.
|
|
94
|
+
|
|
95
|
+
```html:preview
|
|
96
|
+
<zn-preview-frame
|
|
97
|
+
id="preview-frame-demo-error"
|
|
98
|
+
src="/components/preview-frame-demo/"
|
|
99
|
+
data-uri="/data/preview-frame-payload-error.json"
|
|
100
|
+
watch="#preview-frame-demo-error-form"></zn-preview-frame>
|
|
101
|
+
|
|
102
|
+
<script>
|
|
103
|
+
document.getElementById('preview-frame-demo-error').frameOrigin = location.origin;
|
|
104
|
+
</script>
|
|
105
|
+
```
|
|
@@ -170,7 +170,7 @@ Toggles support keyboard navigation using arrow keys. Press the left arrow to tu
|
|
|
170
170
|
|
|
171
171
|
### Form Integration
|
|
172
172
|
|
|
173
|
-
Toggles work seamlessly with forms and
|
|
173
|
+
Toggles work seamlessly with forms and always submit a value: the toggle's `value` (or `on`) when checked, and `off` when unchecked. Use the `fallback` attribute to customize the unchecked value.
|
|
174
174
|
|
|
175
175
|
```html:preview
|
|
176
176
|
<form id="toggle-form">
|
|
@@ -197,7 +197,7 @@ Toggles work seamlessly with forms and will be submitted with form data.
|
|
|
197
197
|
|
|
198
198
|
### Fallback Value
|
|
199
199
|
|
|
200
|
-
|
|
200
|
+
The toggle always submits a value, even when unchecked — `off` by default. Use the `fallback` attribute to submit a specific value instead when the toggle is unchecked.
|
|
201
201
|
|
|
202
202
|
```html:preview
|
|
203
203
|
<form id="fallback-form">
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {classMap} from "lit/directives/class-map.js";
|
|
2
|
-
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
3
|
-
import {HasSlotController} from "../../internal/slot";
|
|
4
|
-
import {property} from 'lit/decorators.js';
|
|
1
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
2
|
+
import { type CSSResultGroup, html, unsafeCSS } from 'lit';
|
|
3
|
+
import { HasSlotController } from "../../internal/slot";
|
|
4
|
+
import { property } from 'lit/decorators.js';
|
|
5
5
|
import ZincElement from '../../internal/zinc-element';
|
|
6
6
|
|
|
7
7
|
import styles from './form-group.scss';
|
|
@@ -13,12 +13,13 @@ import styles from './form-group.scss';
|
|
|
13
13
|
* @since 1.0
|
|
14
14
|
*
|
|
15
15
|
* @slot - The default slot.
|
|
16
|
+
* @slot chip - A chip displayed under the form group's help text.
|
|
16
17
|
*
|
|
17
18
|
*/
|
|
18
19
|
export default class ZnFormGroup extends ZincElement {
|
|
19
20
|
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
20
21
|
|
|
21
|
-
private readonly hasSlotController = new HasSlotController(this, 'help-text', 'label');
|
|
22
|
+
private readonly hasSlotController = new HasSlotController(this, 'help-text', 'label', 'chip');
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* The form group's label. Required for proper accessibility. If you need to display HTML, use the `label` slot
|
|
@@ -30,12 +31,14 @@ export default class ZnFormGroup extends ZincElement {
|
|
|
30
31
|
* Text that appears in a tooltip next to the label. If you need to display HTML in the tooltip, use the
|
|
31
32
|
* `label-tooltip` slot instead.
|
|
32
33
|
*/
|
|
33
|
-
@property({attribute: 'label-tooltip'}) labelTooltip = '';
|
|
34
|
+
@property({ attribute: 'label-tooltip' }) labelTooltip = '';
|
|
34
35
|
|
|
35
36
|
/** The form groups help text. If you need to display HTML, use the `help-text` slot instead. */
|
|
36
|
-
@property({attribute: 'help-text'}) helpText = '';
|
|
37
|
-
@property({attribute: 'cols', type: Boolean}) forceCols = false;
|
|
38
|
-
@property({attribute: 'layout', type: String}) layout = "1,2";
|
|
37
|
+
@property({ attribute: 'help-text' }) helpText = '';
|
|
38
|
+
@property({ attribute: 'cols', type: Boolean }) forceCols = false;
|
|
39
|
+
@property({ attribute: 'layout', type: String }) layout = "1,2";
|
|
40
|
+
|
|
41
|
+
@property({ attribute: 'pad', type: Boolean }) pad: boolean = false;
|
|
39
42
|
|
|
40
43
|
render() {
|
|
41
44
|
const hasLabelSlot = this.hasSlotController.test('label');
|
|
@@ -44,6 +47,7 @@ export default class ZnFormGroup extends ZincElement {
|
|
|
44
47
|
const hasLabel = this.label ? true : hasLabelSlot;
|
|
45
48
|
const hasLabelTooltip = this.labelTooltip ? true : hasLabelTooltipSlot;
|
|
46
49
|
const hasHelpText = this.helpText ? true : hasHelpTextSlot;
|
|
50
|
+
const hasChip = this.hasSlotController.test('chip');
|
|
47
51
|
|
|
48
52
|
return html`
|
|
49
53
|
<fieldset
|
|
@@ -52,14 +56,15 @@ export default class ZnFormGroup extends ZincElement {
|
|
|
52
56
|
'form-control': true,
|
|
53
57
|
'form-control--has-label': hasLabel,
|
|
54
58
|
'form-control--has-label-tooltip': hasLabelTooltip,
|
|
55
|
-
'form-control--has-help-text': hasHelpText
|
|
59
|
+
'form-control--has-help-text': hasHelpText,
|
|
60
|
+
'form-control--pad': this.pad
|
|
56
61
|
})}"
|
|
57
62
|
aria-labelledby="label"
|
|
58
63
|
aria-describedby="help-text">
|
|
59
64
|
|
|
60
65
|
<zn-cols layout="${this.layout}" part="form-control-container" class="form-control__container">
|
|
61
|
-
${hasLabel || hasHelpText || this.forceCols ? html`
|
|
62
|
-
<div>
|
|
66
|
+
${hasLabel || hasHelpText || hasChip || this.forceCols ? html`
|
|
67
|
+
<div class="form-control__text">
|
|
63
68
|
|
|
64
69
|
${hasLabel ? html`
|
|
65
70
|
<label
|
|
@@ -87,6 +92,13 @@ export default class ZnFormGroup extends ZincElement {
|
|
|
87
92
|
<slot name="help-text">${this.helpText}</slot>
|
|
88
93
|
</div>` : html``}
|
|
89
94
|
|
|
95
|
+
${hasChip ? html`
|
|
96
|
+
<div
|
|
97
|
+
part="form-control-chip"
|
|
98
|
+
class="form-control__chip">
|
|
99
|
+
<slot name="chip"></slot>
|
|
100
|
+
</div>` : html``}
|
|
101
|
+
|
|
90
102
|
</div>` : html``}
|
|
91
103
|
|
|
92
104
|
<div part="form-control-input" class="form-control-input">
|
|
@@ -28,6 +28,10 @@
|
|
|
28
28
|
--zn-col-basis: 200px;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
.form-control__chip {
|
|
32
|
+
margin-top: var(--zn-spacing-x-small);
|
|
33
|
+
}
|
|
34
|
+
|
|
31
35
|
.visually-hidden {
|
|
32
36
|
position: absolute;
|
|
33
37
|
width: 1px;
|
|
@@ -87,3 +91,9 @@
|
|
|
87
91
|
zn-cols::part(base) {
|
|
88
92
|
gap: 70px;
|
|
89
93
|
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
.form-control--pad .form-control__text {
|
|
97
|
+
padding-top: var(--zn-base-gap);
|
|
98
|
+
padding-left: var(--zn-base-gap);
|
|
99
|
+
}
|
|
@@ -7,4 +7,23 @@ describe('<zn-form-group>', () => {
|
|
|
7
7
|
|
|
8
8
|
expect(el).to.exist;
|
|
9
9
|
});
|
|
10
|
+
|
|
11
|
+
it('should render the chip slot under the help text', async () => {
|
|
12
|
+
const el = await fixture<HTMLElement>(html`
|
|
13
|
+
<zn-form-group label="Settings" help-text="Configure your settings">
|
|
14
|
+
<zn-chip slot="chip">New</zn-chip>
|
|
15
|
+
</zn-form-group>`);
|
|
16
|
+
|
|
17
|
+
const helpText = el.shadowRoot!.querySelector('[part="form-control-help-text"]')!;
|
|
18
|
+
const chip = el.shadowRoot!.querySelector('[part="form-control-chip"]')!;
|
|
19
|
+
|
|
20
|
+
expect(chip).to.exist;
|
|
21
|
+
expect(helpText.nextElementSibling).to.equal(chip);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should not render the chip container without a chip slot', async () => {
|
|
25
|
+
const el = await fixture<HTMLElement>(html` <zn-form-group label="Settings"></zn-form-group> `);
|
|
26
|
+
|
|
27
|
+
expect(el.shadowRoot!.querySelector('[part="form-control-chip"]')).to.not.exist;
|
|
28
|
+
});
|
|
10
29
|
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import ZnPreviewFrame from './preview-frame.component';
|
|
2
|
+
|
|
3
|
+
export * from './preview-frame.component';
|
|
4
|
+
export default ZnPreviewFrame;
|
|
5
|
+
|
|
6
|
+
ZnPreviewFrame.define('zn-preview-frame');
|
|
7
|
+
|
|
8
|
+
declare global {
|
|
9
|
+
interface HTMLElementTagNameMap {
|
|
10
|
+
'zn-preview-frame': ZnPreviewFrame;
|
|
11
|
+
}
|
|
12
|
+
}
|