@gjermundgaraba-designs/pixel-paper 0.23.0 → 0.24.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/DESIGN.md +8 -7
- package/dist/src/iconButton/iconButton.d.ts +6 -1
- package/dist/src/iconButton/iconButton.d.ts.map +1 -1
- package/dist/src/iconButton/iconButton.js +7 -2
- package/dist/src/panel/panel.d.ts +3 -0
- package/dist/src/panel/panel.d.ts.map +1 -1
- package/dist/src/panel/panel.js +2 -1
- package/dist/src/rail/index.d.ts +1 -1
- package/dist/src/rail/index.d.ts.map +1 -1
- package/dist/src/rail/index.js +1 -1
- package/dist/src/rail/rail.d.ts +78 -17
- package/dist/src/rail/rail.d.ts.map +1 -1
- package/dist/src/rail/rail.js +98 -41
- package/dist/src/tips/tips.d.ts +30 -1
- package/dist/src/tips/tips.d.ts.map +1 -1
- package/dist/src/tips/tips.js +53 -31
- package/package.json +1 -1
- package/src/iconButton/iconButton.ts +19 -2
- package/src/panel/panel.ts +5 -0
- package/src/pixel-paper.css +119 -4
- package/src/rail/index.ts +2 -0
- package/src/rail/rail.ts +119 -41
- package/src/tips/tips.ts +71 -35
- package/src/tokens.css +1 -0
package/dist/src/rail/rail.js
CHANGED
|
@@ -22,8 +22,8 @@ const Resizing = Schema.Struct({
|
|
|
22
22
|
width: Schema.Number,
|
|
23
23
|
});
|
|
24
24
|
/** Schema for a rail: whether it is open as a drawer (at 900px and under; wider, it is always
|
|
25
|
-
* in the page and this stays false), and its splitter while a pointer drags it. Its width
|
|
26
|
-
* the parent's. */
|
|
25
|
+
* in the page and this stays false), and its splitter while a pointer drags it. Its width,
|
|
26
|
+
* and whether the reader hid it, are the parent's. */
|
|
27
27
|
export const Model = Schema.Struct({
|
|
28
28
|
id: Schema.String,
|
|
29
29
|
isOpen: Schema.Boolean,
|
|
@@ -35,6 +35,7 @@ export const Model = Schema.Struct({
|
|
|
35
35
|
* the window growing past 900px while it is open, where the rail is back in the page. */
|
|
36
36
|
export const Message = defineMessageUnion({
|
|
37
37
|
ClickedOpen: {},
|
|
38
|
+
ClickedToggle: {},
|
|
38
39
|
PressedSplitter: { pointerId: Schema.Number, clientX: Schema.Number, width: Schema.Number },
|
|
39
40
|
MovedSplitter: { clientX: Schema.Number },
|
|
40
41
|
ReleasedSplitter: { clientX: Schema.Number },
|
|
@@ -47,12 +48,16 @@ export const Message = defineMessageUnion({
|
|
|
47
48
|
WidenedPastDrawer: {},
|
|
48
49
|
CompletedShowRailDrawer: {},
|
|
49
50
|
CompletedHideRailDrawer: {},
|
|
51
|
+
CompletedFocusRailToggle: {},
|
|
50
52
|
});
|
|
51
53
|
/** What a rail asks of its parent. `ResizedRail`: its splitter was let go, or stepped by a
|
|
52
54
|
* key, at `width` pixels, within the rail's bounds; the parent keeps it (per client) and
|
|
53
|
-
* passes it back as the view's `maybeWidth`.
|
|
55
|
+
* passes it back as the view's `maybeWidth`. `ToggledRail`: its toggle was pressed; the
|
|
56
|
+
* parent flips whether it keeps the rail hidden (per client) and passes it back as the view's
|
|
57
|
+
* `isHidden`. */
|
|
54
58
|
export const OutMessage = defineMessageUnion({
|
|
55
59
|
ResizedRail: { width: Schema.Number },
|
|
60
|
+
ToggledRail: {},
|
|
56
61
|
});
|
|
57
62
|
/** Creates a rail, closed, its splitter at rest. */
|
|
58
63
|
export const init = (config) => (__foldkitBrandViewResult(({
|
|
@@ -75,12 +80,14 @@ export const id = (model) => __foldkitBrandViewResult((model.id), "@gjermundgara
|
|
|
75
80
|
/** Whether the rail is open as a drawer: a parent pauses its own page keys while it is. */
|
|
76
81
|
export const isOpen = (model) => __foldkitBrandViewResult((model.isOpen), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#isOpen");
|
|
77
82
|
const openButtonId = (model) => __foldkitBrandViewResult((`${model.id}-open`), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#openButtonId");
|
|
83
|
+
const toggleId = (model) => __foldkitBrandViewResult((`${model.id}-toggle`), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#toggleId");
|
|
78
84
|
// COMMAND
|
|
79
85
|
const FOCUSABLE = "a[href], button:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]";
|
|
80
86
|
const findRail = (railId) => __foldkitBrandViewResult((Effect.suspend(() => __foldkitBrandViewResult((Effect.fromNullishOr(document.querySelector(`#${CSS.escape(railId)}`))), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous"))), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#findRail");
|
|
81
87
|
/** The drawer's first Tab stop past its head: a control the keyboard reaches, so a tree's
|
|
82
|
-
* items other than its one stop (`tabindex="-1"`) are passed over
|
|
83
|
-
|
|
88
|
+
* items other than its one stop (`tabindex="-1"`) are passed over, and so is the toggle,
|
|
89
|
+
* which the drawer does not print. */
|
|
90
|
+
export const firstTabStop = (rail) => __foldkitBrandViewResult((Array.findFirst(Array.fromIterable(rail.querySelectorAll(`.rail-head ~ * :is(${FOCUSABLE})`)), (control) => __foldkitBrandViewResult((control.tabIndex >= 0 && control.closest("[inert], [hidden], .rail-toggle") === null), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~2"))), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#firstTabStop");
|
|
84
91
|
/** Opens the rail as a drawer over the page and puts focus on its first control past its
|
|
85
92
|
* head. */
|
|
86
93
|
export const ShowRailDrawer = Command.define("ShowRailDrawer", {
|
|
@@ -108,6 +115,22 @@ export const HideRailDrawer = Command.define("HideRailDrawer", {
|
|
|
108
115
|
}
|
|
109
116
|
}).pipe(Effect.ignore, Effect.andThen(isReturningFocus ? Dom.focus(`#${CSS.escape(buttonId)}`).pipe(Effect.ignore) : Effect.void), Effect.as(Message.CompletedHideRailDrawer()))), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#execute~2"),
|
|
110
117
|
});
|
|
118
|
+
/** Puts focus on the rail's toggle once the rail has folded or unfolded, if focus was in the
|
|
119
|
+
* rail or on its splitter: folding takes away every control in it but the toggle, which
|
|
120
|
+
* brings it back, and the splitter with them. Focus anywhere else stays where it is. */
|
|
121
|
+
export const FocusRailToggle = Command.define("FocusRailToggle", {
|
|
122
|
+
args: { railId: Schema.String, toggleId: Schema.String },
|
|
123
|
+
messages: [Message.CompletedFocusRailToggle],
|
|
124
|
+
execute: ({ railId, toggleId: buttonId }) => __foldkitBrandViewResult((Effect.gen(function* () {
|
|
125
|
+
// NOTE: read before the fold renders, which takes away the control focus is on
|
|
126
|
+
const rail = yield* findRail(railId);
|
|
127
|
+
const active = document.activeElement;
|
|
128
|
+
const isOnSplitter = active?.matches(`.rail-resize[aria-controls="${CSS.escape(railId)}"]`) ?? false;
|
|
129
|
+
if (rail.contains(active) || isOnSplitter) {
|
|
130
|
+
yield* Dom.focus(`#${CSS.escape(buttonId)}`);
|
|
131
|
+
}
|
|
132
|
+
}).pipe(Effect.ignore, Effect.as(Message.CompletedFocusRailToggle()))), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#execute~3"),
|
|
133
|
+
});
|
|
111
134
|
const closeDrawer = (model, isReturningFocus) => __foldkitBrandViewResult((model.isOpen
|
|
112
135
|
? {
|
|
113
136
|
model: modifyFields(model, { isOpen: () => __foldkitBrandViewResult((false), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#isOpen~2") }),
|
|
@@ -123,16 +146,25 @@ const open = (model) => (__foldkitBrandViewResult(({
|
|
|
123
146
|
}), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#open"));
|
|
124
147
|
/** Closes the rail's drawer, focus back on its button. */
|
|
125
148
|
export const close = (model) => __foldkitBrandViewResult((closeDrawer(model, true)), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#close");
|
|
149
|
+
/** Folds or unfolds the rail from a key of the parent's: the parent flips whether it keeps the
|
|
150
|
+
* rail hidden, as it does for `ToggledRail`, and folds this in, which moves focus in the rail
|
|
151
|
+
* onto the toggle. */
|
|
152
|
+
export const toggle = (model) => (__foldkitBrandViewResult(({
|
|
153
|
+
model,
|
|
154
|
+
commands: [FocusRailToggle({ railId: model.id, toggleId: toggleId(model) })],
|
|
155
|
+
}), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#toggle"));
|
|
126
156
|
const withResizing = (model, maybeResizing) => __foldkitBrandViewResult((modifyFields(model, { maybeResizing: () => __foldkitBrandViewResult((maybeResizing), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#maybeResizing") })), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#withResizing");
|
|
127
157
|
/** The width a dragged splitter previews with the pointer at `clientX`. */
|
|
128
158
|
const dragTo = (model, clientX) => __foldkitBrandViewResult((withResizing(model, Option.map(model.maybeResizing, (resizing) => (__foldkitBrandViewResult(({
|
|
129
159
|
...resizing,
|
|
130
160
|
width: bounded(resizing.fromWidth + clientX - resizing.pressX),
|
|
131
|
-
}), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~
|
|
161
|
+
}), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~8"))))), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#dragTo");
|
|
132
162
|
/** Processes a rail Message and returns the next Model, Commands and OutMessage: a splitter let
|
|
133
|
-
* go where it changes the width, or stepped by a key, asks for the width
|
|
163
|
+
* go where it changes the width, or stepped by a key, asks for the width, and the toggle asks
|
|
164
|
+
* to fold or unfold the rail. */
|
|
134
165
|
export const update = (model, message) => __foldkitBrandViewResult((Message.match(message, {
|
|
135
166
|
ClickedOpen: () => __foldkitBrandViewResult((open(model)), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#ClickedOpen"),
|
|
167
|
+
ClickedToggle: () => (__foldkitBrandViewResult(({ ...toggle(model), outMessage: OutMessage.ToggledRail() }), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#ClickedToggle")),
|
|
136
168
|
PressedSplitter: ({ pointerId, clientX, width }) => __foldkitBrandViewResult((Option.isSome(model.maybeResizing)
|
|
137
169
|
? { model }
|
|
138
170
|
: {
|
|
@@ -158,6 +190,7 @@ export const update = (model, message) => __foldkitBrandViewResult((Message.matc
|
|
|
158
190
|
WidenedPastDrawer: () => __foldkitBrandViewResult((closeDrawer(model, false)), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#WidenedPastDrawer"),
|
|
159
191
|
CompletedShowRailDrawer: () => (__foldkitBrandViewResult(({ model }), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#CompletedShowRailDrawer")),
|
|
160
192
|
CompletedHideRailDrawer: () => (__foldkitBrandViewResult(({ model }), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#CompletedHideRailDrawer")),
|
|
193
|
+
CompletedFocusRailToggle: () => (__foldkitBrandViewResult(({ model }), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#CompletedFocusRailToggle")),
|
|
161
194
|
})), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#update");
|
|
162
195
|
/** The width at and under which the rail is a drawer, as the stylesheet has it. */
|
|
163
196
|
export const DRAWER_QUERY = "(max-width: 900px)";
|
|
@@ -166,10 +199,10 @@ export const DRAWER_QUERY = "(max-width: 900px)";
|
|
|
166
199
|
export const widthChangeMessage = (isDrawerWidth, isDrawerOpen) => __foldkitBrandViewResult((!isDrawerWidth && isDrawerOpen ? Option.some(Message.WidenedPastDrawer()) : Option.none()), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#widthChangeMessage");
|
|
167
200
|
/** The browser closing the drawer (Escape, a press on the veil); a toggle that opened it says
|
|
168
201
|
* nothing. */
|
|
169
|
-
export const drawerToggleMessage = (event) => __foldkitBrandViewResult((Option.liftPredicate(Message.ClosedDrawer(), () => __foldkitBrandViewResult((event.newState === "closed"), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~
|
|
202
|
+
export const drawerToggleMessage = (event) => __foldkitBrandViewResult((Option.liftPredicate(Message.ClosedDrawer(), () => __foldkitBrandViewResult((event.newState === "closed"), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~9"))), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#drawerToggleMessage");
|
|
170
203
|
/** Focus leaving the drawer while it is open (`isDrawerOpen`, the rail matching
|
|
171
204
|
* `:popover-open`); focus moving inside it says nothing. */
|
|
172
|
-
export const drawerFocusOutMessage = (rail, event, isDrawerOpen) => __foldkitBrandViewResult((Option.liftPredicate(Message.BlurredDrawer(), () => __foldkitBrandViewResult((isDrawerOpen && event.relatedTarget instanceof Node && !rail.contains(event.relatedTarget)), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~
|
|
205
|
+
export const drawerFocusOutMessage = (rail, event, isDrawerOpen) => __foldkitBrandViewResult((Option.liftPredicate(Message.BlurredDrawer(), () => __foldkitBrandViewResult((isDrawerOpen && event.relatedTarget instanceof Node && !rail.contains(event.relatedTarget)), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~10"))), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#drawerFocusOutMessage");
|
|
173
206
|
/** Follows the drawer the browser shows: the browser closing it (Escape, a press on the
|
|
174
207
|
* veil), focus leaving it while it is open, and the window growing past its width while it
|
|
175
208
|
* is open, each of which closes the rail. */
|
|
@@ -190,17 +223,17 @@ export const FollowRailDrawer = Mount.defineStream("FollowRailDrawer", {
|
|
|
190
223
|
const fromWidth = Dom.streamFromMediaQuery({
|
|
191
224
|
query: DRAWER_QUERY,
|
|
192
225
|
mapMatches: (isDrawerWidth) => __foldkitBrandViewResult((widthChangeMessage(isDrawerWidth, isDrawerOpen())), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#mapMatches"),
|
|
193
|
-
}).pipe(Stream.filter(Option.isSome), Stream.map(({ value }) => __foldkitBrandViewResult((value), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~
|
|
226
|
+
}).pipe(Stream.filter(Option.isSome), Stream.map(({ value }) => __foldkitBrandViewResult((value), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~11")));
|
|
194
227
|
return __foldkitBrandViewResult((Stream.mergeAll([fromToggle, fromFocusOut, fromWidth], {
|
|
195
228
|
concurrency: "unbounded",
|
|
196
|
-
})), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#execute~
|
|
229
|
+
})), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#execute~4");
|
|
197
230
|
},
|
|
198
231
|
});
|
|
199
232
|
// SUBSCRIPTION
|
|
200
233
|
const railSubscriptions = Subscription.make()((entry) => (__foldkitBrandViewResult(({
|
|
201
234
|
resize: entry({ maybePointerId: Schema.Option(Schema.Number) }, {
|
|
202
235
|
modelToDependencies: (model) => (__foldkitBrandViewResult(({
|
|
203
|
-
maybePointerId: Option.map(model.maybeResizing, ({ pointerId }) => __foldkitBrandViewResult((pointerId), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~
|
|
236
|
+
maybePointerId: Option.map(model.maybeResizing, ({ pointerId }) => __foldkitBrandViewResult((pointerId), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~13")),
|
|
204
237
|
}), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#modelToDependencies")),
|
|
205
238
|
dependenciesToStream: ({ maybePointerId }) => __foldkitBrandViewResult((Option.match(maybePointerId, {
|
|
206
239
|
onNone: () => __foldkitBrandViewResult((Stream.empty), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#onNone~2"),
|
|
@@ -215,17 +248,18 @@ const railSubscriptions = Subscription.make()((entry) => (__foldkitBrandViewResu
|
|
|
215
248
|
modelToDependencies: (model) => (__foldkitBrandViewResult(({ isResizing: Option.isSome(model.maybeResizing) }), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#modelToDependencies~2")),
|
|
216
249
|
dependenciesToStream: ({ isResizing }) => __foldkitBrandViewResult((isResizing ? escapeKeys(Message.PressedEscape()) : Stream.empty), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#dependenciesToStream~2"),
|
|
217
250
|
}),
|
|
218
|
-
}), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~
|
|
251
|
+
}), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~12")));
|
|
219
252
|
/** A dragged splitter follows the pointer, and Escape puts it back before a dialog or the
|
|
220
253
|
* page sees it, from listeners that run only while it is dragged. Lift them into the
|
|
221
254
|
* application's Subscriptions behind a key prefix of the parent's: `subscriptions("rail")` is
|
|
222
255
|
* keyed `railResize` and `railEscape`. */
|
|
223
256
|
export const subscriptions = (keyPrefix) => __foldkitBrandViewResult((prefixKeys(keyPrefix, railSubscriptions)), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#subscriptions");
|
|
224
257
|
/**
|
|
225
|
-
* A column of panels beside the deck, fixed under the top bar
|
|
226
|
-
* `
|
|
227
|
-
*
|
|
228
|
-
*
|
|
258
|
+
* A column of panels beside the deck, fixed under the top bar: `div.railed >` the deck, then
|
|
259
|
+
* `aside.rail[popover="auto"][aria-label]`, then its splitter, `div.rail-resize[role="separator"]`,
|
|
260
|
+
* on its right edge. What comes before its last panel keeps its height, and the last panel
|
|
261
|
+
* shrinks to the room left, its bar and foot staying while its body scrolls. One element
|
|
262
|
+
* serves both layouts, so nothing in it renders twice or loses its state. At 900px and under it leaves the page, and
|
|
229
263
|
* `span.rail-open > button.btn.small` at the top of the deck opens the same element as a drawer
|
|
230
264
|
* over a veil, its head (the name and a close glyph) showing. Opening focuses its first
|
|
231
265
|
* control; Escape, a press on the veil, the close glyph, focus leaving or the window growing
|
|
@@ -237,14 +271,21 @@ export const subscriptions = (keyPrefix) => __foldkitBrandViewResult((prefixKeys
|
|
|
237
271
|
* and the rail's width follow it (without one, `--rail`). The drawer keeps its own width. Lift
|
|
238
272
|
* `subscriptions(keyPrefix)` into the application's, or a dragged splitter follows nothing.
|
|
239
273
|
*
|
|
274
|
+
* Its toggle, `span.rail-toggle > button.iconbtn.quiet[aria-expanded]` ("Hide <label>"), comes
|
|
275
|
+
* to `toAsideView` to print as the first panel's `lead`. Pressed, it reports `ToggledRail` for
|
|
276
|
+
* the parent to keep and pass back as `isHidden`: `div.railed.folded` then stands the first
|
|
277
|
+
* panel's title bar on end on the ground (the toggle at its top, "Show <label>"), the rest of
|
|
278
|
+
* the rail and its splitter gone, and the deck takes the width. Focus in the rail lands on the
|
|
279
|
+
* toggle. The drawer, at 900px and under, prints neither the toggle nor the fold.
|
|
280
|
+
*
|
|
240
281
|
* Its state is its own, not `@foldkit/ui`'s Popover: that panel is placed by Floating UI and
|
|
241
282
|
* rendered only while open, and this one is always in the page, placed by the stylesheet, and
|
|
242
283
|
* opened as a native popover so the browser keeps it in the top layer.
|
|
243
284
|
*/
|
|
244
285
|
export const view = defineView((model, viewInputs, h) => {
|
|
245
|
-
const { label, toAsideView, toDeckView } = viewInputs;
|
|
246
|
-
const maybeWidth = Option.orElse(Option.map(model.maybeResizing, ({ width }) => __foldkitBrandViewResult((width), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~
|
|
247
|
-
const width = Option.getOrElse(maybeWidth, () => __foldkitBrandViewResult((WIDTH.start), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~
|
|
286
|
+
const { label, isHidden, maybeToggleKeyHint, toAsideView, toDeckView } = viewInputs;
|
|
287
|
+
const maybeWidth = Option.orElse(Option.map(model.maybeResizing, ({ width }) => __foldkitBrandViewResult((width), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~15")), () => __foldkitBrandViewResult((Option.map(viewInputs.maybeWidth, bounded)), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~16"));
|
|
288
|
+
const width = Option.getOrElse(maybeWidth, () => __foldkitBrandViewResult((WIDTH.start), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~17"));
|
|
248
289
|
const openButton = h.span([h.Class("rail-open")], [
|
|
249
290
|
Button.view({
|
|
250
291
|
label,
|
|
@@ -258,11 +299,43 @@ export const view = defineView((model, viewInputs, h) => {
|
|
|
258
299
|
],
|
|
259
300
|
}, h),
|
|
260
301
|
]);
|
|
302
|
+
const toggleButton = h.span([h.Class("rail-toggle")], [
|
|
303
|
+
IconButton.view({
|
|
304
|
+
glyph: "sidebar",
|
|
305
|
+
label: `${isHidden ? "Show" : "Hide"} ${label}`,
|
|
306
|
+
isQuiet: true,
|
|
307
|
+
onClick: Message.ClickedToggle(),
|
|
308
|
+
...Option.match(maybeToggleKeyHint, {
|
|
309
|
+
onNone: () => (__foldkitBrandViewResult(({}), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#onNone~3")),
|
|
310
|
+
onSome: (keyHint) => (__foldkitBrandViewResult(({ keyHint }), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#onSome~3")),
|
|
311
|
+
}),
|
|
312
|
+
attributes: [h.Id(toggleId(model)), h.AriaExpanded(!isHidden), h.AriaControls(model.id)],
|
|
313
|
+
}, h),
|
|
314
|
+
]);
|
|
315
|
+
const splitter = h.div([
|
|
316
|
+
h.Class("rail-resize"),
|
|
317
|
+
h.Role("separator"),
|
|
318
|
+
h.AriaLabel(`Width of ${label}`),
|
|
319
|
+
h.AriaControls(model.id),
|
|
320
|
+
h.AriaValuemin(WIDTH.least),
|
|
321
|
+
h.AriaValuemax(WIDTH.most),
|
|
322
|
+
h.AriaValuenow(width),
|
|
323
|
+
h.AriaValuetext(`${width} pixels`),
|
|
324
|
+
h.Tabindex(0),
|
|
325
|
+
...splitterAttributes({
|
|
326
|
+
orientation: "vertical",
|
|
327
|
+
isIdle: Option.isNone(model.maybeResizing),
|
|
328
|
+
onPress: (pointerId, clientX) => __foldkitBrandViewResult((Message.PressedSplitter({ pointerId, clientX, width })), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#onPress"),
|
|
329
|
+
onStep: (direction) => __foldkitBrandViewResult((Message.PressedSplitterKey({ width: width + direction * WIDTH.step })), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#onStep"),
|
|
330
|
+
}, h),
|
|
331
|
+
]);
|
|
261
332
|
// NOTE: the deck comes first so the page's main content, and its h1, precede the rail's
|
|
262
333
|
// panels in reading order; the stylesheet places the rail, fixed, at the left.
|
|
263
334
|
return __foldkitBrandViewResult((h.div([
|
|
264
|
-
h.Class("railed"),
|
|
265
|
-
...
|
|
335
|
+
h.Class(isHidden ? "railed folded" : "railed"),
|
|
336
|
+
...(isHidden
|
|
337
|
+
? []
|
|
338
|
+
: Array.fromOption(Option.map(maybeWidth, (shown) => __foldkitBrandViewResult((h.Style({ "--railed-width": `${shown}px` })), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~18")))),
|
|
266
339
|
], [
|
|
267
340
|
toDeckView(openButton),
|
|
268
341
|
h.aside([
|
|
@@ -276,24 +349,8 @@ export const view = defineView((model, viewInputs, h) => {
|
|
|
276
349
|
h.span([h.Class("label")], [label]),
|
|
277
350
|
IconButton.view({ glyph: "cross", label: "Close", onClick: Message.ClickedClose() }, h),
|
|
278
351
|
]),
|
|
279
|
-
...toAsideView(),
|
|
280
|
-
]),
|
|
281
|
-
h.div([
|
|
282
|
-
h.Class("rail-resize"),
|
|
283
|
-
h.Role("separator"),
|
|
284
|
-
h.AriaLabel(`Width of ${label}`),
|
|
285
|
-
h.AriaControls(model.id),
|
|
286
|
-
h.AriaValuemin(WIDTH.least),
|
|
287
|
-
h.AriaValuemax(WIDTH.most),
|
|
288
|
-
h.AriaValuenow(width),
|
|
289
|
-
h.AriaValuetext(`${width} pixels`),
|
|
290
|
-
h.Tabindex(0),
|
|
291
|
-
...splitterAttributes({
|
|
292
|
-
orientation: "vertical",
|
|
293
|
-
isIdle: Option.isNone(model.maybeResizing),
|
|
294
|
-
onPress: (pointerId, clientX) => __foldkitBrandViewResult((Message.PressedSplitter({ pointerId, clientX, width })), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#onPress"),
|
|
295
|
-
onStep: (direction) => __foldkitBrandViewResult((Message.PressedSplitterKey({ width: width + direction * WIDTH.step })), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#onStep"),
|
|
296
|
-
}, h),
|
|
352
|
+
...toAsideView(toggleButton),
|
|
297
353
|
]),
|
|
298
|
-
|
|
354
|
+
...(isHidden ? [] : [splitter]),
|
|
355
|
+
])), "@gjermundgaraba-designs/pixel-paper/src/rail/rail.js#anonymous~14");
|
|
299
356
|
});
|
package/dist/src/tips/tips.d.ts
CHANGED
|
@@ -12,15 +12,18 @@ export declare const TipState: import("foldkit/schema").TaggedUnion<{
|
|
|
12
12
|
readonly Cold: {};
|
|
13
13
|
readonly Waiting: {
|
|
14
14
|
text: Schema.String;
|
|
15
|
+
maybeKey: Schema.Option<Schema.String>;
|
|
15
16
|
side: Schema.Literals<readonly ["Top", "Right"]>;
|
|
16
17
|
};
|
|
17
18
|
readonly Shown: {
|
|
18
19
|
text: Schema.String;
|
|
20
|
+
maybeKey: Schema.Option<Schema.String>;
|
|
19
21
|
side: Schema.Literals<readonly ["Top", "Right"]>;
|
|
20
22
|
trigger: Schema.Literals<readonly ["Pointer", "Focus"]>;
|
|
21
23
|
};
|
|
22
24
|
readonly Leaving: {
|
|
23
25
|
text: Schema.String;
|
|
26
|
+
maybeKey: Schema.Option<Schema.String>;
|
|
24
27
|
side: Schema.Literals<readonly ["Top", "Right"]>;
|
|
25
28
|
trigger: Schema.Literals<readonly ["Pointer", "Focus"]>;
|
|
26
29
|
};
|
|
@@ -36,15 +39,18 @@ export declare const Model: Schema.Struct<{
|
|
|
36
39
|
readonly Cold: {};
|
|
37
40
|
readonly Waiting: {
|
|
38
41
|
text: Schema.String;
|
|
42
|
+
maybeKey: Schema.Option<Schema.String>;
|
|
39
43
|
side: Schema.Literals<readonly ["Top", "Right"]>;
|
|
40
44
|
};
|
|
41
45
|
readonly Shown: {
|
|
42
46
|
text: Schema.String;
|
|
47
|
+
maybeKey: Schema.Option<Schema.String>;
|
|
43
48
|
side: Schema.Literals<readonly ["Top", "Right"]>;
|
|
44
49
|
trigger: Schema.Literals<readonly ["Pointer", "Focus"]>;
|
|
45
50
|
};
|
|
46
51
|
readonly Leaving: {
|
|
47
52
|
text: Schema.String;
|
|
53
|
+
maybeKey: Schema.Option<Schema.String>;
|
|
48
54
|
side: Schema.Literals<readonly ["Top", "Right"]>;
|
|
49
55
|
trigger: Schema.Literals<readonly ["Pointer", "Focus"]>;
|
|
50
56
|
};
|
|
@@ -56,12 +62,14 @@ export type Model = typeof Model.Type;
|
|
|
56
62
|
export declare const Message: import("foldkit/message").MessageUnion<{
|
|
57
63
|
readonly EnteredTipTarget: {
|
|
58
64
|
text: Schema.String;
|
|
65
|
+
maybeKey: Schema.Option<Schema.String>;
|
|
59
66
|
side: Schema.Literals<readonly ["Top", "Right"]>;
|
|
60
67
|
};
|
|
61
68
|
readonly LeftTipTarget: {};
|
|
62
69
|
readonly EnteredTip: {};
|
|
63
70
|
readonly FocusedTipTarget: {
|
|
64
71
|
text: Schema.String;
|
|
72
|
+
maybeKey: Schema.Option<Schema.String>;
|
|
65
73
|
side: Schema.Literals<readonly ["Top", "Right"]>;
|
|
66
74
|
};
|
|
67
75
|
readonly BlurredTipTarget: {};
|
|
@@ -136,16 +144,19 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
136
144
|
} | {
|
|
137
145
|
readonly _tag: "Leaving";
|
|
138
146
|
readonly text: string;
|
|
147
|
+
readonly maybeKey: Option.Option<string>;
|
|
139
148
|
readonly side: "Right" | "Top";
|
|
140
149
|
readonly trigger: "Focus" | "Pointer";
|
|
141
150
|
} | {
|
|
142
151
|
readonly _tag: "Shown";
|
|
143
152
|
readonly text: string;
|
|
153
|
+
readonly maybeKey: Option.Option<string>;
|
|
144
154
|
readonly side: "Right" | "Top";
|
|
145
155
|
readonly trigger: "Focus" | "Pointer";
|
|
146
156
|
} | {
|
|
147
157
|
readonly _tag: "Waiting";
|
|
148
158
|
readonly text: string;
|
|
159
|
+
readonly maybeKey: Option.Option<string>;
|
|
149
160
|
readonly side: "Right" | "Top";
|
|
150
161
|
} | {
|
|
151
162
|
readonly _tag: "Warm";
|
|
@@ -171,10 +182,12 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
171
182
|
} | {
|
|
172
183
|
readonly _tag: "EnteredTipTarget";
|
|
173
184
|
readonly text: string;
|
|
185
|
+
readonly maybeKey: Option.Option<string>;
|
|
174
186
|
readonly side: "Right" | "Top";
|
|
175
187
|
} | {
|
|
176
188
|
readonly _tag: "FocusedTipTarget";
|
|
177
189
|
readonly text: string;
|
|
190
|
+
readonly maybeKey: Option.Option<string>;
|
|
178
191
|
readonly side: "Right" | "Top";
|
|
179
192
|
} | {
|
|
180
193
|
readonly _tag: "LeftTipTarget";
|
|
@@ -210,16 +223,19 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
210
223
|
} | {
|
|
211
224
|
readonly _tag: "Leaving";
|
|
212
225
|
readonly text: string;
|
|
226
|
+
readonly maybeKey: Option.Option<string>;
|
|
213
227
|
readonly side: "Right" | "Top";
|
|
214
228
|
readonly trigger: "Focus" | "Pointer";
|
|
215
229
|
} | {
|
|
216
230
|
readonly _tag: "Shown";
|
|
217
231
|
readonly text: string;
|
|
232
|
+
readonly maybeKey: Option.Option<string>;
|
|
218
233
|
readonly side: "Right" | "Top";
|
|
219
234
|
readonly trigger: "Focus" | "Pointer";
|
|
220
235
|
} | {
|
|
221
236
|
readonly _tag: "Waiting";
|
|
222
237
|
readonly text: string;
|
|
238
|
+
readonly maybeKey: Option.Option<string>;
|
|
223
239
|
readonly side: "Right" | "Top";
|
|
224
240
|
} | {
|
|
225
241
|
readonly _tag: "Warm";
|
|
@@ -244,10 +260,12 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
244
260
|
} | {
|
|
245
261
|
readonly _tag: "EnteredTipTarget";
|
|
246
262
|
readonly text: string;
|
|
263
|
+
readonly maybeKey: Option.Option<string>;
|
|
247
264
|
readonly side: "Right" | "Top";
|
|
248
265
|
} | {
|
|
249
266
|
readonly _tag: "FocusedTipTarget";
|
|
250
267
|
readonly text: string;
|
|
268
|
+
readonly maybeKey: Option.Option<string>;
|
|
251
269
|
readonly side: "Right" | "Top";
|
|
252
270
|
} | {
|
|
253
271
|
readonly _tag: "LeftTipTarget";
|
|
@@ -268,16 +286,19 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
268
286
|
} | {
|
|
269
287
|
readonly _tag: "Leaving";
|
|
270
288
|
readonly text: string;
|
|
289
|
+
readonly maybeKey: Option.Option<string>;
|
|
271
290
|
readonly side: "Right" | "Top";
|
|
272
291
|
readonly trigger: "Focus" | "Pointer";
|
|
273
292
|
} | {
|
|
274
293
|
readonly _tag: "Shown";
|
|
275
294
|
readonly text: string;
|
|
295
|
+
readonly maybeKey: Option.Option<string>;
|
|
276
296
|
readonly side: "Right" | "Top";
|
|
277
297
|
readonly trigger: "Focus" | "Pointer";
|
|
278
298
|
} | {
|
|
279
299
|
readonly _tag: "Waiting";
|
|
280
300
|
readonly text: string;
|
|
301
|
+
readonly maybeKey: Option.Option<string>;
|
|
281
302
|
readonly side: "Right" | "Top";
|
|
282
303
|
} | {
|
|
283
304
|
readonly _tag: "Warm";
|
|
@@ -302,10 +323,12 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
302
323
|
} | {
|
|
303
324
|
readonly _tag: "EnteredTipTarget";
|
|
304
325
|
readonly text: string;
|
|
326
|
+
readonly maybeKey: Option.Option<string>;
|
|
305
327
|
readonly side: "Right" | "Top";
|
|
306
328
|
} | {
|
|
307
329
|
readonly _tag: "FocusedTipTarget";
|
|
308
330
|
readonly text: string;
|
|
331
|
+
readonly maybeKey: Option.Option<string>;
|
|
309
332
|
readonly side: "Right" | "Top";
|
|
310
333
|
} | {
|
|
311
334
|
readonly _tag: "LeftTipTarget";
|
|
@@ -321,7 +344,8 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
321
344
|
} extends infer T ? { readonly [Key in keyof T as `${Prefix}${Capitalize<Key>}`]: T[Key]; } : never;
|
|
322
345
|
/**
|
|
323
346
|
* The page's one tip: `div.tip[popover="manual"][aria-hidden="true"]`, which shows the words
|
|
324
|
-
* of any control carrying `data-tip` (IconButton, the glyph switch, a board's grip)
|
|
347
|
+
* of any control carrying `data-tip` (IconButton, the glyph switch, a board's grip), then the
|
|
348
|
+
* key in its `data-tip-key` where it has one (an IconButton's `keyHint`). Render it
|
|
325
349
|
* once, beside the Announcer, and lift `subscriptions(keyPrefix)`. It opens on a resting
|
|
326
350
|
* pointer after a moment (at once while another has just closed), never on touch, and on
|
|
327
351
|
* keyboard focus; it can be hovered; leaving, blur, a press or any key closes it, and Escape
|
|
@@ -340,16 +364,19 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
340
364
|
} | {
|
|
341
365
|
readonly _tag: "Leaving";
|
|
342
366
|
readonly text: string;
|
|
367
|
+
readonly maybeKey: Option.Option<string>;
|
|
343
368
|
readonly side: "Right" | "Top";
|
|
344
369
|
readonly trigger: "Focus" | "Pointer";
|
|
345
370
|
} | {
|
|
346
371
|
readonly _tag: "Shown";
|
|
347
372
|
readonly text: string;
|
|
373
|
+
readonly maybeKey: Option.Option<string>;
|
|
348
374
|
readonly side: "Right" | "Top";
|
|
349
375
|
readonly trigger: "Focus" | "Pointer";
|
|
350
376
|
} | {
|
|
351
377
|
readonly _tag: "Waiting";
|
|
352
378
|
readonly text: string;
|
|
379
|
+
readonly maybeKey: Option.Option<string>;
|
|
353
380
|
readonly side: "Right" | "Top";
|
|
354
381
|
} | {
|
|
355
382
|
readonly _tag: "Warm";
|
|
@@ -374,10 +401,12 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
374
401
|
} | {
|
|
375
402
|
readonly _tag: "EnteredTipTarget";
|
|
376
403
|
readonly text: string;
|
|
404
|
+
readonly maybeKey: Option.Option<string>;
|
|
377
405
|
readonly side: "Right" | "Top";
|
|
378
406
|
} | {
|
|
379
407
|
readonly _tag: "FocusedTipTarget";
|
|
380
408
|
readonly text: string;
|
|
409
|
+
readonly maybeKey: Option.Option<string>;
|
|
381
410
|
readonly side: "Right" | "Top";
|
|
382
411
|
} | {
|
|
383
412
|
readonly _tag: "LeftTipTarget";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tips.d.ts","sourceRoot":"","sources":["../../../src/tips/tips.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"tips.d.ts","sourceRoot":"","sources":["../../../src/tips/tips.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,MAAM,EAIN,MAAM,EACN,MAAM,EAGP,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAC;AAQ3C,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAW9C,iEAAiE;AACjE,eAAO,MAAM,OAAO,gDAAwC,CAAC;AAC7D,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAQ1C;;+FAE+F;AAC/F,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;EAMnB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;AAE5C;sDACsD;AACtD,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;EAIhB,CAAC;AACH,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAItC,uDAAuD;AACvD,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;QAQY,OAAO;;;QACR,OAAO;;;QACN,OAAO;;;;EAGrC,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAI1C,2FAA2F;AAC3F,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAElD,yCAAyC;AACzC,eAAO,MAAM,IAAI,WAAY,UAAU,KAAG,KAIxC,CAAC;AAIH,oDAAoD;AACpD,eAAO,MAAM,EAAE,UAAW,KAAK,KAAG,MAAkB,CAAC;AA8DrD;;;0CAG0C;AAC1C,eAAO,MAAM,OAAO;;;;;;iBAmBlB,CAAC;AAEH,sBAAsB;AACtB,eAAO,MAAM,OAAO;;;;iBAQlB,CAAC;AAEH,mCAAmC;AACnC,eAAO,MAAM,iBAAiB;;;;;iBAK5B,CAAC;AAEH,iDAAiD;AACjD,eAAO,MAAM,gBAAgB;;;;;iBAK3B,CAAC;AAEH,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB;;;;;iBAK5B,CAAC;AAyEH,6EAA6E;AAC7E,eAAO,MAAM,MAAM,UAAW,KAAK,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmDjD,CAAC;AAIL,KAAK,aAAa,GACd,OAAO,OAAO,CAAC,gBAAgB,CAAC,IAAI,GACpC,OAAO,OAAO,CAAC,aAAa,CAAC,IAAI,GACjC,OAAO,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;AA0BnC;gEACgE;AAChE,eAAO,MAAM,kBAAkB,UACtB,MAAM,SACN,YAAY,KAClB,MAAM,CAAC,MAAM,CAAC,aAAa,CAkB7B,CAAC;AAUF;kCACkC;AAClC,eAAO,MAAM,eAAe,UAAW,UAAU,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAQtE,CAAC;AAEJ;;;0CAG0C;AAC1C,eAAO,MAAM,UAAU,UAAW,aAAa,WAAW,OAAO,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAUxF,CAAC;AAoEF;;;8BAG8B;AAC9B,eAAO,MAAM,aAAa,GAAI,MAAM,SAAS,MAAM,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mGAC7B,CAAC;AAW1C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAqBf,CAAC"}
|