@gjermundgaraba-designs/pixel-paper 0.22.1 → 0.23.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 +14 -14
- package/dist/src/adapters/mermaid.d.ts.map +1 -1
- package/dist/src/adapters/mermaid.js +0 -24
- package/dist/src/announcer/announcer.d.ts.map +1 -1
- package/dist/src/announcer/announcer.js +12 -12
- package/dist/src/board/board.d.ts +0 -10
- package/dist/src/board/board.d.ts.map +1 -1
- package/dist/src/board/board.js +36 -64
- package/dist/src/board/index.d.ts +2 -1
- package/dist/src/board/index.d.ts.map +1 -1
- package/dist/src/board/index.js +2 -1
- package/dist/src/button/button.d.ts +1 -1
- package/dist/src/button/button.d.ts.map +1 -1
- package/dist/src/chip/chip.d.ts.map +1 -1
- package/dist/src/chip/chip.js +1 -8
- package/dist/src/commandPalette/commandPalette.d.ts.map +1 -1
- package/dist/src/commandPalette/commandPalette.js +78 -83
- package/dist/src/commandPalette/keys.d.ts +2 -2
- package/dist/src/commandPalette/keys.d.ts.map +1 -1
- package/dist/src/commandPalette/keys.js +2 -4
- package/dist/src/commandPalette/match.d.ts.map +1 -1
- package/dist/src/commandPalette/match.js +2 -2
- package/dist/src/confirmDialog/confirmDialog.d.ts.map +1 -1
- package/dist/src/confirmDialog/confirmDialog.js +1 -2
- package/dist/src/copyButton/copyButton.d.ts +0 -5
- package/dist/src/copyButton/copyButton.d.ts.map +1 -1
- package/dist/src/copyButton/copyButton.js +2 -2
- package/dist/src/crumbs/crumbs.d.ts +0 -2
- package/dist/src/crumbs/crumbs.d.ts.map +1 -1
- package/dist/src/crumbs/crumbs.js +2 -2
- package/dist/src/dialog/dialog.d.ts +2 -0
- package/dist/src/dialog/dialog.d.ts.map +1 -1
- package/dist/src/dialog/dialog.js +3 -2
- package/dist/src/drag/drag.d.ts +28 -3
- package/dist/src/drag/drag.d.ts.map +1 -1
- package/dist/src/drag/drag.js +39 -17
- package/dist/src/editableTitle/editableTitle.d.ts +4 -4
- package/dist/src/field/field.d.ts +7 -1
- package/dist/src/field/field.d.ts.map +1 -1
- package/dist/src/field/field.js +14 -6
- package/dist/src/fieldset/fieldset.d.ts.map +1 -1
- package/dist/src/fieldset/fieldset.js +2 -4
- package/dist/src/fileTree/fileTree.d.ts.map +1 -1
- package/dist/src/fileTree/fileTree.js +16 -16
- package/dist/src/inlineInput/inlineInput.d.ts +4 -0
- package/dist/src/inlineInput/inlineInput.d.ts.map +1 -1
- package/dist/src/inlineInput/inlineInput.js +9 -6
- package/dist/src/keyHelp/index.d.ts +1 -1
- package/dist/src/keyHelp/index.d.ts.map +1 -1
- package/dist/src/keyHelp/index.js +1 -1
- package/dist/src/keyHelp/keyHelp.d.ts +1 -3
- package/dist/src/keyHelp/keyHelp.d.ts.map +1 -1
- package/dist/src/keyHelp/keyHelp.js +3 -6
- package/dist/src/keyHint/keyLabel.d.ts +2 -0
- package/dist/src/keyHint/keyLabel.d.ts.map +1 -1
- package/dist/src/keyHint/keyLabel.js +3 -2
- package/dist/src/lineDiff/diff.d.ts +6 -3
- package/dist/src/lineDiff/diff.d.ts.map +1 -1
- package/dist/src/lineDiff/diff.js +40 -28
- package/dist/src/lineDiff/patch.d.ts.map +1 -1
- package/dist/src/lineDiff/patch.js +18 -13
- package/dist/src/linkState/linkState.d.ts.map +1 -1
- package/dist/src/linkState/linkState.js +1 -7
- package/dist/src/menu/slip.js +2 -2
- package/dist/src/meter/meter.d.ts.map +1 -1
- package/dist/src/meter/meter.js +22 -17
- package/dist/src/notice/notice.d.ts +2 -0
- package/dist/src/notice/notice.d.ts.map +1 -1
- package/dist/src/notice/notice.js +2 -1
- package/dist/src/passwordField/passwordField.d.ts.map +1 -1
- package/dist/src/passwordField/passwordField.js +3 -7
- package/dist/src/rail/rail.d.ts +17 -3
- package/dist/src/rail/rail.d.ts.map +1 -1
- package/dist/src/rail/rail.js +7 -7
- package/dist/src/reel/layout.d.ts +9 -5
- package/dist/src/reel/layout.d.ts.map +1 -1
- package/dist/src/reel/layout.js +12 -6
- package/dist/src/reel/reel.d.ts.map +1 -1
- package/dist/src/reel/reel.js +131 -75
- package/dist/src/scheme/scheme.d.ts +1 -1
- package/dist/src/scheme/scheme.d.ts.map +1 -1
- package/dist/src/segmented/segmented.d.ts +0 -3
- package/dist/src/segmented/segmented.d.ts.map +1 -1
- package/dist/src/segmented/segmented.js +1 -6
- package/dist/src/selectField/selectField.d.ts.map +1 -1
- package/dist/src/selectField/selectField.js +3 -10
- package/dist/src/sortable/index.d.ts +1 -1
- package/dist/src/sortable/index.d.ts.map +1 -1
- package/dist/src/sortable/index.js +1 -1
- package/dist/src/sortable/sortable.d.ts +40 -49
- package/dist/src/sortable/sortable.d.ts.map +1 -1
- package/dist/src/sortable/sortable.js +41 -54
- package/dist/src/stack/stack.d.ts +1 -1
- package/dist/src/stack/stack.d.ts.map +1 -1
- package/dist/src/stack/stack.js +1 -1
- package/dist/src/tabs/tabs.d.ts +1 -1
- package/dist/src/tabs/tabs.d.ts.map +1 -1
- package/dist/src/tabs/tabs.js +1 -1
- package/dist/src/textareaField/textareaField.d.ts.map +1 -1
- package/dist/src/textareaField/textareaField.js +3 -7
- package/dist/src/time/time.d.ts.map +1 -1
- package/dist/src/time/time.js +4 -2
- package/dist/src/tips/index.d.ts +1 -1
- package/dist/src/tips/index.d.ts.map +1 -1
- package/dist/src/toast/index.d.ts +1 -1
- package/dist/src/toast/index.d.ts.map +1 -1
- package/dist/src/toast/toast.d.ts +5 -5
- package/dist/src/toast/toast.d.ts.map +1 -1
- package/dist/src/toast/toast.js +1 -6
- package/dist/src/toolbar/toolbar.d.ts +0 -3
- package/dist/src/toolbar/toolbar.d.ts.map +1 -1
- package/dist/src/toolbar/toolbar.js +1 -2
- package/package.json +1 -1
- package/src/adapters/mermaid.ts +0 -24
- package/src/announcer/announcer.ts +13 -17
- package/src/board/board.ts +32 -80
- package/src/board/index.ts +1 -1
- package/src/button/button.ts +1 -1
- package/src/chip/chip.ts +1 -9
- package/src/commandPalette/commandPalette.ts +21 -38
- package/src/commandPalette/keys.ts +2 -4
- package/src/commandPalette/match.ts +3 -3
- package/src/confirmDialog/confirmDialog.ts +5 -3
- package/src/copyButton/copyButton.ts +2 -5
- package/src/crumbs/crumbs.ts +2 -4
- package/src/dialog/dialog.ts +3 -2
- package/src/drag/drag.ts +55 -6
- package/src/field/field.ts +29 -7
- package/src/fieldset/fieldset.ts +2 -4
- package/src/fileTree/fileTree.ts +10 -12
- package/src/inlineInput/inlineInput.ts +11 -2
- package/src/keyHelp/index.ts +0 -1
- package/src/keyHelp/keyHelp.ts +3 -9
- package/src/keyHint/keyLabel.ts +5 -2
- package/src/lineDiff/diff.ts +70 -54
- package/src/lineDiff/patch.ts +27 -14
- package/src/linkState/linkState.ts +1 -8
- package/src/menu/slip.ts +2 -2
- package/src/meter/meter.ts +25 -15
- package/src/notice/notice.ts +2 -1
- package/src/passwordField/passwordField.ts +3 -7
- package/src/pixel-paper.css +84 -133
- package/src/rail/rail.ts +9 -7
- package/src/reel/layout.ts +20 -15
- package/src/reel/reel.ts +146 -77
- package/src/scheme/scheme.ts +1 -1
- package/src/segmented/segmented.ts +1 -9
- package/src/selectField/selectField.ts +3 -10
- package/src/sortable/index.ts +0 -1
- package/src/sortable/sortable.ts +42 -63
- package/src/stack/stack.ts +1 -1
- package/src/tabs/tabs.ts +1 -1
- package/src/textareaField/textareaField.ts +3 -7
- package/src/time/time.ts +6 -7
- package/src/tips/index.ts +1 -1
- package/src/toast/index.ts +1 -1
- package/src/toast/toast.ts +2 -8
- package/src/tokens.css +6 -0
- package/src/toolbar/toolbar.ts +0 -5
- package/dist/src/inlineInput/inline.d.ts +0 -6
- package/dist/src/inlineInput/inline.d.ts.map +0 -1
- package/dist/src/inlineInput/inline.js +0 -7
- package/src/inlineInput/inline.ts +0 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textareaField.d.ts","sourceRoot":"","sources":["../../../src/textareaField/textareaField.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAMzF,gEAAgE;AAChE,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;uCAEmC;IACnC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,yFAAyF;IACzF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;uDACmD;IACnD,kBAAkB,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,CAAC;CACjF,CAAC,CAAC;AAEH;;;2EAG2E;AAC3E,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,
|
|
1
|
+
{"version":3,"file":"textareaField.d.ts","sourceRoot":"","sources":["../../../src/textareaField/textareaField.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAMzF,gEAAgE;AAChE,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;uCAEmC;IACnC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,yFAAyF;IACzF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;uDACmD;IACnD,kBAAkB,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,CAAC;CACjF,CAAC,CAAC;AAEH;;;2EAG2E;AAC3E,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAuCpF,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
2
|
import { Textarea as UiTextarea } from "@foldkit/ui";
|
|
3
|
-
import {
|
|
3
|
+
import { controlAttributes, errorView, helpView } from "../field/field.js";
|
|
4
4
|
/** A labelled textarea with its help line, built on `@foldkit/ui`'s `Textarea`: the label
|
|
5
5
|
* names the textarea, the help line describes it (`aria-describedby`), an `error` sets
|
|
6
6
|
* `aria-invalid` and describes it before the help, and `isRequired` sets `aria-required`.
|
|
@@ -16,17 +16,13 @@ export const view = (config, h) => {
|
|
|
16
16
|
...(rows !== undefined && { rows }),
|
|
17
17
|
toView: (groups) => __foldkitBrandViewResult((h.div([h.Class(`field${isMono ? " mono" : ""}`)], [
|
|
18
18
|
h.label(groups.label, [label]),
|
|
19
|
-
// NOTE: @foldkit/ui gap: Textarea has no required option, so the wrapper says it.
|
|
20
19
|
h.textarea([
|
|
21
20
|
...textareaAttributes,
|
|
22
21
|
...groups.textarea,
|
|
23
|
-
...
|
|
24
|
-
...(isRequired ? [h.AriaRequired(true)] : []),
|
|
22
|
+
...controlAttributes(id, error, help, isRequired, h),
|
|
25
23
|
]),
|
|
26
24
|
...errorView(id, error, h),
|
|
27
|
-
...(help
|
|
28
|
-
? []
|
|
29
|
-
: [h.p([...groups.description, h.Class("field-help")], [help])]),
|
|
25
|
+
...helpView(help, groups.description, h),
|
|
30
26
|
])), "@gjermundgaraba-designs/pixel-paper/src/textareaField/textareaField.js#toView"),
|
|
31
27
|
}, h)), "@gjermundgaraba-designs/pixel-paper/src/textareaField/textareaField.js#view");
|
|
32
28
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../../src/time/time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,QAAQ,
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../../src/time/time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,QAAQ,EAAS,MAAM,EAAY,MAAM,EAAU,MAAM,QAAQ,CAAC;AAClF,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAMlE;;YAEY;AACZ,eAAO,MAAM,UAAU,uEAA+D,CAAC;AACvF,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;AAUhD,wDAAwD;AACxD,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;2CAEuC;IACvC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,UAAU,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC;CAChC,CAAC,CAAC;AAqDH;oFACoF;AACpF,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAc3E,CAAC;AAMF,8DAA8D;AAC9D,MAAM,MAAM,WAAW,CAAC,KAAK,EAAE,OAAO,IAAI,QAAQ,CAAC;IACjD,kFAAkF;IAClF,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;IACpC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACrC,CAAC,CAAC;AAEH;;;sBAGsB;AACtB,eAAO,MAAM,UAAU,GAAI,KAAK,EAAE,OAAO,UAC/B,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,KAClC,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,EAAE,KAAK,CAS7E,CAAC"}
|
package/dist/src/time/time.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
-
import { Clock, Duration,
|
|
2
|
+
import { Clock, Duration, Match, Option, Schedule, Schema, Stream } from "effect";
|
|
3
3
|
import { formatDate, formatDateTime, formatRemaining, formatSpan } from "../format/format.js";
|
|
4
4
|
// FORMAT
|
|
5
5
|
/** How a moment is said. `Age`: `"19d"`, the age register. `Ago`: `"4m ago"`. `Until`:
|
|
@@ -57,5 +57,7 @@ const TICK = Duration.seconds(1);
|
|
|
57
57
|
export const clockEntry = (config) => (__foldkitBrandViewResult(({
|
|
58
58
|
dependenciesSchema: Schema.Struct({ isActive: Schema.Boolean }),
|
|
59
59
|
modelToDependencies: (model) => (__foldkitBrandViewResult(({ isActive: config.isActive(model) }), "@gjermundgaraba-designs/pixel-paper/src/time/time.js#modelToDependencies")),
|
|
60
|
-
dependenciesToStream: ({ isActive }) => __foldkitBrandViewResult((
|
|
60
|
+
dependenciesToStream: ({ isActive }) => __foldkitBrandViewResult((isActive
|
|
61
|
+
? Stream.fromEffectSchedule(Clock.currentTimeMillis, Schedule.spaced(TICK)).pipe(Stream.map(config.toMessage))
|
|
62
|
+
: Stream.empty), "@gjermundgaraba-designs/pixel-paper/src/time/time.js#dependenciesToStream"),
|
|
61
63
|
}), "@gjermundgaraba-designs/pixel-paper/src/time/time.js#clockEntry"));
|
package/dist/src/tips/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { HideTip, Message, Model, ShowTip, WaitBeforeCooling, WaitBeforeHiding, WaitBeforeShowing, id, init, subscriptions, update, view, } from "./tips.ts";
|
|
2
|
-
export type { InitConfig
|
|
2
|
+
export type { InitConfig } from "./tips.ts";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tips/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,OAAO,EACP,KAAK,EACL,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,EAAE,EACF,IAAI,EACJ,aAAa,EACb,MAAM,EACN,IAAI,GACL,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tips/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,OAAO,EACP,KAAK,EACL,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,EAAE,EACF,IAAI,EACJ,aAAa,EACb,MAAM,EACN,IAAI,GACL,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { AnnounceSlip, BindStack, FocusSlip, Message, Model, OutMessage, dismiss, id, init, sceneMounts, show, update, view, } from "./toast.ts";
|
|
2
|
-
export type { InitConfig, ShowConfig
|
|
2
|
+
export type { InitConfig, ShowConfig } from "./toast.ts";
|
|
3
3
|
export type { Action, Tone } from "./stack.ts";
|
|
4
4
|
export { Focus } from "../focus/focus.ts";
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/toast/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,SAAS,EACT,OAAO,EACP,KAAK,EACL,UAAU,EACV,OAAO,EACP,EAAE,EACF,IAAI,EACJ,WAAW,EACX,IAAI,EACJ,MAAM,EACN,IAAI,GACL,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/toast/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,SAAS,EACT,OAAO,EACP,KAAK,EACL,UAAU,EACV,OAAO,EACP,EAAE,EACF,IAAI,EACJ,WAAW,EACX,IAAI,EACJ,MAAM,EACN,IAAI,GACL,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -326,8 +326,6 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
326
326
|
readonly pendingDismissVersion: number;
|
|
327
327
|
readonly isHovered: boolean;
|
|
328
328
|
readonly swipeState: {
|
|
329
|
-
readonly _tag: "Idle";
|
|
330
|
-
} | {
|
|
331
329
|
readonly _tag: "Dismissing";
|
|
332
330
|
readonly offsetX: number;
|
|
333
331
|
readonly direction: "Left" | "Right";
|
|
@@ -336,6 +334,8 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
336
334
|
readonly pointerId: number;
|
|
337
335
|
readonly startX: number;
|
|
338
336
|
readonly currentX: number;
|
|
337
|
+
} | {
|
|
338
|
+
readonly _tag: "Idle";
|
|
339
339
|
} | {
|
|
340
340
|
readonly _tag: "Settling";
|
|
341
341
|
readonly offsetX: number;
|
|
@@ -421,7 +421,7 @@ export type ShowConfig = Readonly<{
|
|
|
421
421
|
}>;
|
|
422
422
|
/** What `show` returns: the next Model and Commands, and the new slip's id, to take it back
|
|
423
423
|
* with `dismiss`. */
|
|
424
|
-
|
|
424
|
+
type ShowReturn = Update.Return<Model, Message> & Readonly<{
|
|
425
425
|
entryId: string;
|
|
426
426
|
}>;
|
|
427
427
|
/**
|
|
@@ -557,8 +557,6 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
557
557
|
readonly pendingDismissVersion: number;
|
|
558
558
|
readonly isHovered: boolean;
|
|
559
559
|
readonly swipeState: {
|
|
560
|
-
readonly _tag: "Idle";
|
|
561
|
-
} | {
|
|
562
560
|
readonly _tag: "Dismissing";
|
|
563
561
|
readonly offsetX: number;
|
|
564
562
|
readonly direction: "Left" | "Right";
|
|
@@ -567,6 +565,8 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
567
565
|
readonly pointerId: number;
|
|
568
566
|
readonly startX: number;
|
|
569
567
|
readonly currentX: number;
|
|
568
|
+
} | {
|
|
569
|
+
readonly _tag: "Idle";
|
|
570
570
|
} | {
|
|
571
571
|
readonly _tag: "Settling";
|
|
572
572
|
readonly offsetX: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../../src/toast/toast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,QAAQ,EAAE,MAAM,EAAS,MAAM,EAAE,MAAM,EAAgB,MAAM,QAAQ,CAAC;AACtF,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAC;AAI3C,OAAO,KAAK,KAAK,MAAM,eAAe,CAAC;AAIvC,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AASzC,OAAO,EAAE,MAAM,EAAgB,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAI7D;;wDAEwD;AACxD,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKhB,CAAC;AACH,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAItC,yDAAyD;AACzD,eAAO,MAAM,OAAO;;QACC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QACV,WAAW;;;;;;QAIV,OAAO;QAAiB,MAAM;;;;;;QAC7B,OAAO;;;;;EAIzB,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAI1C;yDACyD;AACzD,eAAO,MAAM,UAAU;;QACH,EAAE;QAAiB,OAAO;;EAC5C,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;AAWhD;gBACgB;AAChB,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAElD,oCAAoC;AACpC,eAAO,MAAM,IAAI,WAAY,UAAU,KAAG,KAKxC,CAAC;AAIH,8CAA8C;AAC9C,eAAO,MAAM,EAAE,UAAW,KAAK,KAAG,MAAwB,CAAC;AAU3D,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AA2EhD;uCACuC;AACvC,eAAO,MAAM,SAAS;;;;iBAQpB,CAAC;AASH;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY;;;;;iBAiBvB,CAAC;AAgCH,2FAA2F;AAC3F,eAAO,MAAM,MAAM,UAAW,KAAK,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCjD,CAAC;AAEL,0BAA0B;AAC1B,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,IAAI,EAAE,IAAI,CAAC;IACX,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAOH;sBACsB;AACtB,
|
|
1
|
+
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../../src/toast/toast.ts"],"names":[],"mappings":"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"}
|
package/dist/src/toast/toast.js
CHANGED
|
@@ -215,14 +215,9 @@ export const show = (model, config) => {
|
|
|
215
215
|
/** Takes a slip back by its id: what it reported has recovered. */
|
|
216
216
|
export const dismiss = (model, entryId) => __foldkitBrandViewResult((dismissKeepingFocus(model, entryId)), "@gjermundgaraba-designs/pixel-paper/src/toast/toast.js#dismiss");
|
|
217
217
|
// VIEW
|
|
218
|
-
const TONE_CLASS = {
|
|
219
|
-
Ok: "notice toast ok",
|
|
220
|
-
Error: "notice toast error",
|
|
221
|
-
Quiet: "notice toast quiet",
|
|
222
|
-
};
|
|
223
218
|
const slipView = (entry, h) => {
|
|
224
219
|
const { tone, title, maybeBody, maybeAction } = entry.payload;
|
|
225
|
-
return __foldkitBrandViewResult((h.div([h.Class(TONE_CLASS[tone])], [
|
|
220
|
+
return __foldkitBrandViewResult((h.div([h.Class(`notice toast${Notice.TONE_CLASS[tone]}`)], [
|
|
226
221
|
Notice.toneGlyphView({ tone }, h),
|
|
227
222
|
h.div([], [h.strong([], [title]), ...Option.toArray(maybeBody)]),
|
|
228
223
|
...Array.fromOption(Option.map(maybeAction, (action) => __foldkitBrandViewResult((Button.view({
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
2
|
import type { Html, HtmlBuilder } from "foldkit/html";
|
|
3
3
|
import * as Mount from "foldkit/mount";
|
|
4
|
-
import type { Attributes } from "../attributes/attributes.ts";
|
|
5
4
|
/** Which way the strip lies. A `Vertical` strip stands on end: a canvas's tools down its left
|
|
6
5
|
* edge. The arrows of both axes move in either. */
|
|
7
6
|
export declare const Orientation: Schema.Literals<readonly ["Horizontal", "Vertical"]>;
|
|
@@ -38,8 +37,6 @@ export type ViewConfig<ParentMessage> = Readonly<{
|
|
|
38
37
|
* Scene, resolve the Mount by name with the lifted Message:
|
|
39
38
|
* `Scene.Mount.resolve({ name: Toolbar.BindToolKeys.name }, toParentMessage(Toolbar.Message.MovedToolFocus({ move })))`. */
|
|
40
39
|
toParentMessage: (message: Message) => ParentMessage;
|
|
41
|
-
/** Further attributes for the toolbar, never a class. */
|
|
42
|
-
attributes?: Attributes<ParentMessage>;
|
|
43
40
|
}>;
|
|
44
41
|
/** A strip of tools that is one stop for Tab (`role="toolbar"`, named by its label, with its
|
|
45
42
|
* `aria-orientation`): the arrows move between the tools and stop at the ends, Home and End
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/toolbar/toolbar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAEpF,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,KAAK,KAAK,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../../src/toolbar/toolbar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAEpF,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,KAAK,KAAK,MAAM,eAAe,CAAC;AAMvC;oDACoD;AACpD,eAAO,MAAM,WAAW,sDAA8C,CAAC;AACvE,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC;AAQlD,6FAA6F;AAC7F,eAAO,MAAM,OAAO;;QAA0C,IAAI;;EAAe,CAAC;AAClF,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAsG1C;;;;;;yDAMyD;AACzD,eAAO,MAAM,YAAY;;;EAuBvB,CAAC;AAIH,yDAAyD;AACzD,MAAM,MAAM,UAAU,CAAC,aAAa,IAAI,QAAQ,CAAC;IAC/C,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;iIAG6H;IAC7H,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,aAAa,CAAC;CACtD,CAAC,CAAC;AAEH;;gEAEgE;AAChE,eAAO,MAAM,IAAI,GAAI,aAAa,UACxB,UAAU,CAAC,aAAa,CAAC,KAC9B,WAAW,CAAC,aAAa,CAAC,KAC5B,IAmBF,CAAC"}
|
|
@@ -90,9 +90,8 @@ export const BindToolKeys = Mount.defineStream("BindToolKeys", {
|
|
|
90
90
|
* `aria-orientation`): the arrows move between the tools and stop at the ends, Home and End
|
|
91
91
|
* go to the ends, and Tab comes back to the tool used last. */
|
|
92
92
|
export const view = (config, h) => {
|
|
93
|
-
const { label, tools: toolViews, orientation = "Horizontal", isFloating = false, toParentMessage,
|
|
93
|
+
const { label, tools: toolViews, orientation = "Horizontal", isFloating = false, toParentMessage, } = config;
|
|
94
94
|
return __foldkitBrandViewResult((h.div([
|
|
95
|
-
...attributes,
|
|
96
95
|
h.Role("toolbar"),
|
|
97
96
|
h.AriaLabel(label),
|
|
98
97
|
h.AriaOrientation(orientation === "Vertical" ? "vertical" : "horizontal"),
|
package/package.json
CHANGED
package/src/adapters/mermaid.ts
CHANGED
|
@@ -2,30 +2,6 @@
|
|
|
2
2
|
// faces, in the page's palette. An optional entry point ("./adapters/mermaid"):
|
|
3
3
|
// mermaid is the adopter's own dependency, loaded here only when a diagram is drawn.
|
|
4
4
|
//
|
|
5
|
-
// `view` renders the diagram's box and draws into it from a Mount (`DrawDiagram`), so it
|
|
6
|
-
// needs the DOM only once the box is on the page, never while rendering on the server. The
|
|
7
|
-
// box is keyed by the palette the page prints in, from the application's SchemeSwitch
|
|
8
|
-
// (`Scheme.SchemeSwitch.palette`, which under "System" follows the reader's system as it
|
|
9
|
-
// changes), so a new palette mounts a new box and draws the diagram again; a new source does
|
|
10
|
-
// the same. The box reports `SucceededDrawDiagram`, `FailedLoadMermaid` or `FailedDrawDiagram`
|
|
11
|
-
// through the caller's `toParentMessage`, and the caller keeps what it shows meanwhile (a
|
|
12
|
-
// Loading line, an error Notice) in its own Model:
|
|
13
|
-
//
|
|
14
|
-
// Mermaid.view(
|
|
15
|
-
// {
|
|
16
|
-
// source,
|
|
17
|
-
// palette: Scheme.SchemeSwitch.palette(model.schemeSwitch),
|
|
18
|
-
// toParentMessage: (message) => GotDiagramMessage({ message }),
|
|
19
|
-
// },
|
|
20
|
-
// h,
|
|
21
|
-
// );
|
|
22
|
-
//
|
|
23
|
-
// `renderDiagram` waits for the faces, so words are measured in them and not a fallback;
|
|
24
|
-
// renders in the box (it must be on the page), so labels are measured where they will print;
|
|
25
|
-
// and returns the SVG. Mermaid's settings are global, so draws run one at a time. It fails with
|
|
26
|
-
// `MermaidMissing` when mermaid itself does not load, and with `DiagramError` when mermaid
|
|
27
|
-
// loads but the diagram is not drawn.
|
|
28
|
-
//
|
|
29
5
|
// Two layers. themeCSS repaints with var(…), so the parts it names (nodes, edges, labels,
|
|
30
6
|
// clusters, actors, messages, notes) follow a palette switch in place. themeVariables must be
|
|
31
7
|
// colours, not var() strings (mermaid mixes its own shades from them), so they are read from
|
|
@@ -35,7 +35,7 @@ export const view = <Message>(h: HtmlBuilder<Message>): Html =>
|
|
|
35
35
|
h.Class("sr-only"),
|
|
36
36
|
h.Role("status"),
|
|
37
37
|
h.AriaLive("polite"),
|
|
38
|
-
h.
|
|
38
|
+
h.Attribute(ANNOUNCER_ATTRIBUTE, ""),
|
|
39
39
|
]);
|
|
40
40
|
|
|
41
41
|
// ANNOUNCE
|
|
@@ -97,28 +97,21 @@ export const announce = (text: string): Effect.Effect<void> =>
|
|
|
97
97
|
// FLASH
|
|
98
98
|
|
|
99
99
|
const FLASH_ID = "pixel-paper-flash";
|
|
100
|
-
const DEFAULT_BEAT = Duration.millis(700);
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
/** The beat in milliseconds, from the stylesheet's `--motion-flash`: none on a page that has
|
|
102
|
+
* not loaded the stylesheet, which has nothing to flash with. */
|
|
103
|
+
const beatOf = (element: Element): Option.Option<number> => {
|
|
104
|
+
const time = getComputedStyle(element).getPropertyValue("--motion-flash").trim();
|
|
105
|
+
return pipe(
|
|
104
106
|
Option.liftPredicate(Number.parseFloat(time), Number.isFinite),
|
|
105
107
|
Option.map((value) => (time.endsWith("ms") ? value : value * 1000)),
|
|
106
108
|
);
|
|
107
|
-
|
|
108
|
-
const beatOf = (element: Element): number =>
|
|
109
|
-
Option.getOrElse(
|
|
110
|
-
toMillis(getComputedStyle(element).getPropertyValue("--motion-flash").trim()),
|
|
111
|
-
() => Duration.toMillis(DEFAULT_BEAT),
|
|
112
|
-
);
|
|
109
|
+
};
|
|
113
110
|
|
|
114
111
|
const prefersReducedMotion = (): boolean =>
|
|
115
112
|
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
116
113
|
|
|
117
|
-
const runFlash = (element: Element): void => {
|
|
118
|
-
if (!("animate" in element)) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
const beat = beatOf(element);
|
|
114
|
+
const runFlash = (element: Element, beat: number): void => {
|
|
122
115
|
Array.forEach(
|
|
123
116
|
Array.filter(element.getAnimations(), (animation) => animation.id === FLASH_ID),
|
|
124
117
|
(animation) => animation.cancel(),
|
|
@@ -141,8 +134,11 @@ const runFlash = (element: Element): void => {
|
|
|
141
134
|
export const flash = (selector: string): Effect.Effect<void> =>
|
|
142
135
|
Effect.sync(() => {
|
|
143
136
|
const maybeElement = Option.fromNullishOr(document.querySelector(selector));
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
const maybeFlash = Option.flatMap(maybeElement, (element) =>
|
|
138
|
+
Option.map(beatOf(element), (beat) => ({ element, beat })),
|
|
139
|
+
);
|
|
140
|
+
if (Option.isSome(maybeFlash)) {
|
|
141
|
+
runFlash(maybeFlash.value.element, maybeFlash.value.beat);
|
|
146
142
|
}
|
|
147
143
|
});
|
|
148
144
|
|
package/src/board/board.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Button as UiButton, DragAndDrop as UiDragAndDrop } from "@foldkit/ui";
|
|
2
|
-
import { Array, Effect, Equal, Match, Option, Schema,
|
|
2
|
+
import { Array, Effect, Equal, Match, Option, Schema, pipe } from "effect";
|
|
3
3
|
import * as Command from "foldkit/command";
|
|
4
4
|
import {
|
|
5
5
|
type Attribute,
|
|
@@ -26,13 +26,15 @@ import { prefixKeys } from "../subscription/prefixKeys.ts";
|
|
|
26
26
|
import {
|
|
27
27
|
LEFT_BUTTON,
|
|
28
28
|
activatedKeyboardDrag,
|
|
29
|
+
canLift,
|
|
29
30
|
cancelledDrag,
|
|
30
|
-
|
|
31
|
+
escapeSubscriptions,
|
|
31
32
|
innerControls,
|
|
32
33
|
isCarrying,
|
|
33
34
|
measureLift,
|
|
34
35
|
phaseOf,
|
|
35
36
|
pressedDraggable,
|
|
37
|
+
settle as settleDrag,
|
|
36
38
|
} from "../drag/drag.ts";
|
|
37
39
|
|
|
38
40
|
// MODEL
|
|
@@ -50,19 +52,20 @@ export const Column = Schema.Struct({
|
|
|
50
52
|
});
|
|
51
53
|
export type Column = typeof Column.Type;
|
|
52
54
|
|
|
55
|
+
/** How the keyboard carries what it holds: said on the grip and once it is picked up. */
|
|
56
|
+
const KEYBOARD_MOVES = "Arrow keys move it to another column, space drops it, escape cancels.";
|
|
57
|
+
|
|
53
58
|
/** The words a board says. `{card}` stands for the card's label and `{column}` for a
|
|
54
59
|
* column's title. */
|
|
55
60
|
const COPY = {
|
|
56
61
|
/** The grip's name. */
|
|
57
62
|
gripLabel: "Move {card}",
|
|
58
63
|
/** What the grip describes: how to move a card from the keyboard. */
|
|
59
|
-
gripHelp:
|
|
60
|
-
"Press space to pick the card up. Arrow keys move it to another column, space drops it, escape cancels.",
|
|
64
|
+
gripHelp: `Press space to pick the card up. ${KEYBOARD_MOVES}`,
|
|
61
65
|
/** A pointer has lifted the card. */
|
|
62
66
|
pickedUp: "Picked up {card}.",
|
|
63
67
|
/** The keyboard has lifted the card: say how to go on. */
|
|
64
|
-
pickedUpByKeyboard:
|
|
65
|
-
"Picked up {card}. Arrow keys move it to another column, space drops it, escape cancels.",
|
|
68
|
+
pickedUpByKeyboard: `Picked up {card}. ${KEYBOARD_MOVES}`,
|
|
66
69
|
/** The held card is over another column. */
|
|
67
70
|
over: "{card} is over {column}.",
|
|
68
71
|
/** The card was dropped in a column. */
|
|
@@ -177,12 +180,6 @@ export const id = (model: Model): string => model.dragAndDrop.id;
|
|
|
177
180
|
/** Whether a card is held by a pointer or the keyboard. */
|
|
178
181
|
export const isDragging = (model: Model): boolean => UiDragAndDrop.isDragging(model.dragAndDrop);
|
|
179
182
|
|
|
180
|
-
/** Whether a card is pressed or held. While it is, the arrow keys, Space and Escape belong to
|
|
181
|
-
* the board: pause the page's own bindings for them. The board takes Escape before anything
|
|
182
|
-
* else sees it. */
|
|
183
|
-
export const isHolding = (model: Model): boolean =>
|
|
184
|
-
Option.isSome(UiDragAndDrop.maybeDraggedItemId(model.dragAndDrop));
|
|
185
|
-
|
|
186
183
|
// DOM HOOKS
|
|
187
184
|
|
|
188
185
|
const hookId = (boardId: string, localId: string): string => `${boardId}/${localId}`;
|
|
@@ -234,9 +231,6 @@ const overColumn = (model: Model): Option.Option<Column> =>
|
|
|
234
231
|
),
|
|
235
232
|
);
|
|
236
233
|
|
|
237
|
-
const announceMove = (maybeText: Option.Option<string>): ReadonlyArray<Command.Command<Message>> =>
|
|
238
|
-
Array.fromOption(Option.map(maybeText, (text) => AnnounceMove({ text })));
|
|
239
|
-
|
|
240
234
|
const placementOf = (
|
|
241
235
|
model: Model,
|
|
242
236
|
held: Held,
|
|
@@ -263,10 +257,7 @@ const placementOf = (
|
|
|
263
257
|
fromIndex: from.index,
|
|
264
258
|
toColumnId: to.id,
|
|
265
259
|
toIndex,
|
|
266
|
-
maybeAfterCardId: Option.map(
|
|
267
|
-
toIndex > 0 ? Array.get(others, toIndex - 1) : Option.none(),
|
|
268
|
-
(card) => card.id,
|
|
269
|
-
),
|
|
260
|
+
maybeAfterCardId: Option.map(Array.get(others, toIndex - 1), (card) => card.id),
|
|
270
261
|
maybeBeforeCardId: Option.map(Array.get(others, toIndex), (card) => card.id),
|
|
271
262
|
});
|
|
272
263
|
});
|
|
@@ -349,35 +340,26 @@ const moveText = (
|
|
|
349
340
|
* A card set down without a move says `putBack`. */
|
|
350
341
|
const settle =
|
|
351
342
|
(previous: Model, putBack = COPY.putBack) =>
|
|
352
|
-
(dragAndDropUpdate: UpdateReturn): UpdateReturn =>
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
343
|
+
(dragAndDropUpdate: UpdateReturn): UpdateReturn =>
|
|
344
|
+
settleDrag(
|
|
345
|
+
dragAndDropUpdate,
|
|
346
|
+
Option.map(
|
|
347
|
+
Option.flatMap(previous.maybeHeld, (held) =>
|
|
348
|
+
moveText(
|
|
349
|
+
held,
|
|
350
|
+
previous,
|
|
351
|
+
dragAndDropUpdate.model,
|
|
352
|
+
Option.fromNullishOr(dragAndDropUpdate.outMessage),
|
|
353
|
+
putBack,
|
|
354
|
+
),
|
|
355
|
+
),
|
|
356
|
+
(text) => AnnounceMove({ text }),
|
|
364
357
|
),
|
|
365
358
|
);
|
|
366
359
|
|
|
367
|
-
return Update.withOutMessage(
|
|
368
|
-
{
|
|
369
|
-
model: nextModel,
|
|
370
|
-
commands: [...(dragAndDropUpdate.commands ?? []), ...announceMove(maybeText)],
|
|
371
|
-
},
|
|
372
|
-
dragAndDropUpdate.outMessage,
|
|
373
|
-
);
|
|
374
|
-
};
|
|
375
|
-
|
|
376
360
|
const holding = (model: Model, held: Held): Model =>
|
|
377
361
|
modifyFields(model, { maybeHeld: () => Option.some(held) });
|
|
378
362
|
|
|
379
|
-
const canLift = (model: Model): boolean => model.isMovable && phaseOf(model.dragAndDrop) === "Idle";
|
|
380
|
-
|
|
381
363
|
const liftByKeyboard = (model: Model, place: Place, columns: ReadonlyArray<Column>) => {
|
|
382
364
|
const pressed = holding(model, { card: place.card, columns, maybePressPoint: Option.none() });
|
|
383
365
|
return settle(pressed)(
|
|
@@ -545,17 +527,6 @@ export const setMovable = (model: Model, isMovable: boolean): UpdateReturn => {
|
|
|
545
527
|
|
|
546
528
|
// SUBSCRIPTION
|
|
547
529
|
|
|
548
|
-
const holdingSubscriptions = Subscription.make<Model, Message>()((entry) => ({
|
|
549
|
-
escape: entry(
|
|
550
|
-
{ isHolding: Schema.Boolean },
|
|
551
|
-
{
|
|
552
|
-
modelToDependencies: (model) => ({ isHolding: isHolding(model) }),
|
|
553
|
-
dependenciesToStream: ({ isHolding: isHoldingNow }) =>
|
|
554
|
-
isHoldingNow ? escapeKeys(Message.PressedEscape()) : Stream.empty,
|
|
555
|
-
},
|
|
556
|
-
),
|
|
557
|
-
}));
|
|
558
|
-
|
|
559
530
|
// NOTE: @foldkit/ui gap: DragAndDrop's Subscription keys are fixed, so two of its users on a
|
|
560
531
|
// page would share them. The board lifts them under its own names, behind the parent's prefix.
|
|
561
532
|
const dragSubscriptions = Subscription.lift({
|
|
@@ -567,7 +538,10 @@ const dragSubscriptions = Subscription.lift({
|
|
|
567
538
|
toParentMessage: toDragAndDropMessage,
|
|
568
539
|
});
|
|
569
540
|
|
|
570
|
-
const boardSubscriptions = Subscription.aggregate(
|
|
541
|
+
const boardSubscriptions = Subscription.aggregate(
|
|
542
|
+
escapeSubscriptions<Model, Message>(Message.PressedEscape()),
|
|
543
|
+
dragSubscriptions,
|
|
544
|
+
);
|
|
571
545
|
|
|
572
546
|
/** A held card follows the pointer, the arrows and Space move and drop it, Escape puts it
|
|
573
547
|
* back and the page scrolls near its edges, all from listeners that run only while a card is
|
|
@@ -581,9 +555,6 @@ export const subscriptions = <Prefix extends string>(keyPrefix: Prefix) =>
|
|
|
581
555
|
|
|
582
556
|
// LIFTED CARD
|
|
583
557
|
|
|
584
|
-
const pressPointOf = (model: Model): Option.Option<typeof PressPoint.Type> =>
|
|
585
|
-
Option.flatMap(model.maybeHeld, (held) => held.maybePressPoint);
|
|
586
|
-
|
|
587
558
|
/** Sizes the copy that follows the pointer to the card it lifts, and keeps the pointer where
|
|
588
559
|
* it pressed the card. Measures the card once, when the copy appears. */
|
|
589
560
|
export const SizeLiftedCard = Mount.define("SizeLiftedCard", {
|
|
@@ -627,9 +598,6 @@ export type ViewInputs = Readonly<{
|
|
|
627
598
|
toEmptyView?: (column: Column) => ReadonlyArray<Html>;
|
|
628
599
|
/** Controls at the right of a column's head, after its count ("capture here"). */
|
|
629
600
|
toColumnActions?: (column: Column) => ReadonlyArray<Html>;
|
|
630
|
-
/** Further attributes for a column's `div.board-col` (`data-status`), never a class. Wrap
|
|
631
|
-
* them with `childAttributes` so their handlers dispatch the parent's Messages. */
|
|
632
|
-
toColumnAttributes?: (column: Column) => ReadonlyArray<ChildAttribute>;
|
|
633
601
|
}>;
|
|
634
602
|
|
|
635
603
|
const INNER_CONTROL = innerControls(`[data-${TITLE_ATTRIBUTE}], [data-${GRIP_ATTRIBUTE}]`);
|
|
@@ -664,7 +632,6 @@ type PlaceInfo = Readonly<{
|
|
|
664
632
|
toCardView: (card: Card, render: CardRender) => Html;
|
|
665
633
|
toEmptyView: (column: Column) => ReadonlyArray<Html>;
|
|
666
634
|
toColumnActions: (column: Column) => ReadonlyArray<Html>;
|
|
667
|
-
toColumnAttributes: (column: Column) => ReadonlyArray<ChildAttribute>;
|
|
668
635
|
}>;
|
|
669
636
|
|
|
670
637
|
const gripHelpId = (model: Model): string => `${id(model)}-grip-help`;
|
|
@@ -872,7 +839,6 @@ const columnView = (info: PlaceInfo, column: Column, h: HtmlBuilder<Message>): H
|
|
|
872
839
|
return h.keyed("div")(
|
|
873
840
|
column.id,
|
|
874
841
|
[
|
|
875
|
-
...info.toColumnAttributes(column),
|
|
876
842
|
h.DataAttribute("droppable-id", columnHook(model, column.id)),
|
|
877
843
|
h.Class(isTarget ? "board-col drop-target" : "board-col"),
|
|
878
844
|
],
|
|
@@ -905,12 +871,11 @@ const liftedCopyView = (info: PlaceInfo, h: HtmlBuilder<Message>): ReadonlyArray
|
|
|
905
871
|
const maybeLifted = Option.all({
|
|
906
872
|
style: UiDragAndDrop.ghostStyle(model.dragAndDrop),
|
|
907
873
|
held: model.maybeHeld,
|
|
874
|
+
pressPoint: Option.flatMap(model.maybeHeld, (held) => held.maybePressPoint),
|
|
908
875
|
});
|
|
909
876
|
|
|
910
|
-
const pressPoint = Option.getOrElse(pressPointOf(model), () => ({ clientX: 0, clientY: 0 }));
|
|
911
|
-
|
|
912
877
|
return Array.fromOption(
|
|
913
|
-
Option.map(maybeLifted, ({ style, held }) =>
|
|
878
|
+
Option.map(maybeLifted, ({ style, held, pressPoint }) =>
|
|
914
879
|
h.div(
|
|
915
880
|
[
|
|
916
881
|
h.Class("board-lift"),
|
|
@@ -946,21 +911,8 @@ const liftedCopyView = (info: PlaceInfo, h: HtmlBuilder<Message>): ReadonlyArray
|
|
|
946
911
|
* follows the pointer or the keys.
|
|
947
912
|
*/
|
|
948
913
|
export const view = defineView<Model, Message, ViewInputs>((model, viewInputs, h): Html => {
|
|
949
|
-
const {
|
|
950
|
-
|
|
951
|
-
toCardView,
|
|
952
|
-
toEmptyView = () => [],
|
|
953
|
-
toColumnActions = () => [],
|
|
954
|
-
toColumnAttributes = () => [],
|
|
955
|
-
} = viewInputs;
|
|
956
|
-
const info: PlaceInfo = {
|
|
957
|
-
model,
|
|
958
|
-
columns,
|
|
959
|
-
toCardView,
|
|
960
|
-
toEmptyView,
|
|
961
|
-
toColumnActions,
|
|
962
|
-
toColumnAttributes,
|
|
963
|
-
};
|
|
914
|
+
const { columns, toCardView, toEmptyView = () => [], toColumnActions = () => [] } = viewInputs;
|
|
915
|
+
const info: PlaceInfo = { model, columns, toCardView, toEmptyView, toColumnActions };
|
|
964
916
|
|
|
965
917
|
return h.div(
|
|
966
918
|
[h.Class("board"), h.Style({ "--cols": `${columns.length}` })],
|
package/src/board/index.ts
CHANGED
|
@@ -10,10 +10,10 @@ export {
|
|
|
10
10
|
cardView,
|
|
11
11
|
id,
|
|
12
12
|
init,
|
|
13
|
-
isHolding,
|
|
14
13
|
setMovable,
|
|
15
14
|
subscriptions,
|
|
16
15
|
update,
|
|
17
16
|
view,
|
|
18
17
|
} from "./board.ts";
|
|
18
|
+
export { isHolding } from "../drag/drag.ts";
|
|
19
19
|
export type { CardRender, CardViewConfig, InitConfig, ViewInputs } from "./board.ts";
|
package/src/button/button.ts
CHANGED
|
@@ -76,7 +76,7 @@ export type ViewConfig<Message> = Look &
|
|
|
76
76
|
isDisabled?: boolean;
|
|
77
77
|
keyHint?: KeyHintConfig;
|
|
78
78
|
/** `submit` makes it its form's submit button while it is not held. */
|
|
79
|
-
type?: "button" | "submit"
|
|
79
|
+
type?: "button" | "submit";
|
|
80
80
|
/** Further attributes for the `<button>`, such as an id or a Submodel's attribute group. */
|
|
81
81
|
attributes?: Attributes<Message>;
|
|
82
82
|
}> &
|
package/src/chip/chip.ts
CHANGED
|
@@ -47,14 +47,6 @@ export type DotConfig = Readonly<{
|
|
|
47
47
|
tone?: Tone;
|
|
48
48
|
}>;
|
|
49
49
|
|
|
50
|
-
const DOT_CLASS: Readonly<Record<Tone, string>> = {
|
|
51
|
-
Plain: "chip-dot",
|
|
52
|
-
Go: "chip-dot go",
|
|
53
|
-
Warn: "chip-dot warn",
|
|
54
|
-
Blocked: "chip-dot blocked",
|
|
55
|
-
Done: "chip-dot done",
|
|
56
|
-
};
|
|
57
|
-
|
|
58
50
|
/** A chip as a 10px cell in its tone, where a word would take the room a title needs (a task
|
|
59
51
|
* row's status, before its title). It is an image (`role="img"`) named by the word, which its
|
|
60
52
|
* tip shows, so the state never rests on its colour. */
|
|
@@ -65,6 +57,6 @@ export const dotView = <Message>(config: DotConfig, h: HtmlBuilder<Message>): Ht
|
|
|
65
57
|
h.Role("img"),
|
|
66
58
|
h.AriaLabel(label),
|
|
67
59
|
h.DataAttribute("tip", label),
|
|
68
|
-
h.Class(
|
|
60
|
+
h.Class(`chip-dot${TONE_CLASS[tone]}`),
|
|
69
61
|
]);
|
|
70
62
|
};
|