@gjermundgaraba-designs/pixel-paper 0.20.1 → 0.22.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 +21 -15
- package/dist/src/bench/bench.d.ts +14 -0
- package/dist/src/bench/bench.d.ts.map +1 -0
- package/dist/src/bench/bench.js +9 -0
- package/dist/src/bench/index.d.ts +3 -0
- package/dist/src/bench/index.d.ts.map +1 -0
- package/dist/src/bench/index.js +1 -0
- package/dist/src/chip/chip.d.ts +10 -0
- package/dist/src/chip/chip.d.ts.map +1 -1
- package/dist/src/chip/chip.js +19 -0
- package/dist/src/chip/index.d.ts +2 -2
- package/dist/src/chip/index.d.ts.map +1 -1
- package/dist/src/chip/index.js +1 -1
- package/dist/src/drag/drag.d.ts +18 -0
- package/dist/src/drag/drag.d.ts.map +1 -1
- package/dist/src/drag/drag.js +35 -7
- package/dist/src/field/field.d.ts +3 -0
- package/dist/src/field/field.d.ts.map +1 -1
- package/dist/src/field/field.js +2 -2
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/lineDiff/index.d.ts +2 -0
- package/dist/src/lineDiff/index.d.ts.map +1 -1
- package/dist/src/lineDiff/index.js +1 -0
- package/dist/src/lineDiff/lineDiff.d.ts +8 -4
- package/dist/src/lineDiff/lineDiff.d.ts.map +1 -1
- package/dist/src/lineDiff/lineDiff.js +19 -15
- package/dist/src/lineDiff/patch.d.ts +35 -0
- package/dist/src/lineDiff/patch.d.ts.map +1 -0
- package/dist/src/lineDiff/patch.js +146 -0
- package/dist/src/menu/menu.d.ts +6 -6
- package/dist/src/rail/index.d.ts +1 -1
- package/dist/src/rail/index.d.ts.map +1 -1
- package/dist/src/rail/index.js +1 -1
- package/dist/src/rail/rail.d.ts +217 -17
- package/dist/src/rail/rail.d.ts.map +1 -1
- package/dist/src/rail/rail.js +133 -15
- package/dist/src/reel/index.d.ts +1 -1
- package/dist/src/reel/index.d.ts.map +1 -1
- package/dist/src/reel/index.js +1 -1
- package/dist/src/reel/layout.d.ts +21 -26
- package/dist/src/reel/layout.d.ts.map +1 -1
- package/dist/src/reel/layout.js +84 -106
- package/dist/src/reel/reel.d.ts +30 -172
- package/dist/src/reel/reel.d.ts.map +1 -1
- package/dist/src/reel/reel.js +144 -195
- package/dist/src/rows/rows.d.ts +9 -1
- package/dist/src/rows/rows.d.ts.map +1 -1
- package/dist/src/rows/rows.js +1 -1
- package/dist/src/sortable/sortable.d.ts +30 -30
- package/dist/src/toast/toast.d.ts +12 -12
- package/dist/src/window/window.d.ts +3 -1
- package/dist/src/window/window.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/bench/bench.ts +24 -0
- package/src/bench/index.ts +2 -0
- package/src/chip/chip.ts +31 -0
- package/src/chip/index.ts +2 -2
- package/src/drag/drag.ts +60 -1
- package/src/field/field.ts +5 -1
- package/src/index.ts +1 -0
- package/src/lineDiff/index.ts +2 -0
- package/src/lineDiff/lineDiff.ts +29 -24
- package/src/lineDiff/patch.ts +218 -0
- package/src/pixel-paper.css +202 -32
- package/src/rail/index.ts +2 -0
- package/src/rail/rail.ts +181 -16
- package/src/reel/index.ts +0 -1
- package/src/reel/layout.ts +78 -118
- package/src/reel/reel.ts +108 -216
- package/src/rows/rows.ts +14 -2
- package/src/tokens.css +2 -1
- package/src/window/window.ts +3 -1
package/dist/src/rows/rows.d.ts
CHANGED
|
@@ -47,7 +47,8 @@ export type TreegridPlace = Readonly<{
|
|
|
47
47
|
export type RowConfig<Message> = Readonly<{
|
|
48
48
|
/** The row's stable id among its siblings. */
|
|
49
49
|
key: string;
|
|
50
|
-
/** The 18px glyph slot at the left: a `glyphView`,
|
|
50
|
+
/** The 18px glyph slot at the left: a `glyphView`, a `toggleView`, or a status as a
|
|
51
|
+
* `Chip.dotView`. */
|
|
51
52
|
glyph?: Html;
|
|
52
53
|
/** The row's text; it takes the free width and ellipsises. */
|
|
53
54
|
body: ReadonlyArray<Html | string>;
|
|
@@ -68,6 +69,13 @@ export type RowConfig<Message> = Readonly<{
|
|
|
68
69
|
* after its text for screen readers, which the muting does not reach. In a selectable
|
|
69
70
|
* row the text names the box, so the box's name says it too. */
|
|
70
71
|
isContext?: boolean;
|
|
72
|
+
/** The row's text holds one link (a task, a page), and the row's whole box is its target: a
|
|
73
|
+
* press anywhere on the row follows it, while the row's own controls (the box, a toggle,
|
|
74
|
+
* the actions and tools) and whatever has a tip stay their own targets. The row takes no
|
|
75
|
+
* Tab stop of its own, and the link's ring is drawn round the row. A link that is
|
|
76
|
+
* `aria-current` inverts the row. For a list no keyboard drives: a treegrid's row (with
|
|
77
|
+
* `treegrid`) is already its own stop, and ignores it. */
|
|
78
|
+
isLink?: boolean;
|
|
71
79
|
/** Makes the row selectable: a box at its left edge. */
|
|
72
80
|
select?: RowSelect<Message>;
|
|
73
81
|
/** The row's place in a treegrid; every row of a treegrid has one. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../../src/rows/rows.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAKpD,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,gCAAgC;IAChC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IAC1B,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;gCAE4B;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC,CAAC;AAEH,2BAA2B;AAC3B,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAQzE,CAAC;AAIJ;;+FAE+F;AAC/F,MAAM,MAAM,SAAS,CAAC,OAAO,IAAI,QAAQ,CAAC;IACxC;cACU;IACV,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,OAAO,CAAC;IAC1C;4EACwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH;;uBAEuB;AACvB,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC,CAAC;AAEH,wDAAwD;AACxD,MAAM,MAAM,SAAS,CAAC,OAAO,IAAI,QAAQ,CAAC;IACxC,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ
|
|
1
|
+
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../../src/rows/rows.ts"],"names":[],"mappings":"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"}
|
package/dist/src/rows/rows.js
CHANGED
|
@@ -29,7 +29,7 @@ const textOf = (config, h) => __foldkitBrandViewResult((config.isContext === tru
|
|
|
29
29
|
const lineView = (config, box, text, h) => __foldkitBrandViewResult((h.div([
|
|
30
30
|
...(config.attributes ?? []),
|
|
31
31
|
...rowRole(config.treegrid, h),
|
|
32
|
-
h.Class(config.isContext === true ? "
|
|
32
|
+
h.Class(`row${config.isContext === true ? " context" : ""}${config.isLink === true && config.treegrid === undefined ? " linked" : ""}`),
|
|
33
33
|
], [
|
|
34
34
|
...box,
|
|
35
35
|
...cellView(config, "cell", config.glyph === undefined ? [] : [config.glyph], h),
|
|
@@ -245,8 +245,6 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
245
245
|
}>;
|
|
246
246
|
};
|
|
247
247
|
commands?: Update.Commands<{
|
|
248
|
-
readonly _tag: "PressedEscape";
|
|
249
|
-
} | {
|
|
250
248
|
readonly _tag: "CancelledPointer";
|
|
251
249
|
} | {
|
|
252
250
|
readonly _tag: "CompletedAnnounceReorder";
|
|
@@ -255,9 +253,6 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
255
253
|
} | {
|
|
256
254
|
readonly _tag: "GotDragAndDropMessage";
|
|
257
255
|
readonly message: {
|
|
258
|
-
readonly _tag: "PressedArrowKey";
|
|
259
|
-
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
260
|
-
} | {
|
|
261
256
|
readonly _tag: "ActivatedKeyboardDrag";
|
|
262
257
|
readonly itemId: string;
|
|
263
258
|
readonly containerId: string;
|
|
@@ -284,6 +279,9 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
284
279
|
readonly containerId: string;
|
|
285
280
|
readonly index: number;
|
|
286
281
|
}>;
|
|
282
|
+
} | {
|
|
283
|
+
readonly _tag: "PressedArrowKey";
|
|
284
|
+
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
287
285
|
} | {
|
|
288
286
|
readonly _tag: "PressedDraggable";
|
|
289
287
|
readonly itemId: string;
|
|
@@ -301,6 +299,8 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
301
299
|
readonly clientX: number;
|
|
302
300
|
readonly clientY: number;
|
|
303
301
|
readonly maybeIndex: Option.Option<number>;
|
|
302
|
+
} | {
|
|
303
|
+
readonly _tag: "PressedEscape";
|
|
304
304
|
} | {
|
|
305
305
|
readonly _tag: "PressedGripKey";
|
|
306
306
|
readonly itemId: string;
|
|
@@ -413,8 +413,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
413
413
|
}>;
|
|
414
414
|
}>;
|
|
415
415
|
}, {
|
|
416
|
-
readonly _tag: "PressedEscape";
|
|
417
|
-
} | {
|
|
418
416
|
readonly _tag: "CancelledPointer";
|
|
419
417
|
} | {
|
|
420
418
|
readonly _tag: "CompletedAnnounceReorder";
|
|
@@ -423,9 +421,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
423
421
|
} | {
|
|
424
422
|
readonly _tag: "GotDragAndDropMessage";
|
|
425
423
|
readonly message: {
|
|
426
|
-
readonly _tag: "PressedArrowKey";
|
|
427
|
-
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
428
|
-
} | {
|
|
429
424
|
readonly _tag: "ActivatedKeyboardDrag";
|
|
430
425
|
readonly itemId: string;
|
|
431
426
|
readonly containerId: string;
|
|
@@ -452,6 +447,9 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
452
447
|
readonly containerId: string;
|
|
453
448
|
readonly index: number;
|
|
454
449
|
}>;
|
|
450
|
+
} | {
|
|
451
|
+
readonly _tag: "PressedArrowKey";
|
|
452
|
+
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
455
453
|
} | {
|
|
456
454
|
readonly _tag: "PressedDraggable";
|
|
457
455
|
readonly itemId: string;
|
|
@@ -469,6 +467,8 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
469
467
|
readonly clientX: number;
|
|
470
468
|
readonly clientY: number;
|
|
471
469
|
readonly maybeIndex: Option.Option<number>;
|
|
470
|
+
} | {
|
|
471
|
+
readonly _tag: "PressedEscape";
|
|
472
472
|
} | {
|
|
473
473
|
readonly _tag: "PressedGripKey";
|
|
474
474
|
readonly itemId: string;
|
|
@@ -559,8 +559,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
559
559
|
}>;
|
|
560
560
|
}>;
|
|
561
561
|
}, {
|
|
562
|
-
readonly _tag: "PressedEscape";
|
|
563
|
-
} | {
|
|
564
562
|
readonly _tag: "CancelledPointer";
|
|
565
563
|
} | {
|
|
566
564
|
readonly _tag: "CompletedAnnounceReorder";
|
|
@@ -569,9 +567,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
569
567
|
} | {
|
|
570
568
|
readonly _tag: "GotDragAndDropMessage";
|
|
571
569
|
readonly message: {
|
|
572
|
-
readonly _tag: "PressedArrowKey";
|
|
573
|
-
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
574
|
-
} | {
|
|
575
570
|
readonly _tag: "ActivatedKeyboardDrag";
|
|
576
571
|
readonly itemId: string;
|
|
577
572
|
readonly containerId: string;
|
|
@@ -598,6 +593,9 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
598
593
|
readonly containerId: string;
|
|
599
594
|
readonly index: number;
|
|
600
595
|
}>;
|
|
596
|
+
} | {
|
|
597
|
+
readonly _tag: "PressedArrowKey";
|
|
598
|
+
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
601
599
|
} | {
|
|
602
600
|
readonly _tag: "PressedDraggable";
|
|
603
601
|
readonly itemId: string;
|
|
@@ -615,6 +613,8 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
615
613
|
readonly clientX: number;
|
|
616
614
|
readonly clientY: number;
|
|
617
615
|
readonly maybeIndex: Option.Option<number>;
|
|
616
|
+
} | {
|
|
617
|
+
readonly _tag: "PressedEscape";
|
|
618
618
|
} | {
|
|
619
619
|
readonly _tag: "PressedGripKey";
|
|
620
620
|
readonly itemId: string;
|
|
@@ -710,8 +710,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
710
710
|
}>;
|
|
711
711
|
}>;
|
|
712
712
|
}, {
|
|
713
|
-
readonly _tag: "PressedEscape";
|
|
714
|
-
} | {
|
|
715
713
|
readonly _tag: "CancelledPointer";
|
|
716
714
|
} | {
|
|
717
715
|
readonly _tag: "CompletedAnnounceReorder";
|
|
@@ -720,9 +718,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
720
718
|
} | {
|
|
721
719
|
readonly _tag: "GotDragAndDropMessage";
|
|
722
720
|
readonly message: {
|
|
723
|
-
readonly _tag: "PressedArrowKey";
|
|
724
|
-
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
725
|
-
} | {
|
|
726
721
|
readonly _tag: "ActivatedKeyboardDrag";
|
|
727
722
|
readonly itemId: string;
|
|
728
723
|
readonly containerId: string;
|
|
@@ -749,6 +744,9 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
749
744
|
readonly containerId: string;
|
|
750
745
|
readonly index: number;
|
|
751
746
|
}>;
|
|
747
|
+
} | {
|
|
748
|
+
readonly _tag: "PressedArrowKey";
|
|
749
|
+
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
752
750
|
} | {
|
|
753
751
|
readonly _tag: "PressedDraggable";
|
|
754
752
|
readonly itemId: string;
|
|
@@ -766,6 +764,8 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
766
764
|
readonly clientX: number;
|
|
767
765
|
readonly clientY: number;
|
|
768
766
|
readonly maybeIndex: Option.Option<number>;
|
|
767
|
+
} | {
|
|
768
|
+
readonly _tag: "PressedEscape";
|
|
769
769
|
} | {
|
|
770
770
|
readonly _tag: "PressedGripKey";
|
|
771
771
|
readonly itemId: string;
|
|
@@ -857,8 +857,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
857
857
|
}>;
|
|
858
858
|
}>;
|
|
859
859
|
}, {
|
|
860
|
-
readonly _tag: "PressedEscape";
|
|
861
|
-
} | {
|
|
862
860
|
readonly _tag: "CancelledPointer";
|
|
863
861
|
} | {
|
|
864
862
|
readonly _tag: "CompletedAnnounceReorder";
|
|
@@ -867,9 +865,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
867
865
|
} | {
|
|
868
866
|
readonly _tag: "GotDragAndDropMessage";
|
|
869
867
|
readonly message: {
|
|
870
|
-
readonly _tag: "PressedArrowKey";
|
|
871
|
-
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
872
|
-
} | {
|
|
873
868
|
readonly _tag: "ActivatedKeyboardDrag";
|
|
874
869
|
readonly itemId: string;
|
|
875
870
|
readonly containerId: string;
|
|
@@ -896,6 +891,9 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
896
891
|
readonly containerId: string;
|
|
897
892
|
readonly index: number;
|
|
898
893
|
}>;
|
|
894
|
+
} | {
|
|
895
|
+
readonly _tag: "PressedArrowKey";
|
|
896
|
+
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
899
897
|
} | {
|
|
900
898
|
readonly _tag: "PressedDraggable";
|
|
901
899
|
readonly itemId: string;
|
|
@@ -913,6 +911,8 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
913
911
|
readonly clientX: number;
|
|
914
912
|
readonly clientY: number;
|
|
915
913
|
readonly maybeIndex: Option.Option<number>;
|
|
914
|
+
} | {
|
|
915
|
+
readonly _tag: "PressedEscape";
|
|
916
916
|
} | {
|
|
917
917
|
readonly _tag: "PressedGripKey";
|
|
918
918
|
readonly itemId: string;
|
|
@@ -1055,8 +1055,6 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
1055
1055
|
}>;
|
|
1056
1056
|
}>;
|
|
1057
1057
|
}, {
|
|
1058
|
-
readonly _tag: "PressedEscape";
|
|
1059
|
-
} | {
|
|
1060
1058
|
readonly _tag: "CancelledPointer";
|
|
1061
1059
|
} | {
|
|
1062
1060
|
readonly _tag: "CompletedAnnounceReorder";
|
|
@@ -1065,9 +1063,6 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
1065
1063
|
} | {
|
|
1066
1064
|
readonly _tag: "GotDragAndDropMessage";
|
|
1067
1065
|
readonly message: {
|
|
1068
|
-
readonly _tag: "PressedArrowKey";
|
|
1069
|
-
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
1070
|
-
} | {
|
|
1071
1066
|
readonly _tag: "ActivatedKeyboardDrag";
|
|
1072
1067
|
readonly itemId: string;
|
|
1073
1068
|
readonly containerId: string;
|
|
@@ -1094,6 +1089,9 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
1094
1089
|
readonly containerId: string;
|
|
1095
1090
|
readonly index: number;
|
|
1096
1091
|
}>;
|
|
1092
|
+
} | {
|
|
1093
|
+
readonly _tag: "PressedArrowKey";
|
|
1094
|
+
readonly direction: "Down" | "Left" | "NextContainer" | "PreviousContainer" | "Right" | "Up";
|
|
1097
1095
|
} | {
|
|
1098
1096
|
readonly _tag: "PressedDraggable";
|
|
1099
1097
|
readonly itemId: string;
|
|
@@ -1111,6 +1109,8 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
1111
1109
|
readonly clientX: number;
|
|
1112
1110
|
readonly clientY: number;
|
|
1113
1111
|
readonly maybeIndex: Option.Option<number>;
|
|
1112
|
+
} | {
|
|
1113
|
+
readonly _tag: "PressedEscape";
|
|
1114
1114
|
} | {
|
|
1115
1115
|
readonly _tag: "PressedGripKey";
|
|
1116
1116
|
readonly itemId: string;
|
|
@@ -326,6 +326,8 @@ 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
|
+
} | {
|
|
329
331
|
readonly _tag: "Dismissing";
|
|
330
332
|
readonly offsetX: number;
|
|
331
333
|
readonly direction: "Left" | "Right";
|
|
@@ -334,8 +336,6 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
334
336
|
readonly pointerId: number;
|
|
335
337
|
readonly startX: number;
|
|
336
338
|
readonly currentX: number;
|
|
337
|
-
} | {
|
|
338
|
-
readonly _tag: "Idle";
|
|
339
339
|
} | {
|
|
340
340
|
readonly _tag: "Settling";
|
|
341
341
|
readonly offsetX: number;
|
|
@@ -371,15 +371,15 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
371
371
|
readonly _tag: "GotAnimationMessage";
|
|
372
372
|
readonly entryId: string;
|
|
373
373
|
readonly message: {
|
|
374
|
+
readonly _tag: "Hid";
|
|
375
|
+
} | {
|
|
376
|
+
readonly _tag: "Showed";
|
|
377
|
+
} | {
|
|
374
378
|
readonly _tag: "CompletedWaitForPaint";
|
|
375
379
|
readonly generation: number;
|
|
376
380
|
} | {
|
|
377
381
|
readonly _tag: "EndedAnimation";
|
|
378
382
|
readonly generation: number;
|
|
379
|
-
} | {
|
|
380
|
-
readonly _tag: "Hid";
|
|
381
|
-
} | {
|
|
382
|
-
readonly _tag: "Showed";
|
|
383
383
|
};
|
|
384
384
|
} | {
|
|
385
385
|
readonly _tag: "HoveredEntry";
|
|
@@ -557,6 +557,8 @@ 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
|
+
} | {
|
|
560
562
|
readonly _tag: "Dismissing";
|
|
561
563
|
readonly offsetX: number;
|
|
562
564
|
readonly direction: "Left" | "Right";
|
|
@@ -565,8 +567,6 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
565
567
|
readonly pointerId: number;
|
|
566
568
|
readonly startX: number;
|
|
567
569
|
readonly currentX: number;
|
|
568
|
-
} | {
|
|
569
|
-
readonly _tag: "Idle";
|
|
570
570
|
} | {
|
|
571
571
|
readonly _tag: "Settling";
|
|
572
572
|
readonly offsetX: number;
|
|
@@ -602,15 +602,15 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
602
602
|
readonly _tag: "GotAnimationMessage";
|
|
603
603
|
readonly entryId: string;
|
|
604
604
|
readonly message: {
|
|
605
|
+
readonly _tag: "Hid";
|
|
606
|
+
} | {
|
|
607
|
+
readonly _tag: "Showed";
|
|
608
|
+
} | {
|
|
605
609
|
readonly _tag: "CompletedWaitForPaint";
|
|
606
610
|
readonly generation: number;
|
|
607
611
|
} | {
|
|
608
612
|
readonly _tag: "EndedAnimation";
|
|
609
613
|
readonly generation: number;
|
|
610
|
-
} | {
|
|
611
|
-
readonly _tag: "Hid";
|
|
612
|
-
} | {
|
|
613
|
-
readonly _tag: "Showed";
|
|
614
614
|
};
|
|
615
615
|
} | {
|
|
616
616
|
readonly _tag: "HoveredEntry";
|
|
@@ -12,7 +12,9 @@ export type ViewConfig<Message> = Readonly<{
|
|
|
12
12
|
glyph?: GlyphName;
|
|
13
13
|
/** A chip in the title bar: its state. */
|
|
14
14
|
status?: ReadonlyArray<Html | string>;
|
|
15
|
-
/** IconButtons in the title bar, before the close.
|
|
15
|
+
/** IconButtons in the title bar, before the close. A child Submodel, whose view is one
|
|
16
|
+
* `Html`, hands back several in a `span.window-tools`: it is no box of its own
|
|
17
|
+
* (`display: contents`), so its buttons sit in the bar as the others do. */
|
|
16
18
|
tools?: ReadonlyArray<Html>;
|
|
17
19
|
/** The close glyph's Message; the glyph prints when it is given. */
|
|
18
20
|
onClose?: Message;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../../src/window/window.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAOpD,wDAAwD;AACxD,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,oFAAoF;IACpF,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,IAAI,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3B,+DAA+D;IAC/D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACtC
|
|
1
|
+
{"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../../src/window/window.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAOpD,wDAAwD;AACxD,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,oFAAoF;IACpF,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,IAAI,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3B,+DAA+D;IAC/D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACtC;;iFAE6E;IAC7E,KAAK,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IAC5B,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACnC,iEAAiE;IACjE,IAAI,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACpC,8DAA8D;IAC9D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC,CAAC;AAEH;;6DAE6D;AAC7D,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAsCpF,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Html, HtmlBuilder } from "foldkit/html";
|
|
2
|
+
|
|
3
|
+
// VIEW
|
|
4
|
+
|
|
5
|
+
/** Configuration for rendering a bench with `view`. */
|
|
6
|
+
export type ViewConfig = Readonly<{
|
|
7
|
+
/** Above the work, at its own height: a PageHead, notices, and a Rail's open button first. */
|
|
8
|
+
head: ReadonlyArray<Html | string>;
|
|
9
|
+
/** The work, taking the rest of the window's height: a Reel, which fills it. */
|
|
10
|
+
body: ReadonlyArray<Html | string>;
|
|
11
|
+
}>;
|
|
12
|
+
|
|
13
|
+
/** A page whose work is the window: its head at its own height, then the work in all the
|
|
14
|
+
* height left, from under the top bar to the window's bottom and edge to edge (beside a Rail,
|
|
15
|
+
* from the rail's edge). The main landmark (`<main id="main">`). The page does not scroll;
|
|
16
|
+
* the work scrolls itself where it must (a reel's columns, sideways). */
|
|
17
|
+
export const view = <Message>(config: ViewConfig, h: HtmlBuilder<Message>): Html => {
|
|
18
|
+
const { head, body } = config;
|
|
19
|
+
|
|
20
|
+
return h.main(
|
|
21
|
+
[h.Id("main"), h.Class("bench")],
|
|
22
|
+
[h.div([h.Class("bench-head")], head), h.div([h.Class("bench-work")], body)],
|
|
23
|
+
);
|
|
24
|
+
};
|
package/src/chip/chip.ts
CHANGED
|
@@ -37,3 +37,34 @@ export const view = <Message>(config: ViewConfig, h: HtmlBuilder<Message>): Html
|
|
|
37
37
|
[label, ...(isBusy ? [h.span([h.Class("cursor"), h.AriaHidden(true)])] : [])],
|
|
38
38
|
);
|
|
39
39
|
};
|
|
40
|
+
|
|
41
|
+
// DOT
|
|
42
|
+
|
|
43
|
+
/** Configuration for rendering a dot with `dotView`. */
|
|
44
|
+
export type DotConfig = Readonly<{
|
|
45
|
+
/** The state word: the dot's accessible name and its tip. */
|
|
46
|
+
label: string;
|
|
47
|
+
tone?: Tone;
|
|
48
|
+
}>;
|
|
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
|
+
/** A chip as a 10px cell in its tone, where a word would take the room a title needs (a task
|
|
59
|
+
* row's status, before its title). It is an image (`role="img"`) named by the word, which its
|
|
60
|
+
* tip shows, so the state never rests on its colour. */
|
|
61
|
+
export const dotView = <Message>(config: DotConfig, h: HtmlBuilder<Message>): Html => {
|
|
62
|
+
const { label, tone = "Plain" } = config;
|
|
63
|
+
|
|
64
|
+
return h.span([
|
|
65
|
+
h.Role("img"),
|
|
66
|
+
h.AriaLabel(label),
|
|
67
|
+
h.DataAttribute("tip", label),
|
|
68
|
+
h.Class(DOT_CLASS[tone]),
|
|
69
|
+
]);
|
|
70
|
+
};
|
package/src/chip/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { view } from "./chip.ts";
|
|
2
|
-
export type { Tone, ViewConfig } from "./chip.ts";
|
|
1
|
+
export { dotView, view } from "./chip.ts";
|
|
2
|
+
export type { DotConfig, Tone, ViewConfig } from "./chip.ts";
|
package/src/drag/drag.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
// Shared by Board and Sortable, the two users of @foldkit/ui's DragAndDrop, and Reel, which
|
|
2
2
|
// holds its own: the phase a drag is in, the DragAndDrop Messages both build, what a press
|
|
3
3
|
// lifts, Escape taken before anything else, the pressing pointer's events, the lifted copy's
|
|
4
|
-
// measure, and the closest-centre drop target a sortable resolves for a pointer.
|
|
4
|
+
// measure, and the closest-centre drop target a sortable resolves for a pointer. A splitter's
|
|
5
|
+
// handlers are the Reel's and the Rail's.
|
|
5
6
|
|
|
6
7
|
import { DragAndDrop as UiDragAndDrop } from "@foldkit/ui";
|
|
7
8
|
import { Array, Effect, Option, Order, Stream, pipe } from "effect";
|
|
8
9
|
import * as Dom from "foldkit/dom";
|
|
10
|
+
import type { Attribute, HtmlBuilder } from "foldkit/html";
|
|
11
|
+
|
|
12
|
+
import { isPlain } from "../keys/keys.ts";
|
|
9
13
|
|
|
10
14
|
// PHASE
|
|
11
15
|
|
|
@@ -125,6 +129,61 @@ export const pressingPointer = (pointerId: number): Stream.Stream<PointerEvent>
|
|
|
125
129
|
(event) => event.pointerId === pointerId,
|
|
126
130
|
);
|
|
127
131
|
|
|
132
|
+
/** What the pressing pointer `pointerId` does, as Messages: each move, the release and the
|
|
133
|
+
* browser's cancel. */
|
|
134
|
+
export const pointerMessages = <Message>(
|
|
135
|
+
pointerId: number,
|
|
136
|
+
toMessage: Readonly<{
|
|
137
|
+
moved: (event: PointerEvent) => Message;
|
|
138
|
+
released: (event: PointerEvent) => Message;
|
|
139
|
+
cancelled: () => Message;
|
|
140
|
+
}>,
|
|
141
|
+
): Stream.Stream<Message> =>
|
|
142
|
+
Stream.map(pressingPointer(pointerId), (event) => {
|
|
143
|
+
if (event.type === "pointermove") {
|
|
144
|
+
return toMessage.moved(event);
|
|
145
|
+
} else if (event.type === "pointerup") {
|
|
146
|
+
return toMessage.released(event);
|
|
147
|
+
} else {
|
|
148
|
+
return toMessage.cancelled();
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// SPLITTER
|
|
153
|
+
|
|
154
|
+
/** A splitter's handlers. The main button of a pointer presses it (`onPress`, while
|
|
155
|
+
* `isIdle`), and its arrows, unmodified, step it (`onStep`, one way or the other): the side
|
|
156
|
+
* arrows across a `"vertical"` splitter (it sizes a width), up and down along a
|
|
157
|
+
* `"horizontal"` one (a height). A modified arrow is the application's. */
|
|
158
|
+
export const splitterAttributes = <Message>(
|
|
159
|
+
config: Readonly<{
|
|
160
|
+
orientation: "vertical" | "horizontal";
|
|
161
|
+
isIdle: boolean;
|
|
162
|
+
onPress: (pointerId: number, clientX: number, clientY: number) => Message;
|
|
163
|
+
onStep: (direction: -1 | 1) => Message;
|
|
164
|
+
}>,
|
|
165
|
+
h: HtmlBuilder<Message>,
|
|
166
|
+
): ReadonlyArray<Attribute<Message>> => {
|
|
167
|
+
const [less, more] =
|
|
168
|
+
config.orientation === "vertical" ? ["ArrowLeft", "ArrowRight"] : ["ArrowUp", "ArrowDown"];
|
|
169
|
+
return [
|
|
170
|
+
h.AriaOrientation(config.orientation),
|
|
171
|
+
h.OnPointerDown(
|
|
172
|
+
(_pointerType, button, _screenX, _screenY, _time, clientX, clientY, pointerId) =>
|
|
173
|
+
Option.liftPredicate(
|
|
174
|
+
config.onPress(pointerId, clientX, clientY),
|
|
175
|
+
() => button === LEFT_BUTTON && config.isIdle,
|
|
176
|
+
),
|
|
177
|
+
),
|
|
178
|
+
h.OnKeyDownPreventDefault((key, modifiers) =>
|
|
179
|
+
Option.liftPredicate(
|
|
180
|
+
config.onStep(key === more ? 1 : -1),
|
|
181
|
+
() => isPlain(modifiers) && (key === less || key === more),
|
|
182
|
+
),
|
|
183
|
+
),
|
|
184
|
+
];
|
|
185
|
+
};
|
|
186
|
+
|
|
128
187
|
// LIFTED COPY
|
|
129
188
|
|
|
130
189
|
/** Sizes the copy that follows the pointer to the element `sourceSelector` finds, and keeps the
|
package/src/field/field.ts
CHANGED
|
@@ -48,6 +48,9 @@ export type ViewConfig<Message> = Readonly<{
|
|
|
48
48
|
isBoxed?: boolean;
|
|
49
49
|
/** Code and identifiers: the system monospace. */
|
|
50
50
|
isMono?: boolean;
|
|
51
|
+
/** The label is for screen readers only (`.sr-only`): a field whose place says what it is,
|
|
52
|
+
* such as a browser's address bar. It still names the input. */
|
|
53
|
+
isLabelHidden?: boolean;
|
|
51
54
|
/** The input's type (`"date"` for the browser's date control, always boxed); text when not
|
|
52
55
|
* given. */
|
|
53
56
|
type?: string;
|
|
@@ -71,6 +74,7 @@ export const view = <Message>(config: ViewConfig<Message>, h: HtmlBuilder<Messag
|
|
|
71
74
|
isRequired = false,
|
|
72
75
|
isBoxed = false,
|
|
73
76
|
isMono = false,
|
|
77
|
+
isLabelHidden = false,
|
|
74
78
|
type,
|
|
75
79
|
inputAttributes = [],
|
|
76
80
|
} = config;
|
|
@@ -87,7 +91,7 @@ export const view = <Message>(config: ViewConfig<Message>, h: HtmlBuilder<Messag
|
|
|
87
91
|
h.div(
|
|
88
92
|
[h.Class(`field${isBoxed || type === "date" ? " boxed" : ""}${isMono ? " mono" : ""}`)],
|
|
89
93
|
[
|
|
90
|
-
h.label(groups.label, [label]),
|
|
94
|
+
h.label([...groups.label, ...(isLabelHidden ? [h.Class("sr-only")] : [])], [label]),
|
|
91
95
|
// NOTE: @foldkit/ui gap: Input has no required option, so the wrapper says it.
|
|
92
96
|
h.input([
|
|
93
97
|
...inputAttributes,
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * as Announcer from "./announcer/index.ts";
|
|
|
2
2
|
export * as AudioFrame from "./audioFrame/index.ts";
|
|
3
3
|
export * as Banner from "./banner/index.ts";
|
|
4
4
|
export * as BarChart from "./barChart/index.ts";
|
|
5
|
+
export * as Bench from "./bench/index.ts";
|
|
5
6
|
export * as Board from "./board/index.ts";
|
|
6
7
|
export * as Button from "./button/index.ts";
|
|
7
8
|
export * as Card from "./card/index.ts";
|
package/src/lineDiff/index.ts
CHANGED
package/src/lineDiff/lineDiff.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import { Array, Option
|
|
1
|
+
import { Array, Option } from "effect";
|
|
2
2
|
import type { Html, HtmlBuilder } from "foldkit/html";
|
|
3
3
|
|
|
4
4
|
import { LOCALE } from "../locale/locale.ts";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
type LineKind,
|
|
8
|
-
diffRowsOf,
|
|
9
|
-
diffRowsOfPatch,
|
|
10
|
-
foldUnchanged,
|
|
11
|
-
hasChanges,
|
|
12
|
-
} from "./diff.ts";
|
|
5
|
+
import { DiffRow, type LineKind, diffRowsOf, foldUnchanged, hasChanges } from "./diff.ts";
|
|
6
|
+
import { SAME_NOTE, readPatch } from "./patch.ts";
|
|
13
7
|
|
|
14
8
|
// VIEW
|
|
15
9
|
|
|
@@ -29,7 +23,8 @@ export type ViewConfig = Readonly<{
|
|
|
29
23
|
|
|
30
24
|
/** Configuration for rendering a unified diff with `patchView`. */
|
|
31
25
|
export type PatchViewConfig = Readonly<{
|
|
32
|
-
/** One file's unified diff, as `diff -u` or `git diff -- <path>` writes it
|
|
26
|
+
/** One file's unified diff, as `diff -u` or `git diff -- <path>` writes it, its git header
|
|
27
|
+
* included. */
|
|
33
28
|
patch: string;
|
|
34
29
|
/** Names the two sides for screen readers: `"Version 3 against version 4"`. */
|
|
35
30
|
label: string;
|
|
@@ -86,8 +81,6 @@ const rowView = <Message>(row: DiffRow, h: HtmlBuilder<Message>): Html =>
|
|
|
86
81
|
const noteView = <Message>(note: string, h: HtmlBuilder<Message>): Html =>
|
|
87
82
|
h.p([h.Class("note-line")], [note]);
|
|
88
83
|
|
|
89
|
-
const SAME_NOTE = "No difference: both sides hold the same text.";
|
|
90
|
-
|
|
91
84
|
const tableView = <Message>(
|
|
92
85
|
rows: ReadonlyArray<DiffRow>,
|
|
93
86
|
label: string,
|
|
@@ -123,18 +116,30 @@ export const view = <Message>(config: ViewConfig, h: HtmlBuilder<Message>): Html
|
|
|
123
116
|
/** A unified diff the caller already has (from a server, or `git diff -- <path>`) as `view`'s
|
|
124
117
|
* table: its hunks' lines, numbered from their headers, and the unchanged lines between hunks
|
|
125
118
|
* folded into a counted row. Lines past the last hunk are not in the patch, so nothing counts
|
|
126
|
-
* them.
|
|
127
|
-
*
|
|
128
|
-
*
|
|
119
|
+
* them. What git's header says beyond the lines prints as a note line above the table, or in
|
|
120
|
+
* its place: a rename, a mode change, an empty or binary file (`describePatch` has the
|
|
121
|
+
* sentences). A file whose type changed (a file that became a symlink) is two sections, each
|
|
122
|
+
* its own table under one note, named for its side (`"<label>, as it was"`). An empty patch
|
|
123
|
+
* says there is no difference, as `view` does; text that is not a diff, or holds several
|
|
124
|
+
* files, says it cannot be shown as lines. */
|
|
129
125
|
export const patchView = <Message>(config: PatchViewConfig, h: HtmlBuilder<Message>): Html => {
|
|
130
126
|
const { patch, label } = config;
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
127
|
+
const { notes, tables } = readPatch(patch);
|
|
128
|
+
const parts = [
|
|
129
|
+
...(Array.isReadonlyArrayNonEmpty(notes) ? [noteView(Array.join(notes, " "), h)] : []),
|
|
130
|
+
...Array.map(tables, ({ rows, maybeSide }) =>
|
|
131
|
+
tableView(
|
|
132
|
+
rows,
|
|
133
|
+
Option.match(maybeSide, { onNone: () => label, onSome: (side) => `${label}, ${side}` }),
|
|
134
|
+
h,
|
|
135
|
+
),
|
|
136
|
+
),
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
// a lone table or note is drawn bare, so a flush window's body still meets its table
|
|
140
|
+
return Array.match(parts, {
|
|
141
|
+
onEmpty: () => noteView(SAME_NOTE, h),
|
|
142
|
+
onNonEmpty: ([part, ...others]) =>
|
|
143
|
+
Array.isArrayEmpty(others) ? part : h.div([h.Class("stack gap-s")], parts),
|
|
144
|
+
});
|
|
140
145
|
};
|