@gjermundgaraba-designs/pixel-paper 0.12.0 → 0.14.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 +32 -25
- package/dist/src/announcer/announcer.d.ts +34 -26
- package/dist/src/announcer/announcer.d.ts.map +1 -1
- package/dist/src/announcer/announcer.js +42 -32
- package/dist/src/announcer/index.d.ts +1 -1
- package/dist/src/announcer/index.d.ts.map +1 -1
- package/dist/src/announcer/index.js +1 -1
- package/dist/src/banner/banner.d.ts +1 -1
- package/dist/src/banner/banner.js +1 -1
- package/dist/src/barChart/barChart.js +1 -1
- package/dist/src/board/board.d.ts +1 -4
- package/dist/src/board/board.d.ts.map +1 -1
- package/dist/src/board/board.js +8 -71
- package/dist/src/button/button.d.ts +1 -1
- package/dist/src/button/button.js +1 -1
- package/dist/src/card/card.d.ts +35 -9
- package/dist/src/card/card.d.ts.map +1 -1
- package/dist/src/card/card.js +46 -8
- package/dist/src/card/index.d.ts +2 -2
- package/dist/src/card/index.d.ts.map +1 -1
- package/dist/src/card/index.js +1 -1
- package/dist/src/commandPalette/commandPalette.d.ts +4 -0
- package/dist/src/commandPalette/commandPalette.d.ts.map +1 -1
- package/dist/src/confirmDialog/confirmDialog.d.ts +18 -26
- package/dist/src/confirmDialog/confirmDialog.d.ts.map +1 -1
- package/dist/src/confirmDialog/confirmDialog.js +21 -19
- 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/contextMenu/contextMenu.d.ts +6 -6
- package/dist/src/dialog/dialog.d.ts +36 -7
- package/dist/src/dialog/dialog.d.ts.map +1 -1
- package/dist/src/dialog/dialog.js +32 -12
- package/dist/src/dialog/index.d.ts +1 -1
- package/dist/src/dialog/index.d.ts.map +1 -1
- package/dist/src/dialog/index.js +1 -1
- package/dist/src/drag/drag.d.ts +40 -0
- package/dist/src/drag/drag.d.ts.map +1 -0
- package/dist/src/drag/drag.js +134 -0
- package/dist/src/emptyState/emptyState.d.ts +6 -4
- package/dist/src/emptyState/emptyState.d.ts.map +1 -1
- package/dist/src/emptyState/emptyState.js +1 -1
- package/dist/src/errorSummary/errorSummary.d.ts +1 -1
- package/dist/src/errorSummary/errorSummary.js +1 -1
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -0
- package/dist/src/keyHelp/keyHelp.d.ts +4 -0
- package/dist/src/keyHelp/keyHelp.d.ts.map +1 -1
- package/dist/src/lineChart/lineChart.js +1 -1
- package/dist/src/liveRegion/index.d.ts +3 -0
- package/dist/src/liveRegion/index.d.ts.map +1 -0
- package/dist/src/liveRegion/index.js +1 -0
- package/dist/src/liveRegion/liveRegion.d.ts +42 -0
- package/dist/src/liveRegion/liveRegion.d.ts.map +1 -0
- package/dist/src/liveRegion/liveRegion.js +35 -0
- package/dist/src/loading/loading.d.ts +8 -3
- package/dist/src/loading/loading.d.ts.map +1 -1
- package/dist/src/loading/loading.js +4 -3
- package/dist/src/menu/menu.d.ts +6 -6
- package/dist/src/meter/meter.d.ts +3 -0
- package/dist/src/meter/meter.d.ts.map +1 -1
- package/dist/src/meter/meter.js +6 -3
- package/dist/src/places/places.d.ts +15 -5
- package/dist/src/places/places.d.ts.map +1 -1
- package/dist/src/places/places.js +19 -17
- package/dist/src/remote/index.d.ts +3 -0
- package/dist/src/remote/index.d.ts.map +1 -0
- package/dist/src/remote/index.js +1 -0
- package/dist/src/remote/remote.d.ts +29 -0
- package/dist/src/remote/remote.d.ts.map +1 -0
- package/dist/src/remote/remote.js +41 -0
- package/dist/src/rows/index.d.ts +1 -1
- package/dist/src/rows/index.d.ts.map +1 -1
- package/dist/src/rows/rows.d.ts +24 -3
- package/dist/src/rows/rows.d.ts.map +1 -1
- package/dist/src/rows/rows.js +44 -15
- package/dist/src/skipLink/index.d.ts +1 -1
- package/dist/src/skipLink/index.d.ts.map +1 -1
- package/dist/src/skipLink/index.js +1 -1
- package/dist/src/skipLink/skipLink.d.ts +24 -8
- package/dist/src/skipLink/skipLink.d.ts.map +1 -1
- package/dist/src/skipLink/skipLink.js +27 -8
- package/dist/src/sortable/index.d.ts +3 -0
- package/dist/src/sortable/index.d.ts.map +1 -0
- package/dist/src/sortable/index.js +1 -0
- package/dist/src/sortable/sortable.d.ts +1144 -0
- package/dist/src/sortable/sortable.d.ts.map +1 -0
- package/dist/src/sortable/sortable.js +504 -0
- package/dist/src/toast/index.d.ts +1 -1
- package/dist/src/toast/index.d.ts.map +1 -1
- package/dist/src/toast/index.js +1 -1
- package/dist/src/toast/toast.d.ts +32 -20
- package/dist/src/toast/toast.d.ts.map +1 -1
- package/dist/src/toast/toast.js +8 -3
- package/dist/src/topBar/barHeight.d.ts +6 -0
- package/dist/src/topBar/barHeight.d.ts.map +1 -1
- package/dist/src/topBar/barHeight.js +4 -0
- package/dist/src/topBar/index.d.ts +1 -1
- package/dist/src/topBar/index.d.ts.map +1 -1
- package/dist/src/topBar/index.js +1 -1
- package/dist/src/topBar/topBar.d.ts +1 -2
- package/dist/src/topBar/topBar.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/announcer/announcer.ts +48 -32
- package/src/announcer/index.ts +1 -1
- package/src/banner/banner.ts +1 -1
- package/src/barChart/barChart.ts +1 -1
- package/src/board/board.ts +18 -87
- package/src/button/button.ts +1 -1
- package/src/card/card.ts +120 -21
- package/src/card/index.ts +2 -2
- package/src/confirmDialog/confirmDialog.ts +25 -32
- package/src/confirmDialog/index.ts +2 -0
- package/src/dialog/dialog.ts +39 -13
- package/src/dialog/index.ts +3 -1
- package/src/drag/drag.ts +207 -0
- package/src/emptyState/emptyState.ts +7 -5
- package/src/errorSummary/errorSummary.ts +1 -1
- package/src/index.ts +3 -0
- package/src/lineChart/lineChart.ts +1 -1
- package/src/liveRegion/index.ts +2 -0
- package/src/liveRegion/liveRegion.ts +75 -0
- package/src/loading/loading.ts +11 -5
- package/src/meter/meter.ts +17 -3
- package/src/pixel-paper.css +197 -28
- package/src/places/places.ts +43 -30
- package/src/remote/index.ts +2 -0
- package/src/remote/remote.ts +76 -0
- package/src/rows/index.ts +1 -0
- package/src/rows/rows.ts +87 -22
- package/src/skipLink/index.ts +1 -1
- package/src/skipLink/skipLink.ts +38 -9
- package/src/sortable/index.ts +14 -0
- package/src/sortable/sortable.ts +857 -0
- package/src/toast/index.ts +1 -0
- package/src/toast/toast.ts +9 -3
- package/src/tokens.css +13 -11
- package/src/topBar/barHeight.ts +6 -0
- package/src/topBar/index.ts +1 -1
- package/src/topBar/topBar.ts +1 -2
|
@@ -15,19 +15,17 @@ export const Model = Schema.Struct({
|
|
|
15
15
|
dialog: Dialog.Model,
|
|
16
16
|
});
|
|
17
17
|
// MESSAGE
|
|
18
|
-
/** Union of all Messages a confirm dialog can produce.
|
|
19
|
-
* press on the veil while `isCloseHeld` is set; nothing follows it. */
|
|
18
|
+
/** Union of all Messages a confirm dialog can produce. */
|
|
20
19
|
export const Message = defineMessageUnion({
|
|
21
20
|
GotDialogMessage: { message: Dialog.Message },
|
|
22
21
|
ClickedConfirm: {},
|
|
23
22
|
ClickedCancel: {},
|
|
24
|
-
RequestedCloseWhileHeld: {},
|
|
25
23
|
});
|
|
26
24
|
// OUT MESSAGE
|
|
27
25
|
/** Union of OutMessages a confirm dialog reports. `Confirmed`: the reader pressed the action;
|
|
28
26
|
* the dialog stays open until the parent calls `close`. `Cancelled`: cancel, Escape or a click
|
|
29
27
|
* on the veil; the dialog has closed, and whether that also stops work already running is
|
|
30
|
-
* the parent's to decide. Never reported while `
|
|
28
|
+
* the parent's to decide. Never reported while its ways out are held (`setCloseHeld`). */
|
|
31
29
|
export const OutMessage = defineMessageUnion({
|
|
32
30
|
Confirmed: {},
|
|
33
31
|
Cancelled: {},
|
|
@@ -50,21 +48,29 @@ const dialogFold = foldDialog(Dialog, {
|
|
|
50
48
|
export const update = (model, message) => __foldkitBrandViewResult((Message.match(message, {
|
|
51
49
|
GotDialogMessage: ({ message: dialogMessage }) => __foldkitBrandViewResult((dialogFold.update(model, dialogMessage)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#GotDialogMessage"),
|
|
52
50
|
ClickedConfirm: () => (__foldkitBrandViewResult(({ model, outMessage: OutMessage.Confirmed() }), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#ClickedConfirm")),
|
|
53
|
-
ClickedCancel: () => __foldkitBrandViewResult((
|
|
54
|
-
|
|
51
|
+
ClickedCancel: () => __foldkitBrandViewResult((Dialog.isCloseHeld(model.dialog)
|
|
52
|
+
? { model }
|
|
53
|
+
: pipe(dialogFold.close(model), Update.withOutMessage(OutMessage.Cancelled()))), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#ClickedCancel"),
|
|
55
54
|
})), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#update");
|
|
56
55
|
/** Opens the confirm dialog: focus starts on the action, or on cancel when it is `isDanger`. */
|
|
57
56
|
export const open = (model) => __foldkitBrandViewResult((dialogFold.open(model)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#open");
|
|
58
|
-
/** Closes the confirm dialog without reporting `Cancelled
|
|
59
|
-
* landed. */
|
|
57
|
+
/** Closes the confirm dialog without reporting `Cancelled`, and lets go of a hold: call it
|
|
58
|
+
* once confirmed work has landed. */
|
|
60
59
|
export const close = (model) => __foldkitBrandViewResult((dialogFold.close(model)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#close");
|
|
60
|
+
/** Holds cancel, Escape and the veil, or lets them go: while held the dialog stays open and
|
|
61
|
+
* reports no `Cancelled`, and cancel prints held (`aria-disabled`, in the keyboard). Hold it
|
|
62
|
+
* in the update that starts confirmed work whose failure must land here, and let go in the
|
|
63
|
+
* update where the work fails; `close` lets go once it lands. */
|
|
64
|
+
export const setCloseHeld = (model, isHeld) => __foldkitBrandViewResult((modifyFields(model, { dialog: (dialog) => __foldkitBrandViewResult((Dialog.setCloseHeld(dialog, isHeld)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#dialog~2") })), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#setCloseHeld");
|
|
61
65
|
// ACCESSORS
|
|
62
66
|
/** The confirm dialog's id, unique in the document. */
|
|
63
67
|
export const id = (model) => __foldkitBrandViewResult((Dialog.id(model.dialog)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#id");
|
|
64
68
|
/** Whether the confirm dialog is open. */
|
|
65
69
|
export const isOpen = (model) => __foldkitBrandViewResult((Dialog.isOpen(model.dialog)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#isOpen");
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
/** Whether its ways out are held (`setCloseHeld`). */
|
|
71
|
+
export const isCloseHeld = (model) => __foldkitBrandViewResult((Dialog.isCloseHeld(model.dialog)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#isCloseHeld");
|
|
72
|
+
const cardView = (model, viewInputs, render, h) => {
|
|
73
|
+
const { isDanger = false, isBusy = false, isDisabled = false, toDetailView } = viewInputs;
|
|
68
74
|
const commit = Button.view({
|
|
69
75
|
label: viewInputs.label,
|
|
70
76
|
variant: isDanger ? "Danger" : "Primary",
|
|
@@ -77,7 +83,7 @@ const cardView = (viewInputs, render, h) => {
|
|
|
77
83
|
const cancel = Button.view({
|
|
78
84
|
label: "cancel",
|
|
79
85
|
isDefault: isDanger,
|
|
80
|
-
isDisabled: isCloseHeld,
|
|
86
|
+
isDisabled: Dialog.isCloseHeld(model.dialog),
|
|
81
87
|
onClick: Message.ClickedCancel(),
|
|
82
88
|
attributes: isDanger ? render.initialFocus : [],
|
|
83
89
|
}, h);
|
|
@@ -108,8 +114,8 @@ const cardView = (viewInputs, render, h) => {
|
|
|
108
114
|
* double-click through.
|
|
109
115
|
*
|
|
110
116
|
* Work that takes a while stays in the dialog: set `isBusy` while it runs, `close` once it
|
|
111
|
-
* has landed, and on failure keep it open with the error in `toDetailView`.
|
|
112
|
-
* `
|
|
117
|
+
* has landed, and on failure keep it open with the error in `toDetailView`. Hold its ways
|
|
118
|
+
* out with `setCloseHeld` too when the reader must stay to see how it ends.
|
|
113
119
|
*/
|
|
114
120
|
export const view = defineView((model, viewInputs, h) => __foldkitBrandViewResult((h.submodel({
|
|
115
121
|
slotId: id(model),
|
|
@@ -119,11 +125,7 @@ export const view = defineView((model, viewInputs, h) => __foldkitBrandViewResul
|
|
|
119
125
|
isAlert: viewInputs.isDanger ?? false,
|
|
120
126
|
hasDescription: true,
|
|
121
127
|
toLiveRegionView: viewInputs.toLiveRegionView,
|
|
122
|
-
toView: (render) => __foldkitBrandViewResult((cardView(viewInputs, render, h)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#toView"),
|
|
128
|
+
toView: (render) => __foldkitBrandViewResult((cardView(model, viewInputs, render, h)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#toView"),
|
|
123
129
|
},
|
|
124
|
-
|
|
125
|
-
// `RequestedCloseWhileHeld` instead of reaching the Dialog.
|
|
126
|
-
toParentMessage: (message) => __foldkitBrandViewResult((viewInputs.isCloseHeld === true && Dialog.isCloseRequest(message)
|
|
127
|
-
? Message.RequestedCloseWhileHeld()
|
|
128
|
-
: Message.GotDialogMessage({ message })), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#toParentMessage~2"),
|
|
130
|
+
toParentMessage: (message) => __foldkitBrandViewResult((Message.GotDialogMessage({ message })), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#toParentMessage~2"),
|
|
129
131
|
})), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#anonymous"));
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Message, Model, OutMessage, close, id, init, isOpen, open, update, view, } from "./confirmDialog.ts";
|
|
1
|
+
export { Message, Model, OutMessage, close, id, init, isCloseHeld, isOpen, open, setCloseHeld, update, view, } from "./confirmDialog.ts";
|
|
2
2
|
export type { InitConfig, ViewInputs } from "./confirmDialog.ts";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/confirmDialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,EACL,UAAU,EACV,KAAK,EACL,EAAE,EACF,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,MAAM,EACN,IAAI,GACL,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/confirmDialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,EACL,UAAU,EACV,KAAK,EACL,EAAE,EACF,IAAI,EACJ,WAAW,EACX,MAAM,EACN,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,IAAI,GACL,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Message, Model, OutMessage, close, id, init, isOpen, open, update, view, } from "./confirmDialog.js";
|
|
1
|
+
export { Message, Model, OutMessage, close, id, init, isCloseHeld, isOpen, open, setCloseHeld, update, view, } from "./confirmDialog.js";
|
|
@@ -84,13 +84,13 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
84
84
|
}>;
|
|
85
85
|
};
|
|
86
86
|
commands?: Update.Commands<{
|
|
87
|
+
readonly _tag: "PressedEscape";
|
|
88
|
+
} | {
|
|
87
89
|
readonly _tag: "CompletedFocus";
|
|
88
90
|
} | {
|
|
89
91
|
readonly _tag: "CompletedPlaceSlip";
|
|
90
92
|
} | {
|
|
91
93
|
readonly _tag: "LeftSlip";
|
|
92
|
-
} | {
|
|
93
|
-
readonly _tag: "PressedEscape";
|
|
94
94
|
} | {
|
|
95
95
|
readonly _tag: "PressedTab";
|
|
96
96
|
} | {
|
|
@@ -163,11 +163,11 @@ export declare const BindPointSlip: Mount.MountDefinitionWithArgs<"BindPointSlip
|
|
|
163
163
|
readonly y: Schema.Number;
|
|
164
164
|
}>;
|
|
165
165
|
}, {
|
|
166
|
+
readonly _tag: "PressedEscape";
|
|
167
|
+
} | {
|
|
166
168
|
readonly _tag: "CompletedPlaceSlip";
|
|
167
169
|
} | {
|
|
168
170
|
readonly _tag: "LeftSlip";
|
|
169
|
-
} | {
|
|
170
|
-
readonly _tag: "PressedEscape";
|
|
171
171
|
} | {
|
|
172
172
|
readonly _tag: "PressedTab";
|
|
173
173
|
}>;
|
|
@@ -197,13 +197,13 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
197
197
|
readonly maybeReturnFocusId: Option.Option<string>;
|
|
198
198
|
}>;
|
|
199
199
|
}, {
|
|
200
|
+
readonly _tag: "PressedEscape";
|
|
201
|
+
} | {
|
|
200
202
|
readonly _tag: "CompletedFocus";
|
|
201
203
|
} | {
|
|
202
204
|
readonly _tag: "CompletedPlaceSlip";
|
|
203
205
|
} | {
|
|
204
206
|
readonly _tag: "LeftSlip";
|
|
205
|
-
} | {
|
|
206
|
-
readonly _tag: "PressedEscape";
|
|
207
207
|
} | {
|
|
208
208
|
readonly _tag: "PressedTab";
|
|
209
209
|
} | {
|
|
@@ -2,7 +2,8 @@ import { Option, Schema } from "effect";
|
|
|
2
2
|
import { type ChildAttribute, type Html } from "foldkit/html";
|
|
3
3
|
import * as Mount from "foldkit/mount";
|
|
4
4
|
import type * as Update from "foldkit/update";
|
|
5
|
-
/** Schema for a pixel-paper dialog: the `@foldkit/ui` Dialog it is built on
|
|
5
|
+
/** Schema for a pixel-paper dialog: the `@foldkit/ui` Dialog it is built on, and whether its
|
|
6
|
+
* ways out are held (`setCloseHeld`). */
|
|
6
7
|
export declare const Model: Schema.Struct<{
|
|
7
8
|
readonly dialog: Schema.Struct<{
|
|
8
9
|
readonly id: Schema.String;
|
|
@@ -16,6 +17,7 @@ export declare const Model: Schema.Struct<{
|
|
|
16
17
|
}>;
|
|
17
18
|
readonly maybeFocusSelector: Schema.Option<Schema.String>;
|
|
18
19
|
}>;
|
|
20
|
+
readonly isCloseHeld: Schema.Boolean;
|
|
19
21
|
}>;
|
|
20
22
|
export type Model = typeof Model.Type;
|
|
21
23
|
/** Which way h, l and the side arrows move focus in a dialog's action bar. */
|
|
@@ -73,6 +75,8 @@ export declare const init: (config: InitConfig) => Model;
|
|
|
73
75
|
export declare const id: (model: Model) => string;
|
|
74
76
|
/** Whether the dialog is open. */
|
|
75
77
|
export declare const isOpen: (model: Model) => boolean;
|
|
78
|
+
/** Whether the dialog's ways out are held (`setCloseHeld`). */
|
|
79
|
+
export declare const isCloseHeld: (model: Model) => boolean;
|
|
76
80
|
/** Processes a dialog Message and returns the next Model, Commands and OutMessage. */
|
|
77
81
|
export declare const update: (model: Model, message: Message) => Readonly<{
|
|
78
82
|
model: {
|
|
@@ -88,6 +92,7 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
88
92
|
};
|
|
89
93
|
readonly maybeFocusSelector: Option.Option<string>;
|
|
90
94
|
};
|
|
95
|
+
readonly isCloseHeld: boolean;
|
|
91
96
|
};
|
|
92
97
|
commands?: Update.Commands<{
|
|
93
98
|
readonly _tag: "GotDialogMessage";
|
|
@@ -134,12 +139,15 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
134
139
|
/** Opens the dialog: focus moves to the element given the `initialFocus` group, else to the
|
|
135
140
|
* first control, and returns to where it was when the dialog closes. */
|
|
136
141
|
export declare const open: (model: Model) => Update.Return<Model, Message>;
|
|
137
|
-
/** Closes the dialog without reporting `Closed
|
|
142
|
+
/** Closes the dialog without reporting `Closed`, and lets go of a hold. */
|
|
138
143
|
export declare const close: (model: Model) => Update.Return<Model, Message>;
|
|
139
|
-
/**
|
|
140
|
-
* the `closeButton` group
|
|
141
|
-
*
|
|
142
|
-
|
|
144
|
+
/** Holds the dialog's ways out, or lets them go: while held, Escape, a press on the veil and
|
|
145
|
+
* a control given the `closeButton` group leave it open and report no `Closed`, so the
|
|
146
|
+
* result of work the reader may not walk away from (a save whose failure must land here)
|
|
147
|
+
* lands in it. Hold it in the update that starts the work, and let go in the update where
|
|
148
|
+
* the work fails, or the reader is shut in with the failure; `close` lets go once it lands.
|
|
149
|
+
* Hold the card's own close controls too (`Card.formView`'s `isBusy`). */
|
|
150
|
+
export declare const setCloseHeld: (model: Model, isHeld: boolean) => Model;
|
|
143
151
|
/** Moves focus for one keydown in an action bar, and says which way it moved. It moves only
|
|
144
152
|
* when the key's target is one of the bar's own actions and there is an action that way:
|
|
145
153
|
* a key typed in a field, a menu's item or a nested dialog inside the bar, a key an IME is
|
|
@@ -149,11 +157,31 @@ export declare const isCloseRequest: (message: Message) => boolean;
|
|
|
149
157
|
export declare const moveActionFocus: (bar: Element, event: KeyboardEvent) => Option.Option<ActionDirection>;
|
|
150
158
|
/** The action bar's keys: h or ←, and l or →, move focus between its actions (see
|
|
151
159
|
* `moveActionFocus`). Attached by the `actionBar` group. In a Scene, resolve it with
|
|
152
|
-
* `
|
|
160
|
+
* `sceneMounts`. */
|
|
153
161
|
export declare const BindActionKeys: Mount.MountDefinitionNoArgs<"BindActionKeys", {
|
|
154
162
|
readonly _tag: "PressedActionKey";
|
|
155
163
|
readonly direction: "Next" | "Previous";
|
|
156
164
|
}>;
|
|
165
|
+
/** What a parent's Scene resolves an open dialog's Mounts with (`@foldkit/ui`'s resources,
|
|
166
|
+
* then the action bar's keys), each with a Message that changes nothing:
|
|
167
|
+
* `Scene.Mount.resolveAll(...Dialog.sceneMounts)`. It serves every dialog built on this one
|
|
168
|
+
* (ConfirmDialog, KeyHelp, CommandPalette), since a Scene lifts the Messages for it. */
|
|
169
|
+
export declare const sceneMounts: readonly [readonly [Mount.MountDefinitionWithArgs<"AcquireResources", {
|
|
170
|
+
id: Schema.String;
|
|
171
|
+
focusSelector: Schema.String;
|
|
172
|
+
}, {
|
|
173
|
+
readonly _tag: "SucceededAcquireResources";
|
|
174
|
+
} | {
|
|
175
|
+
readonly _tag: "FailedAcquireResources";
|
|
176
|
+
}>, {
|
|
177
|
+
readonly _tag: "SucceededAcquireResources";
|
|
178
|
+
}], readonly [Mount.MountDefinitionNoArgs<"BindActionKeys", {
|
|
179
|
+
readonly _tag: "PressedActionKey";
|
|
180
|
+
readonly direction: "Next" | "Previous";
|
|
181
|
+
}>, {
|
|
182
|
+
readonly _tag: "PressedActionKey";
|
|
183
|
+
readonly direction: "Next" | "Previous";
|
|
184
|
+
}]];
|
|
157
185
|
/** Attribute groups a dialog hands its content. Spread each onto the element it names; a Card
|
|
158
186
|
* takes `title` and `actionBar` directly. None of them carries a class. */
|
|
159
187
|
export type RenderInfo = Readonly<{
|
|
@@ -207,6 +235,7 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
207
235
|
};
|
|
208
236
|
readonly maybeFocusSelector: Option.Option<string>;
|
|
209
237
|
};
|
|
238
|
+
readonly isCloseHeld: boolean;
|
|
210
239
|
}, {
|
|
211
240
|
readonly _tag: "GotDialogMessage";
|
|
212
241
|
readonly message: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../src/dialog/dialog.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,MAAM,EAAE,MAAM,EAAQ,MAAM,QAAQ,CAAC;AAE5D,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAmB,MAAM,cAAc,CAAC;AAE/E,OAAO,KAAK,KAAK,MAAM,eAAe,CAAC;AAGvC,OAAO,KAAK,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAO9C
|
|
1
|
+
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../src/dialog/dialog.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,9 +10,11 @@ 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
|
|
13
|
+
/** Schema for a pixel-paper dialog: the `@foldkit/ui` Dialog it is built on, and whether its
|
|
14
|
+
* ways out are held (`setCloseHeld`). */
|
|
14
15
|
export const Model = Schema.Struct({
|
|
15
16
|
dialog: UiDialog.Model,
|
|
17
|
+
isCloseHeld: Schema.Boolean,
|
|
16
18
|
});
|
|
17
19
|
/** Which way h, l and the side arrows move focus in a dialog's action bar. */
|
|
18
20
|
const ActionDirection = Schema.Literals(["Previous", "Next"]);
|
|
@@ -34,12 +36,15 @@ export const OutMessage = defineMessageUnion({
|
|
|
34
36
|
/** Creates a closed dialog. */
|
|
35
37
|
export const init = (config) => (__foldkitBrandViewResult(({
|
|
36
38
|
dialog: UiDialog.init({ id: config.id }),
|
|
39
|
+
isCloseHeld: false,
|
|
37
40
|
}), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#init"));
|
|
38
41
|
// ACCESSORS
|
|
39
42
|
/** The dialog's id, unique in the document. */
|
|
40
43
|
export const id = (model) => __foldkitBrandViewResult((model.dialog.id), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#id");
|
|
41
44
|
/** Whether the dialog is open. */
|
|
42
45
|
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");
|
|
43
48
|
// UPDATE
|
|
44
49
|
const toOutMessage = UiDialog.OutMessage.match({
|
|
45
50
|
Opened: () => __foldkitBrandViewResult((undefined), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#Opened"),
|
|
@@ -51,23 +56,27 @@ const dialogFold = foldDialog(UiDialog, {
|
|
|
51
56
|
toParentMessage: (message) => __foldkitBrandViewResult((Message.GotDialogMessage({ message })), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#toParentMessage"),
|
|
52
57
|
toParentOutMessage: toOutMessage,
|
|
53
58
|
});
|
|
59
|
+
// NOTE: @foldkit/ui gap: Dialog has no way to hold a close. Escape, a press on the veil and a
|
|
60
|
+
// control given the `closeButton` group all send `RequestedClose`, so a held dialog reads it
|
|
61
|
+
// 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");
|
|
54
63
|
/** Processes a dialog Message and returns the next Model, Commands and OutMessage. */
|
|
55
64
|
export const update = (model, message) => __foldkitBrandViewResult((Message.match(message, {
|
|
56
|
-
GotDialogMessage: ({ message: dialogMessage }) => __foldkitBrandViewResult((dialogFold.update(model, dialogMessage)), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#GotDialogMessage"),
|
|
65
|
+
GotDialogMessage: ({ message: dialogMessage }) => __foldkitBrandViewResult((isHeldClose(model, dialogMessage) ? { model } : dialogFold.update(model, dialogMessage)), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#GotDialogMessage"),
|
|
57
66
|
PressedActionKey: () => (__foldkitBrandViewResult(({ model }), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#PressedActionKey")),
|
|
58
67
|
})), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#update");
|
|
59
68
|
/** Opens the dialog: focus moves to the element given the `initialFocus` group, else to the
|
|
60
69
|
* first control, and returns to where it was when the dialog closes. */
|
|
61
70
|
export const open = (model) => __foldkitBrandViewResult((dialogFold.open(model)), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#open");
|
|
62
|
-
/** Closes the dialog without reporting `Closed
|
|
63
|
-
export const close = (model) => __foldkitBrandViewResult((dialogFold.close(model)), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#close");
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
* the
|
|
69
|
-
*
|
|
70
|
-
export const
|
|
71
|
+
/** Closes the dialog without reporting `Closed`, and lets go of a hold. */
|
|
72
|
+
export const close = (model) => __foldkitBrandViewResult((dialogFold.close(modifyFields(model, { isCloseHeld: () => __foldkitBrandViewResult((false), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#isCloseHeld~2") }))), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#close");
|
|
73
|
+
/** Holds the dialog's ways out, or lets them go: while held, Escape, a press on the veil and
|
|
74
|
+
* a control given the `closeButton` group leave it open and report no `Closed`, so the
|
|
75
|
+
* result of work the reader may not walk away from (a save whose failure must land here)
|
|
76
|
+
* lands in it. Hold it in the update that starts the work, and let go in the update where
|
|
77
|
+
* the work fails, or the reader is shut in with the failure; `close` lets go once it lands.
|
|
78
|
+
* Hold the card's own close controls too (`Card.formView`'s `isBusy`). */
|
|
79
|
+
export const setCloseHeld = (model, isHeld) => __foldkitBrandViewResult((modifyFields(model, { isCloseHeld: () => __foldkitBrandViewResult((isHeld), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#isCloseHeld~3") })), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#setCloseHeld");
|
|
71
80
|
// ACTION BAR KEYS
|
|
72
81
|
const ACTION_BAR_ATTRIBUTE = "data-pixel-paper-action-bar";
|
|
73
82
|
const ACTION_SELECTOR = "button:not(:disabled), a[href]";
|
|
@@ -96,7 +105,7 @@ export const moveActionFocus = (bar, event) => {
|
|
|
96
105
|
};
|
|
97
106
|
/** The action bar's keys: h or ←, and l or →, move focus between its actions (see
|
|
98
107
|
* `moveActionFocus`). Attached by the `actionBar` group. In a Scene, resolve it with
|
|
99
|
-
* `
|
|
108
|
+
* `sceneMounts`. */
|
|
100
109
|
export const BindActionKeys = Mount.defineStream("BindActionKeys", {
|
|
101
110
|
messages: [Message.PressedActionKey],
|
|
102
111
|
execute: ({ element }) => __foldkitBrandViewResult((Dom.streamFromEventFilterMap({
|
|
@@ -105,6 +114,17 @@ export const BindActionKeys = Mount.defineStream("BindActionKeys", {
|
|
|
105
114
|
filterMapEvent: (event) => __foldkitBrandViewResult((Option.map(moveActionFocus(element, event), (direction) => __foldkitBrandViewResult((Message.PressedActionKey({ direction })), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#anonymous~9"))), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#filterMapEvent"),
|
|
106
115
|
})), "@gjermundgaraba-designs/pixel-paper/src/dialog/dialog.js#execute"),
|
|
107
116
|
});
|
|
117
|
+
/** What a parent's Scene resolves an open dialog's Mounts with (`@foldkit/ui`'s resources,
|
|
118
|
+
* then the action bar's keys), each with a Message that changes nothing:
|
|
119
|
+
* `Scene.Mount.resolveAll(...Dialog.sceneMounts)`. It serves every dialog built on this one
|
|
120
|
+
* (ConfirmDialog, KeyHelp, CommandPalette), since a Scene lifts the Messages for it. */
|
|
121
|
+
export const sceneMounts = [
|
|
122
|
+
// NOTE: @foldkit/ui gap: its Dialog ships no Scene resolution for its resources Mount, so
|
|
123
|
+
// this test helper builds the child Message the Mount would report
|
|
124
|
+
// oxlint-disable-next-line foldkit/no-child-message-construction-in-root
|
|
125
|
+
[UiDialog.AcquireResources, UiDialog.Message.SucceededAcquireResources()],
|
|
126
|
+
[BindActionKeys, Message.PressedActionKey({ direction: "Next" })],
|
|
127
|
+
];
|
|
108
128
|
/**
|
|
109
129
|
* A modal dialog on the ink veil with its checker grain, built on `@foldkit/ui`'s Dialog. It
|
|
110
130
|
* opens with `show()` in place, not in the top layer: Foldkit makes the page behind it inert
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { BindActionKeys, Message, Model, OutMessage, close, id, init,
|
|
1
|
+
export { BindActionKeys, Message, Model, OutMessage, close, id, init, isCloseHeld, isOpen, open, sceneMounts, setCloseHeld, update, view, } from "./dialog.ts";
|
|
2
2
|
export type { InitConfig, Placement, RenderInfo, 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,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"}
|
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, isCloseHeld, isOpen, open, sceneMounts, setCloseHeld, update, view, } from "./dialog.js";
|
|
2
2
|
export { foldDialog } from "./fold.js";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DragAndDrop as UiDragAndDrop } from "@foldkit/ui";
|
|
2
|
+
import { Option, Stream } from "effect";
|
|
3
|
+
/** Where a drag is: nothing pressed, pressed but not yet moved, carried by a pointer, or
|
|
4
|
+
* carried by the keyboard. */
|
|
5
|
+
type Phase = "Idle" | "Pressed" | "PointerDragging" | "KeyboardDragging";
|
|
6
|
+
export declare const phaseOf: (dragAndDrop: UiDragAndDrop.Model) => Phase;
|
|
7
|
+
/** Whether an item is carried, by a pointer or the keyboard. */
|
|
8
|
+
export declare const isCarrying: (phase: Phase) => boolean;
|
|
9
|
+
export declare const pressedDraggable: (fields: Parameters<typeof UiDragAndDrop.Message.PressedDraggable>[0]) => UiDragAndDrop.Message;
|
|
10
|
+
export declare const activatedKeyboardDrag: (fields: Parameters<typeof UiDragAndDrop.Message.ActivatedKeyboardDrag>[0]) => UiDragAndDrop.Message;
|
|
11
|
+
export declare const movedPointer: (fields: Parameters<typeof UiDragAndDrop.Message.MovedPointer>[0]) => UiDragAndDrop.Message;
|
|
12
|
+
export declare const releasedPointer: () => UiDragAndDrop.Message;
|
|
13
|
+
export declare const cancelledDrag: () => UiDragAndDrop.Message;
|
|
14
|
+
/** The main mouse button, the only one that lifts. */
|
|
15
|
+
export declare const LEFT_BUTTON = 0;
|
|
16
|
+
/** What a press inside an item may land on without lifting it: its controls, but for the
|
|
17
|
+
* buttons `liftingButtons` (a selector list) names, and anything marked `data-no-lift`. */
|
|
18
|
+
export declare const innerControls: (liftingButtons: string) => string;
|
|
19
|
+
/** Takes a plain Escape for `message` and stops it there, so a dialog around the list or the
|
|
20
|
+
* page's own key bindings never see it. */
|
|
21
|
+
export declare const takeEscape: <Message>(event: KeyboardEvent, message: Message) => Option.Option<Message>;
|
|
22
|
+
/** Escape on the window, in the capture phase, as `message`. */
|
|
23
|
+
export declare const escapeKeys: <Message>(message: Message) => Stream.Stream<Message>;
|
|
24
|
+
/** Sizes the copy that follows the pointer to the element `sourceSelector` finds, and keeps the
|
|
25
|
+
* pointer where it pressed that element. */
|
|
26
|
+
export declare const measureLift: (element: Element, sourceSelector: string, pressX: number, pressY: number) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Where a pointer at (`clientX`, `clientY`) would put the held item among the others in
|
|
29
|
+
* `container` (its `[data-sortable-id]` items, the held one, `heldId`, left out): before or
|
|
30
|
+
* after the item whose centre is closest. Where items sit side by side (two share a top, a
|
|
31
|
+
* wrapping grid, the held one counted) the pointer's side of that centre is read across, and
|
|
32
|
+
* in a column of rows it is read down, so one reading serves a list and a grid.
|
|
33
|
+
*/
|
|
34
|
+
export declare const insertionIndex: (container: Element, heldId: string, clientX: number, clientY: number) => number;
|
|
35
|
+
/** While a pointer presses or carries an item, the page is marked
|
|
36
|
+
* (`data-pixel-paper-dragging` on the root), so the stylesheet prints the grabbing cursor and
|
|
37
|
+
* holds text selection, with no style element of its own. */
|
|
38
|
+
export declare const markDragging: Stream.Stream<never>;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=drag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drag.d.ts","sourceRoot":"","sources":["../../../src/drag/drag.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAiB,MAAM,EAAS,MAAM,EAAQ,MAAM,QAAQ,CAAC;AAKpE;+BAC+B;AAC/B,KAAK,KAAK,GAAG,MAAM,GAAG,SAAS,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;AAKzE,eAAO,MAAM,OAAO,gBAAiB,aAAa,CAAC,KAAK,KAAG,KAU1D,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,UAAU,UAAW,KAAK,KAAG,OACmB,CAAC;AAQ9D,eAAO,MAAM,gBAAgB,WACnB,UAAU,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,KACnE,aAAa,CAAC,OAE+B,CAAC;AAEjD,eAAO,MAAM,qBAAqB,WACxB,UAAU,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,KACxE,aAAa,CAAC,OAEoC,CAAC;AAEtD,eAAO,MAAM,YAAY,WACf,UAAU,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAC/D,aAAa,CAAC,OAE2B,CAAC;AAE7C,eAAO,MAAM,eAAe,QAAO,aAAa,CAAC,OAER,CAAC;AAE1C,eAAO,MAAM,aAAa,QAAO,aAAa,CAAC,OAER,CAAC;AAIxC,sDAAsD;AACtD,eAAO,MAAM,WAAW,IAAI,CAAC;AAE7B;4FAC4F;AAC5F,eAAO,MAAM,aAAa,mBAAoB,MAAM,KAAG,MASzC,CAAC;AAMf;4CAC4C;AAC5C,eAAO,MAAM,UAAU,GAAI,OAAO,SACzB,aAAa,WACX,OAAO,KACf,MAAM,CAAC,MAAM,CAAC,OAAO,CAQvB,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,UAAU,GAAI,OAAO,WAAW,OAAO,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAMxE,CAAC;AAIL;6CAC6C;AAC7C,eAAO,MAAM,WAAW,YACb,OAAO,kBACA,MAAM,UACd,MAAM,UACN,MAAM,KACb,IAQF,CAAC;AAoBF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,cACd,OAAO,UACV,MAAM,WACL,MAAM,WACN,MAAM,KACd,MA+BF,CAAC;AAMF;;8DAE8D;AAC9D,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAK7C,CAAC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
// Shared by Board and Sortable, the two users of @foldkit/ui's DragAndDrop: the phase a drag
|
|
3
|
+
// is in, the DragAndDrop Messages both build, what a press lifts, Escape taken before anything
|
|
4
|
+
// else, the lifted copy's measure, and the closest-centre drop target a sortable resolves for
|
|
5
|
+
// a pointer.
|
|
6
|
+
import { DragAndDrop as UiDragAndDrop } from "@foldkit/ui";
|
|
7
|
+
import { Array, Effect, Option, Order, Stream, pipe } from "effect";
|
|
8
|
+
import * as Dom from "foldkit/dom";
|
|
9
|
+
// NOTE: @foldkit/ui gap: DragAndDrop has no accessor for which input holds an item.
|
|
10
|
+
// `ghostStyle` is Some only while a pointer drags, so it tells a pointer drag from a keyboard
|
|
11
|
+
// one.
|
|
12
|
+
export const phaseOf = (dragAndDrop) => {
|
|
13
|
+
if (Option.isNone(UiDragAndDrop.maybeDraggedItemId(dragAndDrop))) {
|
|
14
|
+
return __foldkitBrandViewResult(("Idle"), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#phaseOf");
|
|
15
|
+
}
|
|
16
|
+
else if (!UiDragAndDrop.isDragging(dragAndDrop)) {
|
|
17
|
+
return __foldkitBrandViewResult(("Pressed"), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#phaseOf");
|
|
18
|
+
}
|
|
19
|
+
else if (Option.isSome(UiDragAndDrop.ghostStyle(dragAndDrop))) {
|
|
20
|
+
return __foldkitBrandViewResult(("PointerDragging"), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#phaseOf");
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return __foldkitBrandViewResult(("KeyboardDragging"), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#phaseOf");
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
/** Whether an item is carried, by a pointer or the keyboard. */
|
|
27
|
+
export const isCarrying = (phase) => __foldkitBrandViewResult((phase === "PointerDragging" || phase === "KeyboardDragging"), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#isCarrying");
|
|
28
|
+
// CHILD MESSAGES
|
|
29
|
+
// NOTE: @foldkit/ui gap: DragAndDrop exposes no update capability for a press, a keyboard
|
|
30
|
+
// pick-up, a pointer's move and release, or a cancel, and its `draggable` bundle
|
|
31
|
+
// (`role="option"`, `tabindex`) cannot sit on a grip's button. So Board and Sortable build
|
|
32
|
+
// these child Messages themselves.
|
|
33
|
+
export const pressedDraggable = (fields) =>
|
|
34
|
+
// oxlint-disable-next-line foldkit/no-child-message-construction-in-root
|
|
35
|
+
__foldkitBrandViewResult((UiDragAndDrop.Message.PressedDraggable(fields)), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#pressedDraggable");
|
|
36
|
+
export const activatedKeyboardDrag = (fields) =>
|
|
37
|
+
// oxlint-disable-next-line foldkit/no-child-message-construction-in-root
|
|
38
|
+
__foldkitBrandViewResult((UiDragAndDrop.Message.ActivatedKeyboardDrag(fields)), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#activatedKeyboardDrag");
|
|
39
|
+
export const movedPointer = (fields) =>
|
|
40
|
+
// oxlint-disable-next-line foldkit/no-child-message-construction-in-root
|
|
41
|
+
__foldkitBrandViewResult((UiDragAndDrop.Message.MovedPointer(fields)), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#movedPointer");
|
|
42
|
+
export const releasedPointer = () =>
|
|
43
|
+
// oxlint-disable-next-line foldkit/no-child-message-construction-in-root
|
|
44
|
+
__foldkitBrandViewResult((UiDragAndDrop.Message.ReleasedPointer()), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#releasedPointer");
|
|
45
|
+
export const cancelledDrag = () =>
|
|
46
|
+
// oxlint-disable-next-line foldkit/no-child-message-construction-in-root
|
|
47
|
+
__foldkitBrandViewResult((UiDragAndDrop.Message.CancelledDrag()), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#cancelledDrag");
|
|
48
|
+
// PRESS
|
|
49
|
+
/** The main mouse button, the only one that lifts. */
|
|
50
|
+
export const LEFT_BUTTON = 0;
|
|
51
|
+
/** What a press inside an item may land on without lifting it: its controls, but for the
|
|
52
|
+
* buttons `liftingButtons` (a selector list) names, and anything marked `data-no-lift`. */
|
|
53
|
+
export const innerControls = (liftingButtons) => __foldkitBrandViewResult(([
|
|
54
|
+
"input",
|
|
55
|
+
"textarea",
|
|
56
|
+
"select",
|
|
57
|
+
"a[href]",
|
|
58
|
+
'[contenteditable]:not([contenteditable="false"])',
|
|
59
|
+
`button:not(${liftingButtons})`,
|
|
60
|
+
"[data-no-lift]",
|
|
61
|
+
].join(", ")), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#innerControls");
|
|
62
|
+
// ESCAPE
|
|
63
|
+
// NOTE: @foldkit/ui gap: DragAndDrop's own Escape cancels the move and lets the key travel
|
|
64
|
+
// on, to a dialog around the list. Board and Sortable take the key first and stop it.
|
|
65
|
+
/** Takes a plain Escape for `message` and stops it there, so a dialog around the list or the
|
|
66
|
+
* page's own key bindings never see it. */
|
|
67
|
+
export const takeEscape = (event, message) => {
|
|
68
|
+
if (event.key !== "Escape" || event.isComposing) {
|
|
69
|
+
return __foldkitBrandViewResult((Option.none()), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#takeEscape");
|
|
70
|
+
}
|
|
71
|
+
event.preventDefault();
|
|
72
|
+
event.stopPropagation();
|
|
73
|
+
return __foldkitBrandViewResult((Option.some(message)), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#takeEscape");
|
|
74
|
+
};
|
|
75
|
+
/** Escape on the window, in the capture phase, as `message`. */
|
|
76
|
+
export const escapeKeys = (message) => __foldkitBrandViewResult((Dom.streamFromEventFilterMap({
|
|
77
|
+
target: () => __foldkitBrandViewResult((window), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#target"),
|
|
78
|
+
type: "keydown",
|
|
79
|
+
filterMapEvent: (event) => __foldkitBrandViewResult((takeEscape(event, message)), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#filterMapEvent"),
|
|
80
|
+
options: { capture: true },
|
|
81
|
+
})), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#escapeKeys");
|
|
82
|
+
// LIFTED COPY
|
|
83
|
+
/** Sizes the copy that follows the pointer to the element `sourceSelector` finds, and keeps the
|
|
84
|
+
* pointer where it pressed that element. */
|
|
85
|
+
export const measureLift = (element, sourceSelector, pressX, pressY) => {
|
|
86
|
+
const maybeSource = Option.fromNullishOr(document.querySelector(sourceSelector));
|
|
87
|
+
if (Option.isSome(maybeSource) && element instanceof HTMLElement) {
|
|
88
|
+
const rect = maybeSource.value.getBoundingClientRect();
|
|
89
|
+
element.style.setProperty("--lift-width", `${rect.width}px`);
|
|
90
|
+
element.style.setProperty("--lift-x", `${rect.left - pressX}px`);
|
|
91
|
+
element.style.setProperty("--lift-y", `${rect.top - pressY}px`);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
// POINTER TARGET
|
|
95
|
+
const ROW_TOLERANCE = 1;
|
|
96
|
+
const boxOf = (element) => {
|
|
97
|
+
const rect = element.getBoundingClientRect();
|
|
98
|
+
return __foldkitBrandViewResult(({
|
|
99
|
+
top: rect.top,
|
|
100
|
+
centreX: rect.left + rect.width / 2,
|
|
101
|
+
centreY: rect.top + rect.height / 2,
|
|
102
|
+
}), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#boxOf");
|
|
103
|
+
};
|
|
104
|
+
const isOnSameRow = (box, other) => __foldkitBrandViewResult((Math.abs(other.top - box.top) < ROW_TOLERANCE), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#isOnSameRow");
|
|
105
|
+
/**
|
|
106
|
+
* Where a pointer at (`clientX`, `clientY`) would put the held item among the others in
|
|
107
|
+
* `container` (its `[data-sortable-id]` items, the held one, `heldId`, left out): before or
|
|
108
|
+
* after the item whose centre is closest. Where items sit side by side (two share a top, a
|
|
109
|
+
* wrapping grid, the held one counted) the pointer's side of that centre is read across, and
|
|
110
|
+
* in a column of rows it is read down, so one reading serves a list and a grid.
|
|
111
|
+
*/
|
|
112
|
+
export const insertionIndex = (container, heldId, clientX, clientY) => {
|
|
113
|
+
const items = Array.map(Array.fromIterable(container.querySelectorAll("[data-sortable-id]")), (item) => (__foldkitBrandViewResult(({ id: item.dataset["sortableId"], box: boxOf(item) }), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous")));
|
|
114
|
+
// read with the held item in its place: two tiles side by side are a row even while one of
|
|
115
|
+
// them is held
|
|
116
|
+
const isTiled = Array.some(items, ({ box }, index) => __foldkitBrandViewResult((Option.exists(Array.get(items, index + 1), (next) => __foldkitBrandViewResult((isOnSameRow(box, next.box)), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~3"))), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~2"));
|
|
117
|
+
const boxes = pipe(Array.filter(items, (item) => __foldkitBrandViewResult((item.id !== heldId), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~4")), Array.map(({ box }) => __foldkitBrandViewResult((box), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~5")));
|
|
118
|
+
const distance = (box) => __foldkitBrandViewResult((Math.hypot(box.centreX - clientX, box.centreY - clientY)), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#distance");
|
|
119
|
+
const byDistance = Order.mapInput(Order.Number, ({ box }) => __foldkitBrandViewResult((distance(box)), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~6"));
|
|
120
|
+
return __foldkitBrandViewResult((Array.match(Array.map(boxes, (box, index) => (__foldkitBrandViewResult(({ box, index }), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~7"))), {
|
|
121
|
+
onEmpty: () => __foldkitBrandViewResult((0), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#onEmpty"),
|
|
122
|
+
onNonEmpty: (candidates) => {
|
|
123
|
+
const { box, index } = Array.min(candidates, byDistance);
|
|
124
|
+
const isAfter = isTiled ? clientX > box.centreX : clientY > box.centreY;
|
|
125
|
+
return __foldkitBrandViewResult((isAfter ? index + 1 : index), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#onNonEmpty");
|
|
126
|
+
},
|
|
127
|
+
})), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#insertionIndex");
|
|
128
|
+
};
|
|
129
|
+
// DRAG STYLES
|
|
130
|
+
const DRAGGING_ATTRIBUTE = "data-pixel-paper-dragging";
|
|
131
|
+
/** While a pointer presses or carries an item, the page is marked
|
|
132
|
+
* (`data-pixel-paper-dragging` on the root), so the stylesheet prints the grabbing cursor and
|
|
133
|
+
* holds text selection, with no style element of its own. */
|
|
134
|
+
export const markDragging = Stream.callback(() => __foldkitBrandViewResult((Effect.acquireRelease(Effect.sync(() => __foldkitBrandViewResult((document.documentElement.setAttribute(DRAGGING_ATTRIBUTE, "")), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~9")), () => __foldkitBrandViewResult((Effect.sync(() => __foldkitBrandViewResult((document.documentElement.removeAttribute(DRAGGING_ATTRIBUTE)), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~11"))), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~10")).pipe(Effect.flatMap(() => __foldkitBrandViewResult((Effect.never), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~12")))), "@gjermundgaraba-designs/pixel-paper/src/drag/drag.js#anonymous~8"));
|
|
@@ -3,10 +3,12 @@ import type { Html, HtmlBuilder } from "foldkit/html";
|
|
|
3
3
|
export type ViewConfig = Readonly<{
|
|
4
4
|
/** Pixel caps: what is missing (`"Nothing queued"`). */
|
|
5
5
|
title: string;
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
|
|
6
|
+
/** The title's element, which looks the same either way. A heading at this level where the
|
|
7
|
+
* empty state is the page's or a section's main content: `3` inside a Panel, whose title is
|
|
8
|
+
* an `h2`; `1` for a gate or a missing page. `"Strong"` where it is not (a chart with no
|
|
9
|
+
* data, a picture of the state). Required, because the two look alike and only the outline
|
|
10
|
+
* tells them apart. */
|
|
11
|
+
headingLevel: 1 | 2 | 3 | 4 | 5 | 6 | "Strong";
|
|
10
12
|
/** One sentence: how it gets filled. */
|
|
11
13
|
body?: ReadonlyArray<Html | string>;
|
|
12
14
|
/** What fills it: a button under the sentence. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emptyState.d.ts","sourceRoot":"","sources":["../../../src/emptyState/emptyState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAItD,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd
|
|
1
|
+
{"version":3,"file":"emptyState.d.ts","sourceRoot":"","sources":["../../../src/emptyState/emptyState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAItD,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd;;;;4BAIwB;IACxB,YAAY,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;IAC/C,wCAAwC;IACxC,IAAI,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACpC,kDAAkD;IAClD,OAAO,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;CACxC,CAAC,CAAC;AAEH,yFAAyF;AACzF,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAa3E,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { Array } from "effect";
|
|
|
4
4
|
export const view = (config, h) => {
|
|
5
5
|
const { title, headingLevel, body = [], actions = [] } = config;
|
|
6
6
|
return __foldkitBrandViewResult((h.div([h.Class("empty")], [
|
|
7
|
-
headingLevel ===
|
|
7
|
+
headingLevel === "Strong"
|
|
8
8
|
? h.strong([h.Class("empty-title")], [title])
|
|
9
9
|
: h[`h${headingLevel}`]([h.Class("empty-title")], [title]),
|
|
10
10
|
...Array.match(body, { onEmpty: () => __foldkitBrandViewResult(([]), "@gjermundgaraba-designs/pixel-paper/src/emptyState/emptyState.js#onEmpty"), onNonEmpty: (sentence) => __foldkitBrandViewResult(([h.p([], sentence)]), "@gjermundgaraba-designs/pixel-paper/src/emptyState/emptyState.js#onNonEmpty") }),
|
|
@@ -29,7 +29,7 @@ export type ViewConfig = Readonly<{
|
|
|
29
29
|
* busy) is a failed submit like any other: render the summary from it and focus it.
|
|
30
30
|
*
|
|
31
31
|
* Each link is a fragment link to its field; a Foldkit application's fragment handler moves
|
|
32
|
-
* focus there (
|
|
32
|
+
* focus there (`SkipLink.ScrollToFragment`).
|
|
33
33
|
*/
|
|
34
34
|
export declare const view: <Message>(config: ViewConfig, h: HtmlBuilder<Message>) => Html;
|
|
35
35
|
//# sourceMappingURL=errorSummary.d.ts.map
|