Skip to content

Releases

0.4.0

Choose a tag to compare

@ErikaDyendyeshy ErikaDyendyeshy released this 30 Oct 18:55

Reads document contract 9.33.0 (theme 4.0.1, icon set 1.0.0, data dictionary 1.8.0) and placement map 1.1.0. Folds in the entries that were prepared as 0.4.0 to 0.7.1 and never published (the last release is 0.3.0).

Added

  • Placement schedule (placement map 1.1.0). A place may carry windows of time in which another document, or nothing
    (a pause), stands in it instead of its permanent content. HotlayoutPlacement reads the place against the clock of
    its PlacementSource, sets a timer at the next boundary of the schedule (cut to 2^31 - 1 ms and counted again at its
    end) and decides again there, on every new reading of the map, and when the app returns to the foreground; the map
    is not asked again at a boundary. loadPlacement reads the place at the same clock. PlacementSource has a new last
    parameter clock: () -> Long (milliseconds since the epoch; the device clock by default) to pin time in tests. A
    broken window is skipped on its own, a pause never reads its entry, overlapping windows go to the one that started
    later. Every row of the scheduleCases group of placements/placement-cases.json is run. The README shows how a
    host hides its own padding around a place that is empty.
  • A place with a schedule shows its window on time and with no network. After the first decision of a place,
    PlacementSource reads in the background the documents of every window of the schedule and keeps them in its
    store (at most 64 documents; the oldest copy is dropped first). A failed reading keeps the last good copy, a 404
    drops it, and deciding the place again at a boundary or on return to the foreground while offline does not blank the
    document that stands there.
  • A node that fades in and out when its condition changes. A node with visibilityTransition: fade and a
    visibleIf no longer appears and disappears at once: a node whose condition stops holding keeps its place and
    fades out in 120 ms, then leaves the layout; a node whose condition starts to hold waits 120 ms out of the layout,
    then enters it transparent and fades in over 160 ms. There is no pairing: every node follows its own timeline, so
    two neighbours with exclusive conditions change the layout once, when both are invisible. A change in the middle of
    a transition goes to the new goal from the current opacity, the time scaled by the distance; a node still waiting
    stays hidden. A fading-out node catches no press and is not heard by the screen reader; a fading-in node is a
    control from the moment it enters the layout. The durations and curves are the data of the contract.
  • Everything else stays at once: the first show of a screen, going back to a screen, a change of the language or of
    the width class, a change under a covered screen, and a system whose animation scale is zero. The zones of the
    screen follow the condition at once and do not read the field: a node with pin (bottom or top), a NavBar, a
    NavItem and an AppBar that is the first child of the screen root; an AppBar anywhere else fades like any node.
  • A carousel that tells its active stop. The optional carousel.stopPath names a number path of the data
    dictionary; its value is the number of the snap stop from 0 (stops, not cards). After a person's swipe has settled
    on a stop the reader writes that number to the path, the very write an input field makes (the session of the
    screen and onWrite of the host at the same moment, under writablePaths). It writes only for a move by a
    person (a finger, the wheel, a key), never while the finger still holds the row, never for a move the reader made
    itself, and never the same number again. When the carousel is shown it stands on the stop the value names
    without animation (a number clamped to the stops; a fraction, a text or no value is the first stop), and it moves
    to that stop when the number the value names changes, not while a finger holds the row. A write the host refused
    leaves the carousel where the person put it. A pointer that was cancelled counts as released. A path on a row
    that does not scroll, an empty one, one longer than 128 characters or one that is not a string is no path: the
    carousel then scrolls as before and writes nothing.
  • The bottom safe inset of a modal sheet. A layer shown as a sheet (presentation: modal, no modalPlacement or
    bottom, in a compact area) still reaches the bottom of its area, and the reader now adds the navigation bar
    inset (or the safeAreaBottom the host passed) inside the box of the sheet, under its content: the background and
    the radius of the root extend under the gesture bar, the last node stands above it. The inset is added once: with
    a shown pinned block it goes under the content of that zone, without one it is the bottom padding of the root.
    The height of the sheet is its content plus the inset, no taller than the area; taller content scrolls above the
    inset. While the keyboard is shown the sheet rises above it and adds nothing. A window (center), a sheet shown
    as a window in a wider area and a page are unchanged, and a host that passes zero gets zero.
  • A write action on a long press. A node whose own action does not write may carry setValue or toggleValue in
    longPress; the hold (also Shift+F10 and the named action of a screen reader) performs it through the same write as
    a pressed action: the haptic request and the analytics event go first, then the write into the session and
    onWrite (under writablePaths), and a value already held is not written again. The role of the node still
    comes from action alone, so the node stays a plain button. Before, a write action on a long press was ignored.
  • The node field name (a label for the editor) is accepted and ignored: it is not drawn, not part of an accessible
    name and not passed to actions, events or reports.

Fixed

  • A carousel that tells its stop follows the LAST value when the host changes it twice in a row while the first
    animation is still running. Following compared the new number with the stop the animation was passing and
    took it for "already there", so the carousel stayed where the cancelled move had been. "Where the carousel is"
    is now the target of the reader's own move until that move has settled (a person's touch, wheel or key
    clears it).
  • A row of a list from data fades too. When the template of a Repeater has visibilityTransition: fade and a
    condition on the fields of the record, every row follows its own timeline (the key is the node and the indexes of
    the template instances it stands in): a row whose condition stops holding fades out in place and the rows around
    it do not move until it has left.