@wildwinter/app-shell 0.40.0 → 0.41.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/README.md +44 -0
- package/dist/{chunk-DS4XXAZS.js → chunk-4OAORWEM.js} +2 -2
- package/dist/chunk-4OAORWEM.js.map +1 -0
- package/dist/chunk-BZ3MQDWM.js +153 -0
- package/dist/chunk-BZ3MQDWM.js.map +1 -0
- package/dist/{chunk-SDOKZTAR.js → chunk-G2JT3HZH.js} +15 -2
- package/dist/chunk-G2JT3HZH.js.map +1 -0
- package/dist/index.cjs +161 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/kit-gallery.cjs +369 -0
- package/dist/kit-gallery.cjs.map +1 -0
- package/dist/kit-gallery.css +179 -0
- package/dist/kit-gallery.css.map +1 -0
- package/dist/kit-gallery.d.cts +64 -0
- package/dist/kit-gallery.d.ts +64 -0
- package/dist/kit-gallery.js +6 -0
- package/dist/kit-gallery.js.map +1 -0
- package/dist/link-status.cjs +13 -0
- package/dist/link-status.cjs.map +1 -1
- package/dist/link-status.js +1 -1
- package/dist/problems.cjs.map +1 -1
- package/dist/problems.js +1 -1
- package/dist/stepper.css +1 -0
- package/dist/stepper.css.map +1 -1
- package/package.json +10 -1
- package/dist/chunk-DS4XXAZS.js.map +0 -1
- package/dist/chunk-SDOKZTAR.js.map +0 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/* src/kit-gallery.css */
|
|
2
|
+
.kit-gallery {
|
|
3
|
+
--dialog-width: 880px;
|
|
4
|
+
--kit-art-ink: var(--ink);
|
|
5
|
+
--kit-art-plate: transparent;
|
|
6
|
+
}
|
|
7
|
+
.kit-gallery .shell-dialog-body {
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
}
|
|
10
|
+
.kit-gallery-layout {
|
|
11
|
+
display: grid;
|
|
12
|
+
grid-template-columns: minmax(0, 1fr) 288px;
|
|
13
|
+
gap: 18px;
|
|
14
|
+
min-height: 0;
|
|
15
|
+
max-height: 64vh;
|
|
16
|
+
}
|
|
17
|
+
.kit-gallery-shelves {
|
|
18
|
+
overflow-y: auto;
|
|
19
|
+
min-height: 0;
|
|
20
|
+
padding: 2px;
|
|
21
|
+
}
|
|
22
|
+
.kit-gallery-panel {
|
|
23
|
+
overflow-y: auto;
|
|
24
|
+
min-height: 0;
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
gap: 6px;
|
|
28
|
+
padding: 2px 2px 2px 18px;
|
|
29
|
+
border-left: 1px solid var(--line);
|
|
30
|
+
}
|
|
31
|
+
.kit-gallery-shelf + .kit-gallery-shelf {
|
|
32
|
+
margin-top: 18px;
|
|
33
|
+
}
|
|
34
|
+
.kit-gallery-caption {
|
|
35
|
+
margin: 0 0 6px;
|
|
36
|
+
color: var(--muted);
|
|
37
|
+
font: 600 13px/1.3 var(--font-ui);
|
|
38
|
+
}
|
|
39
|
+
.kit-gallery-shelf-note {
|
|
40
|
+
margin: -2px 0 8px;
|
|
41
|
+
color: var(--muted);
|
|
42
|
+
font: 12.5px/1.45 var(--font-ui);
|
|
43
|
+
}
|
|
44
|
+
.kit-gallery-grid {
|
|
45
|
+
display: grid;
|
|
46
|
+
grid-template-columns: repeat(auto-fill, minmax(176px, 1fr));
|
|
47
|
+
gap: 8px;
|
|
48
|
+
}
|
|
49
|
+
.kit-gallery-tile {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-direction: column;
|
|
52
|
+
align-items: stretch;
|
|
53
|
+
gap: 4px;
|
|
54
|
+
padding: 8px;
|
|
55
|
+
text-align: left;
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
background: none;
|
|
58
|
+
color: var(--ink);
|
|
59
|
+
font: inherit;
|
|
60
|
+
border: 1px solid var(--line);
|
|
61
|
+
border-radius: var(--radius-md);
|
|
62
|
+
transition: background var(--dur-quick) var(--ease-standard), border-color var(--dur-quick) var(--ease-standard);
|
|
63
|
+
}
|
|
64
|
+
.kit-gallery-tile:hover {
|
|
65
|
+
background: color-mix(in oklab, var(--accent) 6%, transparent);
|
|
66
|
+
}
|
|
67
|
+
.kit-gallery-tile[aria-pressed=true] {
|
|
68
|
+
border-color: var(--accent);
|
|
69
|
+
background: color-mix(in oklab, var(--accent) 10%, transparent);
|
|
70
|
+
}
|
|
71
|
+
.kit-gallery-tile-head {
|
|
72
|
+
display: flex;
|
|
73
|
+
align-items: baseline;
|
|
74
|
+
gap: 6px;
|
|
75
|
+
flex-wrap: wrap;
|
|
76
|
+
}
|
|
77
|
+
.kit-gallery-tile-name {
|
|
78
|
+
font: 600 14px/1.3 var(--font-ui);
|
|
79
|
+
}
|
|
80
|
+
.kit-gallery-tile-blurb {
|
|
81
|
+
color: var(--muted);
|
|
82
|
+
font: 12.5px/1.4 var(--font-ui);
|
|
83
|
+
display: -webkit-box;
|
|
84
|
+
-webkit-box-orient: vertical;
|
|
85
|
+
-webkit-line-clamp: 3;
|
|
86
|
+
line-clamp: 3;
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
}
|
|
89
|
+
.kit-gallery-badge {
|
|
90
|
+
padding: 1px 6px;
|
|
91
|
+
border-radius: 999px;
|
|
92
|
+
background: color-mix(in oklab, var(--accent) 16%, transparent);
|
|
93
|
+
color: var(--ink);
|
|
94
|
+
font: 600 11px/1.5 var(--font-ui);
|
|
95
|
+
}
|
|
96
|
+
.kit-gallery-art {
|
|
97
|
+
position: relative;
|
|
98
|
+
aspect-ratio: 5 / 3;
|
|
99
|
+
overflow: hidden;
|
|
100
|
+
border-radius: var(--radius-sm);
|
|
101
|
+
background: var(--kit-art-plate);
|
|
102
|
+
}
|
|
103
|
+
.kit-gallery-art[hidden] {
|
|
104
|
+
display: none;
|
|
105
|
+
}
|
|
106
|
+
.kit-gallery-ink {
|
|
107
|
+
position: absolute;
|
|
108
|
+
inset: 0;
|
|
109
|
+
background: var(--kit-art-ink);
|
|
110
|
+
-webkit-mask: var(--kit-art) center / cover no-repeat;
|
|
111
|
+
mask: var(--kit-art) center / cover no-repeat;
|
|
112
|
+
}
|
|
113
|
+
.kit-gallery-panel-name {
|
|
114
|
+
margin: 2px 0 0;
|
|
115
|
+
font: 600 16px/1.3 var(--font-ui);
|
|
116
|
+
}
|
|
117
|
+
.kit-gallery-panel-blurb,
|
|
118
|
+
.kit-gallery-panel-detail {
|
|
119
|
+
margin: 0;
|
|
120
|
+
font: 13.5px/1.5 var(--font-ui);
|
|
121
|
+
color: var(--ink);
|
|
122
|
+
}
|
|
123
|
+
.kit-gallery-play {
|
|
124
|
+
margin: 0;
|
|
125
|
+
font: 13.5px/1.5 var(--font-ui);
|
|
126
|
+
color: var(--ink);
|
|
127
|
+
}
|
|
128
|
+
.kit-gallery-shows,
|
|
129
|
+
.kit-gallery-note {
|
|
130
|
+
margin: 0;
|
|
131
|
+
font: 12.5px/1.45 var(--font-ui);
|
|
132
|
+
color: var(--muted);
|
|
133
|
+
}
|
|
134
|
+
.kit-gallery-lands-caption {
|
|
135
|
+
margin: 6px 0 0;
|
|
136
|
+
font: 600 13px/1.3 var(--font-ui);
|
|
137
|
+
color: var(--muted);
|
|
138
|
+
}
|
|
139
|
+
.kit-gallery-lands {
|
|
140
|
+
margin: 0;
|
|
141
|
+
padding-left: 18px;
|
|
142
|
+
font: 13px/1.5 var(--font-ui);
|
|
143
|
+
color: var(--ink);
|
|
144
|
+
}
|
|
145
|
+
.kit-gallery-panel [hidden] {
|
|
146
|
+
display: none;
|
|
147
|
+
}
|
|
148
|
+
.kit-gallery-fields {
|
|
149
|
+
display: flex;
|
|
150
|
+
flex-direction: column;
|
|
151
|
+
gap: 6px;
|
|
152
|
+
margin-top: 8px;
|
|
153
|
+
padding-top: 10px;
|
|
154
|
+
border-top: 1px solid var(--line);
|
|
155
|
+
}
|
|
156
|
+
.kit-gallery-label {
|
|
157
|
+
font: 600 13px/1.3 var(--font-ui);
|
|
158
|
+
color: var(--ink);
|
|
159
|
+
}
|
|
160
|
+
.kit-gallery-name.kit-gallery-missing {
|
|
161
|
+
border-color: var(--danger);
|
|
162
|
+
}
|
|
163
|
+
@media (max-width: 760px) {
|
|
164
|
+
.kit-gallery-layout {
|
|
165
|
+
grid-template-columns: minmax(0, 1fr);
|
|
166
|
+
max-height: none;
|
|
167
|
+
overflow-y: auto;
|
|
168
|
+
}
|
|
169
|
+
.kit-gallery-panel {
|
|
170
|
+
border-left: none;
|
|
171
|
+
border-top: 1px solid var(--line);
|
|
172
|
+
padding: 12px 2px 2px;
|
|
173
|
+
overflow: visible;
|
|
174
|
+
}
|
|
175
|
+
.kit-gallery-shelves {
|
|
176
|
+
overflow: visible;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/*# sourceMappingURL=kit-gallery.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/kit-gallery.css"],"sourcesContent":["/* ---------------------------------------------------------------------------\n The kit gallery (kit-gallery.ts): tiles on the left, a details panel on the\n right, on the dialog frame (dialog.css) with `.btn` from controls.css and\n `.field` for the name. Reads the palette (--surface, --ink, --muted,\n --line, --accent) over the shared tokens.\n\n Pictures are masks: the image's opaque pixels are drawn in --kit-art-ink on\n --kit-art-plate. The defaults suit a light theme (ink on the tile). A dark\n theme should NOT invert an engraving, which turns it into a photographic\n negative; it sets a paper-toned plate and a dark ink instead, so the\n picture is always dark on light and only its frame follows the theme.\n --------------------------------------------------------------------------- */\n\n.kit-gallery {\n --dialog-width: 880px;\n --kit-art-ink: var(--ink);\n --kit-art-plate: transparent;\n}\n.kit-gallery .shell-dialog-body { overflow: hidden; }\n\n.kit-gallery-layout {\n display: grid; grid-template-columns: minmax(0, 1fr) 288px; gap: 18px;\n min-height: 0; max-height: 64vh;\n}\n.kit-gallery-shelves { overflow-y: auto; min-height: 0; padding: 2px; }\n.kit-gallery-panel {\n overflow-y: auto; min-height: 0;\n display: flex; flex-direction: column; gap: 6px;\n padding: 2px 2px 2px 18px; border-left: 1px solid var(--line);\n}\n\n/* A shelf per job (start / learn), captioned like the welcome's groups:\n sentence-case label text, never an overline. */\n.kit-gallery-shelf + .kit-gallery-shelf { margin-top: 18px; }\n.kit-gallery-caption { margin: 0 0 6px; color: var(--muted); font: 600 13px/1.3 var(--font-ui); }\n.kit-gallery-shelf-note { margin: -2px 0 8px; color: var(--muted); font: 12.5px/1.45 var(--font-ui); }\n\n.kit-gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: 8px; }\n.kit-gallery-tile {\n display: flex; flex-direction: column; align-items: stretch; gap: 4px;\n padding: 8px; text-align: left; cursor: pointer;\n background: none; color: var(--ink); font: inherit;\n border: 1px solid var(--line); border-radius: var(--radius-md);\n transition: background var(--dur-quick) var(--ease-standard), border-color var(--dur-quick) var(--ease-standard);\n}\n.kit-gallery-tile:hover { background: color-mix(in oklab, var(--accent) 6%, transparent); }\n.kit-gallery-tile[aria-pressed=\"true\"] {\n border-color: var(--accent);\n background: color-mix(in oklab, var(--accent) 10%, transparent);\n}\n.kit-gallery-tile-head { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }\n.kit-gallery-tile-name { font: 600 14px/1.3 var(--font-ui); }\n/* Three lines on the tile; the panel says the rest. */\n.kit-gallery-tile-blurb {\n color: var(--muted); font: 12.5px/1.4 var(--font-ui);\n display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden;\n}\n.kit-gallery-badge {\n padding: 1px 6px; border-radius: 999px;\n background: color-mix(in oklab, var(--accent) 16%, transparent); color: var(--ink);\n font: 600 11px/1.5 var(--font-ui);\n}\n\n/* The picture: a plate, and the ink drawn through the image as a mask. */\n.kit-gallery-art {\n position: relative; aspect-ratio: 5 / 3; overflow: hidden;\n border-radius: var(--radius-sm); background: var(--kit-art-plate);\n}\n.kit-gallery-art[hidden] { display: none; }\n.kit-gallery-ink {\n position: absolute; inset: 0; background: var(--kit-art-ink);\n -webkit-mask: var(--kit-art) center / cover no-repeat;\n mask: var(--kit-art) center / cover no-repeat;\n}\n\n/* The details panel: the chosen kit said in full, then the app's fields. */\n.kit-gallery-panel-name { margin: 2px 0 0; font: 600 16px/1.3 var(--font-ui); }\n.kit-gallery-panel-blurb, .kit-gallery-panel-detail { margin: 0; font: 13.5px/1.5 var(--font-ui); color: var(--ink); }\n.kit-gallery-play { margin: 0; font: 13.5px/1.5 var(--font-ui); color: var(--ink); }\n.kit-gallery-shows, .kit-gallery-note { margin: 0; font: 12.5px/1.45 var(--font-ui); color: var(--muted); }\n.kit-gallery-lands-caption { margin: 6px 0 0; font: 600 13px/1.3 var(--font-ui); color: var(--muted); }\n.kit-gallery-lands { margin: 0; padding-left: 18px; font: 13px/1.5 var(--font-ui); color: var(--ink); }\n.kit-gallery-panel [hidden] { display: none; }\n.kit-gallery-fields { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--line); }\n.kit-gallery-label { font: 600 13px/1.3 var(--font-ui); color: var(--ink); }\n.kit-gallery-name.kit-gallery-missing { border-color: var(--danger); }\n\n/* Narrow windows: the panel goes under the tiles. */\n@media (max-width: 760px) {\n .kit-gallery-layout { grid-template-columns: minmax(0, 1fr); max-height: none; overflow-y: auto; }\n .kit-gallery-panel { border-left: none; border-top: 1px solid var(--line); padding: 12px 2px 2px; overflow: visible; }\n .kit-gallery-shelves { overflow: visible; }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
interface KitGalleryItem<T extends string> {
|
|
2
|
+
id: T;
|
|
3
|
+
/** What you are making, in the author's terms, not the model's. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** What it is FOR: one line on the tile, and the panel's first line. */
|
|
6
|
+
blurb: string;
|
|
7
|
+
/** More, for the panel only. */
|
|
8
|
+
detail?: string;
|
|
9
|
+
/** What pressing Play (or Run) shows, said as a promise. */
|
|
10
|
+
play?: string;
|
|
11
|
+
/** The model's parts it puts to work, second and quieter ("Shows: ..."). */
|
|
12
|
+
shows?: string;
|
|
13
|
+
/** What lands, in the concrete, as a short list in the panel. */
|
|
14
|
+
lands?: string[];
|
|
15
|
+
/** A word or two on the tile ("Start here"). */
|
|
16
|
+
badge?: string;
|
|
17
|
+
/** An illustration: a transparent image whose opaque pixels are the ink.
|
|
18
|
+
* Drawn as a mask in `--kit-art-ink` on `--kit-art-plate`, so one file
|
|
19
|
+
* serves both themes and the app chooses the colours. */
|
|
20
|
+
image?: string;
|
|
21
|
+
}
|
|
22
|
+
interface KitGallerySection<T extends string> {
|
|
23
|
+
/** Sentence-case label text ("Start from a kit"). Absent: no caption. */
|
|
24
|
+
caption?: string;
|
|
25
|
+
/** The consequence of a click, said before the click. */
|
|
26
|
+
note?: string;
|
|
27
|
+
items: KitGalleryItem<T>[];
|
|
28
|
+
/** The primary button's label while an item here is chosen. Default "Create". */
|
|
29
|
+
action?: string;
|
|
30
|
+
/** Show the app's detail fields (and ask for the name) for this section.
|
|
31
|
+
* Default true. An example is opened, not named, so its shelf says false. */
|
|
32
|
+
usesDetails?: boolean;
|
|
33
|
+
}
|
|
34
|
+
interface KitGalleryChoice {
|
|
35
|
+
/** Present when a name was asked for and the chosen section uses details. */
|
|
36
|
+
name?: string;
|
|
37
|
+
}
|
|
38
|
+
interface KitGalleryOptions<T extends string> {
|
|
39
|
+
/** The dialog's heading: "New project", "New box", "New scene". */
|
|
40
|
+
title: string;
|
|
41
|
+
/** What the thing being made IS, in concrete terms. */
|
|
42
|
+
what?: string;
|
|
43
|
+
sections: KitGallerySection<T>[];
|
|
44
|
+
/** Ask for a name in the details panel, with this placeholder. Required
|
|
45
|
+
* when asked: making a thing without one would have to invent a folder. */
|
|
46
|
+
namePlaceholder?: string;
|
|
47
|
+
/** The name field's label. Default "Name". */
|
|
48
|
+
nameLabel?: string;
|
|
49
|
+
/** The app's own fields, below the name (version control, a build path). */
|
|
50
|
+
details?: HTMLElement;
|
|
51
|
+
/** The item chosen when the gallery opens. Default: the first. */
|
|
52
|
+
initial?: T;
|
|
53
|
+
onPick: (id: T, choice: KitGalleryChoice) => void;
|
|
54
|
+
/** Runs once the gallery has closed, whichever way. */
|
|
55
|
+
onClose?: () => void;
|
|
56
|
+
}
|
|
57
|
+
interface KitGallery {
|
|
58
|
+
readonly dialog: HTMLDialogElement;
|
|
59
|
+
close(): void;
|
|
60
|
+
}
|
|
61
|
+
/** Open the gallery as a modal dialog on the family's frame. */
|
|
62
|
+
declare function openKitGallery<T extends string>(opts: KitGalleryOptions<T>): KitGallery;
|
|
63
|
+
|
|
64
|
+
export { type KitGallery, type KitGalleryChoice, type KitGalleryItem, type KitGalleryOptions, type KitGallerySection, openKitGallery };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
interface KitGalleryItem<T extends string> {
|
|
2
|
+
id: T;
|
|
3
|
+
/** What you are making, in the author's terms, not the model's. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** What it is FOR: one line on the tile, and the panel's first line. */
|
|
6
|
+
blurb: string;
|
|
7
|
+
/** More, for the panel only. */
|
|
8
|
+
detail?: string;
|
|
9
|
+
/** What pressing Play (or Run) shows, said as a promise. */
|
|
10
|
+
play?: string;
|
|
11
|
+
/** The model's parts it puts to work, second and quieter ("Shows: ..."). */
|
|
12
|
+
shows?: string;
|
|
13
|
+
/** What lands, in the concrete, as a short list in the panel. */
|
|
14
|
+
lands?: string[];
|
|
15
|
+
/** A word or two on the tile ("Start here"). */
|
|
16
|
+
badge?: string;
|
|
17
|
+
/** An illustration: a transparent image whose opaque pixels are the ink.
|
|
18
|
+
* Drawn as a mask in `--kit-art-ink` on `--kit-art-plate`, so one file
|
|
19
|
+
* serves both themes and the app chooses the colours. */
|
|
20
|
+
image?: string;
|
|
21
|
+
}
|
|
22
|
+
interface KitGallerySection<T extends string> {
|
|
23
|
+
/** Sentence-case label text ("Start from a kit"). Absent: no caption. */
|
|
24
|
+
caption?: string;
|
|
25
|
+
/** The consequence of a click, said before the click. */
|
|
26
|
+
note?: string;
|
|
27
|
+
items: KitGalleryItem<T>[];
|
|
28
|
+
/** The primary button's label while an item here is chosen. Default "Create". */
|
|
29
|
+
action?: string;
|
|
30
|
+
/** Show the app's detail fields (and ask for the name) for this section.
|
|
31
|
+
* Default true. An example is opened, not named, so its shelf says false. */
|
|
32
|
+
usesDetails?: boolean;
|
|
33
|
+
}
|
|
34
|
+
interface KitGalleryChoice {
|
|
35
|
+
/** Present when a name was asked for and the chosen section uses details. */
|
|
36
|
+
name?: string;
|
|
37
|
+
}
|
|
38
|
+
interface KitGalleryOptions<T extends string> {
|
|
39
|
+
/** The dialog's heading: "New project", "New box", "New scene". */
|
|
40
|
+
title: string;
|
|
41
|
+
/** What the thing being made IS, in concrete terms. */
|
|
42
|
+
what?: string;
|
|
43
|
+
sections: KitGallerySection<T>[];
|
|
44
|
+
/** Ask for a name in the details panel, with this placeholder. Required
|
|
45
|
+
* when asked: making a thing without one would have to invent a folder. */
|
|
46
|
+
namePlaceholder?: string;
|
|
47
|
+
/** The name field's label. Default "Name". */
|
|
48
|
+
nameLabel?: string;
|
|
49
|
+
/** The app's own fields, below the name (version control, a build path). */
|
|
50
|
+
details?: HTMLElement;
|
|
51
|
+
/** The item chosen when the gallery opens. Default: the first. */
|
|
52
|
+
initial?: T;
|
|
53
|
+
onPick: (id: T, choice: KitGalleryChoice) => void;
|
|
54
|
+
/** Runs once the gallery has closed, whichever way. */
|
|
55
|
+
onClose?: () => void;
|
|
56
|
+
}
|
|
57
|
+
interface KitGallery {
|
|
58
|
+
readonly dialog: HTMLDialogElement;
|
|
59
|
+
close(): void;
|
|
60
|
+
}
|
|
61
|
+
/** Open the gallery as a modal dialog on the family's frame. */
|
|
62
|
+
declare function openKitGallery<T extends string>(opts: KitGalleryOptions<T>): KitGallery;
|
|
63
|
+
|
|
64
|
+
export { type KitGallery, type KitGalleryChoice, type KitGalleryItem, type KitGalleryOptions, type KitGallerySection, openKitGallery };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"kit-gallery.js"}
|
package/dist/link-status.cjs
CHANGED
|
@@ -367,6 +367,8 @@ function linkAddress(s) {
|
|
|
367
367
|
if (s.state !== "listening" && s.state !== "connected") return void 0;
|
|
368
368
|
return s.address ?? `ws://127.0.0.1:${s.port}`;
|
|
369
369
|
}
|
|
370
|
+
var CORNER_INSET = 14.5;
|
|
371
|
+
var CORNER_GAP = 12;
|
|
370
372
|
function mountLinkStatus(host, opts) {
|
|
371
373
|
const wrap = el("div", "linkstatus");
|
|
372
374
|
wrap.hidden = true;
|
|
@@ -380,6 +382,15 @@ function mountLinkStatus(host, opts) {
|
|
|
380
382
|
wrap.append(...opts.lead ?? [], url, toggle);
|
|
381
383
|
host.append(wrap);
|
|
382
384
|
let status = { state: "off" };
|
|
385
|
+
const root = host.ownerDocument.documentElement;
|
|
386
|
+
const publishReserve = () => {
|
|
387
|
+
const width = wrap.hidden ? 0 : wrap.getBoundingClientRect().width;
|
|
388
|
+
root.style.setProperty(
|
|
389
|
+
"--linkstatus-reserve",
|
|
390
|
+
width > 0 ? `${Math.ceil(width + CORNER_INSET + CORNER_GAP)}px` : "0px"
|
|
391
|
+
);
|
|
392
|
+
};
|
|
393
|
+
if (typeof ResizeObserver !== "undefined") new ResizeObserver(publishReserve).observe(wrap);
|
|
383
394
|
const render = () => {
|
|
384
395
|
toggle.className = `linkstatus-toggle ${linkStatusClass(status)}`;
|
|
385
396
|
const tip2 = linkStatusTip(status);
|
|
@@ -391,6 +402,7 @@ function mountLinkStatus(host, opts) {
|
|
|
391
402
|
url.dataset["tip"] = "Click to copy the live link address";
|
|
392
403
|
url.hidden = false;
|
|
393
404
|
} else url.hidden = true;
|
|
405
|
+
publishReserve();
|
|
394
406
|
};
|
|
395
407
|
const apply = (s) => {
|
|
396
408
|
status = s;
|
|
@@ -415,6 +427,7 @@ function mountLinkStatus(host, opts) {
|
|
|
415
427
|
status: () => status,
|
|
416
428
|
setVisible(on) {
|
|
417
429
|
wrap.hidden = !on;
|
|
430
|
+
publishReserve();
|
|
418
431
|
},
|
|
419
432
|
toggle() {
|
|
420
433
|
toggle.click();
|