@wildwinter/app-shell 0.40.1 → 0.42.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 +42 -0
- package/dist/chunk-3M4EWDFW.js +157 -0
- package/dist/chunk-3M4EWDFW.js.map +1 -0
- package/dist/{chunk-SEWJLUOD.js → chunk-UMMIZ65U.js} +9 -3
- package/dist/chunk-UMMIZ65U.js.map +1 -0
- package/dist/index.cjs +159 -1
- 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 +374 -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 +76 -0
- package/dist/kit-gallery.d.ts +76 -0
- package/dist/kit-gallery.js +6 -0
- package/dist/kit-gallery.js.map +1 -0
- package/dist/welcome.cjs +34 -1
- package/dist/welcome.cjs.map +1 -1
- package/dist/welcome.css +3 -0
- package/dist/welcome.css.map +1 -1
- package/dist/welcome.d.cts +8 -0
- package/dist/welcome.d.ts +8 -0
- package/dist/welcome.js +4 -1
- package/package.json +10 -1
- package/dist/chunk-SEWJLUOD.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,76 @@
|
|
|
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: the panel's first line, and the tile's unless `tile` says otherwise. */
|
|
6
|
+
blurb: string;
|
|
7
|
+
/** The tile's line, when the blurb is longer than a tile holds (three
|
|
8
|
+
* lines). A whole short sentence reads better than a long one cut off. */
|
|
9
|
+
tile?: string;
|
|
10
|
+
/** More, for the panel only. */
|
|
11
|
+
detail?: string;
|
|
12
|
+
/** What pressing Play (or Run) shows, said as a promise. */
|
|
13
|
+
play?: string;
|
|
14
|
+
/** The model's parts it puts to work, second and quieter ("Shows: ..."). */
|
|
15
|
+
shows?: string;
|
|
16
|
+
/** What lands, in the concrete, as a short list in the panel. */
|
|
17
|
+
lands?: string[];
|
|
18
|
+
/** A word or two on the tile ("Start here"). */
|
|
19
|
+
badge?: string;
|
|
20
|
+
/** An illustration: a transparent image whose opaque pixels are the ink.
|
|
21
|
+
* Drawn as a mask in `--kit-art-ink` on `--kit-art-plate`, so one file
|
|
22
|
+
* serves both themes and the app chooses the colours. */
|
|
23
|
+
image?: string;
|
|
24
|
+
}
|
|
25
|
+
interface KitGallerySection<T extends string> {
|
|
26
|
+
/** Sentence-case label text ("Start from a kit"). Absent: no caption. */
|
|
27
|
+
caption?: string;
|
|
28
|
+
/** The consequence of a click, said before the click. */
|
|
29
|
+
note?: string;
|
|
30
|
+
items: KitGalleryItem<T>[];
|
|
31
|
+
/** The primary button's label while an item here is chosen. Default "Create". */
|
|
32
|
+
action?: string;
|
|
33
|
+
/** Show the app's detail fields (and ask for the name) for this section.
|
|
34
|
+
* Default true. An example is opened, not named, so its shelf says false. */
|
|
35
|
+
usesDetails?: boolean;
|
|
36
|
+
}
|
|
37
|
+
interface KitGalleryChoice {
|
|
38
|
+
/** Present when a name was asked for and the chosen section uses details. */
|
|
39
|
+
name?: string;
|
|
40
|
+
}
|
|
41
|
+
interface KitGalleryOptions<T extends string> {
|
|
42
|
+
/** The dialog's heading: "New project", "New box", "New scene". */
|
|
43
|
+
title: string;
|
|
44
|
+
/** What the thing being made IS, in concrete terms. */
|
|
45
|
+
what?: string;
|
|
46
|
+
sections: KitGallerySection<T>[];
|
|
47
|
+
/** Ask for a name in the details panel, with this placeholder. Required
|
|
48
|
+
* when asked: making a thing without one would have to invent a folder. */
|
|
49
|
+
namePlaceholder?: string;
|
|
50
|
+
/** The name field's label. Default "Name". */
|
|
51
|
+
nameLabel?: string;
|
|
52
|
+
/** The app's own fields, below the name (version control, a build path). */
|
|
53
|
+
details?: HTMLElement;
|
|
54
|
+
/** The item chosen when the gallery opens. Default: the first. */
|
|
55
|
+
initial?: T;
|
|
56
|
+
onPick: (id: T, choice: KitGalleryChoice) => void;
|
|
57
|
+
/** Runs once the gallery has closed, whichever way. */
|
|
58
|
+
onClose?: () => void;
|
|
59
|
+
}
|
|
60
|
+
interface KitGallery {
|
|
61
|
+
readonly dialog: HTMLDialogElement;
|
|
62
|
+
close(): void;
|
|
63
|
+
}
|
|
64
|
+
/** One tile: the picture, the name with its badge, the blurb. The gallery's
|
|
65
|
+
* own, and the welcome screen's, so a kit looks the same wherever it is met
|
|
66
|
+
* (welcome.ts draws a tiled group with it; import kit-gallery.css there too). */
|
|
67
|
+
declare function kitTile(item: {
|
|
68
|
+
name: string;
|
|
69
|
+
blurb: string;
|
|
70
|
+
badge?: string;
|
|
71
|
+
image?: string;
|
|
72
|
+
}, onClick: () => void): HTMLButtonElement;
|
|
73
|
+
/** Open the gallery as a modal dialog on the family's frame. */
|
|
74
|
+
declare function openKitGallery<T extends string>(opts: KitGalleryOptions<T>): KitGallery;
|
|
75
|
+
|
|
76
|
+
export { type KitGallery, type KitGalleryChoice, type KitGalleryItem, type KitGalleryOptions, type KitGallerySection, kitTile, openKitGallery };
|
|
@@ -0,0 +1,76 @@
|
|
|
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: the panel's first line, and the tile's unless `tile` says otherwise. */
|
|
6
|
+
blurb: string;
|
|
7
|
+
/** The tile's line, when the blurb is longer than a tile holds (three
|
|
8
|
+
* lines). A whole short sentence reads better than a long one cut off. */
|
|
9
|
+
tile?: string;
|
|
10
|
+
/** More, for the panel only. */
|
|
11
|
+
detail?: string;
|
|
12
|
+
/** What pressing Play (or Run) shows, said as a promise. */
|
|
13
|
+
play?: string;
|
|
14
|
+
/** The model's parts it puts to work, second and quieter ("Shows: ..."). */
|
|
15
|
+
shows?: string;
|
|
16
|
+
/** What lands, in the concrete, as a short list in the panel. */
|
|
17
|
+
lands?: string[];
|
|
18
|
+
/** A word or two on the tile ("Start here"). */
|
|
19
|
+
badge?: string;
|
|
20
|
+
/** An illustration: a transparent image whose opaque pixels are the ink.
|
|
21
|
+
* Drawn as a mask in `--kit-art-ink` on `--kit-art-plate`, so one file
|
|
22
|
+
* serves both themes and the app chooses the colours. */
|
|
23
|
+
image?: string;
|
|
24
|
+
}
|
|
25
|
+
interface KitGallerySection<T extends string> {
|
|
26
|
+
/** Sentence-case label text ("Start from a kit"). Absent: no caption. */
|
|
27
|
+
caption?: string;
|
|
28
|
+
/** The consequence of a click, said before the click. */
|
|
29
|
+
note?: string;
|
|
30
|
+
items: KitGalleryItem<T>[];
|
|
31
|
+
/** The primary button's label while an item here is chosen. Default "Create". */
|
|
32
|
+
action?: string;
|
|
33
|
+
/** Show the app's detail fields (and ask for the name) for this section.
|
|
34
|
+
* Default true. An example is opened, not named, so its shelf says false. */
|
|
35
|
+
usesDetails?: boolean;
|
|
36
|
+
}
|
|
37
|
+
interface KitGalleryChoice {
|
|
38
|
+
/** Present when a name was asked for and the chosen section uses details. */
|
|
39
|
+
name?: string;
|
|
40
|
+
}
|
|
41
|
+
interface KitGalleryOptions<T extends string> {
|
|
42
|
+
/** The dialog's heading: "New project", "New box", "New scene". */
|
|
43
|
+
title: string;
|
|
44
|
+
/** What the thing being made IS, in concrete terms. */
|
|
45
|
+
what?: string;
|
|
46
|
+
sections: KitGallerySection<T>[];
|
|
47
|
+
/** Ask for a name in the details panel, with this placeholder. Required
|
|
48
|
+
* when asked: making a thing without one would have to invent a folder. */
|
|
49
|
+
namePlaceholder?: string;
|
|
50
|
+
/** The name field's label. Default "Name". */
|
|
51
|
+
nameLabel?: string;
|
|
52
|
+
/** The app's own fields, below the name (version control, a build path). */
|
|
53
|
+
details?: HTMLElement;
|
|
54
|
+
/** The item chosen when the gallery opens. Default: the first. */
|
|
55
|
+
initial?: T;
|
|
56
|
+
onPick: (id: T, choice: KitGalleryChoice) => void;
|
|
57
|
+
/** Runs once the gallery has closed, whichever way. */
|
|
58
|
+
onClose?: () => void;
|
|
59
|
+
}
|
|
60
|
+
interface KitGallery {
|
|
61
|
+
readonly dialog: HTMLDialogElement;
|
|
62
|
+
close(): void;
|
|
63
|
+
}
|
|
64
|
+
/** One tile: the picture, the name with its badge, the blurb. The gallery's
|
|
65
|
+
* own, and the welcome screen's, so a kit looks the same wherever it is met
|
|
66
|
+
* (welcome.ts draws a tiled group with it; import kit-gallery.css there too). */
|
|
67
|
+
declare function kitTile(item: {
|
|
68
|
+
name: string;
|
|
69
|
+
blurb: string;
|
|
70
|
+
badge?: string;
|
|
71
|
+
image?: string;
|
|
72
|
+
}, onClick: () => void): HTMLButtonElement;
|
|
73
|
+
/** Open the gallery as a modal dialog on the family's frame. */
|
|
74
|
+
declare function openKitGallery<T extends string>(opts: KitGalleryOptions<T>): KitGallery;
|
|
75
|
+
|
|
76
|
+
export { type KitGallery, type KitGalleryChoice, type KitGalleryItem, type KitGalleryOptions, type KitGallerySection, kitTile, openKitGallery };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"kit-gallery.js"}
|
package/dist/welcome.cjs
CHANGED
|
@@ -145,6 +145,34 @@ function el(tag, classNameOrProps, ...children) {
|
|
|
145
145
|
return node;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
// src/kit-gallery.ts
|
|
149
|
+
function setArt(host, image) {
|
|
150
|
+
host.replaceChildren();
|
|
151
|
+
host.hidden = image === void 0;
|
|
152
|
+
if (image === void 0) return;
|
|
153
|
+
const ink = el("span", "kit-gallery-ink");
|
|
154
|
+
ink.style.setProperty("--kit-art", `url("${image.replace(/"/g, "%22")}")`);
|
|
155
|
+
host.append(ink);
|
|
156
|
+
}
|
|
157
|
+
function kitTile(item, onClick) {
|
|
158
|
+
const art = el("div", "kit-gallery-art");
|
|
159
|
+
setArt(art, item.image);
|
|
160
|
+
const tile = el(
|
|
161
|
+
"button",
|
|
162
|
+
{ className: "kit-gallery-tile", onClick },
|
|
163
|
+
art,
|
|
164
|
+
el(
|
|
165
|
+
"span",
|
|
166
|
+
"kit-gallery-tile-head",
|
|
167
|
+
el("span", "kit-gallery-tile-name", item.name),
|
|
168
|
+
item.badge !== void 0 ? el("span", "kit-gallery-badge", item.badge) : null
|
|
169
|
+
),
|
|
170
|
+
el("span", "kit-gallery-tile-blurb", item.blurb)
|
|
171
|
+
);
|
|
172
|
+
tile.type = "button";
|
|
173
|
+
return tile;
|
|
174
|
+
}
|
|
175
|
+
|
|
148
176
|
// src/welcome.ts
|
|
149
177
|
function mountWelcome(host, opts) {
|
|
150
178
|
const caption = (text) => el("h2", "welcome-caption", text);
|
|
@@ -158,7 +186,12 @@ function mountWelcome(host, opts) {
|
|
|
158
186
|
const groups = (opts.groups ?? []).map((g) => group(
|
|
159
187
|
g.caption,
|
|
160
188
|
g.note !== void 0 ? el("p", "welcome-note", g.note) : null,
|
|
161
|
-
el("div", "welcome-
|
|
189
|
+
g.tiles ? el("div", "kit-gallery-grid welcome-tiles", ...g.items.map((item) => kitTile({
|
|
190
|
+
name: item.name,
|
|
191
|
+
blurb: item.hint ?? "",
|
|
192
|
+
...item.badge !== void 0 ? { badge: item.badge } : {},
|
|
193
|
+
...item.image !== void 0 ? { image: item.image } : {}
|
|
194
|
+
}, item.onOpen))) : el("div", "welcome-list", ...g.items.map((item) => {
|
|
162
195
|
const b = el(
|
|
163
196
|
"button",
|
|
164
197
|
{ className: "welcome-item", onClick: item.onOpen },
|