Skip to content

v0.2.0-alpha.20

Pre-release
Pre-release

Choose a tag to compare

@yomybaby yomybaby released this 23 Oct 03:24
4fd20b1

Published under the next dist-tag (@lablup/ui-common@next, @lablup/ui-common-cli@next). PR #88.

Astryx 0.7.0 → 0.7.3 (@astryxdesign/lab 0.7.3-canary.cac3d8d). Astryx's
own release notes:
https://github.com/facebook/astryx/releases/tag/v0.7.1,
https://github.com/facebook/astryx/releases/tag/v0.7.2,
https://github.com/facebook/astryx/releases/tag/v0.7.3
(Drawer promoted to core, disabled controls stay focusable, List edge,
global mode and the computer-level agent guide in the CLI).

Added

  • New root names: Drawer, DrawerHeader, DrawerProps,
    DrawerHeaderProps and ListEdge. New mirrored subpath: Drawer. New in
    @lablup/ui-common/lab: Comments, CommentThread, CommentComposer,
    CommentPin, DiffViewer (with parseUnifiedDiff, createDiffFile),
    EmojiPicker and their types. No subpath was removed; lab lost Drawer
    and DrawerHeader (below).
  • ui-common init --user: the ui-common skill for every agent on the
    computer
    , ui-common's counterpart of the Astryx skill astryx init --user writes since Astryx 0.7.2. It installs
    ~/.agents/skills/ui-common/SKILL.md (shipped in @lablup/ui-common-cli
    as skill/ui-common/SKILL.md) and links it into ~/.claude/skills/ and
    the skill folders of the other agents Astryx reaches (Kiro, Windsurf,
    Letta, Xcode, ~/.config/agents; a managed copy for Continue) when they are
    installed. The text is short and version-free like Astryx's: in a project
    that depends on @lablup/ui-common, use ui-common search, build,
    template, component and docs, import from @lablup/ui-common, and
    never run astryx or import @astryxdesign/*. Before this,
    ui-common init --user passed through to Astryx and left only Astryx's
    skill, which steers agents to @astryxdesign/core. A file you edited, or
    one ui-common did not write, is never changed; --remove-agents removes
    what it wrote. When Astryx's skill is installed too, the command says how
    to remove it (ui-common astryx init --user --remove-agents) and leaves it.
  • ui-common adopt --from astryx: moves an app that imports Astryx
    directly (@astryxdesign/core, /lab, /theme-neutral) onto ui-common in
    one pass. It rewrites every module specifier in scripts (imports,
    export … from, import(), require(), typeof import(), vi.mock()) and
    stylesheets to the ui-common mirror, renames Dialog / AlertDialog to
    Modal / AlertModal, adds ui-common to the cascade-layer order (and the
    statement to an entry stylesheet or index.html without one), edits
    package.json in every workspace member (@lablup/ui-common and the CLI at
    the CLI's version, core kept only at ui-common's pin, theme-neutral and an
    unused lab dropped, the lab override, pnpm allowBuilds), runs Astryx's own
    codemods for the versions an app moves across to reach ui-common's pin, and
    writes ui-common-adopt-report.md in the upgrade report's format: form
    controls passing the field chrome Form.Item now owns, local Astryx patches
    (which a ui-common fork covers, and which are keyed to a version ui-common
    no longer pins), Modal refs, body overlays, global shortcuts, Escape
    handlers, ASTRYX agent blocks and tools anchored on them, astryx CLI
    calls, and i18n wiring. --dry-run, --check (exit 1
    while anything is left, for CI), --ignore; upgrade --from astryx is an
    alias.
  • ui-common doctor [--json] [--verbose]: read-only checks with a fix and a doc
    section each, exit 1 on a failure: one @astryxdesign/core (lockfile and
    disk, pnpm and npm) with lab on it, lab at the canary ui-common peers on,
    the lab override, no direct Astryx
    import, the layer order (present, first, with ui-common, identical in every
    copy), the Vite pre-bundle fix under @stylexjs/unplugin, Vitest inlining
    ui-common, i18n wiring, the agent block, matching ui-common / ui-common-cli
    versions, and Node for the CLI. It covers every member of a workspace, and
    run from a member it reads the workspace root. doctor <subcommand> still
    reaches Astryx's doctor.
  • The ui-common-adopt agent skill, shipped in @lablup/ui-common-cli
    and installed with ui-common agents --skill [--dir <dir>]: the adopt,
    doctor and verification sequence, with the decisions only a person makes.
    The agent block names it once it is installed in the project.
  • docs/adopting-from-astryx.md: the guide for
    direct-Astryx apps, with each doctor check explained and a prompt for a
    coding agent.
  • TagsInput (@lablup/ui-common/TagsInput), antd's
    Select mode="tags" on ui-common's Tokenizer: string[] tags,
    deduplicated, tokenSeparators on the keystroke and on paste, text left
    in the input committed on blur, and a translated create row
    (uic.TagsInput.create).
  • SegmentedControl for Form.Item: a wrapper like the other form
    controls, named by the item's label. It renders a fork that merges the
    item's aria-describedby instead of overwriting it; import
    SegmentedControlItem from @lablup/ui-common/SegmentedControl too.
  • ui-common's own templates (#70): list-page, tabbed-page,
    settings-page and dashboard-board pages, and list-toolbar,
    create-modal, detail-drawer and info-modal blocks, written against
    @lablup/ui-common and lucide-react. The refresh button in list-page and
    list-toolbar is IconButton inside CountdownBorder. The package exports
    them as source at @lablup/ui-common/astryx/templates/<name>, which the
    Astryx CLI requires of an integration's templates.
  • ui-common template is the CLI's own command: it lists, prints and
    writes ui-common's templates and names the packages a written template
    needs (lucide-react, @astryxdesign/lab).
  • Component docs for PageLayout, StatCard, ErrorState, DigitPopIn,
    SmoothHeight, the Skeleton composites and the lab Tour, so search and
    build find them (the Drawer is described by Astryx's own core doc,
    with ui-common's note). search "data table" now ranks DataGrid
    above Table, and "delete confirm" finds DeleteConfirmModal.

Changed

  • Breaking: Drawer and DrawerHeader moved from @lablup/ui-common/lab
    to @lablup/ui-common/Drawer
    (and the root), because Astryx 0.7.2
    promoted them from lab to core. @lablup/ui-common/lab no longer exports
    either. ui-common's Drawer fork is re-taken from core's and keeps its
    changes (a scrimless drawer stays below Modal and the notification stack,
    a Modal inside a scrimmed drawer opens above it, aria-modal passes
    through); DrawerHeader is Astryx's, re-exported unchanged. A project that
    used lab only for the Drawer no longer needs @astryxdesign/lab, its core
    override or lab.css. pnpm exec ui-common upgrade --from 0.2.0-alpha.19 moves the imports and re-exports, and lists namespace
    imports and module mocks of the lab mirror it cannot prove safe.

  • Breaking: Drawer's isFullWidthOnMobile is now
    experimental={{ isFullWidthOnMobile }}
    , following core's Drawer. A
    top-level isFullWidthOnMobile no longer type-checks and is ignored at
    runtime (the drawer keeps the 56px page reveal on mobile). The same
    upgrade step rewrites the prop on Drawer elements and lists the uses it
    cannot rewrite (a props object or spread, or an element that already has
    experimental).

  • Disabled form controls stay focusable (Astryx 0.7.3). A disabled
    CheckboxInput, CheckboxList item, Switch, Slider, FileInput,
    Selector, MultiSelector, ComplexSelector (and PagedSelector), the
    date and time inputs, Link, ClickableCard and a Token's buttons now
    expose aria-disabled="true" and keep their Tab stop instead of the native
    disabled attribute; activation stays blocked and the value is still left
    out of form submission. Tests that query them with toBeDisabled() or
    :disabled check aria-disabled="true" instead (DataGrid's selection
    checkboxes and the settings and export modals included).

  • pnpm exec ui-common upgrade --from 0.2.0-alpha.19 also runs Astryx's
    0.7.2 codemod (migrate-list-edge-compensation-to-edge: List
    edgeCompensation="inline" → edge="outset"), moves the lab canary to
    0.7.3-canary.cac3d8d and its core override to 0.7.3, and bumps the
    @lablup/ui-common / @lablup/ui-common-cli pins. adopt --from astryx
    moves a direct-Astryx app's lab Drawer to @lablup/ui-common/Drawer too.

  • The CheckboxInput fork is gone: Astryx 0.7.2 passes a caller's id to
    the native checkbox, so the Form.Item wrapper renders Astryx's own
    CheckboxInput. The Switch fork keeps its id fix; its
    aria-describedby fix is upstream's since 0.7.2. The ComplexSelector,
    Switch, FileInput, SegmentedControl and Tour forks are re-taken
    from 0.7.3.

  • The detail-drawer template imports Drawer from @lablup/ui-common
    and needs no @astryxdesign/lab.

  • Clearable inputs' clear-button tooltip reads "Clear" (Astryx's
    @astryx.inputClearButton.tooltip); the button's accessible name still
    names the field.

  • The CLI rewrites the release-pinned runner Astryx 0.7.2 prints when no
    project CLI answers (npx @astryxdesign/cli@0.7.3 …) to the ui-common
    invocation, so the agent block keeps CLI: run every command as \npx ui-common ``.

  • The Lablup theme was rebuilt with astryx theme build 0.7.3.

  • Breaking: the form controls take no field chrome; Form.Item owns it, as
    in antd (#69).
    TextInput, TextArea, NumberInput, Selector, MultiSelector, Typeahead, Tokenizer, DateInput, TimeInput, DateTimeInput, DateRangeInput, Switch, CheckboxInput, CheckboxList, RadioList, SegmentedControl, Slider and FileInput are now ui-common's wrappers at Astryx's names
    and import paths. They drop label, isLabelHidden, description,
    labelTooltip, labelIcon, isRequired, isOptional, isDisabled,
    statusVariant and the status message. Inside a Form.Item they read the
    item's status and paint their border (the item shows the one message),
    take the item's id so its label names them, are disabled by
    <Form disabled>, and announce required from its rules. status is
    antd's 'error' | 'warning' | ''. value and onChange are optional, so
    ?? '' is no longer needed, and MultiSelector no longer throws on a
    missing value. Without value a control is uncontrolled, as in antd, from
    defaultValue (defaultChecked for Switch and CheckboxInput). On its
    own a control is named by aria-label, which also names its parts ("Clear
    Search"); in an item they are named after the item's label. A Modal, the
    Drawer, a Popover or a nested Form inside an item no longer takes its
    status or label: @lablup/ui-common/Popover is now ui-common's, with
    Astryx's API. Switch and CheckboxInput take checked beside value
    (valuePropName="checked" works) and their inline text as children.
    Move each control's label/description to the enclosing Form.Item
    (label/extra) and drop isLabelHidden.

  • The form controls do what a host app's adapter used to add, as
    antd's controls do. TextInput, TextArea, NumberInput, Selector,
    MultiSelector and Tokenizer default to width="100%"; Selector to
    placement="below", so its panel no longer covers the item's label;
    MultiSelector to triggerDisplay="labels". NumberInput defaults to
    hasClear (an emptied field reports null; pass hasClear={false} to
    keep the last number), takes a numeric string as value, and rounds a
    decimal typed into an isIntegerOnly field on blur instead of dropping
    it. Its onChange is (value: number | null) => void. An inline
    onChange={(v) => …} is typed again on Selector (from hasClear, as on
    Astryx's) and on Slider (a single value unless the value is a range,
    which Astryx's leaves untyped), instead of an implicit any.

  • The CLI no longer offers Astryx's templates, which import
    @astryxdesign/* and Heroicons directly: template refuses them,
    search leaves them out, and build recommends ui-common's templates
    instead. ui-common astryx template … still runs Astryx's command.

  • The ui-common agent block lists the templates.

  • @lablup/ui-common declares an optional @astryxdesign/cli peer
    (>=0.6.7): an Astryx CLI before 0.6.6 does not know a template's
    keywords and would drop the templates, and one before 0.6.7 does not let
    a component doc replace Astryx's. A project without the CLI is not
    affected.

  • ui-common component describes the Form.Item wrappers (#75).
    TextInput, Selector, Switch and the other wrapped controls showed
    Astryx's page, with label, isDisabled and status: {type, message}.
    Their docs now replace Astryx's: no field chrome, disabled, status,
    defaultValue, naming by aria-label, the wrappers' defaults, and
    Form.Item examples. TagsInput has a page of its own.

Fixed

  • NOTICE credits Cloudscape's board-components. @cloudscape-design/board-components (Apache-2.0), whose
    layout model and engine the Board's layout.ts and engine.ts adapt, and
    carries its NOTICE; both files name it and its copyright in their headers.
    check:pack asserts the packed NOTICE keeps it.

  • upgrade --from 0.1 writes Selector for the Form.Item wrapper. The
    0.1 Select → Selector step still produced Astryx's own props, which the
    wrapper no longer takes: it set isLabelHidden and label from
    aria-label, renamed disabled to isDisabled, and turned invalid into
    status={{ type: "error" }}. It now keeps aria-label and disabled,
    writes status="error", and moves a 0.1 label to aria-label with a
    TODO to put it on the enclosing Form.Item.

  • Switch and CheckboxInput honour the item's id. Astryx 0.7.0
    replaces it with useId(), so Form.Item's <label htmlFor> pointed at
    nothing. The wrappers render fixed copies (src/forks) that put the id on
    the native checkbox, as TextInput does.

  • Form.Item's message and extra describe Switch and FileInput.
    Astryx 0.7.0 spreads the item's aria-describedby onto Switch's row and
    FileInput's hidden native input. The Switch fork merges it into the
    switch's own; a new FileInput fork hands the aria-* props and the focus
    handlers to its trigger button, so a blur validates it, its required state
    is announced, and focusField lands on the trigger.

  • CheckboxList fills a field that has no initial value, and Tokenizer
    keeps an in-flight search through a parent re-render while empty: list
    wrappers pass one shared empty array instead of a new one per render.

  • An empty status falls back to the item's, as antd's
    getMergedStatus does, instead of clearing the item's error border.

  • UnitGrid draws full-size cells again under Astryx 0.7.0. Cell, gap
    and radius sizes came from parseFloat() on the raw --spacing-4,
    --spacing-0-5 and --radius-element values, which are rem since 0.7.0,
    so a 1rem cell drew 1px wide. The tokens are now resolved to px through
    probe elements; a token that cannot be resolved keeps the 16px / 2px / 4px
    default.

  • DataGrid's column boundaries stay in the header while it has no rows.
    Astryx's resize plugin runs every handle down the whole table, so hovering
    the header of an empty grid drew the boundaries through the empty state. An
    empty grid's body now carries uic-data-grid__body--empty, which caps each
    handle at its header cell.