@gjermundgaraba-designs/pixel-paper 0.14.1 → 0.16.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 +7 -6
- package/dist/src/card/card.d.ts +10 -5
- package/dist/src/card/card.d.ts.map +1 -1
- package/dist/src/card/card.js +4 -4
- package/dist/src/commandPalette/commandPalette.d.ts +0 -4
- package/dist/src/commandPalette/commandPalette.d.ts.map +1 -1
- package/dist/src/confirmDialog/confirmDialog.d.ts +17 -24
- package/dist/src/confirmDialog/confirmDialog.d.ts.map +1 -1
- package/dist/src/confirmDialog/confirmDialog.js +16 -22
- package/dist/src/confirmDialog/index.d.ts +1 -1
- package/dist/src/confirmDialog/index.d.ts.map +1 -1
- package/dist/src/confirmDialog/index.js +1 -1
- package/dist/src/dialog/dialog.d.ts +14 -20
- package/dist/src/dialog/dialog.d.ts.map +1 -1
- package/dist/src/dialog/dialog.js +10 -23
- package/dist/src/dialog/fold.d.ts +9 -1
- package/dist/src/dialog/fold.d.ts.map +1 -1
- package/dist/src/dialog/fold.js +9 -5
- package/dist/src/dialog/index.d.ts +2 -2
- package/dist/src/dialog/index.d.ts.map +1 -1
- package/dist/src/dialog/index.js +1 -1
- package/dist/src/keyHelp/keyHelp.d.ts +0 -4
- package/dist/src/keyHelp/keyHelp.d.ts.map +1 -1
- 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/sortable/sortable.d.ts +19 -7
- package/dist/src/sortable/sortable.d.ts.map +1 -1
- package/dist/src/sortable/sortable.js +30 -21
- package/package.json +1 -1
- package/src/card/card.ts +12 -6
- package/src/confirmDialog/confirmDialog.ts +20 -27
- package/src/confirmDialog/index.ts +0 -2
- package/src/dialog/dialog.ts +23 -30
- package/src/dialog/fold.ts +25 -6
- package/src/dialog/index.ts +1 -3
- package/src/panel/panel.ts +5 -1
- package/src/pixel-paper.css +87 -10
- package/src/sortable/sortable.ts +55 -23
|
@@ -10,11 +10,9 @@ import { defineView } from "foldkit/submodel";
|
|
|
10
10
|
import { isPlain } from "../keys/keys.js";
|
|
11
11
|
import { foldDialog } from "./fold.js";
|
|
12
12
|
// MODEL
|
|
13
|
-
/** Schema for a pixel-paper dialog: the `@foldkit/ui` Dialog it is built on
|
|
14
|
-
* ways out are held (`setCloseHeld`). */
|
|
13
|
+
/** Schema for a pixel-paper dialog: the `@foldkit/ui` Dialog it is built on. */
|
|
15
14
|
export const Model = Schema.Struct({
|
|
16
15
|
dialog: UiDialog.Model,
|
|
17
|
-
isCloseHeld: Schema.Boolean,
|
|
18
16
|
});
|
|
19
17
|
/** Which way h, l and the side arrows move focus in a dialog's action bar. */
|
|
20
18
|
const ActionDirection = Schema.Literals(["Previous", "Next"]);
|
|
@@ -36,15 +34,12 @@ export const OutMessage = defineMessageUnion({
|
|
|
36
34
|
/** Creates a closed dialog. */
|
|
37
35
|
export const init = (config) => (__foldkitBrandViewResult(({
|
|
38
36
|
dialog: UiDialog.init({ id: config.id }),
|
|
39
|
-
isCloseHeld: false,
|
|
40
37
|
}), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#init"));
|
|
41
38
|
// ACCESSORS
|
|
42
39
|
/** The dialog's id, unique in the document. */
|
|
43
40
|
export const id = (model) => __foldkitBrandViewResult((model.dialog.id), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#id");
|
|
44
41
|
/** Whether the dialog is open. */
|
|
45
42
|
export const isOpen = (model) => __foldkitBrandViewResult((model.dialog.isOpen), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#isOpen");
|
|
46
|
-
/** Whether the dialog's ways out are held (`setCloseHeld`). */
|
|
47
|
-
export const isCloseHeld = (model) => __foldkitBrandViewResult((model.isCloseHeld), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#isCloseHeld");
|
|
48
43
|
// UPDATE
|
|
49
44
|
const toOutMessage = UiDialog.OutMessage.match({
|
|
50
45
|
Opened: () => __foldkitBrandViewResult((undefined), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#Opened"),
|
|
@@ -56,29 +51,21 @@ const dialogFold = foldDialog(UiDialog, {
|
|
|
56
51
|
toParentMessage: (message) => __foldkitBrandViewResult((Message.GotDialogMessage({ message })), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#toParentMessage"),
|
|
57
52
|
toParentOutMessage: toOutMessage,
|
|
58
53
|
});
|
|
54
|
+
const FREE = { isCloseHeld: false };
|
|
59
55
|
// NOTE: @foldkit/ui gap: Dialog has no way to hold a close. Escape, a press on the veil and a
|
|
60
56
|
// control given the `closeButton` group all send `RequestedClose`, so a held dialog reads it
|
|
61
57
|
// by its tag and leaves it out.
|
|
62
|
-
const isHeldClose = (
|
|
58
|
+
const isHeldClose = (context, message) => __foldkitBrandViewResult((context.isCloseHeld && message._tag === "RequestedClose"), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#isHeldClose");
|
|
63
59
|
/** Processes a dialog Message and returns the next Model, Commands and OutMessage. */
|
|
64
|
-
export const update = (model, message) => __foldkitBrandViewResult((Message.match(message, {
|
|
65
|
-
GotDialogMessage: ({ message: dialogMessage }) => __foldkitBrandViewResult((isHeldClose(
|
|
60
|
+
export const update = (model, message, context = FREE) => __foldkitBrandViewResult((Message.match(message, {
|
|
61
|
+
GotDialogMessage: ({ message: dialogMessage }) => __foldkitBrandViewResult((isHeldClose(context, dialogMessage) ? { model } : dialogFold.update(model, dialogMessage)), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#GotDialogMessage"),
|
|
66
62
|
PressedActionKey: () => (__foldkitBrandViewResult(({ model }), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#PressedActionKey")),
|
|
67
63
|
})), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#update");
|
|
68
|
-
/** Opens the dialog
|
|
69
|
-
*
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
export const close = (model) => __foldkitBrandViewResult((dialogFold.close(modifyFields(model, { isCloseHeld: () => __foldkitBrandViewResult((false), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#isCloseHeld~3") }))), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#close");
|
|
74
|
-
/** Holds the dialog's ways out, or lets them go: while held, Escape, a press on the veil and
|
|
75
|
-
* a control given the `closeButton` group leave it open and report no `Closed`, so the
|
|
76
|
-
* result of work the reader may not walk away from (a save whose failure must land here)
|
|
77
|
-
* lands in it. Hold it in the update that starts the work, and let go in the update where
|
|
78
|
-
* the work fails, or the reader is shut in with the failure; `close` lets go once it lands,
|
|
79
|
-
* and `open` opens it free.
|
|
80
|
-
* Hold the card's own close controls too (`Card.formView`'s `isBusy`). */
|
|
81
|
-
export const setCloseHeld = (model, isHeld) => __foldkitBrandViewResult((modifyFields(model, { isCloseHeld: () => __foldkitBrandViewResult((isHeld), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#isCloseHeld~4") })), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#setCloseHeld");
|
|
64
|
+
/** Opens the dialog: focus moves to the element given the `initialFocus` group, else to the
|
|
65
|
+
* first control, and returns to where it was when the dialog closes. */
|
|
66
|
+
export const open = (model) => __foldkitBrandViewResult((dialogFold.open(model)), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#open");
|
|
67
|
+
/** Closes the dialog without reporting `Closed`. */
|
|
68
|
+
export const close = (model) => __foldkitBrandViewResult((dialogFold.close(model)), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#close");
|
|
82
69
|
// ACTION BAR KEYS
|
|
83
70
|
const ACTION_BAR_ATTRIBUTE = "data-pixel-paper-action-bar";
|
|
84
71
|
const ACTION_SELECTOR = "button:not(:disabled), a[href]";
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as Update from "foldkit/update";
|
|
2
|
+
import type { UpdateContext } from "./dialog.ts";
|
|
2
3
|
type ChildReturn<ChildModel, ChildMessage, ChildOutMessage> = Update.ReturnWithOutMessage<ChildModel, ChildMessage, ChildOutMessage>;
|
|
3
4
|
/** A dialog a parent holds: its update, and the steps that open and close it (`@foldkit/ui`'s
|
|
4
5
|
* Dialog, or pixel-paper's). */
|
|
5
6
|
type DialogChild<ChildModel, ChildMessage, ChildOutMessage> = Readonly<{
|
|
6
|
-
update: (model: ChildModel, message: ChildMessage) => ChildReturn<ChildModel, ChildMessage, ChildOutMessage>;
|
|
7
|
+
update: (model: ChildModel, message: ChildMessage, context: UpdateContext) => ChildReturn<ChildModel, ChildMessage, ChildOutMessage>;
|
|
7
8
|
open: (model: ChildModel) => ChildReturn<ChildModel, ChildMessage, ChildOutMessage>;
|
|
8
9
|
close: (model: ChildModel) => ChildReturn<ChildModel, ChildMessage, ChildOutMessage>;
|
|
9
10
|
}>;
|
|
@@ -16,10 +17,17 @@ type DialogFoldConfig<ParentModel, ParentMessage, ParentOutMessage, ChildModel,
|
|
|
16
17
|
* veil, a close button). Without it the dialog's OutMessages report nothing: a parent
|
|
17
18
|
* that reads `isOpen` when it needs to. */
|
|
18
19
|
toParentOutMessage?: (outMessage: ChildOutMessage) => ParentOutMessage | undefined;
|
|
20
|
+
/** Whether the dialog's ways out are held, read from the parent's own state as each
|
|
21
|
+
* Message arrives (`(model) => model.isSaving`). Free when not given. See
|
|
22
|
+
* `Dialog.UpdateContext`. */
|
|
23
|
+
isCloseHeld?: (model: ParentModel) => boolean;
|
|
19
24
|
}>;
|
|
20
25
|
/** The dialog folded into its parent: a dialog Message, and opening and closing it. */
|
|
21
26
|
type DialogFold<ParentModel, ParentMessage, ParentOutMessage, ChildMessage> = Readonly<{
|
|
22
27
|
update: (model: ParentModel, message: ChildMessage) => Update.ReturnWithOutMessage<ParentModel, ParentMessage, ParentOutMessage>;
|
|
28
|
+
/** The update a parent that is itself a dialog (ConfirmDialog) runs with the hold its own
|
|
29
|
+
* parent gave it. */
|
|
30
|
+
updateWith: (context: UpdateContext) => (model: ParentModel, message: ChildMessage) => Update.ReturnWithOutMessage<ParentModel, ParentMessage, ParentOutMessage>;
|
|
23
31
|
open: (model: ParentModel) => Update.Return<ParentModel, ParentMessage>;
|
|
24
32
|
close: (model: ParentModel) => Update.Return<ParentModel, ParentMessage>;
|
|
25
33
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../../../src/dialog/fold.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../../../src/dialog/fold.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,KAAK,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,eAAe,IAAI,MAAM,CAAC,oBAAoB,CACvF,UAAU,EACV,YAAY,EACZ,eAAe,CAChB,CAAC;AAEF;iCACiC;AACjC,KAAK,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,eAAe,IAAI,QAAQ,CAAC;IACrE,MAAM,EAAE,CACN,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,aAAa,KACnB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;IAC5D,IAAI,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;IACpF,KAAK,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;CACtF,CAAC,CAAC;AAEH,gGAAgG;AAChG,KAAK,gBAAgB,CACnB,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,eAAe,IACb,QAAQ,CAAC;IACX,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,UAAU,CAAC;IACzC,KAAK,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,KAAK,WAAW,CAAC;IACnE,eAAe,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,aAAa,CAAC;IAC1D;;gDAE4C;IAC5C,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,gBAAgB,GAAG,SAAS,CAAC;IACnF;;kCAE8B;IAC9B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC;CAC/C,CAAC,CAAC;AAEH,uFAAuF;AACvF,KAAK,UAAU,CAAC,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,IAAI,QAAQ,CAAC;IACrF,MAAM,EAAE,CACN,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,YAAY,KAClB,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,aAAa,EAAE,gBAAgB,CAAC,CAAC;IAC/E;0BACsB;IACtB,UAAU,EAAE,CACV,OAAO,EAAE,aAAa,KACnB,CACH,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,YAAY,KAClB,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,aAAa,EAAE,gBAAgB,CAAC,CAAC;IAC/E,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IACxE,KAAK,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;CAC1E,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;uFAsBuF;AACvF,eAAO,MAAM,UAAU,GACrB,WAAW,EACX,aAAa,EACb,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,GAAG,KAAK,SAEjB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,eAAe,CAAC,UACrD,gBAAgB,CACtB,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,eAAe,CAChB,KACA,UAAU,CAAC,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,CAyBvE,CAAC"}
|
package/dist/src/dialog/fold.js
CHANGED
|
@@ -34,12 +34,16 @@ export const foldDialog = (child, config) => {
|
|
|
34
34
|
// `RequestedOpen`, which reports `Opened`), and so can its update, so each fold needs a
|
|
35
35
|
// step for an OutMessage. This one keeps the parent's Model: a step reports nothing.
|
|
36
36
|
const foldOutMessage = () => __foldkitBrandViewResult(((model) => (__foldkitBrandViewResult(({ model }), "@gjermundgaraba-designs/pixel-paper/src/dialog/fold.js#anonymous"))), "@gjermundgaraba-designs/pixel-paper/src/dialog/fold.js#foldOutMessage");
|
|
37
|
-
const { toParentOutMessage } = config;
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
const { toParentOutMessage, isCloseHeld = () => __foldkitBrandViewResult((false), "@gjermundgaraba-designs/pixel-paper/src/dialog/fold.js#anonymous~2") } = config;
|
|
38
|
+
const updateWith = (context) => {
|
|
39
|
+
const childUpdate = (model, message) => __foldkitBrandViewResult((child.update(model, message, context)), "@gjermundgaraba-designs/pixel-paper/src/dialog/fold.js#childUpdate");
|
|
40
|
+
return __foldkitBrandViewResult((toParentOutMessage === undefined
|
|
41
|
+
? Update.foldChild({ update: childUpdate, ...lift, foldOutMessage })
|
|
42
|
+
: Update.foldChild({ update: childUpdate, ...lift, toParentOutMessage })), "@gjermundgaraba-designs/pixel-paper/src/dialog/fold.js#updateWith");
|
|
43
|
+
};
|
|
41
44
|
return __foldkitBrandViewResult(({
|
|
42
|
-
update,
|
|
45
|
+
update: (model, message) => __foldkitBrandViewResult((updateWith({ isCloseHeld: isCloseHeld(model) })(model, message)), "@gjermundgaraba-designs/pixel-paper/src/dialog/fold.js#update"),
|
|
46
|
+
updateWith,
|
|
43
47
|
open: Update.foldChildStep({ update: child.open, ...lift, foldOutMessage }),
|
|
44
48
|
close: Update.foldChildStep({ update: child.close, ...lift, foldOutMessage }),
|
|
45
49
|
}), "@gjermundgaraba-designs/pixel-paper/src/dialog/fold.js#foldDialog");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { BindActionKeys, Message, Model, OutMessage, close, id, init,
|
|
2
|
-
export type { InitConfig, Placement, RenderInfo, ViewInputs } from "./dialog.ts";
|
|
1
|
+
export { BindActionKeys, Message, Model, OutMessage, close, id, init, isOpen, open, sceneMounts, update, view, } from "./dialog.ts";
|
|
2
|
+
export type { InitConfig, Placement, RenderInfo, UpdateContext, ViewInputs } from "./dialog.ts";
|
|
3
3
|
export { foldDialog } from "./fold.ts";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,OAAO,EACP,KAAK,EACL,UAAU,EACV,KAAK,EACL,EAAE,EACF,IAAI,EACJ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,OAAO,EACP,KAAK,EACL,UAAU,EACV,KAAK,EACL,EAAE,EACF,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,WAAW,EACX,MAAM,EACN,IAAI,GACL,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/src/dialog/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { BindActionKeys, Message, Model, OutMessage, close, id, init,
|
|
1
|
+
export { BindActionKeys, Message, Model, OutMessage, close, id, init, isOpen, open, sceneMounts, update, view, } from "./dialog.js";
|
|
2
2
|
export { foldDialog } from "./fold.js";
|
|
@@ -20,7 +20,6 @@ export declare const Model: Schema.Struct<{
|
|
|
20
20
|
}>;
|
|
21
21
|
readonly maybeFocusSelector: Schema.Option<Schema.String>;
|
|
22
22
|
}>;
|
|
23
|
-
readonly isCloseHeld: Schema.Boolean;
|
|
24
23
|
}>;
|
|
25
24
|
readonly query: Schema.String;
|
|
26
25
|
}>;
|
|
@@ -106,7 +105,6 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
106
105
|
};
|
|
107
106
|
readonly maybeFocusSelector: import("effect/Option").Option<string>;
|
|
108
107
|
};
|
|
109
|
-
readonly isCloseHeld: boolean;
|
|
110
108
|
};
|
|
111
109
|
readonly query: string;
|
|
112
110
|
};
|
|
@@ -184,7 +182,6 @@ export declare const subscriptions: {
|
|
|
184
182
|
};
|
|
185
183
|
readonly maybeFocusSelector: import("effect/Option").Option<string>;
|
|
186
184
|
};
|
|
187
|
-
readonly isCloseHeld: boolean;
|
|
188
185
|
};
|
|
189
186
|
readonly query: string;
|
|
190
187
|
}, {
|
|
@@ -271,7 +268,6 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
271
268
|
};
|
|
272
269
|
readonly maybeFocusSelector: import("effect/Option").Option<string>;
|
|
273
270
|
};
|
|
274
|
-
readonly isCloseHeld: boolean;
|
|
275
271
|
};
|
|
276
272
|
readonly query: string;
|
|
277
273
|
}, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyHelp.d.ts","sourceRoot":"","sources":["../../../src/keyHelp/keyHelp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,cAAc,CAAC;AAItD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAOzC,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,MAAM,MAAM,qBAAqB,CAAC;AAI9C,2EAA2E;AAC3E,eAAO,MAAM,KAAK
|
|
1
|
+
{"version":3,"file":"keyHelp.d.ts","sourceRoot":"","sources":["../../../src/keyHelp/keyHelp.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,9 @@ export type ViewConfig = Readonly<{
|
|
|
9
9
|
id: string;
|
|
10
10
|
/** Pixel caps in the inverted title bar. */
|
|
11
11
|
title: string;
|
|
12
|
+
/** A quiet IconButton before the title, such as the grip a Sortable of panels hands each
|
|
13
|
+
* panel. On the ink bar it prints as `actions` do. */
|
|
14
|
+
lead?: ReadonlyArray<Html | string>;
|
|
12
15
|
/** A count or state at the title bar's right. */
|
|
13
16
|
meta?: string;
|
|
14
17
|
/** Small Buttons and IconButtons at the title bar's right end, after the meta. On the ink
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../../src/panel/panel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMtD,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC;;;;kCAI8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;yFACqF;IACrF,OAAO,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACvC,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACnC,2EAA2E;IAC3E,IAAI,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACpC,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC,CAAC;AAEH,iDAAiD;AACjD,eAAO,MAAM,OAAO,OAAQ,MAAM,KAAG,MAAuB,CAAC;AAE7D;gFACgF;AAChF,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../../src/panel/panel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMtD,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC;;;;kCAI8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd;2DACuD;IACvD,IAAI,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACpC,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;yFACqF;IACrF,OAAO,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACvC,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACnC,2EAA2E;IAC3E,IAAI,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACpC,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC,CAAC;AAEH,iDAAiD;AACjD,eAAO,MAAM,OAAO,OAAQ,MAAM,KAAG,MAAuB,CAAC;AAE7D;gFACgF;AAChF,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAoB3E,CAAC"}
|
package/dist/src/panel/panel.js
CHANGED
|
@@ -5,9 +5,10 @@ export const titleId = (id) => __foldkitBrandViewResult((`${id}-title`), "@gjerm
|
|
|
5
5
|
/** The unit of the system: paper in a 2px ink box on a 5px print shadow, under a title bar. A
|
|
6
6
|
* region landmark (`<section>`) named by its `h2` title, keyed by its `id`. */
|
|
7
7
|
export const view = (config, h) => {
|
|
8
|
-
const { id, title, meta, actions = [], body, foot = [], isFlush = false } = config;
|
|
8
|
+
const { id, title, lead = [], meta, actions = [], body, foot = [], isFlush = false } = config;
|
|
9
9
|
return __foldkitBrandViewResult((h.keyed("section")(id, [h.Id(id), h.AriaLabelledBy(titleId(id)), h.Class("panel")], [
|
|
10
10
|
h.header([h.Class("panel-tb")], [
|
|
11
|
+
...slotView("span", "panel-lead", lead, h),
|
|
11
12
|
h.h2([h.Id(titleId(id))], [title]),
|
|
12
13
|
...(meta === undefined ? [] : [h.span([h.Class("meta")], [meta])]),
|
|
13
14
|
...slotView("span", "panel-acts", actions, h),
|
|
@@ -954,13 +954,16 @@ export declare const SizeLiftedItem: Mount.MountDefinitionWithArgs<"SizeLiftedIt
|
|
|
954
954
|
}, {
|
|
955
955
|
readonly _tag: "CompletedSizeLiftedItem";
|
|
956
956
|
}>;
|
|
957
|
-
/** How the items lay out: a column of rows,
|
|
958
|
-
export type Layout = "List" | "Grid";
|
|
957
|
+
/** How the items lay out: a column of rows, tiles that wrap, or the parent's own panels. */
|
|
958
|
+
export type Layout = "List" | "Grid" | "Panels";
|
|
959
959
|
/** What the list hands `toItemView` for each item. */
|
|
960
960
|
export type ItemRender = Readonly<{
|
|
961
961
|
/** This render is the held copy: hidden from screen readers and inert. Leave out ids and
|
|
962
962
|
* anything the page must find once. */
|
|
963
963
|
isLifted: boolean;
|
|
964
|
+
/** The item's grip, for the `"Panels"` layout, where the item places it: in its panel's
|
|
965
|
+
* `lead`. The other layouts print it before the item themselves. */
|
|
966
|
+
grip: Html;
|
|
964
967
|
}>;
|
|
965
968
|
/** Per-render inputs passed to `view` through `h.submodel`'s `viewInputs`. The `to*` members
|
|
966
969
|
* are functions because they may carry the parent's handlers. */
|
|
@@ -969,16 +972,21 @@ export type ViewInputs = Readonly<{
|
|
|
969
972
|
/** Names the list for screen readers. */
|
|
970
973
|
label: string;
|
|
971
974
|
/** `"List"` (the default): rows between 1px rules, for a flush panel. `"Grid"`: tiles that
|
|
972
|
-
* wrap, 180px and up.
|
|
975
|
+
* wrap, 180px and up. `"Panels"`: each item is a Panel the parent prints, with `render.grip`
|
|
976
|
+
* in its `lead`, up to three across in the deck's gutter, 300px and up. */
|
|
973
977
|
layout?: Layout;
|
|
978
|
+
/** The reader may look but not reorder, as a read-only sign-in: every grip prints held, as
|
|
979
|
+
* while moves are held, and nothing lifts. */
|
|
980
|
+
isReadOnly?: boolean;
|
|
974
981
|
/** One item's content, beside its grip. Also called for the held copy, with
|
|
975
982
|
* `render.isLifted`. */
|
|
976
983
|
toItemView: (item: Item, render: ItemRender) => ReadonlyArray<Html>;
|
|
977
984
|
}>;
|
|
978
985
|
/**
|
|
979
|
-
* Items the reader puts in order, as rows or as
|
|
980
|
-
* `div.sortable` holding `ul.sortable-items` (named by `label`) of
|
|
981
|
-
* grip and the parent's content
|
|
986
|
+
* Items the reader puts in order, as rows, as tiles or as panels, built on `@foldkit/ui`'s
|
|
987
|
+
* DragAndDrop: `div.sortable` holding `ul.sortable-items` (named by `label`) of
|
|
988
|
+
* `li.sortable-item`, each its grip and the parent's content (a panel holds its grip in its
|
|
989
|
+
* title bar). The items are the parent's; a drop reports `Moved`.
|
|
982
990
|
*
|
|
983
991
|
* A mouse drags an item by its body or its grip; touch takes the grip alone, so a finger on
|
|
984
992
|
* an item scrolls the page; the keyboard takes the grip too: Space or Enter picks the item
|
|
@@ -1134,8 +1142,12 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
1134
1142
|
/** Names the list for screen readers. */
|
|
1135
1143
|
label: string;
|
|
1136
1144
|
/** `"List"` (the default): rows between 1px rules, for a flush panel. `"Grid"`: tiles that
|
|
1137
|
-
* wrap, 180px and up.
|
|
1145
|
+
* wrap, 180px and up. `"Panels"`: each item is a Panel the parent prints, with `render.grip`
|
|
1146
|
+
* in its `lead`, up to three across in the deck's gutter, 300px and up. */
|
|
1138
1147
|
layout?: Layout;
|
|
1148
|
+
/** The reader may look but not reorder, as a read-only sign-in: every grip prints held, as
|
|
1149
|
+
* while moves are held, and nothing lifts. */
|
|
1150
|
+
isReadOnly?: boolean;
|
|
1139
1151
|
/** One item's content, beside its grip. Also called for the held copy, with
|
|
1140
1152
|
* `render.isLifted`. */
|
|
1141
1153
|
toItemView: (item: Item, render: ItemRender) => ReadonlyArray<Html>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sortable.d.ts","sourceRoot":"","sources":["../../../src/sortable/sortable.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"sortable.d.ts","sourceRoot":"","sources":["../../../src/sortable/sortable.ts"],"names":[],"mappings":"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"}
|
|
@@ -368,9 +368,15 @@ const helpId = (model) => __foldkitBrandViewResult((`${id(model)}-grip-help`), "
|
|
|
368
368
|
const isHeldItem = (model, itemId) => __foldkitBrandViewResult((UiDragAndDrop.isDragging(model.dragAndDrop) &&
|
|
369
369
|
Option.contains(UiDragAndDrop.maybeDraggedItemId(model.dragAndDrop), itemHook(model, itemId))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#isHeldItem");
|
|
370
370
|
const liftedGrip = (h) => __foldkitBrandViewResult((h.span([h.Class("iconbtn quiet"), h.AriaHidden(true)], [Glyph.view({ name: "grip" }, h)])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#liftedGrip");
|
|
371
|
-
|
|
371
|
+
/** The item's content beside its grip, or, in a layout where the item places its grip,
|
|
372
|
+
* alone. */
|
|
373
|
+
const itemContents = (info, item, render, h) => {
|
|
374
|
+
const body = h.div([h.Class("sortable-body")], info.toItemView(item, render));
|
|
375
|
+
return __foldkitBrandViewResult((info.layout === "Panels" ? [body] : [render.grip, body]), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemContents");
|
|
376
|
+
};
|
|
377
|
+
const liftedView = (info, item, h) => __foldkitBrandViewResult((h.div([h.Class("sortable-item lifted")], itemContents(info, item, { isLifted: true, grip: liftedGrip(h) }, h))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#liftedView");
|
|
372
378
|
const gripView = (info, item, h) => {
|
|
373
|
-
const { model, items } = info;
|
|
379
|
+
const { model, isMovable, items } = info;
|
|
374
380
|
const isIdleNow = phaseOf(model.dragAndDrop) === "Idle";
|
|
375
381
|
const onGripKey = h.OnKeyDownPreventDefault((key) => __foldkitBrandViewResult((Option.liftPredicate(Message.PressedGripKey({ itemId: item.id, items }), () => __foldkitBrandViewResult((isIdleNow && (key === " " || key === "Enter")), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~36"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~35"));
|
|
376
382
|
// NOTE: @foldkit/ui gap: DragAndDrop's `draggable` bundle forces `role="option"`, which a
|
|
@@ -381,19 +387,19 @@ const gripView = (info, item, h) => {
|
|
|
381
387
|
glyph: "grip",
|
|
382
388
|
label: fill(COPY.gripLabel, item.label),
|
|
383
389
|
isQuiet: true,
|
|
384
|
-
isDisabled: !
|
|
390
|
+
isDisabled: !isMovable,
|
|
385
391
|
attributes: [
|
|
386
392
|
h.DataAttribute("draggable-id", itemHook(model, item.id)),
|
|
387
393
|
h.DataAttribute(GRIP_ATTRIBUTE, ""),
|
|
388
394
|
h.AriaRoleDescription("draggable"),
|
|
389
395
|
h.AriaDescribedBy(helpId(model)),
|
|
390
396
|
Button.pressedAttribute(isHeldItem(model, item.id), h),
|
|
391
|
-
...(
|
|
397
|
+
...(isMovable ? [onGripKey] : []),
|
|
392
398
|
],
|
|
393
399
|
}, h)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#gripView");
|
|
394
400
|
};
|
|
395
401
|
const itemAttributes = (info, item, h) => {
|
|
396
|
-
const { model, items } = info;
|
|
402
|
+
const { model, isMovable, items } = info;
|
|
397
403
|
const isIdleNow = phaseOf(model.dragAndDrop) === "Idle";
|
|
398
404
|
const onPress = h.OnPointerDown((pointerType, button, screenX, screenY, _time, clientX, clientY, pointerId, target) => __foldkitBrandViewResult((Option.liftPredicate(Message.PressedItem({
|
|
399
405
|
itemId: item.id,
|
|
@@ -403,10 +409,7 @@ const itemAttributes = (info, item, h) => {
|
|
|
403
409
|
clientX,
|
|
404
410
|
clientY,
|
|
405
411
|
items,
|
|
406
|
-
}), () => __foldkitBrandViewResult((isIdleNow &&
|
|
407
|
-
model.isMovable &&
|
|
408
|
-
button === LEFT_BUTTON &&
|
|
409
|
-
isLiftingPress(target, pointerType)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~38"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~37"));
|
|
412
|
+
}), () => __foldkitBrandViewResult((isIdleNow && isMovable && button === LEFT_BUTTON && isLiftingPress(target, pointerType)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~38"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~37"));
|
|
410
413
|
return __foldkitBrandViewResult(([h.DataAttribute(ITEM_ATTRIBUTE, ""), onPress]), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemAttributes");
|
|
411
414
|
};
|
|
412
415
|
/** Where a pointer would drop the held item, marked on the item it would land beside: before
|
|
@@ -425,15 +428,12 @@ const dropClass = (info, item) => __foldkitBrandViewResult((Option.match(Option.
|
|
|
425
428
|
onNone: () => __foldkitBrandViewResult((""), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onNone~5"),
|
|
426
429
|
onSome: ({ side }) => (__foldkitBrandViewResult((side === "Before" ? " drop-before" : " drop-after"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onSome~5")),
|
|
427
430
|
})), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#dropClass");
|
|
428
|
-
const itemClass = (info, item) => __foldkitBrandViewResult((`sortable-item${info.
|
|
431
|
+
const itemClass = (info, item) => __foldkitBrandViewResult((`sortable-item${info.isMovable ? " movable" : ""}${isHeldItem(info.model, item.id) ? " drag-dim" : ""}${dropClass(info, item)}`), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemClass");
|
|
429
432
|
const itemView = (info, item, h) => __foldkitBrandViewResult((h.keyed("li")(item.id, [
|
|
430
433
|
...UiDragAndDrop.sortable(itemHook(info.model, item.id)),
|
|
431
434
|
...itemAttributes(info, item, h),
|
|
432
435
|
h.Class(itemClass(info, item)),
|
|
433
|
-
],
|
|
434
|
-
gripView(info, item, h),
|
|
435
|
-
h.div([h.Class("sortable-body")], info.toItemView(item, { isLifted: false })),
|
|
436
|
-
])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemView");
|
|
436
|
+
], itemContents(info, item, { isLifted: false, grip: gripView(info, item, h) }, h))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemView");
|
|
437
437
|
/** The items in order, with the held item's copy where the keyboard would drop it: before the
|
|
438
438
|
* other item at its target, or last. The copy carries no `data-sortable-id`, so it is not
|
|
439
439
|
* counted as an item. */
|
|
@@ -473,10 +473,12 @@ const liftedCopyView = (info, h) => {
|
|
|
473
473
|
})),
|
|
474
474
|
], [liftedView(info, held.item, h)])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~57")))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#liftedCopyView");
|
|
475
475
|
};
|
|
476
|
+
const layoutClass = (layout) => __foldkitBrandViewResult((Match.value(layout).pipe(Match.withReturnType(), Match.when("List", () => __foldkitBrandViewResult(("sortable"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~58")), Match.when("Grid", () => __foldkitBrandViewResult(("sortable grid"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~59")), Match.when("Panels", () => __foldkitBrandViewResult(("sortable panels"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~60")), Match.exhaustive)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#layoutClass");
|
|
476
477
|
/**
|
|
477
|
-
* Items the reader puts in order, as rows or as
|
|
478
|
-
* `div.sortable` holding `ul.sortable-items` (named by `label`) of
|
|
479
|
-
* grip and the parent's content
|
|
478
|
+
* Items the reader puts in order, as rows, as tiles or as panels, built on `@foldkit/ui`'s
|
|
479
|
+
* DragAndDrop: `div.sortable` holding `ul.sortable-items` (named by `label`) of
|
|
480
|
+
* `li.sortable-item`, each its grip and the parent's content (a panel holds its grip in its
|
|
481
|
+
* title bar). The items are the parent's; a drop reports `Moved`.
|
|
480
482
|
*
|
|
481
483
|
* A mouse drags an item by its body or its grip; touch takes the grip alone, so a finger on
|
|
482
484
|
* an item scrolls the page; the keyboard takes the grip too: Space or Enter picks the item
|
|
@@ -487,9 +489,16 @@ const liftedCopyView = (info, h) => {
|
|
|
487
489
|
* the keys.
|
|
488
490
|
*/
|
|
489
491
|
export const view = defineView((model, viewInputs, h) => {
|
|
490
|
-
const { items, label, layout = "List", toItemView } = viewInputs;
|
|
491
|
-
const info = {
|
|
492
|
-
|
|
492
|
+
const { items, label, layout = "List", isReadOnly = false, toItemView } = viewInputs;
|
|
493
|
+
const info = {
|
|
494
|
+
model,
|
|
495
|
+
layout,
|
|
496
|
+
isMovable: model.isMovable && !isReadOnly,
|
|
497
|
+
items,
|
|
498
|
+
maybeDropMark: dropMarkOf(model),
|
|
499
|
+
toItemView,
|
|
500
|
+
};
|
|
501
|
+
return __foldkitBrandViewResult((h.div([h.Class(layoutClass(layout))], [
|
|
493
502
|
// NOTE: Safari takes list semantics from a list printed without markers, so the list
|
|
494
503
|
// says it is one
|
|
495
504
|
h.ul([
|
|
@@ -500,5 +509,5 @@ export const view = defineView((model, viewInputs, h) => {
|
|
|
500
509
|
], itemsView(info, h)),
|
|
501
510
|
h.p([h.Id(helpId(model)), h.Class("sr-only")], [COPY.gripHelp]),
|
|
502
511
|
...liftedCopyView(info, h),
|
|
503
|
-
])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~
|
|
512
|
+
])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~61");
|
|
504
513
|
});
|
package/package.json
CHANGED
package/src/card/card.ts
CHANGED
|
@@ -102,6 +102,10 @@ export type FormViewConfig<Message> = Omit<
|
|
|
102
102
|
/** The form's content, fields and all, in one Fields group that `isBusy` holds. A link in
|
|
103
103
|
* it (an ErrorSummary's) stays live. */
|
|
104
104
|
body: ReadonlyArray<Html | string>;
|
|
105
|
+
/** Above the fields, outside the group `isBusy` holds: what the page says about the form
|
|
106
|
+
* while it is open (a lost connection with its retry), whose controls stay live while it
|
|
107
|
+
* sends. */
|
|
108
|
+
notices?: ReadonlyArray<Html | string>;
|
|
105
109
|
/** The submit button's words. It prints primary, the card's default. */
|
|
106
110
|
submit: string;
|
|
107
111
|
/** The cancel button's words, before the submit. It closes through `closeAttributes`. */
|
|
@@ -111,9 +115,10 @@ export type FormViewConfig<Message> = Omit<
|
|
|
111
115
|
closeAttributes?: Attributes<Message>;
|
|
112
116
|
/** The form's work is running (it sends): the submit button is busy, the close glyph and
|
|
113
117
|
* cancel are held without `closeAttributes`, and the body is natively disabled, so
|
|
114
|
-
* nothing changes under the send and nothing sends twice. In a Dialog,
|
|
115
|
-
*
|
|
116
|
-
* so the update still ignores `onSubmit` while
|
|
118
|
+
* nothing changes under the send and nothing sends twice. In a Dialog, pass the same state
|
|
119
|
+
* as `isCloseHeld` to its update, so Escape and the veil are held too. Enter in a field
|
|
120
|
+
* can submit before the fields are held, so the update still ignores `onSubmit` while
|
|
121
|
+
* busy. */
|
|
117
122
|
isBusy?: boolean;
|
|
118
123
|
/** The form cannot be sent yet (nothing to send): the submit button is held as a Button
|
|
119
124
|
* is, and the fields and cancel stay live. Enter in a field can still submit, so the
|
|
@@ -128,8 +133,8 @@ export type FormViewConfig<Message> = Omit<
|
|
|
128
133
|
* `Focus.Focus({ id: Card.submitId(id) })`. */
|
|
129
134
|
export const submitId = (id: string): string => `${id}-submit`;
|
|
130
135
|
|
|
131
|
-
/** A card that is a form, named by its title, so a form landmark: its body in
|
|
132
|
-
* group, then cancel and the primary submit button in the action bar. */
|
|
136
|
+
/** A card that is a form, named by its title, so a form landmark: its notices, its body in
|
|
137
|
+
* one Fields group, then cancel and the primary submit button in the action bar. */
|
|
133
138
|
export const formView = <Message>(
|
|
134
139
|
config: FormViewConfig<Message>,
|
|
135
140
|
h: HtmlBuilder<Message>,
|
|
@@ -140,6 +145,7 @@ export const formView = <Message>(
|
|
|
140
145
|
submit,
|
|
141
146
|
cancel,
|
|
142
147
|
closeAttributes,
|
|
148
|
+
notices = [],
|
|
143
149
|
isBusy = false,
|
|
144
150
|
isSubmitDisabled = false,
|
|
145
151
|
onSubmit,
|
|
@@ -182,7 +188,7 @@ export const formView = <Message>(
|
|
|
182
188
|
childrenView(
|
|
183
189
|
{
|
|
184
190
|
...config,
|
|
185
|
-
body: [Fields.view({ body: config.body, isBusy }, h)],
|
|
191
|
+
body: [...notices, Fields.view({ body: config.body, isBusy }, h)],
|
|
186
192
|
isCloseHeld: isBusy,
|
|
187
193
|
actions: [...cancelButton, submitButton],
|
|
188
194
|
},
|
|
@@ -34,7 +34,7 @@ export type Message = typeof Message.Type;
|
|
|
34
34
|
/** Union of OutMessages a confirm dialog reports. `Confirmed`: the reader pressed the action;
|
|
35
35
|
* the dialog stays open until the parent calls `close`. `Cancelled`: cancel, Escape or a click
|
|
36
36
|
* on the veil; the dialog has closed, and whether that also stops work already running is
|
|
37
|
-
* the parent's to decide. Never reported while its ways out are held (`
|
|
37
|
+
* the parent's to decide. Never reported while its ways out are held (`Dialog.UpdateContext`). */
|
|
38
38
|
export const OutMessage = defineMessageUnion({
|
|
39
39
|
Confirmed: {},
|
|
40
40
|
Cancelled: {},
|
|
@@ -65,32 +65,28 @@ const dialogFold = foldDialog(Dialog, {
|
|
|
65
65
|
toParentOutMessage: toCancelled,
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
const FREE: Dialog.UpdateContext = { isCloseHeld: false };
|
|
69
|
+
|
|
70
|
+
/** Processes a confirm dialog Message and returns the next Model, Commands and OutMessage.
|
|
71
|
+
* While `context.isCloseHeld`, cancel, Escape and the veil change nothing. */
|
|
72
|
+
export const update = (model: Model, message: Message, context: Dialog.UpdateContext = FREE) =>
|
|
70
73
|
Message.match<Update.ReturnWithOutMessage<Model, Message, OutMessage>>(message, {
|
|
71
|
-
GotDialogMessage: ({ message: dialogMessage }) =>
|
|
74
|
+
GotDialogMessage: ({ message: dialogMessage }) =>
|
|
75
|
+
dialogFold.updateWith(context)(model, dialogMessage),
|
|
72
76
|
ClickedConfirm: () => ({ model, outMessage: OutMessage.Confirmed() }),
|
|
73
77
|
ClickedCancel: () =>
|
|
74
|
-
|
|
78
|
+
context.isCloseHeld
|
|
75
79
|
? { model }
|
|
76
80
|
: pipe(dialogFold.close(model), Update.withOutMessage(OutMessage.Cancelled())),
|
|
77
81
|
});
|
|
78
82
|
|
|
79
|
-
/** Opens the confirm dialog
|
|
80
|
-
* when it is `isDanger`. */
|
|
83
|
+
/** Opens the confirm dialog: focus starts on the action, or on cancel when it is `isDanger`. */
|
|
81
84
|
export const open = (model: Model): Update.Return<Model, Message> => dialogFold.open(model);
|
|
82
85
|
|
|
83
|
-
/** Closes the confirm dialog without reporting `Cancelled
|
|
84
|
-
*
|
|
86
|
+
/** Closes the confirm dialog without reporting `Cancelled`: call it once confirmed work has
|
|
87
|
+
* landed. */
|
|
85
88
|
export const close = (model: Model): Update.Return<Model, Message> => dialogFold.close(model);
|
|
86
89
|
|
|
87
|
-
/** Holds cancel, Escape and the veil, or lets them go: while held the dialog stays open and
|
|
88
|
-
* reports no `Cancelled`, and cancel prints held (`aria-disabled`, in the keyboard). Hold it
|
|
89
|
-
* in the update that starts confirmed work whose failure must land here, and let go in the
|
|
90
|
-
* update where the work fails; `close` lets go once it lands. */
|
|
91
|
-
export const setCloseHeld = (model: Model, isHeld: boolean): Model =>
|
|
92
|
-
modifyFields(model, { dialog: (dialog) => Dialog.setCloseHeld(dialog, isHeld) });
|
|
93
|
-
|
|
94
90
|
// ACCESSORS
|
|
95
91
|
|
|
96
92
|
/** The confirm dialog's id, unique in the document. */
|
|
@@ -99,9 +95,6 @@ export const id = (model: Model): string => Dialog.id(model.dialog);
|
|
|
99
95
|
/** Whether the confirm dialog is open. */
|
|
100
96
|
export const isOpen = (model: Model): boolean => Dialog.isOpen(model.dialog);
|
|
101
97
|
|
|
102
|
-
/** Whether its ways out are held (`setCloseHeld`). */
|
|
103
|
-
export const isCloseHeld = (model: Model): boolean => Dialog.isCloseHeld(model.dialog);
|
|
104
|
-
|
|
105
98
|
// VIEW
|
|
106
99
|
|
|
107
100
|
/** Per-render inputs passed to `view` through `h.submodel`'s `viewInputs`. */
|
|
@@ -123,8 +116,9 @@ export type ViewInputs = Readonly<{
|
|
|
123
116
|
/** Destructive: the confirming button turns red and cancel becomes the default. */
|
|
124
117
|
isDanger?: boolean;
|
|
125
118
|
/** The confirmed work is running: the confirming button is held (its word stays, the
|
|
126
|
-
* working cursor prints, a second press does nothing) and keeps focus
|
|
127
|
-
*
|
|
119
|
+
* working cursor prints, a second press does nothing) and keeps focus, and cancel is held
|
|
120
|
+
* with it. Pair it with `isCloseHeld` in `update`'s context, from the same state, so
|
|
121
|
+
* Escape and the veil change nothing either. */
|
|
128
122
|
isBusy?: boolean;
|
|
129
123
|
/** The action cannot run now (nothing is running; it is blocked): the confirming button is
|
|
130
124
|
* held, `aria-disabled` without the working cursor, and stays in the keyboard, so focus
|
|
@@ -136,7 +130,6 @@ export type ViewInputs = Readonly<{
|
|
|
136
130
|
}>;
|
|
137
131
|
|
|
138
132
|
const cardView = (
|
|
139
|
-
model: Model,
|
|
140
133
|
viewInputs: ViewInputs,
|
|
141
134
|
render: Dialog.RenderInfo,
|
|
142
135
|
h: HtmlBuilder<Message>,
|
|
@@ -159,7 +152,7 @@ const cardView = (
|
|
|
159
152
|
{
|
|
160
153
|
label: "cancel",
|
|
161
154
|
isDefault: isDanger,
|
|
162
|
-
isDisabled:
|
|
155
|
+
isDisabled: isBusy,
|
|
163
156
|
onClick: Message.ClickedCancel(),
|
|
164
157
|
attributes: isDanger ? render.initialFocus : [],
|
|
165
158
|
},
|
|
@@ -199,9 +192,9 @@ const cardView = (
|
|
|
199
192
|
* arm-then-confirm button: red never rests on a button, and an armed button is easy to
|
|
200
193
|
* double-click through.
|
|
201
194
|
*
|
|
202
|
-
* Work that takes a while stays in the dialog: set `isBusy` while it runs
|
|
203
|
-
* has landed, and on failure keep it open with the
|
|
204
|
-
*
|
|
195
|
+
* Work that takes a while stays in the dialog: set `isBusy` while it runs (and `isCloseHeld`
|
|
196
|
+
* in `update`'s context), `close` once it has landed, and on failure keep it open with the
|
|
197
|
+
* error in `toDetailView`.
|
|
205
198
|
*/
|
|
206
199
|
export const view = defineView<Model, Message, ViewInputs>((model, viewInputs, h): Html =>
|
|
207
200
|
h.submodel({
|
|
@@ -212,7 +205,7 @@ export const view = defineView<Model, Message, ViewInputs>((model, viewInputs, h
|
|
|
212
205
|
isAlert: viewInputs.isDanger ?? false,
|
|
213
206
|
hasDescription: true,
|
|
214
207
|
toLiveRegionView: viewInputs.toLiveRegionView,
|
|
215
|
-
toView: (render) => cardView(
|
|
208
|
+
toView: (render) => cardView(viewInputs, render, h),
|
|
216
209
|
},
|
|
217
210
|
toParentMessage: (message) => Message.GotDialogMessage({ message }),
|
|
218
211
|
}),
|