@gjermundgaraba/pixel-paper 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +50 -2
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/announcer/announcer.d.ts +35 -0
- package/dist/announcer/announcer.js +121 -0
- package/dist/announcer/index.d.ts +5 -0
- package/dist/announcer/index.js +11 -0
- package/dist/attributes/attributes.d.ts +4 -0
- package/dist/banner/banner.d.ts +20 -0
- package/dist/banner/banner.js +18 -0
- package/dist/banner/index.d.ts +5 -0
- package/dist/banner/index.js +6 -0
- package/dist/bench/bench.d.ts +16 -0
- package/dist/bench/bench.js +12 -0
- package/dist/bench/index.d.ts +5 -0
- package/dist/bench/index.js +6 -0
- package/dist/board/board.d.ts +1151 -0
- package/dist/board/board.js +449 -0
- package/dist/board/index.d.ts +6 -0
- package/dist/board/index.js +21 -0
- package/dist/button/button.d.ts +54 -0
- package/dist/button/button.js +50 -0
- package/dist/button/index.d.ts +5 -0
- package/dist/button/index.js +9 -0
- package/dist/card/card.d.ts +66 -0
- package/dist/card/card.js +70 -0
- package/dist/card/index.d.ts +5 -0
- package/dist/card/index.js +10 -0
- package/dist/chip/chip.d.ts +27 -0
- package/dist/chip/chip.js +34 -0
- package/dist/chip/index.d.ts +5 -0
- package/dist/chip/index.js +9 -0
- package/dist/choice/choice.d.ts +16 -0
- package/dist/choice/choice.js +17 -0
- package/dist/choice/index.d.ts +5 -0
- package/dist/choice/index.js +6 -0
- package/dist/code-editor/code-editor.d.ts +15 -0
- package/dist/code-editor/code-editor.js +22 -0
- package/dist/code-editor/index.d.ts +5 -0
- package/dist/code-editor/index.js +6 -0
- package/dist/code-surface/code-surface.d.ts +12 -0
- package/dist/code-surface/code-surface.js +12 -0
- package/dist/code-surface/index.d.ts +5 -0
- package/dist/code-surface/index.js +6 -0
- package/dist/command-palette/command-palette.d.ts +579 -0
- package/dist/command-palette/command-palette.js +600 -0
- package/dist/command-palette/index.d.ts +9 -0
- package/dist/command-palette/index.js +32 -0
- package/dist/command-palette/keys.d.ts +13 -0
- package/dist/command-palette/keys.js +71 -0
- package/dist/command-palette/match.d.ts +43 -0
- package/dist/command-palette/match.js +45 -0
- package/dist/command-palette/message.d.ts +94 -0
- package/dist/command-palette/message.js +46 -0
- package/dist/confirm-dialog/confirm-dialog.d.ts +287 -0
- package/dist/confirm-dialog/confirm-dialog.js +115 -0
- package/dist/confirm-dialog/index.d.ts +5 -0
- package/dist/confirm-dialog/index.js +17 -0
- package/dist/copy-button/copy-button.d.ts +99 -0
- package/dist/copy-button/copy-button.js +96 -0
- package/dist/copy-button/index.d.ts +5 -0
- package/dist/copy-button/index.js +13 -0
- package/dist/crumbs/crumbs.d.ts +15 -0
- package/dist/crumbs/crumbs.js +11 -0
- package/dist/crumbs/index.d.ts +5 -0
- package/dist/crumbs/index.js +6 -0
- package/dist/deck/deck.d.ts +9 -0
- package/dist/deck/deck.js +9 -0
- package/dist/deck/index.d.ts +5 -0
- package/dist/deck/index.js +6 -0
- package/dist/dialog/dialog.d.ts +278 -0
- package/dist/dialog/dialog.js +145 -0
- package/dist/dialog/fold.d.ts +58 -0
- package/dist/dialog/fold.js +63 -0
- package/dist/dialog/index.d.ts +6 -0
- package/dist/dialog/index.js +21 -0
- package/dist/disclosure/disclosure.d.ts +24 -0
- package/dist/disclosure/disclosure.js +25 -0
- package/dist/disclosure/index.d.ts +5 -0
- package/dist/disclosure/index.js +6 -0
- package/dist/dom/html-element.js +8 -0
- package/dist/drag/drag.d.ts +15 -0
- package/dist/drag/drag.js +123 -0
- package/dist/drop-zone/drop-zone.d.ts +119 -0
- package/dist/drop-zone/drop-zone.js +64 -0
- package/dist/drop-zone/index.d.ts +5 -0
- package/dist/drop-zone/index.js +14 -0
- package/dist/empty-state/empty-state.d.ts +18 -0
- package/dist/empty-state/empty-state.js +16 -0
- package/dist/empty-state/index.d.ts +5 -0
- package/dist/empty-state/index.js +6 -0
- package/dist/error-summary/error-summary.d.ts +34 -0
- package/dist/error-summary/error-summary.js +33 -0
- package/dist/error-summary/index.d.ts +5 -0
- package/dist/error-summary/index.js +6 -0
- package/dist/field/field.d.ts +35 -0
- package/dist/field/field.js +34 -0
- package/dist/field/index.d.ts +5 -0
- package/dist/field/index.js +6 -0
- package/dist/field-grid/field-grid.d.ts +8 -0
- package/dist/field-grid/field-grid.js +8 -0
- package/dist/field-grid/index.d.ts +5 -0
- package/dist/field-grid/index.js +6 -0
- package/dist/fields/fields.js +9 -0
- package/dist/fieldset/fieldset.d.ts +13 -0
- package/dist/fieldset/fieldset.js +13 -0
- package/dist/fieldset/index.d.ts +5 -0
- package/dist/fieldset/index.js +6 -0
- package/dist/filter-chip/filter-chip.d.ts +21 -0
- package/dist/filter-chip/filter-chip.js +28 -0
- package/dist/filter-chip/index.d.ts +5 -0
- package/dist/filter-chip/index.js +6 -0
- package/dist/filter-strip/filter-strip.d.ts +12 -0
- package/dist/filter-strip/filter-strip.js +13 -0
- package/dist/filter-strip/index.d.ts +5 -0
- package/dist/filter-strip/index.js +6 -0
- package/dist/flash-word/flash-word.d.ts +31 -0
- package/dist/flash-word/flash-word.js +31 -0
- package/dist/flash-word/index.d.ts +5 -0
- package/dist/flash-word/index.js +9 -0
- package/dist/focus/focus.d.ts +15 -0
- package/dist/focus/focus.js +17 -0
- package/dist/focus/index.d.ts +5 -0
- package/dist/focus/index.js +9 -0
- package/dist/format/format.js +52 -0
- package/dist/format/index.d.ts +5 -0
- package/dist/format/index.js +6 -0
- package/dist/glyph/glyph.d.ts +9 -0
- package/dist/glyph/glyph.js +25 -0
- package/dist/glyph/glyphs.d.ts +381 -0
- package/dist/glyph/glyphs.js +2603 -0
- package/dist/glyph/index.d.ts +5 -0
- package/dist/glyph/index.js +6 -0
- package/dist/group/group.d.ts +8 -0
- package/dist/group/group.js +9 -0
- package/dist/group/index.d.ts +5 -0
- package/dist/group/index.js +6 -0
- package/dist/history/history.d.ts +34 -0
- package/dist/history/history.js +15 -0
- package/dist/history/index.d.ts +5 -0
- package/dist/history/index.js +6 -0
- package/dist/icon-button/icon-button.d.ts +23 -0
- package/dist/icon-button/icon-button.js +23 -0
- package/dist/icon-button/index.d.ts +5 -0
- package/dist/icon-button/index.js +6 -0
- package/dist/identity/identity.d.ts +15 -0
- package/dist/identity/identity.js +15 -0
- package/dist/identity/index.d.ts +5 -0
- package/dist/identity/index.js +6 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +85 -0
- package/dist/inline-input/index.d.ts +5 -0
- package/dist/inline-input/index.js +20 -0
- package/dist/inline-input/inline-input.d.ts +196 -0
- package/dist/inline-input/inline-input.js +212 -0
- package/dist/key-help/index.d.ts +5 -0
- package/dist/key-help/index.js +18 -0
- package/dist/key-help/key-help.d.ts +255 -0
- package/dist/key-help/key-help.js +137 -0
- package/dist/key-hint/index.d.ts +6 -0
- package/dist/key-hint/index.js +12 -0
- package/dist/key-hint/key-hint.d.ts +13 -0
- package/dist/key-hint/key-hint.js +7 -0
- package/dist/key-hint/key-label.d.ts +18 -0
- package/dist/key-hint/key-label.js +77 -0
- package/dist/keymap/keymap.d.ts +11 -0
- package/dist/keymap/keymap.js +9 -0
- package/dist/keys/keys.js +4 -0
- package/dist/line-diff/diff.d.ts +2 -0
- package/dist/line-diff/diff.js +73 -0
- package/dist/line-diff/index.d.ts +6 -0
- package/dist/line-diff/index.js +10 -0
- package/dist/line-diff/line-diff.d.ts +21 -0
- package/dist/line-diff/line-diff.js +75 -0
- package/dist/line-diff/patch.d.ts +15 -0
- package/dist/line-diff/patch.js +120 -0
- package/dist/link-button/index.d.ts +5 -0
- package/dist/link-button/index.js +6 -0
- package/dist/link-button/link-button.d.ts +11 -0
- package/dist/link-button/link-button.js +10 -0
- package/dist/link-state/index.d.ts +5 -0
- package/dist/link-state/index.js +6 -0
- package/dist/link-state/link-state.d.ts +15 -0
- package/dist/link-state/link-state.js +17 -0
- package/dist/live-region/index.d.ts +5 -0
- package/dist/live-region/index.js +9 -0
- package/dist/live-region/live-region.d.ts +39 -0
- package/dist/live-region/live-region.js +33 -0
- package/dist/loading/index.d.ts +5 -0
- package/dist/loading/index.js +6 -0
- package/dist/loading/loading.d.ts +19 -0
- package/dist/loading/loading.js +16 -0
- package/dist/locale/locale.d.ts +3 -0
- package/dist/locale/locale.js +5 -0
- package/dist/mark/index.d.ts +5 -0
- package/dist/mark/index.js +6 -0
- package/dist/mark/mark.d.ts +15 -0
- package/dist/mark/mark.js +30 -0
- package/dist/menu/index.d.ts +7 -0
- package/dist/menu/index.js +25 -0
- package/dist/menu/item.d.ts +236 -0
- package/dist/menu/item.js +19 -0
- package/dist/menu/menu.d.ts +206 -0
- package/dist/menu/menu.js +208 -0
- package/dist/menu/slip.js +163 -0
- package/dist/meter/index.d.ts +5 -0
- package/dist/meter/index.js +6 -0
- package/dist/meter/meter.d.ts +38 -0
- package/dist/meter/meter.js +69 -0
- package/dist/monogram/monogram.js +33 -0
- package/dist/nav-strip/index.d.ts +5 -0
- package/dist/nav-strip/index.js +6 -0
- package/dist/nav-strip/nav-strip.d.ts +19 -0
- package/dist/nav-strip/nav-strip.js +21 -0
- package/dist/notice/index.d.ts +5 -0
- package/dist/notice/index.js +6 -0
- package/dist/notice/notice.d.ts +23 -0
- package/dist/notice/notice.js +35 -0
- package/dist/outcome/index.d.ts +5 -0
- package/dist/outcome/index.js +6 -0
- package/dist/outcome/outcome.d.ts +19 -0
- package/dist/outcome/outcome.js +14 -0
- package/dist/page-head/index.d.ts +5 -0
- package/dist/page-head/index.js +6 -0
- package/dist/page-head/page-head.d.ts +13 -0
- package/dist/page-head/page-head.js +10 -0
- package/dist/panel/index.d.ts +5 -0
- package/dist/panel/index.js +6 -0
- package/dist/panel/panel.d.ts +35 -0
- package/dist/panel/panel.js +25 -0
- package/dist/password-field/index.d.ts +5 -0
- package/dist/password-field/index.js +6 -0
- package/dist/password-field/password-field.d.ts +33 -0
- package/dist/password-field/password-field.js +39 -0
- package/dist/places/index.d.ts +5 -0
- package/dist/places/index.js +6 -0
- package/dist/places/places.d.ts +32 -0
- package/dist/places/places.js +22 -0
- package/dist/props-list/index.d.ts +5 -0
- package/dist/props-list/index.js +6 -0
- package/dist/props-list/props-list.d.ts +18 -0
- package/dist/props-list/props-list.js +12 -0
- package/dist/prose/index.d.ts +5 -0
- package/dist/prose/index.js +6 -0
- package/dist/prose/prose.d.ts +14 -0
- package/dist/prose/prose.js +6 -0
- package/dist/query-chip/index.d.ts +5 -0
- package/dist/query-chip/index.js +6 -0
- package/dist/query-chip/query-chip.d.ts +18 -0
- package/dist/query-chip/query-chip.js +17 -0
- package/dist/radio-choices/index.d.ts +5 -0
- package/dist/radio-choices/index.js +12 -0
- package/dist/radio-choices/radio-choices.d.ts +105 -0
- package/dist/radio-choices/radio-choices.js +56 -0
- package/dist/rail/index.d.ts +5 -0
- package/dist/rail/index.js +22 -0
- package/dist/rail/rail.d.ts +403 -0
- package/dist/rail/rail.js +355 -0
- package/dist/reel/index.d.ts +6 -0
- package/dist/reel/index.js +26 -0
- package/dist/reel/layout.d.ts +58 -0
- package/dist/reel/layout.js +378 -0
- package/dist/reel/reel.d.ts +1070 -0
- package/dist/reel/reel.js +1019 -0
- package/dist/remote/index.d.ts +5 -0
- package/dist/remote/index.js +6 -0
- package/dist/remote/remote.d.ts +28 -0
- package/dist/remote/remote.js +41 -0
- package/dist/rows/index.d.ts +5 -0
- package/dist/rows/index.js +12 -0
- package/dist/rows/rows.d.ts +116 -0
- package/dist/rows/rows.js +67 -0
- package/dist/scheme/index.d.ts +6 -0
- package/dist/scheme/index.js +10 -0
- package/dist/scheme/scheme-switch.d.ts +98 -0
- package/dist/scheme/scheme-switch.js +118 -0
- package/dist/scheme/scheme.d.ts +5 -0
- package/dist/scheme/scheme.js +16 -0
- package/dist/scheme/script.d.ts +8 -0
- package/dist/scheme/script.js +10 -0
- package/dist/secret/index.d.ts +5 -0
- package/dist/secret/index.js +6 -0
- package/dist/secret/secret.d.ts +13 -0
- package/dist/secret/secret.js +9 -0
- package/dist/segmented/index.d.ts +5 -0
- package/dist/segmented/index.js +6 -0
- package/dist/segmented/segmented.d.ts +17 -0
- package/dist/segmented/segmented.js +17 -0
- package/dist/select-field/index.d.ts +5 -0
- package/dist/select-field/index.js +6 -0
- package/dist/select-field/select-field.d.ts +38 -0
- package/dist/select-field/select-field.js +29 -0
- package/dist/sheet/index.d.ts +5 -0
- package/dist/sheet/index.js +6 -0
- package/dist/sheet/sheet.d.ts +16 -0
- package/dist/sheet/sheet.js +15 -0
- package/dist/skip-link/index.d.ts +5 -0
- package/dist/skip-link/index.js +9 -0
- package/dist/skip-link/skip-link.d.ts +23 -0
- package/dist/skip-link/skip-link.js +36 -0
- package/dist/slot/slot.js +8 -0
- package/dist/sortable/index.d.ts +5 -0
- package/dist/sortable/index.js +16 -0
- package/dist/sortable/sortable.d.ts +1125 -0
- package/dist/sortable/sortable.js +431 -0
- package/dist/stack/index.d.ts +5 -0
- package/dist/stack/index.js +6 -0
- package/dist/stack/stack.d.ts +15 -0
- package/dist/stack/stack.js +12 -0
- package/dist/stage/index.d.ts +5 -0
- package/dist/stage/index.js +6 -0
- package/dist/stage/stage.d.ts +14 -0
- package/dist/stage/stage.js +11 -0
- package/dist/stat/index.d.ts +5 -0
- package/dist/stat/index.js +6 -0
- package/dist/stat/stat.d.ts +18 -0
- package/dist/stat/stat.js +13 -0
- package/dist/status-bar/index.d.ts +6 -0
- package/dist/status-bar/index.js +11 -0
- package/dist/status-bar/status-bar.d.ts +28 -0
- package/dist/status-bar/status-bar.js +19 -0
- package/dist/subscription/prefix-keys.js +12 -0
- package/dist/table/index.d.ts +5 -0
- package/dist/table/index.js +6 -0
- package/dist/table/table.d.ts +26 -0
- package/dist/table/table.js +18 -0
- package/dist/tabs/index.d.ts +5 -0
- package/dist/tabs/index.js +14 -0
- package/dist/tabs/tabs.d.ts +125 -0
- package/dist/tabs/tabs.js +57 -0
- package/dist/tag/index.d.ts +5 -0
- package/dist/tag/index.js +6 -0
- package/dist/tag/tag.d.ts +16 -0
- package/dist/tag/tag.js +25 -0
- package/dist/text-button/index.d.ts +5 -0
- package/dist/text-button/index.js +6 -0
- package/dist/text-button/text-button.d.ts +8 -0
- package/dist/text-button/text-button.js +12 -0
- package/dist/textarea-field/index.d.ts +5 -0
- package/dist/textarea-field/index.js +6 -0
- package/dist/textarea-field/textarea-field.d.ts +28 -0
- package/dist/textarea-field/textarea-field.js +30 -0
- package/dist/time/index.d.ts +5 -0
- package/dist/time/index.js +9 -0
- package/dist/time/time.d.ts +38 -0
- package/dist/time/time.js +63 -0
- package/dist/tips/index.d.ts +5 -0
- package/dist/tips/index.js +14 -0
- package/dist/tips/tips.d.ts +339 -0
- package/dist/tips/tips.js +308 -0
- package/dist/toast/index.d.ts +5 -0
- package/dist/toast/index.js +17 -0
- package/dist/toast/stack.d.ts +7 -0
- package/dist/toast/stack.js +23 -0
- package/dist/toast/toast.d.ts +559 -0
- package/dist/toast/toast.js +269 -0
- package/dist/toc/index.d.ts +5 -0
- package/dist/toc/index.js +9 -0
- package/dist/toc/toc.d.ts +42 -0
- package/dist/toc/toc.js +35 -0
- package/dist/top-bar/bar-height.d.ts +26 -0
- package/dist/top-bar/bar-height.js +43 -0
- package/dist/top-bar/index.d.ts +6 -0
- package/dist/top-bar/index.js +12 -0
- package/dist/top-bar/top-bar.d.ts +19 -0
- package/dist/top-bar/top-bar.js +18 -0
- package/dist/wall/index.d.ts +5 -0
- package/dist/wall/index.js +9 -0
- package/dist/wall/wall.d.ts +16 -0
- package/dist/wall/wall.js +15 -0
- package/dist/window/index.d.ts +5 -0
- package/dist/window/index.js +6 -0
- package/dist/window/window.d.ts +28 -0
- package/dist/window/window.js +29 -0
- package/dist/wordmark/index.d.ts +5 -0
- package/dist/wordmark/index.js +6 -0
- package/dist/wordmark/wordmark.d.ts +10 -0
- package/dist/wordmark/wordmark.js +10 -0
- package/dist/wrap/index.d.ts +5 -0
- package/dist/wrap/index.js +6 -0
- package/dist/wrap/wrap.d.ts +12 -0
- package/dist/wrap/wrap.js +9 -0
- package/fonts/DepartureMono-Regular.woff2 +0 -0
- package/fonts/LICENSE.txt +2 -0
- package/package.json +57 -3
- package/src/pixel-paper.css +4611 -0
- package/src/tokens.css +151 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { Option } from "effect";
|
|
3
|
+
// src/dom/html-element.ts
|
|
4
|
+
const htmlElement = (selector, root = document) => {
|
|
5
|
+
const element = root.querySelector(selector);
|
|
6
|
+
return __foldkitBrandViewResult((element instanceof HTMLElement ? Option.some(element) : Option.none()), "@gjermundgaraba/pixel-paper/dom/html-element.js#htmlElement");
|
|
7
|
+
};
|
|
8
|
+
export { htmlElement };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Option, Stream } from "effect";
|
|
2
|
+
import "foldkit/command";
|
|
3
|
+
import { DragAndDrop } from "@foldkit/ui";
|
|
4
|
+
import { Attribute, HtmlBuilder } from "foldkit/html";
|
|
5
|
+
import "foldkit/subscription";
|
|
6
|
+
import "foldkit/update";
|
|
7
|
+
type Holder = Readonly<{
|
|
8
|
+
dragAndDrop: DragAndDrop.Model;
|
|
9
|
+
maybeHeld: Option.Option<unknown>;
|
|
10
|
+
}>;
|
|
11
|
+
/** Whether an item is pressed or held. While it is, the arrow keys, Space and Escape belong to
|
|
12
|
+
* the list: pause the page's own bindings for them. The list takes Escape before anything
|
|
13
|
+
* else sees it. */
|
|
14
|
+
export declare const isHolding: (model: Holder) => boolean;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { isPlain } from "../keys/keys.js";
|
|
3
|
+
import { Array, Effect, Option, Order, Schema, Stream, pipe } from "effect";
|
|
4
|
+
import { DragAndDrop } from "@foldkit/ui";
|
|
5
|
+
import * as Subscription from "foldkit/subscription";
|
|
6
|
+
import * as Update from "foldkit/update";
|
|
7
|
+
import * as Dom from "foldkit/dom";
|
|
8
|
+
// src/drag/drag.ts
|
|
9
|
+
const phaseOf = (dragAndDrop) => {
|
|
10
|
+
if (Option.isNone(DragAndDrop.maybeDraggedItemId(dragAndDrop))) return __foldkitBrandViewResult(("Idle"), "@gjermundgaraba/pixel-paper/drag/drag.js#phaseOf");
|
|
11
|
+
else if (!DragAndDrop.isDragging(dragAndDrop)) return __foldkitBrandViewResult(("Pressed"), "@gjermundgaraba/pixel-paper/drag/drag.js#phaseOf");
|
|
12
|
+
else if (Option.isSome(DragAndDrop.ghostStyle(dragAndDrop))) return __foldkitBrandViewResult(("PointerDragging"), "@gjermundgaraba/pixel-paper/drag/drag.js#phaseOf");
|
|
13
|
+
return __foldkitBrandViewResult(("KeyboardDragging"), "@gjermundgaraba/pixel-paper/drag/drag.js#phaseOf");
|
|
14
|
+
};
|
|
15
|
+
const isCarrying = (phase) => __foldkitBrandViewResult((phase === "PointerDragging" || phase === "KeyboardDragging"), "@gjermundgaraba/pixel-paper/drag/drag.js#isCarrying");
|
|
16
|
+
/** Whether an item is pressed or held. While it is, the arrow keys, Space and Escape belong to
|
|
17
|
+
* the list: pause the page's own bindings for them. The list takes Escape before anything
|
|
18
|
+
* else sees it. */
|
|
19
|
+
const isHolding = (model) => __foldkitBrandViewResult((phaseOf(model.dragAndDrop) !== "Idle"), "@gjermundgaraba/pixel-paper/drag/drag.js#isHolding");
|
|
20
|
+
const canLift = (model) => __foldkitBrandViewResult((!isHolding(model)), "@gjermundgaraba/pixel-paper/drag/drag.js#canLift");
|
|
21
|
+
const settle = (step, maybeAnnouncement) => __foldkitBrandViewResult((Update.withOutMessage({
|
|
22
|
+
model: isHolding(step.model) ? step.model : {
|
|
23
|
+
...step.model,
|
|
24
|
+
maybeHeld: Option.none()
|
|
25
|
+
},
|
|
26
|
+
commands: [...step.commands ?? [], ...Array.fromOption(maybeAnnouncement)]
|
|
27
|
+
}, step.outMessage)), "@gjermundgaraba/pixel-paper/drag/drag.js#settle");
|
|
28
|
+
const pressedDraggable = (fields) => __foldkitBrandViewResult((DragAndDrop.Message.PressedDraggable(fields)), "@gjermundgaraba/pixel-paper/drag/drag.js#pressedDraggable");
|
|
29
|
+
const activatedKeyboardDrag = (fields) => __foldkitBrandViewResult((DragAndDrop.Message.ActivatedKeyboardDrag(fields)), "@gjermundgaraba/pixel-paper/drag/drag.js#activatedKeyboardDrag");
|
|
30
|
+
const movedPointer = (fields) => __foldkitBrandViewResult((DragAndDrop.Message.MovedPointer(fields)), "@gjermundgaraba/pixel-paper/drag/drag.js#movedPointer");
|
|
31
|
+
const releasedPointer = () => __foldkitBrandViewResult((DragAndDrop.Message.ReleasedPointer()), "@gjermundgaraba/pixel-paper/drag/drag.js#releasedPointer");
|
|
32
|
+
const cancelledDrag = () => __foldkitBrandViewResult((DragAndDrop.Message.CancelledDrag()), "@gjermundgaraba/pixel-paper/drag/drag.js#cancelledDrag");
|
|
33
|
+
const innerControls = (liftingButtons) => __foldkitBrandViewResult(([
|
|
34
|
+
"input",
|
|
35
|
+
"textarea",
|
|
36
|
+
"select",
|
|
37
|
+
"a[href]",
|
|
38
|
+
"[contenteditable]:not([contenteditable=\"false\"])",
|
|
39
|
+
`button:not(${liftingButtons})`,
|
|
40
|
+
"[data-no-lift]"
|
|
41
|
+
].join(", ")), "@gjermundgaraba/pixel-paper/drag/drag.js#innerControls");
|
|
42
|
+
const takeEscape = (event, message) => {
|
|
43
|
+
if (event.key !== "Escape" || event.isComposing) return __foldkitBrandViewResult((Option.none()), "@gjermundgaraba/pixel-paper/drag/drag.js#takeEscape");
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
event.stopPropagation();
|
|
46
|
+
return __foldkitBrandViewResult((Option.some(message)), "@gjermundgaraba/pixel-paper/drag/drag.js#takeEscape");
|
|
47
|
+
};
|
|
48
|
+
const escapeKeys = (message) => __foldkitBrandViewResult((Dom.streamFromEventFilterMap({
|
|
49
|
+
target: () => __foldkitBrandViewResult((window), "@gjermundgaraba/pixel-paper/drag/drag.js#target"),
|
|
50
|
+
type: "keydown",
|
|
51
|
+
filterMapEvent: (event) => __foldkitBrandViewResult((takeEscape(event, message)), "@gjermundgaraba/pixel-paper/drag/drag.js#filterMapEvent"),
|
|
52
|
+
options: { capture: true }
|
|
53
|
+
})), "@gjermundgaraba/pixel-paper/drag/drag.js#escapeKeys");
|
|
54
|
+
const escapeSubscriptions = (message) => __foldkitBrandViewResult((Subscription.make()((entry) => (__foldkitBrandViewResult(({ escape: entry({ isHolding: Schema.Boolean }, {
|
|
55
|
+
modelToDependencies: (model) => (__foldkitBrandViewResult(({ isHolding: isHolding(model) }), "@gjermundgaraba/pixel-paper/drag/drag.js#modelToDependencies")),
|
|
56
|
+
dependenciesToStream: ({ isHolding: isHoldingNow }) => __foldkitBrandViewResult((isHoldingNow ? escapeKeys(message) : Stream.empty), "@gjermundgaraba/pixel-paper/drag/drag.js#dependenciesToStream")
|
|
57
|
+
}) }), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous")))), "@gjermundgaraba/pixel-paper/drag/drag.js#escapeSubscriptions");
|
|
58
|
+
const pressingPointer = (pointerId) => __foldkitBrandViewResult((Stream.filter(Stream.mergeAll(Array.map([
|
|
59
|
+
"pointermove",
|
|
60
|
+
"pointerup",
|
|
61
|
+
"pointercancel"
|
|
62
|
+
], (type) => __foldkitBrandViewResult((Stream.fromEventListener(document, type)), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~2")), { concurrency: "unbounded" }), (event) => __foldkitBrandViewResult((event.pointerId === pointerId), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~3"))), "@gjermundgaraba/pixel-paper/drag/drag.js#pressingPointer");
|
|
63
|
+
const pointerMessages = (pointerId, toMessage) => __foldkitBrandViewResult((Stream.map(pressingPointer(pointerId), (event) => {
|
|
64
|
+
if (event.type === "pointermove") return __foldkitBrandViewResult((toMessage.moved(event)), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~4");
|
|
65
|
+
else if (event.type === "pointerup") return __foldkitBrandViewResult((toMessage.released(event)), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~4");
|
|
66
|
+
return __foldkitBrandViewResult((toMessage.cancelled()), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~4");
|
|
67
|
+
})), "@gjermundgaraba/pixel-paper/drag/drag.js#pointerMessages");
|
|
68
|
+
const splitterAttributes = (config, h) => {
|
|
69
|
+
const [less, more] = config.orientation === "vertical" ? ["ArrowLeft", "ArrowRight"] : ["ArrowUp", "ArrowDown"];
|
|
70
|
+
return __foldkitBrandViewResult(([
|
|
71
|
+
h.AriaOrientation(config.orientation),
|
|
72
|
+
h.OnPointerDown((_pointerType, button, _screenX, _screenY, _time, clientX, clientY, pointerId) => __foldkitBrandViewResult((Option.liftPredicate(config.onPress(pointerId, clientX, clientY), () => __foldkitBrandViewResult((button === 0 && config.isIdle), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~6"))), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~5")),
|
|
73
|
+
h.OnKeyDownPreventDefault((key, modifiers) => __foldkitBrandViewResult((Option.liftPredicate(config.onStep(key === more ? 1 : -1), () => __foldkitBrandViewResult((isPlain(modifiers) && (key === less || key === more)), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~8"))), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~7"))
|
|
74
|
+
]), "@gjermundgaraba/pixel-paper/drag/drag.js#splitterAttributes");
|
|
75
|
+
};
|
|
76
|
+
const measureLift = (element, sourceSelector, pressX, pressY) => {
|
|
77
|
+
const maybeSource = Option.fromNullishOr(document.querySelector(sourceSelector));
|
|
78
|
+
if (Option.isSome(maybeSource) && element instanceof HTMLElement) {
|
|
79
|
+
const rect = maybeSource.value.getBoundingClientRect();
|
|
80
|
+
element.style.setProperty("--lift-width", `${rect.width}px`);
|
|
81
|
+
element.style.setProperty("--lift-x", `${rect.left - pressX}px`);
|
|
82
|
+
element.style.setProperty("--lift-y", `${rect.top - pressY}px`);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const ROW_TOLERANCE = 1;
|
|
86
|
+
const boxOf = (element) => {
|
|
87
|
+
const rect = element.getBoundingClientRect();
|
|
88
|
+
return __foldkitBrandViewResult(({
|
|
89
|
+
top: rect.top,
|
|
90
|
+
centreX: rect.left + rect.width / 2,
|
|
91
|
+
centreY: rect.top + rect.height / 2
|
|
92
|
+
}), "@gjermundgaraba/pixel-paper/drag/drag.js#boxOf");
|
|
93
|
+
};
|
|
94
|
+
const isOnSameRow = (box, other) => __foldkitBrandViewResult((Math.abs(other.top - box.top) < ROW_TOLERANCE), "@gjermundgaraba/pixel-paper/drag/drag.js#isOnSameRow");
|
|
95
|
+
const readAxis = (boxesWithHeld) => __foldkitBrandViewResult((Array.some(boxesWithHeld, (box, index) => __foldkitBrandViewResult((Option.exists(Array.get(boxesWithHeld, index + 1), (next) => __foldkitBrandViewResult((isOnSameRow(box, next)), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~10"))), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~9")) ? "Across" : "Down"), "@gjermundgaraba/pixel-paper/drag/drag.js#readAxis");
|
|
96
|
+
const isPastCentre = (axis, box, clientX, clientY) => __foldkitBrandViewResult((axis === "Across" ? clientX > box.centreX : clientY > box.centreY), "@gjermundgaraba/pixel-paper/drag/drag.js#isPastCentre");
|
|
97
|
+
const insertionIndex = (container, heldId, clientX, clientY) => {
|
|
98
|
+
const items = Array.map(Array.fromIterable(container.querySelectorAll("[data-sortable-id]")), (item) => (__foldkitBrandViewResult(({
|
|
99
|
+
id: item.dataset["sortableId"],
|
|
100
|
+
box: boxOf(item)
|
|
101
|
+
}), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~11")));
|
|
102
|
+
const axis = readAxis(Array.map(items, ({ box }) => __foldkitBrandViewResult((box), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~12")));
|
|
103
|
+
const boxes = pipe(Array.filter(items, (item) => __foldkitBrandViewResult((item.id !== heldId), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~13")), Array.map(({ box }) => __foldkitBrandViewResult((box), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~14")));
|
|
104
|
+
const distance = (box) => __foldkitBrandViewResult((Math.hypot(box.centreX - clientX, box.centreY - clientY)), "@gjermundgaraba/pixel-paper/drag/drag.js#distance");
|
|
105
|
+
const byDistance = Order.mapInput(Order.Number, ({ box }) => __foldkitBrandViewResult((distance(box)), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~15"));
|
|
106
|
+
return __foldkitBrandViewResult((Array.match(Array.map(boxes, (box, index) => (__foldkitBrandViewResult(({
|
|
107
|
+
box,
|
|
108
|
+
index
|
|
109
|
+
}), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~16"))), {
|
|
110
|
+
onEmpty: () => __foldkitBrandViewResult((0), "@gjermundgaraba/pixel-paper/drag/drag.js#onEmpty"),
|
|
111
|
+
onNonEmpty: (candidates) => {
|
|
112
|
+
const { box, index } = Array.min(candidates, byDistance);
|
|
113
|
+
return __foldkitBrandViewResult((isPastCentre(axis, box, clientX, clientY) ? index + 1 : index), "@gjermundgaraba/pixel-paper/drag/drag.js#onNonEmpty");
|
|
114
|
+
}
|
|
115
|
+
})), "@gjermundgaraba/pixel-paper/drag/drag.js#insertionIndex");
|
|
116
|
+
};
|
|
117
|
+
const DRAGGING_ATTRIBUTE = "data-pixel-paper-dragging";
|
|
118
|
+
const markDragging = Stream.callback(() => __foldkitBrandViewResult((Effect.acquireRelease(Effect.sync(() => {
|
|
119
|
+
document.documentElement.setAttribute(DRAGGING_ATTRIBUTE, "");
|
|
120
|
+
}), () => __foldkitBrandViewResult((Effect.sync(() => {
|
|
121
|
+
document.documentElement.removeAttribute(DRAGGING_ATTRIBUTE);
|
|
122
|
+
})), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~19")).pipe(Effect.flatMap(() => __foldkitBrandViewResult((Effect.never), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~21")))), "@gjermundgaraba/pixel-paper/drag/drag.js#anonymous~17"));
|
|
123
|
+
export { activatedKeyboardDrag, canLift, cancelledDrag, escapeKeys, escapeSubscriptions, innerControls, insertionIndex, isCarrying, isHolding, markDragging, measureLift, movedPointer, phaseOf, pointerMessages, pressedDraggable, releasedPointer, settle, splitterAttributes, takeEscape };
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { Html } from "foldkit/html";
|
|
3
|
+
import * as Update from "foldkit/update";
|
|
4
|
+
/** Schema for a drop zone: the `@foldkit/ui` FileDrop it is built on, which knows whether a
|
|
5
|
+
* file hovers it. */
|
|
6
|
+
export declare const Model: Schema.Struct<{
|
|
7
|
+
readonly fileDrop: Schema.Struct<{
|
|
8
|
+
readonly id: Schema.String;
|
|
9
|
+
readonly isDragOver: Schema.Boolean;
|
|
10
|
+
}>;
|
|
11
|
+
}>;
|
|
12
|
+
export type Model = typeof Model.Type;
|
|
13
|
+
/** Union of all Messages a drop zone can produce. */
|
|
14
|
+
export declare const Message: import("foldkit/message").MessageUnion<{
|
|
15
|
+
readonly GotFileDropMessage: {
|
|
16
|
+
message: import("foldkit/message").MessageUnion<{
|
|
17
|
+
readonly EnteredDragZone: {};
|
|
18
|
+
readonly LeftDragZone: {};
|
|
19
|
+
readonly DroppedFiles: {
|
|
20
|
+
files: Schema.NonEmptyArray<Schema.Schema<File>>;
|
|
21
|
+
};
|
|
22
|
+
readonly DroppedNonFiles: {};
|
|
23
|
+
}>;
|
|
24
|
+
};
|
|
25
|
+
}>;
|
|
26
|
+
export type Message = typeof Message.Type;
|
|
27
|
+
/** Union of OutMessages a drop zone reports: files dropped on it or chosen with its button,
|
|
28
|
+
* or a drop that held no files (text, a link). */
|
|
29
|
+
export declare const OutMessage: import("foldkit/message").MessageUnion<{
|
|
30
|
+
readonly ReceivedFiles: {
|
|
31
|
+
files: Schema.NonEmptyArray<Schema.Schema<File>>;
|
|
32
|
+
};
|
|
33
|
+
readonly RejectedNonFiles: {};
|
|
34
|
+
}>;
|
|
35
|
+
export type OutMessage = typeof OutMessage.Type;
|
|
36
|
+
/** Configuration for creating a drop zone with `init`. The `id` must be unique in the
|
|
37
|
+
* document: it is the file input's id. */
|
|
38
|
+
export type InitConfig = Readonly<{
|
|
39
|
+
id: string;
|
|
40
|
+
}>;
|
|
41
|
+
/** Creates a drop zone with nothing over it. */
|
|
42
|
+
export declare const init: (config: InitConfig) => Model;
|
|
43
|
+
/** The drop zone's id, unique in the document: its file input's id. */
|
|
44
|
+
export declare const id: (model: Model) => string;
|
|
45
|
+
/** Processes a drop zone Message and returns the next Model, Commands and OutMessage. */
|
|
46
|
+
export declare const update: (model: Model, message: Message) => Readonly<{
|
|
47
|
+
model: {
|
|
48
|
+
readonly fileDrop: {
|
|
49
|
+
readonly id: string;
|
|
50
|
+
readonly isDragOver: boolean;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
commands?: Update.Commands<{
|
|
54
|
+
readonly _tag: "GotFileDropMessage";
|
|
55
|
+
readonly message: {
|
|
56
|
+
readonly _tag: "DroppedFiles";
|
|
57
|
+
readonly files: readonly [File, ...File[]];
|
|
58
|
+
} | {
|
|
59
|
+
readonly _tag: "DroppedNonFiles";
|
|
60
|
+
} | {
|
|
61
|
+
readonly _tag: "EnteredDragZone";
|
|
62
|
+
} | {
|
|
63
|
+
readonly _tag: "LeftDragZone";
|
|
64
|
+
};
|
|
65
|
+
}, never>;
|
|
66
|
+
outMessage?: {
|
|
67
|
+
readonly _tag: "ReceivedFiles";
|
|
68
|
+
readonly files: readonly [File, ...File[]];
|
|
69
|
+
} | {
|
|
70
|
+
readonly _tag: "RejectedNonFiles";
|
|
71
|
+
};
|
|
72
|
+
}>;
|
|
73
|
+
/** Per-render inputs passed to `view` through `h.submodel`'s `viewInputs`. */
|
|
74
|
+
export type ViewInputs = Readonly<{
|
|
75
|
+
/** Pixel caps: `"Drop files here"`. */
|
|
76
|
+
title: string;
|
|
77
|
+
/** One sentence: what happens to what is dropped. Markup here carries no handlers: a
|
|
78
|
+
* Submodel's viewInputs may hold functions only at the top level. */
|
|
79
|
+
body?: ReadonlyArray<Html | string>;
|
|
80
|
+
/** Under the sentence: a word that says what the last drop did. A function because a
|
|
81
|
+
* Submodel's viewInputs may hold functions only at the top level, and Foldkit runs this one
|
|
82
|
+
* in the parent's boundary, so a handler in it (an undo) dispatches the parent's Message. */
|
|
83
|
+
toStatusView?: () => readonly Html[];
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* A dashed box that goes solid and tinted while a file hovers it, with a button to choose
|
|
87
|
+
* files for those who cannot drag, built on `@foldkit/ui`'s FileDrop: `div.drop-zone`
|
|
88
|
+
* (FileDrop sets `data-drag-over` on it while a file hovers) holding a glyph box, the title
|
|
89
|
+
* and a sentence, and `label.btn.small` around a visually hidden file input, so the button's
|
|
90
|
+
* word is the input's name.
|
|
91
|
+
*/
|
|
92
|
+
export declare const view: import("foldkit/submodel").View<{
|
|
93
|
+
readonly fileDrop: {
|
|
94
|
+
readonly id: string;
|
|
95
|
+
readonly isDragOver: boolean;
|
|
96
|
+
};
|
|
97
|
+
}, {
|
|
98
|
+
readonly _tag: "GotFileDropMessage";
|
|
99
|
+
readonly message: {
|
|
100
|
+
readonly _tag: "DroppedFiles";
|
|
101
|
+
readonly files: readonly [File, ...File[]];
|
|
102
|
+
} | {
|
|
103
|
+
readonly _tag: "DroppedNonFiles";
|
|
104
|
+
} | {
|
|
105
|
+
readonly _tag: "EnteredDragZone";
|
|
106
|
+
} | {
|
|
107
|
+
readonly _tag: "LeftDragZone";
|
|
108
|
+
};
|
|
109
|
+
}, Readonly<{
|
|
110
|
+
/** Pixel caps: `"Drop files here"`. */
|
|
111
|
+
title: string;
|
|
112
|
+
/** One sentence: what happens to what is dropped. Markup here carries no handlers: a
|
|
113
|
+
* Submodel's viewInputs may hold functions only at the top level. */
|
|
114
|
+
body?: ReadonlyArray<Html | string>;
|
|
115
|
+
/** Under the sentence: a word that says what the last drop did. A function because a
|
|
116
|
+
* Submodel's viewInputs may hold functions only at the top level, and Foldkit runs this one
|
|
117
|
+
* in the parent's boundary, so a handler in it (an undo) dispatches the parent's Message. */
|
|
118
|
+
toStatusView?: () => readonly Html[];
|
|
119
|
+
}>>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { view as view$1 } from "../glyph/glyph.js";
|
|
3
|
+
import { Option, Schema } from "effect";
|
|
4
|
+
import { defineMessageUnion } from "foldkit/message";
|
|
5
|
+
import { FileDrop } from "@foldkit/ui";
|
|
6
|
+
import { modifyFields } from "foldkit/struct";
|
|
7
|
+
import { defineView } from "foldkit/submodel";
|
|
8
|
+
import * as Update from "foldkit/update";
|
|
9
|
+
import * as File from "foldkit/file";
|
|
10
|
+
// src/drop-zone/drop-zone.ts
|
|
11
|
+
/** Schema for a drop zone: the `@foldkit/ui` FileDrop it is built on, which knows whether a
|
|
12
|
+
* file hovers it. */
|
|
13
|
+
const Model = Schema.Struct({ fileDrop: FileDrop.Model });
|
|
14
|
+
/** Union of all Messages a drop zone can produce. */
|
|
15
|
+
const Message = defineMessageUnion({ GotFileDropMessage: { message: FileDrop.Message } });
|
|
16
|
+
/** Union of OutMessages a drop zone reports: files dropped on it or chosen with its button,
|
|
17
|
+
* or a drop that held no files (text, a link). */
|
|
18
|
+
const OutMessage = defineMessageUnion({
|
|
19
|
+
ReceivedFiles: { files: Schema.NonEmptyArray(File.File) },
|
|
20
|
+
RejectedNonFiles: {}
|
|
21
|
+
});
|
|
22
|
+
/** Creates a drop zone with nothing over it. */
|
|
23
|
+
const init = (config) => (__foldkitBrandViewResult(({ fileDrop: FileDrop.init({ id: config.id }) }), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#init"));
|
|
24
|
+
/** The drop zone's id, unique in the document: its file input's id. */
|
|
25
|
+
const id = (model) => __foldkitBrandViewResult((model.fileDrop.id), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#id");
|
|
26
|
+
const foldFileDrop = Update.foldChild({
|
|
27
|
+
update: FileDrop.update,
|
|
28
|
+
read: (model) => __foldkitBrandViewResult((Option.some(model.fileDrop)), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#read"),
|
|
29
|
+
write: (model, nextFileDrop) => __foldkitBrandViewResult((modifyFields(model, { fileDrop: () => __foldkitBrandViewResult((nextFileDrop), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#fileDrop") })), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#write"),
|
|
30
|
+
toParentMessage: (message) => __foldkitBrandViewResult((Message.GotFileDropMessage({ message })), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#toParentMessage"),
|
|
31
|
+
toParentOutMessage: FileDrop.OutMessage.match({
|
|
32
|
+
ReceivedFiles: ({ files }) => __foldkitBrandViewResult((OutMessage.ReceivedFiles({ files })), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#ReceivedFiles"),
|
|
33
|
+
RejectedNonFiles: () => __foldkitBrandViewResult((OutMessage.RejectedNonFiles()), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#RejectedNonFiles")
|
|
34
|
+
})
|
|
35
|
+
});
|
|
36
|
+
/** Processes a drop zone Message and returns the next Model, Commands and OutMessage. */
|
|
37
|
+
const update = (model, message) => __foldkitBrandViewResult((Message.match(message, { GotFileDropMessage: ({ message: fileDropMessage }) => __foldkitBrandViewResult((foldFileDrop(model, fileDropMessage)), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#GotFileDropMessage") })), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#update");
|
|
38
|
+
/**
|
|
39
|
+
* A dashed box that goes solid and tinted while a file hovers it, with a button to choose
|
|
40
|
+
* files for those who cannot drag, built on `@foldkit/ui`'s FileDrop: `div.drop-zone`
|
|
41
|
+
* (FileDrop sets `data-drag-over` on it while a file hovers) holding a glyph box, the title
|
|
42
|
+
* and a sentence, and `label.btn.small` around a visually hidden file input, so the button's
|
|
43
|
+
* word is the input's name.
|
|
44
|
+
*/
|
|
45
|
+
const view = defineView((model, viewInputs, h) => {
|
|
46
|
+
const { title, body = [], toStatusView = () => __foldkitBrandViewResult(([]), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#anonymous~2") } = viewInputs;
|
|
47
|
+
const toView = (groups) => __foldkitBrandViewResult((h.div([...groups.root, h.Class("drop-zone")], [
|
|
48
|
+
h.span([h.Class("drop-zone-glyph")], [view$1({ name: "upload" }, h)]),
|
|
49
|
+
h.p([], [h.strong([], [title]), ...body]),
|
|
50
|
+
...toStatusView(),
|
|
51
|
+
h.label([h.Class("btn small")], ["choose files", h.input(groups.input)])
|
|
52
|
+
])), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#toView");
|
|
53
|
+
return __foldkitBrandViewResult((h.submodel({
|
|
54
|
+
slotId: id(model),
|
|
55
|
+
model: model.fileDrop,
|
|
56
|
+
view: FileDrop.view,
|
|
57
|
+
viewInputs: {
|
|
58
|
+
toView,
|
|
59
|
+
multiple: true
|
|
60
|
+
},
|
|
61
|
+
toParentMessage: (message) => __foldkitBrandViewResult((Message.GotFileDropMessage({ message })), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#toParentMessage~2")
|
|
62
|
+
})), "@gjermundgaraba/pixel-paper/drop-zone/drop-zone.js#anonymous");
|
|
63
|
+
});
|
|
64
|
+
export { Message, Model, OutMessage, id, init, update, view };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { InitConfig, Message, Model, OutMessage, ViewInputs, id, init, update, view } from "./drop-zone.js";
|
|
2
|
+
declare namespace index_d_exports {
|
|
3
|
+
export { InitConfig, Message, Model, OutMessage, ViewInputs, id, init, update, view };
|
|
4
|
+
}
|
|
5
|
+
export { type InitConfig, Message, Model, OutMessage, type ViewInputs, id, index_d_exports, init, update, view };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
3
|
+
import { Message, Model, OutMessage, id, init, update, view } from "./drop-zone.js";
|
|
4
|
+
// src/drop-zone/index.ts
|
|
5
|
+
var drop_zone_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
+
Message: () => __foldkitBrandViewResult((Message), "@gjermundgaraba/pixel-paper/drop-zone/index.js#Message"),
|
|
7
|
+
Model: () => __foldkitBrandViewResult((Model), "@gjermundgaraba/pixel-paper/drop-zone/index.js#Model"),
|
|
8
|
+
OutMessage: () => __foldkitBrandViewResult((OutMessage), "@gjermundgaraba/pixel-paper/drop-zone/index.js#OutMessage"),
|
|
9
|
+
id: () => __foldkitBrandViewResult((id), "@gjermundgaraba/pixel-paper/drop-zone/index.js#id"),
|
|
10
|
+
init: () => __foldkitBrandViewResult((init), "@gjermundgaraba/pixel-paper/drop-zone/index.js#init"),
|
|
11
|
+
update: () => __foldkitBrandViewResult((update), "@gjermundgaraba/pixel-paper/drop-zone/index.js#update"),
|
|
12
|
+
view: () => __foldkitBrandViewResult((view), "@gjermundgaraba/pixel-paper/drop-zone/index.js#view")
|
|
13
|
+
});
|
|
14
|
+
export { Message, Model, OutMessage, drop_zone_exports, id, init, update, view };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Html, HtmlBuilder } from "foldkit/html";
|
|
2
|
+
/** Configuration for rendering an empty state with `view`. */
|
|
3
|
+
export type ViewConfig = Readonly<{
|
|
4
|
+
/** Pixel caps: what is missing (`"Nothing queued"`). */
|
|
5
|
+
title: string;
|
|
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";
|
|
12
|
+
/** One sentence: how it gets filled. */
|
|
13
|
+
body?: ReadonlyArray<Html | string>;
|
|
14
|
+
/** What fills it: a button under the sentence. */
|
|
15
|
+
actions?: ReadonlyArray<Html | string>;
|
|
16
|
+
}>;
|
|
17
|
+
/** What a panel says when it has nothing to show, centred where its content would be. */
|
|
18
|
+
export declare const view: <Message>(config: ViewConfig, h: HtmlBuilder<Message>) => Html;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { Array } from "effect";
|
|
3
|
+
// src/empty-state/empty-state.ts
|
|
4
|
+
/** What a panel says when it has nothing to show, centred where its content would be. */
|
|
5
|
+
const view = (config, h) => {
|
|
6
|
+
const { title, headingLevel, body = [], actions = [] } = config;
|
|
7
|
+
return __foldkitBrandViewResult((h.div([h.Class("empty")], [
|
|
8
|
+
headingLevel === "Strong" ? h.strong([h.Class("empty-title")], [title]) : h[`h${headingLevel}`]([h.Class("empty-title")], [title]),
|
|
9
|
+
...Array.match(body, {
|
|
10
|
+
onEmpty: () => __foldkitBrandViewResult(([]), "@gjermundgaraba/pixel-paper/empty-state/empty-state.js#onEmpty"),
|
|
11
|
+
onNonEmpty: (sentence) => __foldkitBrandViewResult(([h.p([], sentence)]), "@gjermundgaraba/pixel-paper/empty-state/empty-state.js#onNonEmpty")
|
|
12
|
+
}),
|
|
13
|
+
...actions
|
|
14
|
+
])), "@gjermundgaraba/pixel-paper/empty-state/empty-state.js#view");
|
|
15
|
+
};
|
|
16
|
+
export { view };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
3
|
+
import { view } from "./empty-state.js";
|
|
4
|
+
// src/empty-state/index.ts
|
|
5
|
+
var empty_state_exports = /* @__PURE__ */ __exportAll({ view: () => __foldkitBrandViewResult((view), "@gjermundgaraba/pixel-paper/empty-state/index.js#view") });
|
|
6
|
+
export { empty_state_exports, view };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Html, HtmlBuilder } from "foldkit/html";
|
|
2
|
+
/** One field that failed: its control's id and what to do about it. One entry per control:
|
|
3
|
+
* the summary counts entries as fields and keys each by its `id`, so a caller with several
|
|
4
|
+
* messages for one control joins them into one entry. */
|
|
5
|
+
export type FieldError = Readonly<{
|
|
6
|
+
/** The control's id (a Field's, a Choice's box): the link goes there. */
|
|
7
|
+
id: string;
|
|
8
|
+
/** What is wrong and how to put it right: "Enter the owner name." */
|
|
9
|
+
message: string;
|
|
10
|
+
}>;
|
|
11
|
+
/** Configuration for rendering an error summary with `view`. */
|
|
12
|
+
export type ViewConfig = Readonly<{
|
|
13
|
+
/** Unique in the document: the form's failed submit focuses it by this id. */
|
|
14
|
+
id: string;
|
|
15
|
+
/** The fields that failed, one entry per control, in the order of the form. With none,
|
|
16
|
+
* nothing renders. */
|
|
17
|
+
errors: readonly FieldError[];
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Why a form was not sent, above its fields: the error Notice with a headline that counts the
|
|
21
|
+
* failed fields and a link to each, one entry per control. Render it inside the form when a
|
|
22
|
+
* submit fails, from the errors found at that submit, not live state, and mark the same fields
|
|
23
|
+
* invalid; it holds still while they are put right, until the next submit.
|
|
24
|
+
*
|
|
25
|
+
* It is no live region, since one inserted with its words in it is not reliably read: the
|
|
26
|
+
* form's update, at every failed submit, returns `Focus` with the summary's `id`, which moves
|
|
27
|
+
* focus to it once it has rendered and so reads it, also when it was already showing. A
|
|
28
|
+
* refusal that arrives after the submit (a server that turns a field down while the save is
|
|
29
|
+
* busy) is a failed submit like any other: render the summary from it and focus it.
|
|
30
|
+
*
|
|
31
|
+
* Each link is a fragment link to its field; a Foldkit application's fragment handler moves
|
|
32
|
+
* focus there (`SkipLink.ScrollToFragment`).
|
|
33
|
+
*/
|
|
34
|
+
export declare const view: <Message>(config: ViewConfig, h: HtmlBuilder<Message>) => Html;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { toneGlyphView } from "../notice/notice.js";
|
|
3
|
+
import { LOCALE } from "../locale/locale.js";
|
|
4
|
+
import { Array } from "effect";
|
|
5
|
+
// src/error-summary/error-summary.ts
|
|
6
|
+
const headline = (count) => __foldkitBrandViewResult((count === 1 ? "1 field needs attention" : `${count.toLocaleString(LOCALE)} fields need attention`), "@gjermundgaraba/pixel-paper/error-summary/error-summary.js#headline");
|
|
7
|
+
/**
|
|
8
|
+
* Why a form was not sent, above its fields: the error Notice with a headline that counts the
|
|
9
|
+
* failed fields and a link to each, one entry per control. Render it inside the form when a
|
|
10
|
+
* submit fails, from the errors found at that submit, not live state, and mark the same fields
|
|
11
|
+
* invalid; it holds still while they are put right, until the next submit.
|
|
12
|
+
*
|
|
13
|
+
* It is no live region, since one inserted with its words in it is not reliably read: the
|
|
14
|
+
* form's update, at every failed submit, returns `Focus` with the summary's `id`, which moves
|
|
15
|
+
* focus to it once it has rendered and so reads it, also when it was already showing. A
|
|
16
|
+
* refusal that arrives after the submit (a server that turns a field down while the save is
|
|
17
|
+
* busy) is a failed submit like any other: render the summary from it and focus it.
|
|
18
|
+
*
|
|
19
|
+
* Each link is a fragment link to its field; a Foldkit application's fragment handler moves
|
|
20
|
+
* focus there (`SkipLink.ScrollToFragment`).
|
|
21
|
+
*/
|
|
22
|
+
const view = (config, h) => {
|
|
23
|
+
const { id, errors } = config;
|
|
24
|
+
return __foldkitBrandViewResult((Array.match(errors, {
|
|
25
|
+
onEmpty: () => __foldkitBrandViewResult((h.empty), "@gjermundgaraba/pixel-paper/error-summary/error-summary.js#onEmpty"),
|
|
26
|
+
onNonEmpty: (failed) => __foldkitBrandViewResult((h.div([
|
|
27
|
+
h.Id(id),
|
|
28
|
+
h.Tabindex(-1),
|
|
29
|
+
h.Class("notice error error-summary")
|
|
30
|
+
], [toneGlyphView({ tone: "Error" }, h), h.div([], [h.strong([], [headline(failed.length)]), h.ul([], Array.map(failed, ({ id: fieldId, message }) => __foldkitBrandViewResult((h.keyed("li")(fieldId, [], [h.a([h.Href(`#${fieldId}`)], [message])])), "@gjermundgaraba/pixel-paper/error-summary/error-summary.js#anonymous")))])])), "@gjermundgaraba/pixel-paper/error-summary/error-summary.js#onNonEmpty")
|
|
31
|
+
})), "@gjermundgaraba/pixel-paper/error-summary/error-summary.js#view");
|
|
32
|
+
};
|
|
33
|
+
export { view };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
3
|
+
import { view } from "./error-summary.js";
|
|
4
|
+
// src/error-summary/index.ts
|
|
5
|
+
var error_summary_exports = /* @__PURE__ */ __exportAll({ view: () => __foldkitBrandViewResult((view), "@gjermundgaraba/pixel-paper/error-summary/index.js#view") });
|
|
6
|
+
export { error_summary_exports, view };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Attributes } from "../attributes/attributes.js";
|
|
2
|
+
import { Attribute, Html, HtmlBuilder, TextareaAttribute } from "foldkit/html";
|
|
3
|
+
/** Configuration for rendering a text field with `view`. */
|
|
4
|
+
export type ViewConfig<Message> = Readonly<{
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
value: string;
|
|
8
|
+
onInput: (value: string) => Message;
|
|
9
|
+
/** A sans sentence under the control. */
|
|
10
|
+
help?: string;
|
|
11
|
+
/** Why the value was refused: a red sentence under the control, which the control is
|
|
12
|
+
* described by, with red on its rule and its label (`aria-invalid`). Say it again in an
|
|
13
|
+
* ErrorSummary above the form. */
|
|
14
|
+
error?: string | undefined;
|
|
15
|
+
/** The form is not sent without it: screen readers hear "required" (`aria-required`). */
|
|
16
|
+
isRequired?: boolean;
|
|
17
|
+
/** A 2px ink box: the field that is the whole job of its form. A date is always boxed. */
|
|
18
|
+
isBoxed?: boolean;
|
|
19
|
+
/** Code and identifiers: the system monospace. */
|
|
20
|
+
isMono?: boolean;
|
|
21
|
+
/** The label is for screen readers only (`.sr-only`): a field whose place says what it is,
|
|
22
|
+
* such as a browser's address bar. It still names the input. */
|
|
23
|
+
isLabelHidden?: boolean;
|
|
24
|
+
/** The input's type (`"date"` for the browser's date control, always boxed); text when not
|
|
25
|
+
* given. */
|
|
26
|
+
type?: string;
|
|
27
|
+
/** Further attributes for the `<input>`, such as a Dialog's `initialFocus` group; never a
|
|
28
|
+
* class. */
|
|
29
|
+
inputAttributes?: Attributes<Message>;
|
|
30
|
+
}>;
|
|
31
|
+
/** A labelled text input with its help line, built on `@foldkit/ui`'s `Input`: the label
|
|
32
|
+
* names the input, the help line describes it (`aria-describedby`), an `error` sets
|
|
33
|
+
* `aria-invalid` and describes it before the help, and `isRequired` sets `aria-required`.
|
|
34
|
+
* The input is boxless, a dotted baseline that turns solid ink on focus. */
|
|
35
|
+
export declare const view: <Message>(config: ViewConfig<Message>, h: HtmlBuilder<Message>) => Html;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { Input } from "@foldkit/ui";
|
|
3
|
+
// src/field/field.ts
|
|
4
|
+
const errorId = (id) => __foldkitBrandViewResult((`${id}-error`), "@gjermundgaraba/pixel-paper/field/field.js#errorId");
|
|
5
|
+
const errorView = (id, error, h) => __foldkitBrandViewResult((error === void 0 ? [] : [h.p([h.Id(errorId(id)), h.Class("field-error")], [error])]), "@gjermundgaraba/pixel-paper/field/field.js#errorView");
|
|
6
|
+
const describedByError = (id, error, hasHelp, h) => __foldkitBrandViewResult((error === void 0 ? [] : [h.AriaDescribedBy(hasHelp ? `${errorId(id)} ${Input.descriptionId(id)}` : errorId(id))]), "@gjermundgaraba/pixel-paper/field/field.js#describedByError");
|
|
7
|
+
const controlAttributes = (id, error, help, isRequired, h) => __foldkitBrandViewResult(([...describedByError(id, error, help !== void 0, h), ...isRequired ? [h.AriaRequired(true)] : []]), "@gjermundgaraba/pixel-paper/field/field.js#controlAttributes");
|
|
8
|
+
const helpView = (help, description, h) => __foldkitBrandViewResult((help === void 0 ? [] : [h.p([...description, h.Class("field-help")], [help])]), "@gjermundgaraba/pixel-paper/field/field.js#helpView");
|
|
9
|
+
/** A labelled text input with its help line, built on `@foldkit/ui`'s `Input`: the label
|
|
10
|
+
* names the input, the help line describes it (`aria-describedby`), an `error` sets
|
|
11
|
+
* `aria-invalid` and describes it before the help, and `isRequired` sets `aria-required`.
|
|
12
|
+
* The input is boxless, a dotted baseline that turns solid ink on focus. */
|
|
13
|
+
const view = (config, h) => {
|
|
14
|
+
const { id, label, value, onInput, help, error, isRequired = false, isBoxed = false, isMono = false, isLabelHidden = false, type, inputAttributes = [] } = config;
|
|
15
|
+
return __foldkitBrandViewResult((Input.view({
|
|
16
|
+
id,
|
|
17
|
+
value,
|
|
18
|
+
onInput,
|
|
19
|
+
isInvalid: error !== void 0,
|
|
20
|
+
...type !== void 0 && { type },
|
|
21
|
+
hasDescription: help !== void 0,
|
|
22
|
+
toView: (groups) => __foldkitBrandViewResult((h.div([h.Class(`field${isBoxed || type === "date" ? " boxed" : ""}${isMono ? " mono" : ""}`)], [
|
|
23
|
+
h.label([...groups.label, ...isLabelHidden ? [h.Class("sr-only")] : []], [label]),
|
|
24
|
+
h.input([
|
|
25
|
+
...inputAttributes,
|
|
26
|
+
...groups.input,
|
|
27
|
+
...controlAttributes(id, error, help, isRequired, h)
|
|
28
|
+
]),
|
|
29
|
+
...errorView(id, error, h),
|
|
30
|
+
...helpView(help, groups.description, h)
|
|
31
|
+
])), "@gjermundgaraba/pixel-paper/field/field.js#toView")
|
|
32
|
+
}, h)), "@gjermundgaraba/pixel-paper/field/field.js#view");
|
|
33
|
+
};
|
|
34
|
+
export { controlAttributes, errorView, helpView, view };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
3
|
+
import { view } from "./field.js";
|
|
4
|
+
// src/field/index.ts
|
|
5
|
+
var field_exports = /* @__PURE__ */ __exportAll({ view: () => __foldkitBrandViewResult((view), "@gjermundgaraba/pixel-paper/field/index.js#view") });
|
|
6
|
+
export { field_exports, view };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Html, HtmlBuilder } from "foldkit/html";
|
|
2
|
+
/** Configuration for rendering a field grid with `view`. */
|
|
3
|
+
export type ViewConfig = Readonly<{
|
|
4
|
+
/** Fields. */
|
|
5
|
+
body: ReadonlyArray<Html | string>;
|
|
6
|
+
}>;
|
|
7
|
+
/** Fields side by side while they fit, 160px at least each. */
|
|
8
|
+
export declare const view: <Message>(config: ViewConfig, h: HtmlBuilder<Message>) => Html;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
// src/field-grid/field-grid.ts
|
|
3
|
+
/** Fields side by side while they fit, 160px at least each. */
|
|
4
|
+
const view = (config, h) => {
|
|
5
|
+
const { body } = config;
|
|
6
|
+
return __foldkitBrandViewResult((h.div([h.Class("field-grid")], body)), "@gjermundgaraba/pixel-paper/field-grid/field-grid.js#view");
|
|
7
|
+
};
|
|
8
|
+
export { view };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
3
|
+
import { view } from "./field-grid.js";
|
|
4
|
+
// src/field-grid/index.ts
|
|
5
|
+
var field_grid_exports = /* @__PURE__ */ __exportAll({ view: () => __foldkitBrandViewResult((view), "@gjermundgaraba/pixel-paper/field-grid/index.js#view") });
|
|
6
|
+
export { field_grid_exports, view };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
// src/fields/fields.ts
|
|
3
|
+
/** A form's fields, a column 14px apart (a body's gap), in one unnamed `<fieldset>` that
|
|
4
|
+
* `isBusy` disables. */
|
|
5
|
+
const view = (config, h) => {
|
|
6
|
+
const { body, isBusy = false } = config;
|
|
7
|
+
return __foldkitBrandViewResult((h.fieldset([...isBusy ? [h.Disabled(true), h.AriaBusy(true)] : [], h.Class("stack gap-m")], body)), "@gjermundgaraba/pixel-paper/fields/fields.js#view");
|
|
8
|
+
};
|
|
9
|
+
export { view };
|