1 hours ago
video-react

v0.16.1

0.16.1 (2026-10-09)

Bug Fixes

Documentation

  • feature Video.js 10 on the homepage and deploy docs with GitHub Actions (#469) (03d5472)
  • point migration copy at the Migrate from Video-React guide (ece8f0c)
  • put Bootstrap in a cascade layer so the Video.js skin keeps its styles (9c50011)
  • serve favicons from the site root (50368f8)
  • use the Video.js favicon (963a47e)
3 hours ago
slate

slate-react@0.133.0

Minor Changes

  • #6198 dd6d37f Thanks @GaurangTandon! - Revert "Ignore input events dispatched by script" (#6117). Input, paste and drop events dispatched by script are handled again, as in 0.127.1.
6 hours ago
astryx

Astryx 0.6.7

Astryx 0.6.7 — all @astryxdesign/* packages ship at this version.

npx astryx upgrade --apply

@astryxdesign/core

New Features

  • Item gains swipe actions for touch, per spec:AST-057. swipeActions declares, per side, the verbs a sideways drag uncovers as ItemSwipeAction[] ({id?, label, icon?, onActivate, isDisabled?, variant?: 'neutral' | 'accent' | 'destructive', hasRemoval?}, outermost last); swipeBehavior is reveal (the row rests open with every entry a real button; a long drag or a fling fires the outermost) or commit (the row slides out and the outermost fires; nothing rests). After an entry fires the row springs back, or holds out when the entry has hasRemoval. A mouse never starts the drag, a mostly vertical drag stays the scroller's, a resting row closes on a pointer outside it. Available on a row whose role permits interactive descendants (a listitem, a role-less row); ListItem passes both props through. No element is added to a row: its root translates and its panels counter-translate. List clips its rows in the inline axis (overflow-inline: clip). Types ItemSwipeAction, ItemSwipeActions, ItemSwipeActionVariant and ItemSwipeBehavior are exported.

  • Drawer is a container, like Dialog. A new padding prop takes a spacing step, and a theme's padding on drawer pads the drawer's scrolling content area through container tokens instead of padding the panel. The padded content area publishes its inset, so a Section that is the drawer's only child, and bleed children such as Table and Divider, align against it, and a Layout inside picks the value up for its header, content, and footer regions. With neither set, the inset is --spacing-4, as in Dialog; pass padding={0} for a full-bleed content area. The block-end safe-area inset is preserved in every mode.

  • An option can carry a secondary action; MultiSelector renders it in a grid. SelectorOptionData and SearchableItem gain action?: ReactNode: one node the caller renders and names — an IconButton, a Button, a menu trigger. In MultiSelector, once any option carries one the popup is a role="grid" whose rows pair the option with its action: Up/Down move rows, the inline-end arrow reaches the action (following RTL), Enter fires it, pointer and touch press it directly, and pressing it never changes the selection. The trigger advertises aria-haspopup="grid". Nothing changes for options without an action. Selector and the typeahead panel do not render the key yet and warn in development when an item carries one.

  • useTableRowExpansion accepts panelVariant, and the detail panel now sits on the surface behind the table by default instead of on a wash of its own. (#5995) The panel row painted --color-background-muted unconditionally, and being a <tr> the plugin builds itself, nothing a caller rendered could reach it.

    The panel is the row's continuation, not a surface of its own, so it now takes whatever the table sits on — the same thing the row does. That keeps the plugin unopinionated about the table's background: a table on a Card no longer stacks a third surface, and a striped table no longer paints a band in the same token as its own stripe, which read as a data row rather than as a detail.

    panelVariant: 'muted' keeps the wash for the case that wanted it — a bare table with no card, no dividers and no striping, where nothing else separates the panel from the data around it.

    This changes the default appearance. A table relying on the wash gets it back with panelVariant: 'muted'; in dark themes there is nothing to get back, because --color-background-muted is a low-alpha near-black that is close to invisible over a dark card — dark has effectively been rendering transparent all along.

  • useTableRowExpansion accepts hasRowClickExpansion, so a row opens when you click anywhere on it and not only on its chevron. (#5995) useTableTreeData has had this since it shipped, under the same name and with the same behaviour. The detail-panel plugin is the other half of the same pair — one expands into child rows, one expands into a panel — and a caller who moved between them lost whole-row clicking without anything saying why. There was no way to add it back either: a click handler on the row has to know not to fire on a checkbox, a link or the end of a text drag, and none of that is reachable from the outside.

    Off by default, and pointer-only when on. The chevron button stays the accessible control, so keyboard and assistive-tech users are unaffected — this adds a shortcut for a mouse, not a second way to operate the table. Clicks that land on interactive cell content, clicks that end a text selection, and clicks on rows getIsItemExpandable has ruled out all pass through untouched. The chevron already stops propagation, so it does not toggle twice.

    Collapsed rows are wired up as well as expanded ones, which is most of the point: the row you want to click is the one that has not opened yet.

Fixes

  • A BottomSheet drag writes its transform straight to the sheet once per input sample and renders nothing in between (React state changes when the drag begins and ends, and when its layout split changes). Measured in Chromium: 4 commits for a 24-sample drag, down from 49. The release still animates from wherever the finger left the sheet.

  • BottomSheet hands a touch to the sheet at the scroll edge of the box under the finger, not the body's alone. Content that scrolls inside the body (a pinned header and footer around a scrolling middle, a grid) never moved the body's scrollTop, so every pull down over that scrolled box dragged the sheet and the box could not be scrolled back by hand. From the box's top the pull still drags the sheet.

  • BottomSheet no longer blocks pinch-zoom. A pinch that started on an open sheet (its handle, its content, or across both) did nothing, because the sheet claimed every touch gesture: touch-action: none on the sheet and handle, pan-y on the content. The sheet now leaves pinch to the browser (pinch-zoom, and pan-y pinch-zoom on the content), and a second finger (on the handle, on the content, or off the sheet, whichever lands first) ends any sheet drag in flight or about to start, so the page zooms and the sheet stays at its detent. One-finger drag and scroll are unchanged.

  • A BottomSheet release is judged where the sheet would coast to at the finger's speed, not where the finger left it: a medium throw dismisses from short of the dismiss line and a gentle throw lands on the next detent instead of snapping back, the release speed is read over the finger's last 100ms rather than its last two samples, and a finger that rests before lifting releases no throw. A nudge under 48px still projects nothing.

  • A DropdownMenu opened by a mouse press returns focus to its trigger when it closes, instead of to the control that was focused before the press. A mouse opens the menu on press-down, before the browser's own mousedown has focused the trigger, so the popover remembered the previously focused control and handed focus back there on Escape or after a pick. The trigger now takes focus as the press opens the menu, the state a click-open already had; keyboard opens, taps and the menu's own behavior are unchanged.

  • A field status shown with statusVariant="tooltip" is now announced to screen readers when it appears or changes, the same way the attached and detached message boxes are: errors assertively, warnings and successes politely. Before, the tooltip placement only described the control, so a screen-reader user was not told that a validation message had appeared until they left and re-entered the field. This affects every input that offers the tooltip placement. The attached and detached placements are unchanged and are still announced once.

  • FileInput: invoke changeAction and update optimistic state on clear and file selection

  • swizzle: rewrite every .stylex import to a deep path astryx swizzle Button (and any component that imports a .stylex module from outside its own directory) emitted an import that collapsed to the directory barrel — e.g. @astryxdesign/core/utils instead of @astryxdesign/core/utils/interactionOverlay.stylex. The barrel does not re-export those StyleX symbols, so the swizzled file could not compile.

    rewriteImports now gives every *.stylex module the deep subpath. The exports generator (scripts/sync-exports.js) adds 16 specific subpath exports for the .stylex modules swizzled components actually reference across directories:

    DateInput/tokens.stylex, Icon/IconSize.stylex, Indicator/indicator.markers.stylex, Layer/layerAnimations.stylex, Layer/layerTextReset.stylex, Layer/layerViewportInset.stylex, Layout/container.stylex, Layout/edgeCompensation.stylex, Layout/padding.stylex, NavItem/navItemStyles.stylex, Selector/selectorPresentation.stylex, Stack/stack.stylex, Stack/stackItem.stylex, Text/text.stylex, utils/focusOutline.stylex, utils/interactionOverlay.stylex

    These are public API additions. Each module already ships in the npm tarball (in dist/); only the exports map entry is new. No wildcard — a future cross-directory .stylex import needs a deliberate entry in STATIC_EXPORTS. Precedent: ./theme/dataTokens.stylex (AST-066 FR2).

  • Keep grouped-row custom headers full-width while pinning their 16px disclosure button, and expose expansion state on the button. (#6251)

  • Keep grouped-row collapse chevrons pinned without shrinking custom headers, and increase them from 12px to 16px (#6222)

  • Keep layer portals inside their nearest dialog

  • Markdown: read an indented table with its own columns Markdown no longer adds an empty first column to a table whose rows are indented, such as | a | b |. The indentation before a row's first pipe used to read as a cell of its own.

  • Markdown: keep a definition-shaped line whose label is over 999 characters Markdown no longer drops a line shaped like a link reference definition whose label holds more than 999 characters. CommonMark allows no such definition, so the line now shows as text, as a reference with that label already did.

  • Markdown: end a code block left open at the end of a message on its last line of code When a message ended inside a code block that was never closed, Markdown read the message's final line ending as one more, empty line of code, unlike a closed code block and unlike the streamed render of the same message. A real blank line before the end is still code, and while a message streams, an open code block now shows the blank lines already written instead of adding them later.

  • Markdown: keep a quoted blank line at the end of a code block left open A code block left open inside a block quote keeps a blank quoted line at its end as code, as CommonMark reads it. Only the document's own final line ending is left out of an open code block.

  • Markdown: keep two lists apart while streaming when their bullets or indentation differ While a message streamed, Markdown joined two lists a blank line apart whenever both were bulleted, or both numbered with the same delimiter — even when their bullets (- then *) or indentation differed, where the finished document shows two lists. The streamed render now keeps them apart, as the finished document does.

  • MobileNav no longer blocks pinch-zoom while it is open. The open nav covers the whole viewport and declared touch-action: none (with pan-y on its content), so a pinch anywhere on screen did nothing. It now declares pinch-zoom (and pan-y pinch-zoom on the content): pans are still kept from reaching the page behind, and a pinch zooms the page.

  • MultiSelector: name the listbox of a bottom sheet without search from the component's label, so screen readers announce it

  • Added a @astryx.richTextEditor.* catalog namespace to the shared message catalog, so the RichText editor's toolbar labels, block-format options, link dialog, and Tab escape hint can be translated and overridden through InternationalizationProvider. The editor's character counter now announces through the existing @astryx.textArea.characters* messages, so it is translated in every locale TextArea already ships.

  • In a collapsed SideNav, pressing a SideNavHeading menu trigger right after hovering it now keeps the hover-opened menu open, as the click guard intends. The browser was dismissing the menu on the press because the trigger sat outside the panel; the collapsed trigger is now the panel's native invoker, the same wiring TopNavMenu uses.

  • Keep editable content from toggling tree and expansion rows The shared click guard that row-expansion and tree-data use to decide whether a row click should toggle missed [contenteditable] elements. Clicking or typing inside editable content in a row toggled it. Restored the exclusion with tests on both paths.

  • Whole-row-click expansion reuses the shared clickable-container guards instead of its own selector list. (#5995) useTableRowExpansion and useTableTreeData each carried a hand-rolled copy of "did this click belong to something else" — the same nine selectors, written twice. useClickableContainer already owns that rule for every clickable surface in the system, and its INTERACTIVE_SELECTORS list is the fuller one: it also covers role="link", radio, switch, tab, menuitem, option, combobox, listbox, slider, spinbutton and [data-pressable-container], and it excludes [aria-readonly="true"].

    Both plugins now call the hook's hasInteractiveAncestor and hasTextSelection, newly exported for containers that cannot use the hook itself — a <tr> assembled inside transformBodyRow has no ref to hand it.

    Two behaviour changes fall out of sharing, both fixes:

  • Turn only the chevron glyph in useTableRowExpansion, not the button beneath it. (#5995) The rotation was on the <button>, which is the hit target and carries the hover chip, so opening a row swung that rounded rectangle and its highlight a quarter turn along with the arrow — most visible mid-animation, where the chip passes through a diamond. A finished 90° turn on a 24px rounded square lands back on itself, which is why this only shows up in motion.

    The transform now sits on the glyph and the button stays put. The two transitions move onto --duration-fast and --ease-standard in the same pass, matching what TableRow already uses for its own hover transition.

  • Draw the row divider below a useTableRowExpansion detail panel rather than above it. (#5995) An expanded row and its panel are one unit, but the divider was landing between them: the row drew its own bottom border, which put a line between the row and the detail it had just opened, and the panel drew none, so it ran flush into the next row. Both halves of that are backwards — the pair was split down the middle and then fused to the row below.

    The expanded row now gives up its border and the panel takes one. On a table with no row dividers the suppression removes a border that was never there and the panel's is never applied, so neither side has to consult the divider mode; only the panel does, to know whether to draw at all. The panel row carries tableRowMarker, which is how TableCell scopes its "no trailing line under the last row" rule, so an expanded last row still ends the table cleanly.

  • Start the useTableRowExpansion detail panel at the first column rather than at the row edge. (#5995) The panel is one cell spanning the whole row with a flat 20px inline padding, so its content began under the chevron — a column to the left of every label it describes.

    It now indents by the chevron column's fixed width plus the inline padding a cell of that density gives its own content, read off the table context so it follows density, and written as a logical property so RTL mirrors it. It is not configurable: a panel starting anywhere else reads as a misalignment rather than as a choice.

    The chevron column's width cannot be a token reference — the layout does arithmetic on it — but it is the pixel value of --spacing-10, which is how the indent spells it. A test pins the two together so a change to the scale cannot silently unalign them.

  • Table zebra striping counts data rows only, so expanding a row no longer inverts the stripe of every row below it. (#5995) A row-expansion detail panel is appended as a sibling <tr> in the same <tbody>, and striping is :nth-child(even) — so the panel took a stripe turn of its own and pushed every row after it onto the opposite one. Opening a single row repainted half the table.

    The stripe now counts :nth-child(even of :not([data-expansion-panel])). A panel is not a row and is not counted as one, so the data rows keep their parity whatever is open.

    of S has been Baseline since 2023, inside Astryx's support floor (AST-013). Below it the stripe rule is dropped rather than misapplied: an unstriped table, not a mis-striped one.

    Tables without the row-expansion plugin are unaffected — nothing else in the system emits data-expansion-panel.

  • Table columns without an explicit width now keep a compact readability floor and use the existing horizontal Scroll region when their combined minimums do not fit.

Documentation

  • The README's CDN template command and the icon and token hints in the DropdownMenu item and Indicator docs name the scoped npx @astryxdesign/cli, which runs this CLI whether or not it is installed. Bare npx astryx fetches an unrelated npm package until the CLI is a dependency.
  • align statusVariant documentation and test coverage across ComplexSelector, Tokenizer, and Typeahead

Other Changes

  • A click on a composed control the short list missed — a role="tab", a segmented role="radio", a Slider in a cell — no longer toggles the row underneath it.

  • The text-selection guard is scoped to the row instead of asking the document for any selection at all. Text selected elsewhere on the page no longer makes every row in the table inert.

    The walk also stops at the row rather than climbing to document.body, so an interactive ancestor of the whole table cannot suppress row clicks.

@astryxdesign/cli

New Features

  • Apps can opt into package-managed themes with astryx theme add <slug> --import. The command records the theme in one generated app module with its production CSS, optional font CSS, and default slug. Use theme remove and theme use to manage that record, and pass themes[defaultThemeSlug] to <Theme>. Plain astryx theme add keeps its released source-copy behavior, options, stdout, exit status, and every theme.add data field. It now warns that theme eject is the explicit source-fork command and theme add --import is the way to use the package-managed theme. Its machine result adds the DEP-0005 deprecation entry; the cleanup is CLN-0005 in a later scheduled minor.

    Use defineTheme({extends: importedTheme, ...}) for ordinary customization. theme eject creates an independent local fork with its descriptor. JSON callers receive theme.app from import, remove, and use, or theme.eject from eject.

    Existing bundled source copies stay where they are and keep their bytes. Run astryx upgrade --from 0.6.4 --path . --apply to add the missing unmaintained descriptor beside each bundled copy in src/themes. Until then, theme commands skip those copies and theme list and doctor name them as unmigrated. Package integration themes keep their released complete-directory copy, including the authoring descriptor.

    ASTRYX_THEME is no longer read. In a project with a generated app theme module, component metadata reads that record's default built theme. Without the module, the released package.json#astryx.theme lookup keeps its meaning. Doctor loads every recorded built module through the same theme adapter, so a broken runtime import fails theme-owners instead of passing.

    theme build also writes <out>.css.d.ts so TypeScript accepts generated CSS imports. Check mode stays compatible with released output sets that do not have this new stub yet.

    Integration themes can export built modules and stylesheets. astryx integration add theme creates those exports, and integration verify checks the exported paths against the packed package and source. Missing partner exports alone do not block packing. Every declared export must resolve; staleness is a warning for an incomplete set and an error for the complete importable module and stylesheet pair.

  • Every result now names the package it comes from. A --json result about one artifact (a component and each of its projections, a doc topic, index, section, or docs-tree node, a template, a hook, and swizzle) carries package in its envelope, directly after type. A result that lists artifacts gives each item its own package: every search hit, build's start, alternatives, blocks, and components, a doc's sections, a docs-tree node's children, --blocks entries, and the component --list and upgrade --list entries. Text names the same package; --source, --showcase, and a template's source still print only the source on stdout and name the package on stderr. Existing fields are unchanged.

  • Deprecate the astryx layout command group The astryx layout command group (expand, check, grammar) is deprecated. Use astryx build to choose the template to start from, astryx template to scaffold it, and astryx docs layout for layout guidance.

    In human mode each invocation prints a stderr warning naming the replacement. In JSON mode the response envelope carries machine-readable deprecation metadata in its meta field. Canonical stdout, exit codes, and the layout.expand / layout.check / layout.grammar response schemas are unchanged.

    Deprecation lifecycle (spec:AST-017 FR28, FR31) — removal only in a later minor whose frozen manifest carries both ids of a pair:

  • An integration component can replace a Core component, once its package opts in An @acme/nav component whose doc sets replaces: 'SideNav' takes over SideNav for unqualified component detail, batch selectors, every component --list detail level, search, swizzle, and gap-report routing, when @acme/nav declares "@astryxdesign/cli": ">=0.6.7" in peerDependencies (optional in peerDependenciesMeta). Every result names its package, --package @astryxdesign/core still selects the original Core component, and the replacement keeps answering to its own name. component SideNav --package @acme/nav also selects it.

    Any @astryxdesign/cli range that starts at 0.6.7 or later is the opt-in, including the >=0.7.0 that integration add doc --parent wrote in 0.6.4 and 0.6.5, and integration add theme in 0.6.5. A package whose range admits an earlier CLI keeps its component under its own name and Core stays selected, and an app that loads it sees no new output; its author gets warnings naming the range to add, from astryx doctor integration components and integration verify. For a package that declares the range, astryx doctor integration components reports a missing Core target, an invalid value, a component named after a different Core component, or two replacements for one target in the package as errors and exits 1. When several packages replace one target, an explicitly configured package beats an autolinked one, the later configured package wins, and Doctor warns.

  • Add the model comparison page template with responsive sticky context and accessible interactions. (#6251)

  • New table-collapsible page template: several tables on one page, each in a collapsible card with its own columns, for groups that do not share a schema. Every table sorts on its own, one time range in the page header drives all of them, and rows expand in place into a full-width history chart. Below 720px each table folds to its name and headline figure. (#6065)

Fixes

  • Printed commands name the scoped @astryxdesign/cli package whenever the astryx bin is not installed for the project

  • Compact the generated agent-docs block: fewer lines, same behavioral coverage

  • astryx doctor keeps its themes check, with the same id, label and fields, beside the new theme checks, so scripts that read it by id keep working. Without a generated theme module it reports what it did before: whether an @astryxdesign/theme-* package is installed, and whether the app's package.json names a theme in astryx.theme. Its fix now names theme add --import. With a generated module it reports the overall result of the theme checks. In a workspace, themes reads the app's own package.json, the file the CLI reads when it resolves the theme, rather than the package.json beside the root node_modules. It no longer counts the ASTRYX_THEME variable, which the CLI does not read, as a wired theme.

  • Doctor says why it skipped a check and what it checked, and doctor integration validate no longer crashes on a folder it cannot read

  • upgrade: exclude node_modules from integration codemod discovery When an integration declared its codemods root as the package root (codemods: "./"), the version-folder scan treated node_modules, .git, __tests__, and __fixtures__ as version folders and loaded their files as codemods. The same SKIP_DIRS filter that the recursive file walk already used is now also applied to the top-level version-folder enumeration.

  • Align the layout deprecation (DEP-0006) with the documented envelope and precedent The layout command's JSON envelope now emits meta.deprecations: [{id, replacements}], matching the response schema doc and the DEP-0005 theme add precedent. The deprecated CommandDoc field renders in --help and the manifest. The programmatic API exports (layoutExpand, layoutCheck, layoutGrammar) carry @deprecated in their declarations and generated types. Command and function reference pages name DEP-0006 and the replacement. The DEP-0006 record names its direct authority. All released data fields are unchanged.

  • swizzle: rewrite every .stylex import to a deep path astryx swizzle Button (and any component that imports a .stylex module from outside its own directory) emitted an import that collapsed to the directory barrel — e.g. @astryxdesign/core/utils instead of @astryxdesign/core/utils/interactionOverlay.stylex. The barrel does not re-export those StyleX symbols, so the swizzled file could not compile.

    rewriteImports now gives every *.stylex module the deep subpath. The exports generator (scripts/sync-exports.js) adds 16 specific subpath exports for the .stylex modules swizzled components actually reference across directories:

    DateInput/tokens.stylex, Icon/IconSize.stylex, Indicator/indicator.markers.stylex, Layer/layerAnimations.stylex, Layer/layerTextReset.stylex, Layer/layerViewportInset.stylex, Layout/container.stylex, Layout/edgeCompensation.stylex, Layout/padding.stylex, NavItem/navItemStyles.stylex, Selector/selectorPresentation.stylex, Stack/stack.stylex, Stack/stackItem.stylex, Text/text.stylex, utils/focusOutline.stylex, utils/interactionOverlay.stylex

    These are public API additions. Each module already ships in the npm tarball (in dist/); only the exports map entry is new. No wildcard — a future cross-directory .stylex import needs a deliberate entry in STATIC_EXPORTS. Precedent: ./theme/dataTokens.stylex (AST-066 FR2).

  • template: show a grouped summary by default instead of the full catalog Bare astryx template (no name, no --list) now shows templates grouped by category with counts — about 21 KB instead of the full 149 KB catalog. The full catalog with descriptions is still reachable via astryx template --list.

    JSON output is unchanged — --json template still returns the complete template.list response. This is a text-only rendering change under AST-017 FR11: the machine-readable response schema is the contract; text formatting is not.

    Trade-off: the grouped output still includes every template id (so template <id> works from a copy-paste), at the cost of ~21 KB. An even shorter summary (type + count only, no ids) would be ~500 bytes but would require a second step to discover any id. The current shape serves both human scanning and agent copy-paste without a round-trip.

  • template: bare template --type no longer prints an empty group header

  • A section read on a docs-tree namespace answers from the guide that has the section again, so astryx docs layout side-panels and the other layout section reads released in 0.6.6 work after the layout split. docs(route, section) returns the same docs.detail.section the guide's own section read returns, found by key, then by title, in --dense and --zh too. When no guide or more than one has the section, the read fails with ERR_UNKNOWN_SECTION and names the guides to read it from.

  • astryx search ranks a component, hook, or template that a query word names above a doc that matched only by keyword, heading, or text. font size finds Text first again instead of a typography guide. A doc the query names, such as font setup or migration, or one whose title the query holds, such as resizable side panels, keeps its place. Result scores do not change; only the order between domains moves.

  • astryx search finds a guide when the query is its route or title in the other number: side panel finds the side panels guide first again, and header and footer finds headers and footers. A section's heading still doesn't count as its topic's name, so font size keeps finding Text first.

  • Fix comparison table category from "Table - Frozen Column" to "Table - Comparison" The category described an implementation detail (the frozen label column) instead of what the template is for. Builders searching by layout type now find it under Comparison.

  • Template and build tell you what a scaffolded template needs that your project lacks. When astryx template <name> <path> scaffolds a file that imports packages your project does not have (e.g. @heroicons/react, recharts, lucide-react), the receipt now includes a ready-to-run install command with the project's package manager and version ranges from the CLI workspace. astryx build shows the same note on its start template.

    When a scaffolded template uses StyleX and the project has no compiler plugin configured, the receipt warns and points to astryx docs styling-overview. The agent-docs block no longer says "don't use xstyle" flat-out — it acknowledges that some templates need it and links the setup doc.

    detectStylingSystem now recognizes the official @stylexjs/rollup-plugin, @stylexjs/webpack-plugin, and @stylexjs/nextjs-plugin alongside the existing entries.

  • astryx theme build prints one line per built theme, plus one line naming fonts the themes do not load. Before, every theme printed the same install example and font recipe, so a build of many themes printed the same blocks again and again. --detail full prints the install example and font recipe, once for a batch instead of once per theme; for one theme it prints what the default printed before. Only the text report changes: --json output, --check, exit codes and written files are unchanged.

  • Wherever the CLI shows the <Theme> wrapper, it now also shows where Theme comes from: import {Theme} from '@astryxdesign/core'. This covers the astryx init next steps, theme add and theme build output, the doctor fix for an unimported theme module, build help, and the theme guides.

  • astryx theme add <slug> --import names the npm package that owns the added theme, in its JSON envelope (package, directly after type) and in its text output, the same way other results about one artifact do. A local theme has no package, so its result has no package, and theme remove and theme use are unchanged. astryx theme add --list keeps its JSON. Its text now names theme add <slug> --import to use a theme and theme eject <slug> to fork one, instead of the deprecated copy form.

    astryx doctor adds a theme-management check, and focused theme-* checks once a project has a generated theme module.

  • One-off commands in a classic Yarn (1.x) project use npx @astryxdesign/cli … instead of yarn dlx, which classic Yarn does not have

Documentation

  • astryx docs migration, internationalization, styling, styling-libraries, typography and tokens still work and now list focused guides. Each section is also readable under its guide, for example astryx docs tokens/tokens-spacing or astryx docs styling/tokens-and-setup stylex-setup, and astryx docs <topic> <section> keeps working: every section key these topics had still opens the same section. astryx docs tokens --depth all --detail full prints every token table, and a token-ref to tokens keeps resolving through the guide that holds the table. Integrations: these six names are now docs-tree sections, not topics, so an integration doc that declares extends or replaces with one of them is reported as naming no topic, and its content no longer shows. To keep that content, ship it as your own topic under a new name, or as a guide in your package's own section (astryx integration add doc <name> --parent <your-section>). Topics that are still flat, such as theme or color, can still be extended or replaced.

    (#7184)

  • astryx docs layout still works and now lists the focused guides. Each section is also readable under its guide, for example astryx docs layout/side-panels or astryx docs layout/scaffold shell, and astryx docs layout <section> keeps working. (#7125)

  • astryx docs layout opens with its overview again, and astryx docs author-a-theme and use-a-theme restore guidance the theme split dropped: what a bad extends base does, how adaptation rules are validated, what __built means, the icon-registry specifier traps, registerTheme, and wiring built themes in development too. (#7204)

  • Add a choose-a-path styling overview and restore the import-based workflow across the theme guides. (#7134)

  • Split the theme documentation into focused guides for using and authoring themes, with a concise overview that points to both workflows. (#7141)

Other Changes

  • A hint uses npx astryx … (or pnpm exec, yarn, bunx) only when the astryx bin is in node_modules/.bin, in the project or a folder above it. Otherwise it prints npx @astryxdesign/cli … (pnpm dlx, yarn dlx, bunx), as it already did when the CLI ran from an npx or dlx cache.

  • A global install, or a workspace install used in a fresh package, used to print npx astryx …. The npm package named astryx is not this CLI, so following that hint fetched an unrelated package.

  • astryx blog follows the same rule, and the incident console template names the scoped package.

    Classification: contract-restoring. JSON shapes are unchanged; only hint text changes, and projects with the CLI installed keep npx astryx ….

  • deprecation DEP-0006 / cleanup CLN-0006 — astryx layout command group (expand, check, grammar)

  • A check that needs the loaded project quotes the reason the CLI could not load it, instead of only "Skipped".

  • The config check warns when astryx.config imports but the CLI cannot load the project from it. Before, it said the config loaded cleanly.

  • Integration contributions name the integrations they checked; with none loaded, the check reports info and says there is nothing to check.

  • The agent-docs check reads every file init can write (Hermes included) and looks in the project root as well as the working directory, so running doctor from a subfolder no longer reports that there are no agent docs.

  • astryx doctor integration validate names a folder it cannot read and keeps checking. A declared root that is a file or that cannot be read is reported as invalid_root or unreadable_root instead of a raw error or a crash.

    Classification: contract-restoring. No check becomes stricter: every new finding is a warning or info, and the only exit-code change is that an unreadable folder outside every root no longer crashes validation.

  • Whenever the CLI prints its scoped one-off form (it ran from an npx or dlx cache, or the astryx bin is not installed for the project), a Yarn project got yarn dlx @astryxdesign/cli …. On classic Yarn that command fails.

  • Classic Yarn is read from the declared packageManager version, the yarn.lock header (# yarn lockfile v1), a committed .yarnrc (without .yarnrc.yml), or the runner. Yarn 2 and later keep yarn dlx.

    Classification: contract-restoring. JSON shapes are unchanged; only hint text changes.

@astryxdesign/theme-butter

New Features

  • Each theme package now exports /fonts.css beside /built and /theme.css. Import it when the theme uses non-system fonts.

@astryxdesign/theme-chocolate

New Features

  • Each theme package now exports /fonts.css beside /built and /theme.css. Import it when the theme uses non-system fonts.

@astryxdesign/theme-gothic

New Features

  • Each theme package now exports /fonts.css beside /built and /theme.css. Import it when the theme uses non-system fonts.

@astryxdesign/theme-matcha

New Features

  • Each theme package now exports /fonts.css beside /built and /theme.css. Import it when the theme uses non-system fonts.

@astryxdesign/theme-neutral

New Features

  • Each theme package now exports /fonts.css beside /built and /theme.css. Import it when the theme uses non-system fonts.

@astryxdesign/theme-stone

New Features

  • Each theme package now exports /fonts.css beside /built and /theme.css. Import it when the theme uses non-system fonts.

@astryxdesign/theme-y2k

New Features

  • Each theme package now exports /fonts.css beside /built and /theme.css. Import it when the theme uses non-system fonts.

Contributors

Thanks to everyone who contributed to this release:

@AKnassa @cixzhang @ernestt @humbertovirtudes @imdreamrunner @josephfarina @Lee-Dongwook @ManoharPaturi @vjeux

Full Changelog: https://github.com/facebook/astryx/compare/v0.6.6...v0.6.7

6 hours ago
next.js

v16.5.0-canary.6

Core Changes

  • Add more metadata to agent upgrade telemetry: #99925
  • perf: reduce build tree view allocations: #99930
  • fix: classify collapsed generated paths from child routes: #99864
  • Upgrade React from d75b0697-20261006 to b618bbb4-20261007: #99879

Misc Changes

  • docs(skills): use agent-agnostic branch prefix in create-pr: #99934
  • [test] Regression test for XSS-safe GoogleTagManager#dataLayer: #99464
  • [image-optimization] Expose next/image-optimizer-transform as a public subpath: #99312
  • fix(next): register the chunk groups that are chunked: #99749
  • refactor(turbopack): chunk several chunk groups in one chunk_group call: #99686
  • Turbopack: canonicalize chunk group identity: #98733
  • Turbopack: add zstd compression flags for NEXT_TURBOPACK_TRACING: #99808
  • Turbopack: omit Exit+Enter trace row pairs with (almost) no gap: #99780
  • Turbopack: delta-encode trace allocation counters and skip unchanged ones: #99779
  • Turbopack: merge allocation counters into trace Enter/Exit rows: #99778
  • [cd] Replace versioned release branches with fixed releases/lts/* refs: #99807
  • test: Really use pnpm on deploy tests: #95360
  • test: compare cache-control directives as a set in deploy tests: #99892

Credits

Huge thanks to @devjiwonchoi, @aurorascharff, @sokra, @eps1lon, and @mischnic for helping!

7 hours ago
apexcharts.js

💎 Version 8.0.0

8.0 takes three chart types and four features out of the default bundle, so most pages download less, and adds a bundle that has everything. If a chart stops drawing after the upgrade, the console names the line to add.

Moved out of the default bundle Import next to 'apexcharts'
unit (with waffle and beeswarm) apexcharts/unit
sunburst apexcharts/sunburst
violin apexcharts/violin
drilldown apexcharts/features/drilldown
waterfall apexcharts/features/waterfall
dumbbell apexcharts/features/dumbbell
streamgraph apexcharts/features/streamgraph

With script tags, add the matching file: dist/unit.js, dist/sunburst.js, dist/violin.js, or dist/features/.js for the four features. Raincloud, already opt-in, now needs dist/violin.js before dist/features/raincloud.js. Add-on tags may come before or after the ApexCharts one. Or load apexcharts.full.min.js (import ApexCharts from 'apexcharts/full' in a bundler), which has every chart type and feature.

On the lean core (apexcharts/core), violin and raincloud also need apexcharts/bar, and a boxPlot or violin of raw observations needs apexcharts/features/stats; without it the console now says so.

Unversioned CDN URLs move to 8.0 today. Pin apexcharts@7 to stay on 7, or add the add-on tags now: the files exist in 7.9.1 too.

🐛 Fixes

  • Keep the chart when an update asks for a chart or series type the page never loaded.
  • Keep the drill state when a level is refused.
  • Point lean-core missing-renderer errors at files that exist.
  • Resolve typed subpaths (apexcharts/core, ssr, client, full) under node10 module resolution.
  • Warn when a boxPlot or violin has raw data and no stats feature.
  • Let a script-tag add-on load before the ApexCharts script.

The default bundle is 263,188 B gzipped, down 28,575 B (9.8%) from 7.9.1. The new full bundle, apexcharts.full.min.js, has every chart type and feature in one file: 381,135 B gzipped.

Upgrading is npm install apexcharts@8.0.0.

Full changelog, with the detail behind each change: https://github.com/apexcharts/apexcharts.js/compare/v7.9.1...v8.0.0

7 hours ago
virtual

@tanstack/vue-virtual@3.13.40

Patch Changes

7 hours ago
virtual

@tanstack/react-virtual@3.14.14

Patch Changes

  • #1301 ce57b78 - fix(react-virtual): position directDomUpdates rows that mount without the owner re-rendering

    Rows were only positioned by the owner's layout effect or the next onChange. A row mounted by a child that re-renders on its own (local state, context, a resolved Suspense boundary) skipped both when it was fixed-size, and stayed unpositioned until the range changed. Rows are now positioned as they register through measureElement, and containerRef positions the rows that mounted together with the container.

  • Updated dependencies [43675bc, 9df47a3, c644f10, 2a631f4]:

    • @tanstack/virtual-core@3.18.0
7 hours ago
virtual

@tanstack/virtual-core@3.18.0

Minor Changes

  • #1300 43675bc - feat(virtual-core): add cancelScroll() to stop an in-flight scrollToIndex / scrollToOffset / scrollBy / scrollToEnd from correcting toward its target, so a user gesture can take over the viewport (#1285)

Patch Changes

  • #1276 9df47a3 - Fix scrollToIndex(last, { align: 'end' }) overshooting the last item by paddingEnd; it now respects scrollPaddingEnd like other end-aligned items. To scroll to the very bottom including paddingEnd, use scrollToEnd().

  • #1293 c644f10 - fix(virtual-core): don't cache a 0 size when measureElement receives a node that isn't attached to the document yet

  • #1294 2a631f4 - Keep scrollToIndex reconciliation active until pending ResizeObserver measurements can update its target, including when useAnimationFrameWithResizeObserver is enabled. Respect an external scroll away from a reached target during this settling period.

7 hours ago
virtual

@tanstack/svelte-virtual@3.13.40

Patch Changes

7 hours ago
virtual

@tanstack/solid-virtual@3.13.41

Patch Changes