@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.
Files changed (39) hide show
  1. package/DESIGN.md +7 -6
  2. package/dist/src/card/card.d.ts +10 -5
  3. package/dist/src/card/card.d.ts.map +1 -1
  4. package/dist/src/card/card.js +4 -4
  5. package/dist/src/commandPalette/commandPalette.d.ts +0 -4
  6. package/dist/src/commandPalette/commandPalette.d.ts.map +1 -1
  7. package/dist/src/confirmDialog/confirmDialog.d.ts +17 -24
  8. package/dist/src/confirmDialog/confirmDialog.d.ts.map +1 -1
  9. package/dist/src/confirmDialog/confirmDialog.js +16 -22
  10. package/dist/src/confirmDialog/index.d.ts +1 -1
  11. package/dist/src/confirmDialog/index.d.ts.map +1 -1
  12. package/dist/src/confirmDialog/index.js +1 -1
  13. package/dist/src/dialog/dialog.d.ts +14 -20
  14. package/dist/src/dialog/dialog.d.ts.map +1 -1
  15. package/dist/src/dialog/dialog.js +10 -23
  16. package/dist/src/dialog/fold.d.ts +9 -1
  17. package/dist/src/dialog/fold.d.ts.map +1 -1
  18. package/dist/src/dialog/fold.js +9 -5
  19. package/dist/src/dialog/index.d.ts +2 -2
  20. package/dist/src/dialog/index.d.ts.map +1 -1
  21. package/dist/src/dialog/index.js +1 -1
  22. package/dist/src/keyHelp/keyHelp.d.ts +0 -4
  23. package/dist/src/keyHelp/keyHelp.d.ts.map +1 -1
  24. package/dist/src/panel/panel.d.ts +3 -0
  25. package/dist/src/panel/panel.d.ts.map +1 -1
  26. package/dist/src/panel/panel.js +2 -1
  27. package/dist/src/sortable/sortable.d.ts +19 -7
  28. package/dist/src/sortable/sortable.d.ts.map +1 -1
  29. package/dist/src/sortable/sortable.js +30 -21
  30. package/package.json +1 -1
  31. package/src/card/card.ts +12 -6
  32. package/src/confirmDialog/confirmDialog.ts +20 -27
  33. package/src/confirmDialog/index.ts +0 -2
  34. package/src/dialog/dialog.ts +23 -30
  35. package/src/dialog/fold.ts +25 -6
  36. package/src/dialog/index.ts +1 -3
  37. package/src/panel/panel.ts +5 -1
  38. package/src/pixel-paper.css +87 -10
  39. 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, and whether its
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 = (model, message) => __foldkitBrandViewResult((model.isCloseHeld && message._tag === "RequestedClose"), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#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(model, dialogMessage) ? { model } : dialogFold.update(model, dialogMessage)), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#GotDialogMessage"),
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 with its ways out free: focus moves to the element given the
69
- * `initialFocus` group, else to the first control, and returns to where it was when the
70
- * dialog closes. */
71
- export const open = (model) => __foldkitBrandViewResult((dialogFold.open(modifyFields(model, { isCloseHeld: () => __foldkitBrandViewResult((false), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#isCloseHeld~2") }))), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#open");
72
- /** Closes the dialog without reporting `Closed`, and lets go of a hold. */
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;AAIzC,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,KAClB,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;CACpF,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,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,CAqBvE,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"}
@@ -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 update = toParentOutMessage === undefined
39
- ? Update.foldChild({ update: child.update, ...lift, foldOutMessage })
40
- : Update.foldChild({ update: child.update, ...lift, toParentOutMessage });
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, isCloseHeld, isOpen, open, sceneMounts, setCloseHeld, update, view, } from "./dialog.ts";
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,WAAW,EACX,MAAM,EACN,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,MAAM,EACN,IAAI,GACL,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
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"}
@@ -1,2 +1,2 @@
1
- export { BindActionKeys, Message, Model, OutMessage, close, id, init, isCloseHeld, isOpen, open, sceneMounts, setCloseHeld, update, view, } from "./dialog.js";
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;;;;;;;;;;;;;;;;;EAGhB,CAAC;AACH,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAEtC;;;6CAG6C;AAC7C,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC;IAC7B,IAAI,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH,qFAAqF;AACrF,eAAO,MAAM,SAAS,EAAE,WAAuB,CAAC;AAEhD,0CAA0C;AAC1C,eAAO,MAAM,WAAW,EAAE,OAAkE,CAAC;AAI7F,sDAAsD;AACtD,eAAO,MAAM,OAAO;;QACE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QACX,KAAK;;;EAErB,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAI1C;uFACuF;AACvF,eAAO,MAAM,UAAU;;EAErB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;AAIhD,2DAA2D;AAC3D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAElD,oCAAoC;AACpC,eAAO,MAAM,IAAI,WAAY,UAAU,KAAG,KAGxC,CAAC;AAkBH,wFAAwF;AACxF,eAAO,MAAM,MAAM,UAAW,KAAK,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKjD,CAAC;AAEL,gFAAgF;AAChF,eAAO,MAAM,IAAI,UAAW,KAAK,KAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAC5B,CAAC;AAErC,sDAAsD;AACtD,eAAO,MAAM,KAAK,UAAW,KAAK,KAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAA4B,CAAC;AAI9F,iDAAiD;AACjD,eAAO,MAAM,EAAE,UAAW,KAAK,KAAG,MAAiC,CAAC;AAEpE,oCAAoC;AACpC,eAAO,MAAM,MAAM,UAAW,KAAK,KAAG,OAAsC,CAAC;AAI7E,8FAA8F;AAC9F,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiBvB,CAAC;AAeJ;8FAC8F;AAC9F,eAAO,MAAM,cAAc,aACf,aAAa,CAAC,OAAO,CAAC,YACtB,WAAW,SACd,MAAM,KACZ,aAAa,CAAC,MAAM,CAAC,WAAW,CA2BlC,CAAC;AAIF,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACjC,QAAQ,EAAE,WAAW,CAAC;IACtB;;+DAE2D;IAC3D,WAAW,CAAC,EAAE,MAAM,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACjD;0CACsC;IACtC,gBAAgB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CAC7C,CAAC,CAAC;AAsDH;;qBAEqB;AACrB,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAnEf,8DAA8D;cACpD,aAAa,CAAC,OAAO,CAAC;cACtB,WAAW;IACrB;;+DAE2D;kBAC7C,MAAM,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC;IAChD;0CACsC;uBACnB,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;GAqE5C,CAAC"}
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,IAmB3E,CAAC"}
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"}
@@ -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, or tiles that wrap. */
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 tiles, built on `@foldkit/ui`'s DragAndDrop:
980
- * `div.sortable` holding `ul.sortable-items` (named by `label`) of `li.sortable-item`, each its
981
- * grip and the parent's content. The items are the parent's; a drop reports `Moved`.
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":"AACA,OAAO,EAAS,MAAM,EAAS,MAAM,EAAE,MAAM,EAAE,MAAM,EAAQ,MAAM,QAAQ,CAAC;AAC5E,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAAa,IAAI,EAAe,MAAM,cAAc,CAAC;AAEjE,OAAO,KAAK,KAAK,MAAM,eAAe,CAAC;AAGvC,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AA0BzC;oDACoD;AACpD,eAAO,MAAM,IAAI;;;EAA6D,CAAC;AAC/E,MAAM,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,CAAC;AAiCpC;iFACiF;AACjF,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIhB,CAAC;AACH,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAItC,oDAAoD;AACpD,eAAO,MAAM,OAAO;;QACO,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAE9B,MAAM;QACN,SAAS;QACT,OAAO;QACP,OAAO;QACP,OAAO;QACP,OAAO;QACP,KAAK;;;;;;QAEW,MAAM;QAAiB,KAAK;;;;;;QAE5C,OAAO;QACP,OAAO;QACP,OAAO;QACP,OAAO;QACP,UAAU;;;QAGV,OAAO;QACP,OAAO;QACP,OAAO;QACP,OAAO;QACP,UAAU;;;;;;EAMZ,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAI1C;;;;0EAI0E;AAC1E,eAAO,MAAM,UAAU;;QAEnB,MAAM;QACN,SAAS;QACT,OAAO;QACP,gBAAgB;QAChB,iBAAiB;;EAEnB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;AAIhD;6CAC6C;AAC7C,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAElD,kEAAkE;AAClE,eAAO,MAAM,IAAI,WAAY,UAAU,KAAG,KAIxC,CAAC;AAOH,0CAA0C;AAC1C,eAAO,MAAM,SAAS,UAAW,KAAK,KAAG,OAC2B,CAAC;AAWrE,2FAA2F;AAC3F,eAAO,MAAM,eAAe;;;;iBAK1B,CAAC;AAIH,KAAK,YAAY,GAAG,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;AAuN5E,wFAAwF;AACxF,eAAO,MAAM,MAAM,UAAW,KAAK,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwCjD,CAAC;AAIL;6DAC6D;AAC7D,eAAO,MAAM,UAAU,UAAW,KAAK,aAAa,OAAO,KAAG,YAG7D,CAAC;AAoBF,QAAA,MAAM,WAAW;;;;EAIf,CAAC;AACH,KAAK,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC;AAU3C,8FAA8F;AAC9F,eAAO,MAAM,eAAe,SAAU,WAAW,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAgBxE,CAAC;AAmDF;;;;6CAI6C;AAC7C,eAAO,MAAM,aAAa,GAAI,MAAM,SAAS,MAAM,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mGACxB,CAAC;AAI/C;0EAC0E;AAC1E,eAAO,MAAM,cAAc;;;;;;EAQzB,CAAC;AAIH,4FAA4F;AAC5F,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEhD,sDAAsD;AACtD,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC;4CACwC;IACxC,QAAQ,EAAE,OAAO,CAAC;IAClB;yEACqE;IACrE,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC,CAAC;AAEH;kEACkE;AAClE,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3B,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd;;gFAE4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;mDAC+C;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;6BACyB;IACzB,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,KAAK,aAAa,CAAC,IAAI,CAAC,CAAC;CACrE,CAAC,CAAC;AAyPH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WApRR,aAAa,CAAC,IAAI,CAAC;IAC1B,yCAAyC;WAClC,MAAM;IACb;;gFAE4E;aACnE,MAAM;IACf;mDAC+C;iBAClC,OAAO;IACpB;6BACyB;gBACb,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,KAAK,aAAa,CAAC,IAAI,CAAC;GAqSnE,CAAC"}
@@ -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
- const liftedView = (info, item, h) => __foldkitBrandViewResult((h.div([h.Class("sortable-item lifted")], [liftedGrip(h), h.div([h.Class("sortable-body")], info.toItemView(item, { isLifted: true }))])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#liftedView");
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: !model.isMovable,
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
- ...(model.isMovable ? [onGripKey] : []),
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.model.isMovable ? " movable" : ""}${isHeldItem(info.model, item.id) ? " drag-dim" : ""}${dropClass(info, item)}`), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemClass");
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 tiles, built on `@foldkit/ui`'s DragAndDrop:
478
- * `div.sortable` holding `ul.sortable-items` (named by `label`) of `li.sortable-item`, each its
479
- * grip and the parent's content. The items are the parent's; a drop reports `Moved`.
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 = { model, items, maybeDropMark: dropMarkOf(model), toItemView };
492
- return __foldkitBrandViewResult((h.div([h.Class(layout === "Grid" ? "sortable grid" : "sortable")], [
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~58");
512
+ ])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~61");
504
513
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjermundgaraba-designs/pixel-paper",
3
- "version": "0.14.1",
3
+ "version": "0.16.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
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, hold its ways out
115
- * too (`Dialog.setCloseHeld`), and let go of both where the send fails. Enter in a field can submit before the fields are held,
116
- * so the update still ignores `onSubmit` while busy. */
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 one Fields
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 (`setCloseHeld`). */
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
- /** Processes a confirm dialog Message and returns the next Model, Commands and OutMessage. */
69
- export const update = (model: Model, message: Message) =>
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 }) => dialogFold.update(model, dialogMessage),
74
+ GotDialogMessage: ({ message: dialogMessage }) =>
75
+ dialogFold.updateWith(context)(model, dialogMessage),
72
76
  ClickedConfirm: () => ({ model, outMessage: OutMessage.Confirmed() }),
73
77
  ClickedCancel: () =>
74
- Dialog.isCloseHeld(model.dialog)
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 with its ways out free: focus starts on the action, or on cancel
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`, and lets go of a hold: call it
84
- * once confirmed work has landed. */
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. Cancel stays live
127
- * unless the dialog's ways out are held (`setCloseHeld`). */
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: Dialog.isCloseHeld(model.dialog),
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, `close` once it
203
- * has landed, and on failure keep it open with the error in `toDetailView`. Hold its ways
204
- * out with `setCloseHeld` too when the reader must stay to see how it ends.
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(model, viewInputs, render, h),
208
+ toView: (render) => cardView(viewInputs, render, h),
216
209
  },
217
210
  toParentMessage: (message) => Message.GotDialogMessage({ message }),
218
211
  }),