@gjermundgaraba-designs/pixel-paper 0.16.0 → 0.17.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 CHANGED
@@ -1097,7 +1097,7 @@ One keyboard for the page, Vim first, with the arrows beside the letters. The ke
1097
1097
 
1098
1098
  ### Sortable
1099
1099
 
1100
- **Sortable** (Submodel over `@foldkit/ui`'s DragAndDrop, for items the reader puts in order: a list of rows, a grid of tiles, or a grid of the page's panels) → `div.sortable (.grid, .panels)` holding `ul.sortable-items[aria-label]` (a plain list: no listbox, so an item's content may hold anything) of `li.sortable-item (.movable, .drag-dim, .drop-before, .drop-after)`, each a grip, then `div.sortable-body` with the parent's content, and the list's keyboard help in a `p.sr-only`. `"List"` (the default) prints rows edge to edge between 1px rules, for a flush panel, `8px 16px 8px 10px`, tinted head on hover; `"Grid"` prints tiles that wrap, 180px and up, 12px apart: paper slips in a 2px ink border on the 3px print shadow. `"Panels"` prints each item as the parent's own Panel, up to three across in the deck's 24px gutter and 300px and up, so two across and then one as the column narrows; a row takes its tallest panel's height, each panel's foot sits at its bottom, and the list hands each item its grip (`render.grip`) for the panel's `lead` instead of printing it beside the item. The held copy is the whole panel, tinted head on the 8px card shadow, under ids of its own, and the drop line runs down the middle of the gutter. `isReadOnly`, for a reader who may look but not reorder, prints every grip held and lifts nothing, as holding moves does. Each item starts with a quiet `button.iconbtn` grip (in a panel's title bar, for `"Panels"`) (the grip glyph, named "Move <label>", `aria-roledescription="draggable"`, `aria-pressed`, described by the keyboard help); while moves are held it stays, held (`aria-disabled`, in the keyboard), so focus on it stays put when holding moves cancels one. A mouse drags an item by its body or its grip (`cursor: grab`); touch takes the grip alone (`touch-action: none` on a movable grip only, so a finger on a row scrolls the page); the keyboard takes the grip too: Space or Enter picks the item up, every arrow moves it one place in reading order, Space or Enter drops it, Escape puts it back (taken before a dialog or the page's keys see it), and Tab leaves it where it is. A press on a control inside an item, or on anything `[data-no-lift]`, never lifts it. Only the pointer that pressed moves the item; the browser cancelling it puts the item back. The held item dims to 40% in place (`.drag-dim`) and keeps its own print; a copy of it, `.lifted`, tinted head on the 8px card shadow in a 2px ink border (`aria-hidden`, `inert`, rendered with `isLifted`, so it carries no ids), follows the pointer in `div.sortable-lift`, or, held by the keyboard, prints in the list where it would land, in `li.sortable-slot`, counted as no item. Where a pointer would drop it, a 2px dashed ink line prints beside the item it lands next to (`.drop-before`, or `.drop-after` past the last), over the layout, so nothing moves under the pointer. The pointer's place is read from the item whose centre is closest, across where items sit side by side and down a column, and read again where the pointer is let go, so a page that scrolled under a still pointer drops where the pointer is. Each step is said through the page's live region in words from the item's `label` and its place, counted from one ("Beta, 3 of 4."). The items are the parent's: a drop reports `Moved`, and the parent moves the item, or decides not to, and flashes it; a drop where the item was, outside the list, or while moves are held reports nothing. While a pointer presses or carries an item the page's root carries `data-pixel-paper-dragging`, which prints the grabbing cursor everywhere and holds text selection.
1100
+ **Sortable** (Submodel over `@foldkit/ui`'s DragAndDrop, for items the reader puts in order: a list of rows, a grid of tiles, or a grid of the page's panels) → `div.sortable (.grid, .panels)` holding `ul.sortable-items[aria-label]` (a plain list: no listbox, so an item's content may hold anything) of `li.sortable-item (.movable, .drag-dim, .drop-before, .drop-after)`, each a grip, then `div.sortable-body` with the parent's content, and the list's keyboard help in a `p.sr-only`. `"List"` (the default) prints rows edge to edge between 1px rules, for a flush panel, `8px 16px 8px 10px`; `"Grid"` prints tiles that wrap, 180px and up, 12px apart: paper slips in a 2px ink border on the 3px print shadow. `"Panels"` prints each item as the parent's own Panel, up to three across in the deck's 24px gutter and 300px and up, so two across and then one as the column narrows; a row takes its tallest panel's height, each panel's foot sits at its bottom, and the list hands each item its grip (`render.grip`) for the panel's `lead` instead of printing it beside the item. The held copy is the whole panel, tinted head on the 8px card shadow, under ids of its own, and the drop line runs down the middle of the gutter. `isReadOnly`, for a reader who may look but not reorder, prints every grip held and lifts nothing, as holding moves does. Each item starts with a quiet `button.iconbtn` grip (in a panel's title bar, for `"Panels"`) (the grip glyph, named "Move <label>", `aria-roledescription="draggable"`, `aria-pressed`, described by the keyboard help); while moves are held it stays, held (`aria-disabled`, in the keyboard), so focus on it stays put when holding moves cancels one. Only the grip lifts an item, under a mouse, a finger or a pen (`cursor: grab` and `touch-action: none` on a movable grip only), so the rest of an item selects its text and a finger on it scrolls the page; the keyboard takes the grip too: Space or Enter picks the item up, every arrow moves it one place in reading order, Space or Enter drops it, Escape puts it back (taken before a dialog or the page's keys see it), and Tab leaves it where it is. Only the pointer that pressed moves the item; the browser cancelling it puts the item back. The held item dims to 40% in place (`.drag-dim`) and keeps its own print; a copy of it, `.lifted`, tinted head on the 8px card shadow in a 2px ink border (`aria-hidden`, `inert`, rendered with `isLifted`, so it carries no ids), follows the pointer in `div.sortable-lift`, or, held by the keyboard, prints in the list where it would land, in `li.sortable-slot`, counted as no item. Where a pointer would drop it, a 2px dashed ink line prints beside the item it lands next to (`.drop-before`, or `.drop-after` past the last), over the layout, so nothing moves under the pointer. The pointer's place is read from the item whose centre is closest, across where items sit side by side and down a column, and read again where the pointer is let go, so a page that scrolled under a still pointer drops where the pointer is. Each step is said through the page's live region in words from the item's `label` and its place, counted from one ("Beta, 3 of 4."). The items are the parent's: a drop reports `Moved`, and the parent moves the item, or decides not to, and flashes it; a drop where the item was, outside the list, or while moves are held reports nothing. While a pointer presses or carries an item the page's root carries `data-pixel-paper-dragging`, which prints the grabbing cursor everywhere and holds text selection.
1101
1101
 
1102
1102
  ### Inputs / Fields
1103
1103
 
@@ -1,3 +1,3 @@
1
- export { AnnounceReorder, Item, Message, Model, OutMessage, SizeLiftedItem, init, setMovable, subscriptions, update, view, } from "./sortable.ts";
1
+ export { AnnounceReorder, Item, Message, Model, OutMessage, SizeLiftedItem, init, isHolding, setMovable, subscriptions, update, view, } from "./sortable.ts";
2
2
  export type { InitConfig, ItemRender, Layout, ViewInputs } from "./sortable.ts";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sortable/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,IAAI,EACJ,OAAO,EACP,KAAK,EACL,UAAU,EACV,cAAc,EACd,IAAI,EACJ,UAAU,EACV,aAAa,EACb,MAAM,EACN,IAAI,GACL,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sortable/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,IAAI,EACJ,OAAO,EACP,KAAK,EACL,UAAU,EACV,cAAc,EACd,IAAI,EACJ,SAAS,EACT,UAAU,EACV,aAAa,EACb,MAAM,EACN,IAAI,GACL,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
@@ -1 +1 @@
1
- export { AnnounceReorder, Item, Message, Model, OutMessage, SizeLiftedItem, init, setMovable, subscriptions, update, view, } from "./sortable.js";
1
+ export { AnnounceReorder, Item, Message, Model, OutMessage, SizeLiftedItem, init, isHolding, setMovable, subscriptions, update, view, } from "./sortable.js";
@@ -988,9 +988,9 @@ export type ViewInputs = Readonly<{
988
988
  * `li.sortable-item`, each its grip and the parent's content (a panel holds its grip in its
989
989
  * title bar). The items are the parent's; a drop reports `Moved`.
990
990
  *
991
- * A mouse drags an item by its body or its grip; touch takes the grip alone, so a finger on
992
- * an item scrolls the page; the keyboard takes the grip too: Space or Enter picks the item
993
- * up, every arrow moves it one place in reading order, Space drops it and Escape puts it back.
991
+ * Only the grip lifts an item, under every pointer, so the item's own text selects and a
992
+ * finger on it scrolls the page; the keyboard takes the grip too: Space or Enter picks the
993
+ * item up, every arrow moves it one place in reading order, Space drops it and Escape puts it back.
994
994
  * The held item dims in place; a copy, lifted onto the card shadow, follows the pointer or
995
995
  * prints where the keyboard would drop it; each step is said through the page's live region.
996
996
  * Lift `subscriptions(keyPrefix)` into the application's, or nothing follows the pointer or
@@ -1 +1 @@
1
- {"version":3,"file":"sortable.d.ts","sourceRoot":"","sources":["../../../src/sortable/sortable.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sortable.d.ts","sourceRoot":"","sources":["../../../src/sortable/sortable.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@ import * as Subscription from "foldkit/subscription";
10
10
  import * as Update from "foldkit/update";
11
11
  import * as Announcer from "../announcer/announcer.js";
12
12
  import * as Button from "../button/button.js";
13
- import { LEFT_BUTTON, activatedKeyboardDrag, cancelledDrag, escapeKeys, innerControls, insertionIndex, isCarrying, markDragging, measureLift, movedPointer, phaseOf, pressedDraggable, releasedPointer, } from "../drag/drag.js";
13
+ import { LEFT_BUTTON, activatedKeyboardDrag, cancelledDrag, escapeKeys, insertionIndex, isCarrying, markDragging, measureLift, movedPointer, phaseOf, pressedDraggable, releasedPointer, } from "../drag/drag.js";
14
14
  import * as Glyph from "../glyph/glyph.js";
15
15
  import * as IconButton from "../iconButton/iconButton.js";
16
16
  import { LOCALE } from "../locale/locale.js";
@@ -112,7 +112,6 @@ const id = (model) => __foldkitBrandViewResult((model.dragAndDrop.id), "@gjermun
112
112
  export const isHolding = (model) => __foldkitBrandViewResult((Option.isSome(UiDragAndDrop.maybeDraggedItemId(model.dragAndDrop))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#isHolding");
113
113
  // DOM HOOKS
114
114
  const itemHook = (model, itemId) => __foldkitBrandViewResult((`${id(model)}/${itemId}`), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemHook");
115
- const ITEM_ATTRIBUTE = "sortable-item";
116
115
  const GRIP_ATTRIBUTE = "sortable-grip";
117
116
  // COMMAND
118
117
  /** Says a step of a move through the page's live region (as `Announcer.Announce` does). */
@@ -349,21 +348,6 @@ export const SizeLiftedItem = Mount.define("SizeLiftedItem", {
349
348
  return __foldkitBrandViewResult((Message.CompletedSizeLiftedItem()), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~33");
350
349
  })), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#execute~2"),
351
350
  });
352
- const INNER_CONTROL = innerControls(`[data-${GRIP_ATTRIBUTE}]`);
353
- /** Whether a press lifts the item: on its grip under any pointer, on its body under a mouse,
354
- * and never on a control inside it. */
355
- const isLiftingPress = (target, pointerType) => {
356
- if (!(target instanceof Element)) {
357
- return __foldkitBrandViewResult((pointerType === "mouse"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#isLiftingPress");
358
- }
359
- const isOnGrip = target.closest(`[data-${GRIP_ATTRIBUTE}]`) !== null;
360
- const maybeItem = Option.fromNullishOr(target.closest(`[data-${ITEM_ATTRIBUTE}]`));
361
- const isOnControl = Option.exists(maybeItem, (item) => {
362
- const control = target.closest(INNER_CONTROL);
363
- return __foldkitBrandViewResult((control !== null && item.contains(control)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~34");
364
- });
365
- return __foldkitBrandViewResult((isOnGrip || (pointerType === "mouse" && !isOnControl)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#isLiftingPress");
366
- };
367
351
  const helpId = (model) => __foldkitBrandViewResult((`${id(model)}-grip-help`), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#helpId");
368
352
  const isHeldItem = (model, itemId) => __foldkitBrandViewResult((UiDragAndDrop.isDragging(model.dragAndDrop) &&
369
353
  Option.contains(UiDragAndDrop.maybeDraggedItemId(model.dragAndDrop), itemHook(model, itemId))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#isHeldItem");
@@ -378,7 +362,16 @@ const liftedView = (info, item, h) => __foldkitBrandViewResult((h.div([h.Class("
378
362
  const gripView = (info, item, h) => {
379
363
  const { model, isMovable, items } = info;
380
364
  const isIdleNow = phaseOf(model.dragAndDrop) === "Idle";
381
- const onGripKey = h.OnKeyDownPreventDefault((key) => __foldkitBrandViewResult((Option.liftPredicate(Message.PressedGripKey({ itemId: item.id, items }), () => __foldkitBrandViewResult((isIdleNow && (key === " " || key === "Enter")), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~36"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~35"));
365
+ const onGripKey = h.OnKeyDownPreventDefault((key) => __foldkitBrandViewResult((Option.liftPredicate(Message.PressedGripKey({ itemId: item.id, items }), () => __foldkitBrandViewResult((isIdleNow && (key === " " || key === "Enter")), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~35"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~34"));
366
+ const onGripPress = h.OnPointerDown((_pointerType, button, screenX, screenY, _time, clientX, clientY, pointerId) => __foldkitBrandViewResult((Option.liftPredicate(Message.PressedItem({
367
+ itemId: item.id,
368
+ pointerId,
369
+ screenX,
370
+ screenY,
371
+ clientX,
372
+ clientY,
373
+ items,
374
+ }), () => __foldkitBrandViewResult((isIdleNow && button === LEFT_BUTTON), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~37"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~36"));
382
375
  // NOTE: @foldkit/ui gap: DragAndDrop's `draggable` bundle forces `role="option"`, which a
383
376
  // plain list's items are not. So the grip carries the ui's `data-draggable-id` by hand, and
384
377
  // FocusItem finds the grip by it. While moves are held the grip stays, held, so the focus
@@ -394,62 +387,44 @@ const gripView = (info, item, h) => {
394
387
  h.AriaRoleDescription("draggable"),
395
388
  h.AriaDescribedBy(helpId(model)),
396
389
  Button.pressedAttribute(isHeldItem(model, item.id), h),
397
- ...(isMovable ? [onGripKey] : []),
390
+ ...(isMovable ? [onGripKey, onGripPress] : []),
398
391
  ],
399
392
  }, h)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#gripView");
400
393
  };
401
- const itemAttributes = (info, item, h) => {
402
- const { model, isMovable, items } = info;
403
- const isIdleNow = phaseOf(model.dragAndDrop) === "Idle";
404
- const onPress = h.OnPointerDown((pointerType, button, screenX, screenY, _time, clientX, clientY, pointerId, target) => __foldkitBrandViewResult((Option.liftPredicate(Message.PressedItem({
405
- itemId: item.id,
406
- pointerId,
407
- screenX,
408
- screenY,
409
- clientX,
410
- clientY,
411
- items,
412
- }), () => __foldkitBrandViewResult((isIdleNow && isMovable && button === LEFT_BUTTON && isLiftingPress(target, pointerType)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~38"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~37"));
413
- return __foldkitBrandViewResult(([h.DataAttribute(ITEM_ATTRIBUTE, ""), onPress]), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemAttributes");
414
- };
415
394
  /** Where a pointer would drop the held item, marked on the item it would land beside: before
416
395
  * the other item at its target, or after the last. None where it already was. */
417
- const dropMarkOf = (model) => __foldkitBrandViewResult((pipe(model.maybeHeld, Option.filter(() => __foldkitBrandViewResult((phaseOf(model.dragAndDrop) === "PointerDragging"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~39")), Option.flatMap((held) => __foldkitBrandViewResult((pipe(targetIndex(model, held), Option.filter((index) => __foldkitBrandViewResult((!Option.contains(indexOf(held.items, held.item.id), index)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~41")), Option.flatMap((index) => {
418
- const others = Array.filter(held.items, (item) => __foldkitBrandViewResult((item.id !== held.item.id), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~43"));
396
+ const dropMarkOf = (model) => __foldkitBrandViewResult((pipe(model.maybeHeld, Option.filter(() => __foldkitBrandViewResult((phaseOf(model.dragAndDrop) === "PointerDragging"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~38")), Option.flatMap((held) => __foldkitBrandViewResult((pipe(targetIndex(model, held), Option.filter((index) => __foldkitBrandViewResult((!Option.contains(indexOf(held.items, held.item.id), index)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~40")), Option.flatMap((index) => {
397
+ const others = Array.filter(held.items, (item) => __foldkitBrandViewResult((item.id !== held.item.id), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~42"));
419
398
  return __foldkitBrandViewResult((Option.orElse(Option.map(Array.get(others, index), (item) => (__foldkitBrandViewResult(({
420
399
  itemId: item.id,
421
400
  side: "Before",
422
- }), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~44"))), () => __foldkitBrandViewResult((Option.map(Array.last(others), (item) => (__foldkitBrandViewResult(({
401
+ }), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~43"))), () => __foldkitBrandViewResult((Option.map(Array.last(others), (item) => (__foldkitBrandViewResult(({
423
402
  itemId: item.id,
424
403
  side: "After",
425
- }), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~46")))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~45"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~42");
426
- }))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~40")))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#dropMarkOf");
427
- const dropClass = (info, item) => __foldkitBrandViewResult((Option.match(Option.filter(info.maybeDropMark, ({ itemId }) => __foldkitBrandViewResult((itemId === item.id), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~47")), {
404
+ }), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~45")))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~44"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~41");
405
+ }))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~39")))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#dropMarkOf");
406
+ const dropClass = (info, item) => __foldkitBrandViewResult((Option.match(Option.filter(info.maybeDropMark, ({ itemId }) => __foldkitBrandViewResult((itemId === item.id), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~46")), {
428
407
  onNone: () => __foldkitBrandViewResult((""), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onNone~5"),
429
408
  onSome: ({ side }) => (__foldkitBrandViewResult((side === "Before" ? " drop-before" : " drop-after"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onSome~5")),
430
409
  })), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#dropClass");
431
410
  const itemClass = (info, item) => __foldkitBrandViewResult((`sortable-item${info.isMovable ? " movable" : ""}${isHeldItem(info.model, item.id) ? " drag-dim" : ""}${dropClass(info, item)}`), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemClass");
432
- const itemView = (info, item, h) => __foldkitBrandViewResult((h.keyed("li")(item.id, [
433
- ...UiDragAndDrop.sortable(itemHook(info.model, item.id)),
434
- ...itemAttributes(info, item, h),
435
- h.Class(itemClass(info, item)),
436
- ], itemContents(info, item, { isLifted: false, grip: gripView(info, item, h) }, h))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemView");
411
+ const itemView = (info, item, h) => __foldkitBrandViewResult((h.keyed("li")(item.id, [...UiDragAndDrop.sortable(itemHook(info.model, item.id)), h.Class(itemClass(info, item))], itemContents(info, item, { isLifted: false, grip: gripView(info, item, h) }, h))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemView");
437
412
  /** The items in order, with the held item's copy where the keyboard would drop it: before the
438
413
  * other item at its target, or last. The copy carries no `data-sortable-id`, so it is not
439
414
  * counted as an item. */
440
415
  const itemsView = (info, h) => {
441
416
  const { model, items } = info;
442
- const rows = Array.map(items, (item) => (__foldkitBrandViewResult(({ item, html: itemView(info, item, h) }), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~48")));
443
- const maybeSlot = pipe(model.maybeHeld, Option.filter(() => __foldkitBrandViewResult((phaseOf(model.dragAndDrop) === "KeyboardDragging"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~49")), Option.flatMap((held) => __foldkitBrandViewResult((Option.map(targetIndex(model, held), (index) => (__foldkitBrandViewResult(({ held, index }), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~51")))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~50")));
417
+ const rows = Array.map(items, (item) => (__foldkitBrandViewResult(({ item, html: itemView(info, item, h) }), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~47")));
418
+ const maybeSlot = pipe(model.maybeHeld, Option.filter(() => __foldkitBrandViewResult((phaseOf(model.dragAndDrop) === "KeyboardDragging"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~48")), Option.flatMap((held) => __foldkitBrandViewResult((Option.map(targetIndex(model, held), (index) => (__foldkitBrandViewResult(({ held, index }), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~50")))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~49")));
444
419
  return __foldkitBrandViewResult((Option.match(maybeSlot, {
445
- onNone: () => __foldkitBrandViewResult((Array.map(rows, ({ html }) => __foldkitBrandViewResult((html), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~52"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onNone~6"),
420
+ onNone: () => __foldkitBrandViewResult((Array.map(rows, ({ html }) => __foldkitBrandViewResult((html), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~51"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onNone~6"),
446
421
  onSome: ({ held, index }) => {
447
422
  const slot = h.keyed("li")("sortable-slot", [h.Class("sortable-slot"), h.AriaHidden(true), h.Inert(true)], [liftedView(info, held.item, h)]);
448
- const others = Array.filter(rows, ({ item }) => __foldkitBrandViewResult((item.id !== held.item.id), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~53"));
423
+ const others = Array.filter(rows, ({ item }) => __foldkitBrandViewResult((item.id !== held.item.id), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~52"));
449
424
  const maybeBefore = Array.get(others, index);
450
425
  return __foldkitBrandViewResult((Option.match(maybeBefore, {
451
- onNone: () => __foldkitBrandViewResult(([...Array.map(rows, ({ html }) => __foldkitBrandViewResult((html), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~54")), slot]), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onNone~7"),
452
- onSome: (before) => __foldkitBrandViewResult((Array.flatMap(rows, ({ item, html }) => __foldkitBrandViewResult((item.id === before.item.id ? [slot, html] : [html]), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~55"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onSome~7"),
426
+ onNone: () => __foldkitBrandViewResult(([...Array.map(rows, ({ html }) => __foldkitBrandViewResult((html), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~53")), slot]), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onNone~7"),
427
+ onSome: (before) => __foldkitBrandViewResult((Array.flatMap(rows, ({ item, html }) => __foldkitBrandViewResult((item.id === before.item.id ? [slot, html] : [html]), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~54"))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onSome~7"),
453
428
  })), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#onSome~6");
454
429
  },
455
430
  })), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#itemsView");
@@ -459,7 +434,7 @@ const liftedCopyView = (info, h) => {
459
434
  const maybeLifted = Option.all({
460
435
  style: UiDragAndDrop.ghostStyle(model.dragAndDrop),
461
436
  held: model.maybeHeld,
462
- press: Option.flatMap(model.maybeHeld, ({ maybePress }) => __foldkitBrandViewResult((maybePress), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~56")),
437
+ press: Option.flatMap(model.maybeHeld, ({ maybePress }) => __foldkitBrandViewResult((maybePress), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~55")),
463
438
  });
464
439
  return __foldkitBrandViewResult((Array.fromOption(Option.map(maybeLifted, ({ style, held, press }) => __foldkitBrandViewResult((h.div([
465
440
  h.Class("sortable-lift"),
@@ -471,18 +446,18 @@ const liftedCopyView = (info, h) => {
471
446
  pressX: press.clientX,
472
447
  pressY: press.clientY,
473
448
  })),
474
- ], [liftedView(info, held.item, h)])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~57")))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#liftedCopyView");
449
+ ], [liftedView(info, held.item, h)])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~56")))), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#liftedCopyView");
475
450
  };
476
- const layoutClass = (layout) => __foldkitBrandViewResult((Match.value(layout).pipe(Match.withReturnType(), Match.when("List", () => __foldkitBrandViewResult(("sortable"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~58")), Match.when("Grid", () => __foldkitBrandViewResult(("sortable grid"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~59")), Match.when("Panels", () => __foldkitBrandViewResult(("sortable panels"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~60")), Match.exhaustive)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#layoutClass");
451
+ const layoutClass = (layout) => __foldkitBrandViewResult((Match.value(layout).pipe(Match.withReturnType(), Match.when("List", () => __foldkitBrandViewResult(("sortable"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~57")), Match.when("Grid", () => __foldkitBrandViewResult(("sortable grid"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~58")), Match.when("Panels", () => __foldkitBrandViewResult(("sortable panels"), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~59")), Match.exhaustive)), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#layoutClass");
477
452
  /**
478
453
  * Items the reader puts in order, as rows, as tiles or as panels, built on `@foldkit/ui`'s
479
454
  * DragAndDrop: `div.sortable` holding `ul.sortable-items` (named by `label`) of
480
455
  * `li.sortable-item`, each its grip and the parent's content (a panel holds its grip in its
481
456
  * title bar). The items are the parent's; a drop reports `Moved`.
482
457
  *
483
- * A mouse drags an item by its body or its grip; touch takes the grip alone, so a finger on
484
- * an item scrolls the page; the keyboard takes the grip too: Space or Enter picks the item
485
- * up, every arrow moves it one place in reading order, Space drops it and Escape puts it back.
458
+ * Only the grip lifts an item, under every pointer, so the item's own text selects and a
459
+ * finger on it scrolls the page; the keyboard takes the grip too: Space or Enter picks the
460
+ * item up, every arrow moves it one place in reading order, Space drops it and Escape puts it back.
486
461
  * The held item dims in place; a copy, lifted onto the card shadow, follows the pointer or
487
462
  * prints where the keyboard would drop it; each step is said through the page's live region.
488
463
  * Lift `subscriptions(keyPrefix)` into the application's, or nothing follows the pointer or
@@ -509,5 +484,5 @@ export const view = defineView((model, viewInputs, h) => {
509
484
  ], itemsView(info, h)),
510
485
  h.p([h.Id(helpId(model)), h.Class("sr-only")], [COPY.gripHelp]),
511
486
  ...liftedCopyView(info, h),
512
- ])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~61");
487
+ ])), "@gjermundgaraba-designs/pixel-paper/src/sortable/sortable.js#anonymous~60");
513
488
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjermundgaraba-designs/pixel-paper",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -3369,24 +3369,16 @@ dialog.veil:focus {
3369
3369
  min-width: 0;
3370
3370
  }
3371
3371
 
3372
- .sortable-item.movable {
3373
- cursor: grab;
3374
- }
3375
-
3376
3372
  .sortable-item [data-sortable-grip] {
3377
3373
  flex: none;
3378
3374
  }
3379
3375
 
3376
+ /* the grip is the only handle: the rest of the item selects its text and scrolls the page */
3380
3377
  .sortable-item.movable [data-sortable-grip] {
3381
3378
  cursor: grab;
3382
- /* the grip is where a finger drags; the rest of the item scrolls the page */
3383
3379
  touch-action: none;
3384
3380
  }
3385
3381
 
3386
- .sortable-item.movable:hover {
3387
- background: var(--head);
3388
- }
3389
-
3390
3382
  .sortable-item.drag-dim {
3391
3383
  opacity: 0.4;
3392
3384
  }
@@ -3489,10 +3481,6 @@ dialog.veil:focus {
3489
3481
  background: none;
3490
3482
  }
3491
3483
 
3492
- .sortable.panels .sortable-item.movable:hover {
3493
- background: none;
3494
- }
3495
-
3496
3484
  .sortable.panels .sortable-body {
3497
3485
  height: 100%;
3498
3486
  }
@@ -6,6 +6,7 @@ export {
6
6
  OutMessage,
7
7
  SizeLiftedItem,
8
8
  init,
9
+ isHolding,
9
10
  setMovable,
10
11
  subscriptions,
11
12
  update,
@@ -16,7 +16,6 @@ import {
16
16
  activatedKeyboardDrag,
17
17
  cancelledDrag,
18
18
  escapeKeys,
19
- innerControls,
20
19
  insertionIndex,
21
20
  isCarrying,
22
21
  markDragging,
@@ -158,7 +157,6 @@ export const isHolding = (model: Model): boolean =>
158
157
 
159
158
  const itemHook = (model: Model, itemId: string): string => `${id(model)}/${itemId}`;
160
159
 
161
- const ITEM_ATTRIBUTE = "sortable-item";
162
160
  const GRIP_ATTRIBUTE = "sortable-grip";
163
161
 
164
162
  // COMMAND
@@ -596,25 +594,6 @@ export type ViewInputs = Readonly<{
596
594
  toItemView: (item: Item, render: ItemRender) => ReadonlyArray<Html>;
597
595
  }>;
598
596
 
599
- const INNER_CONTROL = innerControls(`[data-${GRIP_ATTRIBUTE}]`);
600
-
601
- /** Whether a press lifts the item: on its grip under any pointer, on its body under a mouse,
602
- * and never on a control inside it. */
603
- const isLiftingPress = (target: EventTarget | null, pointerType: string): boolean => {
604
- if (!(target instanceof Element)) {
605
- return pointerType === "mouse";
606
- }
607
-
608
- const isOnGrip = target.closest(`[data-${GRIP_ATTRIBUTE}]`) !== null;
609
- const maybeItem = Option.fromNullishOr(target.closest(`[data-${ITEM_ATTRIBUTE}]`));
610
- const isOnControl = Option.exists(maybeItem, (item) => {
611
- const control = target.closest(INNER_CONTROL);
612
- return control !== null && item.contains(control);
613
- });
614
-
615
- return isOnGrip || (pointerType === "mouse" && !isOnControl);
616
- };
617
-
618
597
  type ListInfo = Readonly<{
619
598
  model: Model;
620
599
  layout: Layout;
@@ -666,6 +645,22 @@ const gripView = (info: ListInfo, item: Item, h: HtmlBuilder<Message>): Html =>
666
645
  ),
667
646
  );
668
647
 
648
+ const onGripPress: Attribute<Message> = h.OnPointerDown(
649
+ (_pointerType, button, screenX, screenY, _time, clientX, clientY, pointerId) =>
650
+ Option.liftPredicate(
651
+ Message.PressedItem({
652
+ itemId: item.id,
653
+ pointerId,
654
+ screenX,
655
+ screenY,
656
+ clientX,
657
+ clientY,
658
+ items,
659
+ }),
660
+ () => isIdleNow && button === LEFT_BUTTON,
661
+ ),
662
+ );
663
+
669
664
  // NOTE: @foldkit/ui gap: DragAndDrop's `draggable` bundle forces `role="option"`, which a
670
665
  // plain list's items are not. So the grip carries the ui's `data-draggable-id` by hand, and
671
666
  // FocusItem finds the grip by it. While moves are held the grip stays, held, so the focus
@@ -682,41 +677,13 @@ const gripView = (info: ListInfo, item: Item, h: HtmlBuilder<Message>): Html =>
682
677
  h.AriaRoleDescription("draggable"),
683
678
  h.AriaDescribedBy(helpId(model)),
684
679
  Button.pressedAttribute(isHeldItem(model, item.id), h),
685
- ...(isMovable ? [onGripKey] : []),
680
+ ...(isMovable ? [onGripKey, onGripPress] : []),
686
681
  ],
687
682
  },
688
683
  h,
689
684
  );
690
685
  };
691
686
 
692
- const itemAttributes = (
693
- info: ListInfo,
694
- item: Item,
695
- h: HtmlBuilder<Message>,
696
- ): ReadonlyArray<Attribute<Message>> => {
697
- const { model, isMovable, items } = info;
698
- const isIdleNow = phaseOf(model.dragAndDrop) === "Idle";
699
-
700
- const onPress = h.OnPointerDown(
701
- (pointerType, button, screenX, screenY, _time, clientX, clientY, pointerId, target) =>
702
- Option.liftPredicate(
703
- Message.PressedItem({
704
- itemId: item.id,
705
- pointerId,
706
- screenX,
707
- screenY,
708
- clientX,
709
- clientY,
710
- items,
711
- }),
712
- () =>
713
- isIdleNow && isMovable && button === LEFT_BUTTON && isLiftingPress(target, pointerType),
714
- ),
715
- );
716
-
717
- return [h.DataAttribute(ITEM_ATTRIBUTE, ""), onPress];
718
- };
719
-
720
687
  type DropMark = Readonly<{ itemId: string; side: "Before" | "After" }>;
721
688
 
722
689
  /** Where a pointer would drop the held item, marked on the item it would land beside: before
@@ -762,11 +729,7 @@ const itemClass = (info: ListInfo, item: Item): string =>
762
729
  const itemView = (info: ListInfo, item: Item, h: HtmlBuilder<Message>): Html =>
763
730
  h.keyed("li")(
764
731
  item.id,
765
- [
766
- ...UiDragAndDrop.sortable(itemHook(info.model, item.id)),
767
- ...itemAttributes(info, item, h),
768
- h.Class(itemClass(info, item)),
769
- ],
732
+ [...UiDragAndDrop.sortable(itemHook(info.model, item.id)), h.Class(itemClass(info, item))],
770
733
  itemContents(info, item, { isLifted: false, grip: gripView(info, item, h) }, h),
771
734
  );
772
735
 
@@ -849,9 +812,9 @@ const layoutClass = (layout: Layout): string =>
849
812
  * `li.sortable-item`, each its grip and the parent's content (a panel holds its grip in its
850
813
  * title bar). The items are the parent's; a drop reports `Moved`.
851
814
  *
852
- * A mouse drags an item by its body or its grip; touch takes the grip alone, so a finger on
853
- * an item scrolls the page; the keyboard takes the grip too: Space or Enter picks the item
854
- * up, every arrow moves it one place in reading order, Space drops it and Escape puts it back.
815
+ * Only the grip lifts an item, under every pointer, so the item's own text selects and a
816
+ * finger on it scrolls the page; the keyboard takes the grip too: Space or Enter picks the
817
+ * item up, every arrow moves it one place in reading order, Space drops it and Escape puts it back.
855
818
  * The held item dims in place; a copy, lifted onto the card shadow, follows the pointer or
856
819
  * prints where the keyboard would drop it; each step is said through the page's live region.
857
820
  * Lift `subscriptions(keyPrefix)` into the application's, or nothing follows the pointer or