@taprootio/espalier 6.3.0 → 6.4.0
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/CHANGELOG.md +8 -0
- package/custom-elements.json +558 -542
- package/dist/box/esp-box.d.ts +35 -0
- package/dist/box/esp-box.js +24 -9
- package/dist/dialog/esp-dialog.d.ts +76 -0
- package/dist/dialog/esp-dialog.js +29 -17
- package/espalier.css-data.json +16 -0
- package/espalier.token-manifest.json +24 -0
- package/package.json +1 -1
package/dist/box/esp-box.d.ts
CHANGED
|
@@ -136,6 +136,41 @@ export declare class EspalierBox extends EspalierElementBase {
|
|
|
136
136
|
* </script>
|
|
137
137
|
* ```
|
|
138
138
|
*
|
|
139
|
+
* A full-screen box fills the viewport. Inside a
|
|
140
|
+
* [bounded dialog](/components/dialog) it fills exactly the dialog's
|
|
141
|
+
* rectangle instead: it takes its position and size from the same
|
|
142
|
+
* `--esp-dialog-inset-*` custom properties, set on the `esp-dialog` or any
|
|
143
|
+
* ancestor of the box.
|
|
144
|
+
*
|
|
145
|
+
* ```html
|
|
146
|
+
* <style>
|
|
147
|
+
* esp-dialog.bounded-box {
|
|
148
|
+
* --esp-dialog-inset-block-start: 6rem;
|
|
149
|
+
* --esp-dialog-inset-inline-start: 3rem;
|
|
150
|
+
* --esp-dialog-inset-inline-end: 3rem;
|
|
151
|
+
* --esp-dialog-inset-block-end: 2rem;
|
|
152
|
+
* }
|
|
153
|
+
* </style>
|
|
154
|
+
* <esp-dialog class="bounded-box" full-screen>
|
|
155
|
+
* <esp-box full-screen>
|
|
156
|
+
* <h2>Box in a bounded dialog</h2>
|
|
157
|
+
* <p>This box fills the rectangle the dialog is bounded to.</p>
|
|
158
|
+
* <esp-button intent="danger" label="Close"></esp-button>
|
|
159
|
+
* </esp-box>
|
|
160
|
+
* </esp-dialog>
|
|
161
|
+
* <esp-button label="Show Dialog"></esp-button>
|
|
162
|
+
* <script>
|
|
163
|
+
* const theDialog = findByTagName("esp-dialog")[0];
|
|
164
|
+
* const buttons = findByTagName("esp-button");
|
|
165
|
+
* buttons[0].addEventListener("esp-clicked", () => {
|
|
166
|
+
* theDialog.toggleOpen();
|
|
167
|
+
* });
|
|
168
|
+
* buttons[1].addEventListener("esp-clicked", () => {
|
|
169
|
+
* theDialog.toggleOpen();
|
|
170
|
+
* });
|
|
171
|
+
* </script>
|
|
172
|
+
* ```
|
|
173
|
+
*
|
|
139
174
|
* @type {boolean}
|
|
140
175
|
*/
|
|
141
176
|
fullScreen: boolean;
|
package/dist/box/esp-box.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
1
|
+
var p=function(r,e,s,i){var a=arguments.length,o=a<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,s):i,l;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")o=Reflect.decorate(r,e,s,i);else for(var n=r.length-1;n>=0;n--)(l=r[n])&&(o=(a<3?l(o):a>3?l(e,s,o):l(e,s))||o);return a>3&&o&&Object.defineProperty(e,s,o),o};import{paintedSurface as c}from"../shared/surface-layer.js";import{css as v,html as b}from"lit";import{customElement as f,property as h}from"lit/decorators.js";import{classMap as u}from"lit/directives/class-map.js";import{EspalierElementBase as d}from"../shared/esp-element-base.js";let t=class extends d{constructor(){super(...arguments),this.fullScreen=!1}render(){const{fullScreen:e}=this;return b`
|
|
2
2
|
<div class=${u({"esp-box":!0,"full-screen":e})}>
|
|
3
3
|
<div part="box">
|
|
4
4
|
<slot></slot>
|
|
5
5
|
</div>
|
|
6
6
|
</div>
|
|
7
|
-
`}};
|
|
7
|
+
`}};t.styles=[...d.styles,c(1),v`
|
|
8
8
|
:host {
|
|
9
9
|
display: block;
|
|
10
10
|
}
|
|
@@ -42,16 +42,31 @@ var n=function(t,e,r,i){var a=arguments.length,o=a<3?e:i===null?i=Object.getOwnP
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
&.full-screen {
|
|
45
|
-
width:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
width: calc(
|
|
46
|
+
100vw - var(--esp-dialog-inset-inline-start, 0px) - var(
|
|
47
|
+
--esp-dialog-inset-inline-end,
|
|
48
|
+
0px
|
|
49
|
+
)
|
|
50
|
+
);
|
|
51
|
+
height: calc(
|
|
52
|
+
100vh - var(--esp-dialog-inset-block-start, 0px) - var(
|
|
53
|
+
--esp-dialog-inset-block-end,
|
|
54
|
+
0px
|
|
55
|
+
)
|
|
56
|
+
);
|
|
57
|
+
height: calc(
|
|
58
|
+
100dvh - var(--esp-dialog-inset-block-start, 0px) - var(
|
|
59
|
+
--esp-dialog-inset-block-end,
|
|
60
|
+
0px
|
|
61
|
+
)
|
|
62
|
+
);
|
|
49
63
|
position: fixed;
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
inset-block-start: var(--esp-dialog-inset-block-start, 0px);
|
|
65
|
+
inset-inline-start: var(--esp-dialog-inset-inline-start, 0px);
|
|
52
66
|
z-index: 10;
|
|
53
67
|
|
|
54
68
|
> div {
|
|
69
|
+
position: relative;
|
|
55
70
|
overflow-y: auto;
|
|
56
71
|
|
|
57
72
|
padding-bottom: max(
|
|
@@ -61,4 +76,4 @@ var n=function(t,e,r,i){var a=arguments.length,o=a<3?e:i===null?i=Object.getOwnP
|
|
|
61
76
|
}
|
|
62
77
|
}
|
|
63
78
|
}
|
|
64
|
-
`],
|
|
79
|
+
`],p([h({attribute:"full-screen",type:Boolean})],t.prototype,"fullScreen",void 0),t=p([f("esp-box")],t);export{t as EspalierBox};
|
|
@@ -20,6 +20,78 @@ import { LitElement } from "lit";
|
|
|
20
20
|
* - Restores focus to the element that was focused before the
|
|
21
21
|
* dialog was opened.
|
|
22
22
|
*
|
|
23
|
+
* ### Bounded dialog
|
|
24
|
+
*
|
|
25
|
+
* A dialog covers the whole viewport by default. Set the four inset custom
|
|
26
|
+
* properties on the `esp-dialog` host to confine it to a rectangle and leave
|
|
27
|
+
* the rest of the page visible, for example to keep a header or a live preview
|
|
28
|
+
* on screen while a full-screen editor is open. The vellum (the dialog's
|
|
29
|
+
* scrolling surface) and its backdrop paint only inside the rectangle, and a
|
|
30
|
+
* slotted `esp-box full-screen` fills exactly that rectangle.
|
|
31
|
+
*
|
|
32
|
+
* The insets are lengths (`0px`, `4rem`, `var(--header-height)`), not unitless
|
|
33
|
+
* numbers, and they are measured from the viewport edges. They are logical, so
|
|
34
|
+
* "inline start" is the left edge in left-to-right text and the right edge in
|
|
35
|
+
* right-to-left text. Because custom properties inherit, a dialog nested inside
|
|
36
|
+
* a bounded dialog's markup is bounded the same way unless it sets its own
|
|
37
|
+
* insets.
|
|
38
|
+
*
|
|
39
|
+
* Bounds change only where the dialog paints. What stays reachable is decided
|
|
40
|
+
* by the same rules as an unbounded dialog:
|
|
41
|
+
*
|
|
42
|
+
* - The dialog has no click-outside dismissal, bounded or not. It closes on
|
|
43
|
+
* `Escape`, an `esp-form-dialog-close-requested` event, or `toggleOpen()`, so
|
|
44
|
+
* a click on the uncovered region never counts as an "outside" click.
|
|
45
|
+
* - The dialog marks `inert` the siblings of its anchor element, not the
|
|
46
|
+
* regions its bounds leave uncovered. The anchor is `esp-page`'s dialog drop
|
|
47
|
+
* zone when the dialog sits in the page's markup, so there the page's
|
|
48
|
+
* internal tracks (header, menus, preview, help, footer) are inert and not
|
|
49
|
+
* clickable even where the dialog does not cover them. A dialog that is a
|
|
50
|
+
* direct child of another component's shadow root is anchored on the nearest
|
|
51
|
+
* ancestor host that has a light-DOM parent, and only that host's siblings
|
|
52
|
+
* go inert; the page around it stays live. A dialog wrapped in an element
|
|
53
|
+
* inside that shadow root is anchored on itself, so its siblings in the
|
|
54
|
+
* wrapper go inert instead.
|
|
55
|
+
* - A region that is not inert receives clicks and keyboard focus. The focus
|
|
56
|
+
* trap wraps `Tab` and `Shift+Tab` at the dialog's first and last focusable
|
|
57
|
+
* elements, and `Escape` is handled on the dialog, both only while focus is
|
|
58
|
+
* inside it. A click on an uncovered control moves focus there, and from then
|
|
59
|
+
* on `Tab` continues through the page and `Escape` no longer closes the
|
|
60
|
+
* dialog. Set `inert` on the uncovered regions that must not be reachable
|
|
61
|
+
* while the dialog is open (an inert region is also skipped by screen
|
|
62
|
+
* readers).
|
|
63
|
+
* - Bounds assume a horizontal writing mode: the insets are logical, but the
|
|
64
|
+
* dialog's width and height are physical.
|
|
65
|
+
*
|
|
66
|
+
* ```html
|
|
67
|
+
* <style>
|
|
68
|
+
* esp-dialog.bounded {
|
|
69
|
+
* --esp-dialog-inset-block-start: 6rem;
|
|
70
|
+
* --esp-dialog-inset-inline-start: 3rem;
|
|
71
|
+
* --esp-dialog-inset-inline-end: 3rem;
|
|
72
|
+
* --esp-dialog-inset-block-end: 2rem;
|
|
73
|
+
* }
|
|
74
|
+
* </style>
|
|
75
|
+
* <esp-dialog class="bounded" full-screen>
|
|
76
|
+
* <esp-box full-screen>
|
|
77
|
+
* <h2>Bounded dialog</h2>
|
|
78
|
+
* <p>The page above and around this box stays visible.</p>
|
|
79
|
+
* <esp-button intent="danger" label="Close"></esp-button>
|
|
80
|
+
* </esp-box>
|
|
81
|
+
* </esp-dialog>
|
|
82
|
+
* <esp-button label="Show Dialog"></esp-button>
|
|
83
|
+
* <script>
|
|
84
|
+
* const theDialog = findByTagName("esp-dialog")[0];
|
|
85
|
+
* const buttons = findByTagName("esp-button");
|
|
86
|
+
* buttons[0].addEventListener("esp-clicked", () => {
|
|
87
|
+
* theDialog.toggleOpen();
|
|
88
|
+
* });
|
|
89
|
+
* buttons[1].addEventListener("esp-clicked", () => {
|
|
90
|
+
* theDialog.toggleOpen();
|
|
91
|
+
* });
|
|
92
|
+
* </script>
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
23
95
|
* @slot - Place content to show modally in the default slot.
|
|
24
96
|
*
|
|
25
97
|
* ```html
|
|
@@ -105,6 +177,10 @@ import { LitElement } from "lit";
|
|
|
105
177
|
*
|
|
106
178
|
* @cssprop --esp-color-dialog-bg - The background color of the dialog overlay.
|
|
107
179
|
* @cssprop --esp-dialog-bg-opacity - The opacity of the dialog overlay background.
|
|
180
|
+
* @cssprop --esp-dialog-inset-block-start - The top edge of the area the dialog covers, as a length from the viewport top. Defaults to `0px`.
|
|
181
|
+
* @cssprop --esp-dialog-inset-inline-start - The leading edge (left in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`.
|
|
182
|
+
* @cssprop --esp-dialog-inset-inline-end - The trailing edge (right in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`.
|
|
183
|
+
* @cssprop --esp-dialog-inset-block-end - The bottom edge of the area the dialog covers, as a length from the viewport bottom. Defaults to `0px`.
|
|
108
184
|
* @attr {"1"|"2"|"3"|"4"} surface-layer - Declares the painted surface depth; defaults to layer 3.
|
|
109
185
|
* @customElement esp-dialog
|
|
110
186
|
* @docPageTitle Dialog
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
var
|
|
1
|
+
var p=function(l,e,t,i){var n=arguments.length,s=n<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(l,e,t,i);else for(var r=l.length-1;r>=0;r--)(a=l[r])&&(s=(n<3?a(s):n>3?a(e,t,s):a(e,t))||s);return n>3&&s&&Object.defineProperty(e,t,s),s};import{paintedSurface as v,surfaceLayerAttributes as f}from"../shared/surface-layer.js";import{LitElement as g,css as b,html as m,nothing as d}from"lit";import{customElement as y,property as k,state as _}from"lit/decorators.js";import{classMap as x}from"lit/directives/class-map.js";import{createRef as u,ref as h}from"lit/directives/ref.js";import{OverlayController as O}from"../shared/overlay-controller.js";import{ESP_EVENTS as c}from"../shared/events.js";let o=class extends g{constructor(){super(...arguments),this.dialogSlot=u(),this.vellumRef=u(),this.isOpen=!1,this._overlay=new O({host:this,getFocusTrapContainer:()=>this.vellumRef.value??null,getFocusFallback:()=>this.vellumRef.value??null}),this._closeReason="api",this._lifecycleToken=0,this.fullScreen=!1}toggleOpen(){if(this.isOpen){const e=this._closeReason;this._closeReason="api";const t=new CustomEvent(c.DIALOG_CLOSING,{detail:{reason:e},bubbles:!0,composed:!0,cancelable:!0});if(!this.dispatchEvent(t))return;const i=++this._lifecycleToken;this.removeAttribute("is-open"),this.isOpen=!1,this._overlay.close(),this.updateComplete.then(()=>{this.isOpen||this._lifecycleToken!==i||this.dispatchEvent(new CustomEvent(c.DIALOG_CLOSED,{detail:{reason:e},bubbles:!0,composed:!0}))})}else{const e=++this._lifecycleToken;this.setAttribute("is-open","true"),this.isOpen=!0,this._overlay.open(),this.updateComplete.then(()=>{!this.isOpen||this._lifecycleToken!==e||(this._moveFocusIntoDialog(),this.dispatchEvent(new CustomEvent(c.DIALOG_OPENED,{detail:{},bubbles:!0,composed:!0})))})}}_handleKeyDown(e){if(this.isOpen){if(e.key==="Escape"){e.preventDefault(),this._closeReason="escape",this.toggleOpen();return}e.key==="Tab"&&this._overlay.trapFocus(e)}}_moveFocusIntoDialog(){this._overlay.moveFocusInto()}firstUpdated(){this.dialogSlot.value&&this.dialogSlot.value.addEventListener("esp-form-dialog-close-requested",e=>{this._closeReason="close-dialog",this.toggleOpen(),e.preventDefault()})}disconnectedCallback(){super.disconnectedCallback()}render(){const{isOpen:e,fullScreen:t}=this,i={"is-open":e,"full-screen":t};return m`<div
|
|
2
2
|
${h(this.vellumRef)}
|
|
3
|
-
class="vellum ${
|
|
3
|
+
class="vellum ${x(i)}"
|
|
4
4
|
data-no-swipe
|
|
5
|
-
role=${e?"dialog":
|
|
6
|
-
aria-modal=${e?"true":
|
|
5
|
+
role=${e?"dialog":d}
|
|
6
|
+
aria-modal=${e?"true":d}
|
|
7
7
|
tabindex="-1"
|
|
8
8
|
@keydown=${this._handleKeyDown}
|
|
9
9
|
>
|
|
10
10
|
<slot ${h(this.dialogSlot)}></slot>
|
|
11
|
-
</div>`}};
|
|
11
|
+
</div>`}};o.styles=[v(3),f(":host"),b`
|
|
12
12
|
:host {
|
|
13
13
|
display: block;
|
|
14
14
|
}
|
|
@@ -20,12 +20,21 @@ var c=function(l,e,t,o){var n=arguments.length,i=n<3?e:o===null?o=Object.getOwnP
|
|
|
20
20
|
visibility: hidden;
|
|
21
21
|
position: fixed;
|
|
22
22
|
z-index: 10000;
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
inset-inline-start: var(--esp-dialog-inset-inline-start, 0px);
|
|
24
|
+
inset-block-start: var(--esp-dialog-inset-block-start, 0px);
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
width: calc(
|
|
27
|
+
100vw - var(--esp-dialog-inset-inline-start, 0px) - var(
|
|
28
|
+
--esp-dialog-inset-inline-end,
|
|
29
|
+
0px
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
height: calc(
|
|
33
|
+
100vh - var(--esp-dialog-inset-block-start, 0px) - var(--esp-dialog-inset-block-end, 0px)
|
|
34
|
+
);
|
|
35
|
+
height: calc(
|
|
36
|
+
100dvh - var(--esp-dialog-inset-block-start, 0px) - var(--esp-dialog-inset-block-end, 0px)
|
|
37
|
+
);
|
|
29
38
|
overflow-y: auto;
|
|
30
39
|
outline: none;
|
|
31
40
|
|
|
@@ -34,11 +43,18 @@ var c=function(l,e,t,o){var n=arguments.length,i=n<3?e:o===null?o=Object.getOwnP
|
|
|
34
43
|
position: relative;
|
|
35
44
|
}
|
|
36
45
|
|
|
37
|
-
&::before
|
|
46
|
+
&::before,
|
|
47
|
+
&::after {
|
|
38
48
|
content: "";
|
|
39
49
|
display: block;
|
|
40
50
|
position: fixed;
|
|
41
|
-
inset:
|
|
51
|
+
inset-inline: var(--esp-dialog-inset-inline-start, 0px)
|
|
52
|
+
var(--esp-dialog-inset-inline-end, 0px);
|
|
53
|
+
inset-block: var(--esp-dialog-inset-block-start, 0px)
|
|
54
|
+
var(--esp-dialog-inset-block-end, 0px);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&::before {
|
|
42
58
|
opacity: var(--esp-dialog-bg-opacity, var(--esp-vellum-opacity, 0.85));
|
|
43
59
|
background: var(
|
|
44
60
|
--esp-color-dialog-bg,
|
|
@@ -48,10 +64,6 @@ var c=function(l,e,t,o){var n=arguments.length,i=n<3?e:o===null?o=Object.getOwnP
|
|
|
48
64
|
}
|
|
49
65
|
|
|
50
66
|
&::after {
|
|
51
|
-
content: "";
|
|
52
|
-
display: block;
|
|
53
|
-
position: fixed;
|
|
54
|
-
inset: 0;
|
|
55
67
|
background-image: var(--esp-vellum-background-image, none);
|
|
56
68
|
background-repeat: repeat;
|
|
57
69
|
opacity: var(--esp-vellum-background-image-opacity, 0.3);
|
|
@@ -74,4 +86,4 @@ var c=function(l,e,t,o){var n=arguments.length,i=n<3?e:o===null?o=Object.getOwnP
|
|
|
74
86
|
}
|
|
75
87
|
}
|
|
76
88
|
}
|
|
77
|
-
`],
|
|
89
|
+
`],p([_()],o.prototype,"isOpen",void 0),p([k({attribute:"full-screen",type:Boolean})],o.prototype,"fullScreen",void 0),o=p([y("esp-dialog")],o);export{o as EspalierDialog};
|
package/espalier.css-data.json
CHANGED
|
@@ -469,6 +469,22 @@
|
|
|
469
469
|
"name": "--esp-dialog-bg-opacity",
|
|
470
470
|
"description": "The opacity of the dialog overlay background."
|
|
471
471
|
},
|
|
472
|
+
{
|
|
473
|
+
"name": "--esp-dialog-inset-block-end",
|
|
474
|
+
"description": "The bottom edge of the area the dialog covers, as a length from the viewport bottom. Defaults to `0px`."
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
"name": "--esp-dialog-inset-block-start",
|
|
478
|
+
"description": "The top edge of the area the dialog covers, as a length from the viewport top. Defaults to `0px`."
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
"name": "--esp-dialog-inset-inline-end",
|
|
482
|
+
"description": "The trailing edge (right in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`."
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
"name": "--esp-dialog-inset-inline-start",
|
|
486
|
+
"description": "The leading edge (left in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`."
|
|
487
|
+
},
|
|
472
488
|
{
|
|
473
489
|
"name": "--esp-field-background",
|
|
474
490
|
"description": "Background color of the shared field shell. Defaults to one layer above the nearest declared surface, capped at `var(--esp-color-layer-4)`, or `var(--esp-color-layer-2)` without a declared surface. An explicit override wins."
|
|
@@ -633,6 +633,30 @@
|
|
|
633
633
|
"component": "esp-dialog",
|
|
634
634
|
"description": "The opacity of the dialog overlay background."
|
|
635
635
|
},
|
|
636
|
+
{
|
|
637
|
+
"name": "--esp-dialog-inset-block-end",
|
|
638
|
+
"category": "component",
|
|
639
|
+
"component": "esp-dialog",
|
|
640
|
+
"description": "The bottom edge of the area the dialog covers, as a length from the viewport bottom. Defaults to `0px`."
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
"name": "--esp-dialog-inset-block-start",
|
|
644
|
+
"category": "component",
|
|
645
|
+
"component": "esp-dialog",
|
|
646
|
+
"description": "The top edge of the area the dialog covers, as a length from the viewport top. Defaults to `0px`."
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
"name": "--esp-dialog-inset-inline-end",
|
|
650
|
+
"category": "component",
|
|
651
|
+
"component": "esp-dialog",
|
|
652
|
+
"description": "The trailing edge (right in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`."
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
"name": "--esp-dialog-inset-inline-start",
|
|
656
|
+
"category": "component",
|
|
657
|
+
"component": "esp-dialog",
|
|
658
|
+
"description": "The leading edge (left in left-to-right text) of the area the dialog covers, as a length from the viewport edge. Defaults to `0px`."
|
|
659
|
+
},
|
|
636
660
|
{
|
|
637
661
|
"name": "--esp-field-background",
|
|
638
662
|
"category": "shared-hook",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taprootio/espalier",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0",
|
|
4
4
|
"packageManager": "bun@1.3.12",
|
|
5
5
|
"description": "Espalier — a themeable, accessible, framework-agnostic, enterprise-grade design system built on web standards and love.",
|
|
6
6
|
"customElements": "custom-elements.json",
|