v7.5.1
I am pleased to announce the release of officeParser v7.5.1! This patch release closes three reported issues around one theme: trusting the file in front of us less, and telling you more. Unreadable input now fails with typed errors instead of parsing as an empty document, type detection reads the archive's own declaration when magic-byte sniffing gives up, and the browser bundles no longer break webpack builds.
Thanks to @benhid, @SteveNewhouse and @ayazaurie, whose reports drove this release.
[!WARNING] Behavior changes
- Corrupt input throws; it no longer parses as an empty document. Data that is not a ZIP archive, an archive cut off in transfer (or carrying data after its end-of-archive record), and a readable ZIP missing the part its format requires (
word/document.xml,xl/workbook.xml,ppt/presentation.xml, ODFcontent.xml, the EPUB OPF) now reject withZIP_NO_ENTRIES_FOUND,ZIP_TRUNCATEDandREQUIRED_PART_MISSINGrespectively. An empty result therefore means the document really is empty. If you relied on unreadable files resolving quietly, catch and branch onerror.officeIssue.code.- DOCX headers, footers and comments now appear in output. They were documented but never extracted, so
ast.auxiliary.headers/.footerswere always empty and comments never reached the AST. Documents that have them will now produce them;ignoreHeadersAndFootersandignoreCommentsrestore the old shape if you want it.- Config objects are no longer shared with the library. Reusing one config across calls previously leaked each parse's warnings into earlier, already-returned
ast.warningsarrays, and generation could silently rewritehtmlConfig.containerWidthon your own object. Resolution now copies; callbacks andabortSignalkeep their identity.
Since the 7.3.0 streaming ZIP rewrite, a corrupt buffer resolved into an empty AST with no warnings, indistinguishable from a genuinely empty document. Three distinct failure modes are now typed rejections, and every thrown error carries its structured issue so you branch on a stable code instead of matching message text:
try {
const ast = await parseOffice(buffer, { fileType: 'docx' });
} catch (err) {
switch (err.officeIssue?.code) {
case 'ZIP_NO_ENTRIES_FOUND': // not a ZIP archive at all
case 'ZIP_TRUNCATED': // cut off in transfer, entries incomplete
case 'REQUIRED_PART_MISSING': // readable ZIP, but not the format it claims
console.error('Unusable file:', err.officeIssue.message);
break;
default:
throw err;
}
}
The OfficeError type is exported for TypeScript users. Files that are legitimately empty still parse and now say so: a chartsheet-only workbook emits NO_WORKSHEETS_FOUND and a zero-slide deck emits NO_SLIDES_FOUND through onWarning / ast.warnings, so an empty result is never silent in either direction. Two ODF gaps closed alongside: a valid .ods/.odp without a mimetype entry was walked as a text document and came back empty (it now falls back to your fileType or the extension), and a missing root content.xml can no longer silently promote an embedded Object N/content.xml chart to the document body.
Passing a bare Buffer relied entirely on magic-byte sniffing, which walks a ZIP under fixed budgets: at most 1024 entries, and roughly 1 MiB of scanning when entry sizes are deferred to trailing data descriptors (general-purpose flag bit 3, what streaming ZIP writers produce). A valid PPTX whose [Content_Types].xml sat beyond either budget was reported as generic zip, so parseOffice threw "Sorry, OfficeParser currently supports docx, pptx, xlsx... add support for zip files" for a perfectly good document. Both layouts occur in the wild, and every ZIP-backed format was affected, in Node and in the browser.
When sniffing is inconclusive, the archive is now opened with officeParser's own reader, which has neither budget, and the format is taken from [Content_Types].xml or the ODF/EPUB mimetype entry. Detection inflates at most 4 MiB regardless of your decompression limits, a correct fileType hint skips the archive scan entirely and remains the fastest path, and a bare zip sniff is no longer misreported as a BUFFER_TYPE_MISMATCH against your own hint.
One dynamic import inside the bundles escaped the build's webpackIgnore annotations, because the annotator treated an interpolated template literal as a static string. Webpack does not skip a specifier it cannot resolve: it builds a context module over the whole directory, so consumers ended up bundling all of dist/, Node-only files included, and their builds failed on child_process. The annotator was rewritten around a shared, tested classifier, child_process and url now resolve to browser stubs, and a webpack 5 build of the ESM and slim ESM bundles is warning-free. Shipping checks now scan every bundle so this class of regression cannot ship again.
- DOCX headers, footers and comments were never extracted. The parse code existed but the parts were missing from the archive extraction filter, so it could never run. Part names now also match past
header9.xml, which documents with several sections reach. - PPTX document-property parts were parsed as slide candidates.
docProps/app.xmlandcustom.xmlare now skipped in the slide loop on identity, closing the same phantom-slide trap thatppt/presentation.xmlneeded. - Typed errors were reported twice, with a doubled
[OfficeParser]:prefix and their code flattened toFILE_CORRUPTEDby the wrapping layer. Errors now pass through once, intact. - Archive extraction errors ignored
outputErrorToConsoleandonWarning, always writing to the console. They now report through your handlers like every other issue. - Memory: the Word, Excel and PowerPoint parsers each kept the full XML source of every extracted part in a write-only buffer under
includeRawContent. Dropped; serialized ASTs are byte-identical.
npm install officeparser@7.5.1
🔗 Full Changelog: View v7.5.1 details 🔗 Documentation & Visualizer: officeparser.harshankur.com
v0.2.0
- TabList: remove orientation prop (misleading no-op). The prop did not render vertical tabs; it only toggled the keyboard-hint badge arrows. Arrow navigation has always accepted both axes (horizontal and vertical) via orientation: both in useListFocus. Run astryx upgrade to auto-strip the prop from your code.
Avatargains optional interactivity viahref/onClick(withas/target/rel), following Button's element-swap trichotomy:hrefrenders a link throughuseLinkComponent,onClick(no href) renders a<button type="button">, and with neither the avatar stays the static, non-focusable element it is today (non-breaking default). Interactive avatars get the focus-visible accent ring and a required accessible name (fromalt/name). InsideAvatarGroup, interactive avatars — and an interactiveAvatarGroupOverflow— now share a single Tab stop with roving ArrowLeft/ArrowRight focus, and the group exposes a screen-reader keyboard hint viaaria-describedby. A purely static facepile is unchanged. (#4170)- Citation:
CitationSource.iconnow accepts aReactNode(e.g. an Astryx<Icon>, an SVG, or a custom element) in addition to an image URL string, and a newCitationSource.srcfield holds a favicon/logo image URL (mirroringAvatar/Thumbnail). Additive and non-breaking: a stringiconstill renders as the favicon<img>, so existing callers are unaffected. When both a nodeiconandsrcare set, the node wins. The icon stays decorative — the accessible name still comes solely from the citation'saria-label. - CodeBlock: move the collapse chevron to the left of the title/language label, following the leading-disclosure convention (points right
>when collapsed, downvwhen expanded). It grows into place (width + inline margin) so it slides the title over smoothly instead of popping in and shifting the header. Respectsprefers-reduced-motion(#4513) - Collapsible: expose the trigger button as a distinct theming target (
astryx-collapsible-trigger) so themes can style the trigger independently from the content — e.g. a heading font on the trigger while the content keeps the body font. - DateInput: add
astryx-date-input-clear-iconandastryx-date-input-toggle-icontheme targets on the clear and calendar-toggle glyphs, so consumers can recolor, resize, and hover-style each icon — and style the toggle's open/closed state — viadefineThemeinstead of a fragile descendant selector or raw CSS. The toggle reflects its open/closed state as adata-stateattribute.Iconnow fully handles its styling props (className,style,xstyle) so they compose with its base styles instead of being dropped. Default rendering is unchanged. - DateRangeInput: add
astryx-date-range-input-clear-iconandastryx-date-range-input-toggle-icontheme targets on the clear and calendar-toggle glyphs, so consumers can recolor, hover-morph, and resize them viadefineThemeinstead of a fragile descendant selector or raw CSS. The toggle icon reflects its open/closed state as adata-stateattribute.Iconnow fully handles its styling props (className,style,xstyle) so they compose with its base styles instead of being dropped. Default rendering is unchanged. - DateTimeInput: add
astryx-date-time-input-date-segmentandastryx-date-time-input-time-segmenttheme targets on the two segment wrappers, so a theme can restyle their geometry (padding/height/font) viadefineThemeinstead of being unable to reach them at all. Both reflectsizeandstatusas data attributes, mirroring the root target. Default rendering is unchanged. - DropdownMenu: add submenus via a single
DropdownMenuSubMenucomponent (or a nesteditemsarray in data mode). The row adopts DropdownMenuItem semantics (label / icon / description / isDisabled) and its children — or anitemsarray — become the flyout content. Flyouts open inline-end with auto-flip, hover-intent, and full keyboard support (Right/Enter/Space opens and focuses the first item; Left/Escape closes and returns focus to the trigger). - Bordered inputs gain a
statusVariant="tooltip"option that hides the status message box and surfaces the status as an info-tip on the on-field status icon. The icon is a real focusable button so the status is reachable by everyone: keyboard users tab to it (with a visible focus ring) and see the message on focus, pointer users see it on hover, and touch users tap to toggle it. The message is piped into both the input's and the button'saria-describedby, and the tooltip is dismissible with Escape. Added to TextInput, TextArea, NumberInput, DateInput, DateRangeInput, TimeInput, and FileInput. - The bordered input family now accepts a
statusVariantprop ('attached' | 'detached', default'attached') that forwards to the underlyingField, letting you float the status message below the input with spacing instead of overlapping it. Added to TextInput, TextArea, NumberInput, DateInput, DateRangeInput, TimeInput, Selector, MultiSelector, Typeahead, Tokenizer, FileInput, and PowerSearch. Non-breaking: the default matches today's behavior. (#4187) - Add RTL direction API:
useDirection()hook,getLocaleDirection(locale)server-safe helper, and an optionaldirprop onInternationalizationProvider. - RTL: mirror directional disclosure/navigation chevrons under RTL via a shared
rtlStyles.mirrorCSS transform, applied to the icon wrapper in Lightbox and the Table tree / grouped-rows / row-expansion plugins. The mirror composes correctly with the Table chevrons' state-rotation (expanded chevrons still point down under RTL). Semantic aria-labels are unchanged. - Selector & MultiSelector: add
astryx-selector-clear-icon,astryx-selector-indicator-icon,astryx-multi-selector-clear-icon, andastryx-multi-selector-indicator-icontheme targets on the clear and chevron glyphs, so consumers can recolor, resize, and hover-style each icon — and style the chevron's open/closed state — viadefineThemeinstead of a fragile descendant selector or raw CSS. Each chevron reflects its open/closed state as adata-stateattribute.Iconnow fully handles its styling props (className,style,xstyle) so they compose with its base styles instead of being dropped. Default rendering is unchanged. - add size prop (sm / md) to Switch to match CheckboxInput and RadioList boolean control scales (#4230)
- Table:
rowIndexStartandrowCountprops expose row numbering as a table-level ARIA concern, soaria-rowindex/aria-rowcountreflect a row's position in the full dataset: correct across pagination and even when no visible index column is rendered. Opt-in; tables that set neither prop are unchanged. Closes #3939. - Timestamp: new
tooltipEntriesprop renders the hover tooltip across several time zones and/or formats at once — one line per entry, each with an optionaltimezoneID(IANA id; omit it or pass'local'for the viewer's zone),format(every non-relativeTimestampFormatplus'full'), andlabel. The default is unchanged: with no entries the tooltip stays the single full absolute line in the viewer's zone. Configuring entries also attaches the tooltip to absolute formats, which previously had none — note that this gives those timestamps a tab stop and focus ring, as relative timestamps already have, so a column of them gains one tab stop per row.hasTooltip={false}still suppresses the tooltip, and an empty array counts as no configuration. Also correctsisTimezoneShown's documentation, which claimed it applied to thesystem_date_timeandsystem_timeformats; it never has, and those formats stay machine-readable. (#4188) - Token: make the
colorprop extensible via module augmentation.TokenColoris now derived from aTokenColorMapinterface, so theme packages can add custom colors (andastryx theme buildgenerates the type augmentation), matching Badge and Button. - TreeList: the per-level indentation step is now the themeable
--tree-list-indentvariable (defaultvar(--spacing-4)), so a theme can retune the indent metric viadefineThemeon thetree-listtarget instead of the previously hardcoded, unreachable step (#4308). - TreeList: add a
variantprop ('lineGuides' | 'noGuides', default'lineGuides') to select the base hierarchy guide-line look.noGuideshides the connector lines while keeping indentation intact. Orthogonal todensity(spacing); the guides stay themeable via theastryx-tree-list-guidetarget. Non-breaking — omitting the prop renders exactly as before.
- Avatar: compose the status dot's label into the avatar's accessible name so assistive tech can reach the status the
role="img"root previously pruned (WCAG 4.1.2) - Calendar: expose selected state in day-button accessible names, announce range-selection progress and completion via the polite live region, and set aria-multiselectable on the grid in range mode
- CommandPalette: announce result counts, empty, and loading states to screen readers via the shared polite live region (WCAG 4.1.3)
- Divider: expose the label as the separator's accessible name via aria-labelledby; Spinner: name the status element from the visible label instead of duplicating it as aria-label
- FileInput: announce the required state via a visually hidden description on the trigger (aria-required is unsupported on role="button") and announce validation errors exactly once
- hooks: resolve focus-trap Escape by DOM depth instead of push order, exclude aria-hidden subtrees from trap tab cycles, and auto-clear live regions after announcing so stale status text does not linger
- List: keep list semantics for all listStyle variants by always emitting an explicit role="list", since the base style strips list-style-type for every variant and Safari/VoiceOver drops implicit list roles for such lists (WCAG 1.3.1)
- NumberInput: announce the units text through the input's accessible description, and stop TextInput/NumberInput from referencing the non-rendered status message id in aria-describedby inside InputGroup
- reset: stop suppressing
:focus-visibleoutlines on coarse-pointer devices so keyboard users keep the WCAG 2.4.7 focus indicator - hooks: auto-detect RTL direction for arrow-key navigation in useListFocus and useGridFocus (WCAG 1.3.2)
- Slider: constrain range thumb aria-valuemin/aria-valuemax by the sibling thumb (including minStepsBetweenThumbs) and render the label as a group label wired via aria-labelledby instead of an inert
- TopNav: disabled TopNavItems now render href-less anchors so they no longer navigate or fire clicks, and Outline's active item uses aria-current="location"
- Avatar: avoid remounting the avatar subtree when the name tooltip toggles — render the tooltip as a conditional sibling instead of forking the return so the avatar keeps its position in the React tree (and its image-load state) across tooltip changes.
- Card: rest the bordered variant on the subtle
--color-borderinstead of--color-border-emphasized, so a Card's outer frame matches its own LayoutHeader/LayoutFooter dividers and neighboring ClickableCards instead of rendering a heavier edge. - CheckboxInput, RadioList, Switch: align control sizes. The visible checkbox and radio controls now fill their size exactly (20px at
sm, 24px atmd) instead of being inset 2px. ThesmSwitch track is now 32px wide with a 2px inset. - Export the
BasePropstype through the@astryxdesign/core/BasePropssubpath. Previously it was only reachable through the package barrel, so theimport type {BaseProps} from '@astryxdesign/core/BaseProps'specifier thatastryx swizzlegenerates failed to resolve (#4091). - Guard DropdownMenu item hover styles with
@media (hover: hover)to prevent sticky highlights on touch devices. Forward BaseProps pass-throughs to the menu element. - FieldStatus renders a leading status icon on the
detachedmessage so status is not conveyed by color/position alone (WCAG 1.4.1). The icon is decorative for assistive tech; the message text and live-region announcement carry the status. Theattachedvariant is unchanged. - FileInput no longer nests interactive controls (the clear and status buttons) inside a role="button" trigger. The trigger is now a visually hidden button alongside them in a non-interactive container, resolving the nested-interactive a11y violation (WCAG 4.1.2) while keeping click, keyboard, and drag-and-drop behavior. (#4522)
- Inputs no longer show the hover ring while disabled. The shared input wrapper's disabled state now suppresses both the base and status hover shadows, so TextInput, TextArea, NumberInput, DateInput, TimeInput, Selector, MultiSelector, Typeahead, and Tokenizer stay visually inert on hover when disabled.
- HoverCard: move themeProps className to the layer container (where bg/radius/shadow live) so themes can target the visual surface. Forward consumer xstyle/className/style to that same layer container so surface customization lands next to the theme class, instead of silently dropping them.
- With
statusVariant="detached", bordered inputs no longer render a status icon inside the control (this also covers DateTimeInput, which is fixed to the detached presentation) — the detached message box already carries a leading icon, so the on-field glyph was a duplicate. Also centers the detached message's icon on the first line of text. - DropdownMenu/ContextMenu: mouse hover now moves the highlight instead of adding a second one, so keyboard focus and pointer hover share a single highlighted item (#4493)
- utils: clamp plainDateAddMonths to the target month's last day Adding a month to Jan 31 landed on Mar 3 (Date#setMonth overflow) instead of Feb 28, so month arithmetic from end-of-month dates skipped February entirely. The helper now uses pure month arithmetic and clamps the day, matching Temporal.PlainDate.add and date-fns.
- Calendar RTL: month-navigation chevrons now mirror correctly under RTL (via the shared
rtlStyles.mirrortransform on the nav-icon wrapper), and the range-selection / hover-preview fill pills use logical CSS (insetInline*,border*Start/EndRadius) so their rounded start/end caps follow the reading direction instead of the physical left/right. LTR rendering is unchanged. - Carousel now supports RTL: the directional scroll-button chevrons mirror under RTL, the scroll buttons respect RTL scroll semantics (previously the button was a no-op under RTL), and the button pills sit on the correct edges.
- RTL: migrate physical
left/rightCSS properties to their logical equivalents so components mirror correctly underdir="rtl". This is the Phase 2 mechanical, one-to-one follow-up to the RTL direction API — a no-op in the default LTR direction with no visual change. - RTL Phase 4 (behavioral): mirror directional behavior that logical-CSS and icon name-swaps alone couldn't fix. SideNavCollapseButton and TreeListItem now compose
rtlStyles.mirroron the icon wrapper outside the state rotation, so the chevrons point toward the correct edge in every collapsed/expanded × LTR/RTL combination. TreeList connector/guide lines position via logicalinset-inline-start/inset-inline-endso they mirror to the inline-start (right) edge under RTL alongside the chevron and row indent. Slider positions its thumb, fill, and marks via logicalinset-inline-startand flips the physical centering transform under RTL, and its pointer/click math measures the value fraction from the inline-start (right) edge under RTL — so a click at 25% of the track maps to 75 instead of 25. - RTL Phase 4b behavioral fixes: ChatMessageBubble grouped-bubble tail corners now use logical border radii so the tail follows reading direction (mirrors under RTL, text unaffected); Table sticky-column shadows make their
translateXand gradient direction-aware so the shadow fades from the pinned edge toward scrolled content in both LTR and RTL instead of rendering inside-out, and gate shadow visibility onMath.abs(scrollLeft)so the start/end shadows still appear under RTL (where spec-compliant browsers report a negativescrollLeft); ResizeHandle's hit-area bias is now direction-aware (mirrors about center under RTL) and the pointer-drag delta reads the handle's computed direction so dragging resizes intuitively in RTL. - Markdown honors the
components.imageoverride for standalone (block) images, matching the inline image path. A standaloneline parses as a block image, whose render path previously hardcoded a bare<img>and ignored a suppliedcomponents.image; it now uses the override just like an inline image does. - Selector & MultiSelector: keep group headers visible while searching; hide groups with no matching items. Previously, typing a query flattened grouped options into a single ungrouped list; now each group header stays above its matching items and a group is hidden only when none of its items match.
- SideNav: remove the top border above the footer region so the
footerslot no longer renders a divider line. - Slider: round snapped values to the min/step decimal precision With fractional steps,
min + steps * stepaccumulated binary floating-point error, so a keyboard nudge on astep={0.1}slider emitted0.30000000000000004throughonChange/onChangeEnd(and intoaria-valuenow/the value tooltip once the consumer echoed it back). Snapped values are now rounded to the combined decimal precision ofminandstep, which removes only the error — exact steps are unaffected. - Tooltip: dismiss the tooltip when its trigger is pressed. Previously the tooltip stayed open through a click (e.g. a "Copy link" button's tooltip lingered after activation); now pressing the trigger hides its own tooltip. Applies to uncontrolled tooltips only.
- Typeahead: omit aria-activedescendant when search results are empty or index is out of bounds (#4059)
- document
widthprop across 17 input component doc files (#4163)
- Add
@astryx/no-physical-propertiesESLint rule that flags physical left/right CSS properties insidestylex.create()and suggests the CSS logical equivalent for RTL support. - KEY-BASED:
marginLeft/marginRight,paddingLeft/paddingRight,borderLeft/borderRight(+ theirWidth/Style/Colorlonghands),left/right→insetInlineStart/insetInlineEnd, and the four physical corner radii → their diagonal-aware logical names (borderTopLeftRadius→borderStartStartRadius, etc.). - VALUE-BASED:
textAlign: 'left'|'right',float: 'left'|'right', andclear: 'left'|'right'(the key stays, only the physical value is flagged). - Scoped strictly to
stylex.create()— physical identifiers used elsewhere are ignored. useDirection()returns'ltr' | 'rtl'for the current provider context (falls back to'ltr'when called outside a provider).getLocaleDirection(locale)computes direction from a BCP 47 locale viaIntl.Locale.getTextInfo()— safe to call from React Server Components and Next.js layouts to set<html dir>.<InternationalizationProvider locale="ar">auto-derivesdir="rtl". Pass an explicitdirprop to override (useful for RTL testing under an English catalog, or to force LTR).- Pagination is the first component to consume the hook: prev/next chevron icons flip under RTL while the aria-labels stay semantic.
- Storybook gains a global
Directiontoolbar for toggling every story between LTR and RTL. - Component-level CSS migrations (borders, chevrons, sliders, calendar range pills, etc.) land in follow-up PRs.
textAlign: 'left' | 'right'→'start' | 'end'(Selector, Typeahead, Chat trigger menu, DropdownMenu, CommandPalette, NavMenu items).borderLeft*/borderRight*→borderInlineStart*/borderInlineEnd*, kept as separate start/end declarations (Banner, Table cell/header dividers, DateRangeInput preset sidebar).- Static
left/rightpositioning →insetInlineStart/insetInlineEndfor full-bleed overlays and single-side offsets (Button spinner overlay, Chat dock/blur/placeholder, Field sr-only label, Lightbox close/nav/counter buttons, TabList indicators, Thumbnail remove slot, CodeBlock copy button). - Inline
marginLeftindentation →marginInlineStart(TreeList rows).
- cli/json: remove the central
CLIAnyResponse,CLIResponseType, andCLIResponseDataMaptypes.jsonOutis now a structural serializer andparseResponse/assertResponsereturn the structuralCLIResponse({type, data, meta?}) instead of the discriminated union, soresult.dataisunknownuntil you narrow it yourself. Runtime output is unchanged (every--jsonenvelope is byte-identical). This only affects consumers importing those types or relying onparseResponse/assertResponseto auto-narrow.data. - component/hook
--jsonlist responses collapsed.--detail compact/fullpreviously emitted distinctcomponent.brief/component.full(andhook.*) envelopes; they now all emitcomponent.list(resp.hook.list) with adata.detail: 'names' | 'compact' | 'full'field. Migrate: switch ondata.detail, not the.brief/.fulldiscriminator. Removed types: ComponentBriefResponse, ComponentFullResponse, HookBriefResponse, HookFullResponse.
- CLI:
blogis now a normal, agent-facing command — it appears in--helpand the capability manifest and supports--json(emittingblog.list/blog.detailenvelopes), instead of being hidden. Human output is unchanged; the reader still consumes the public RSS feed. Also scriptable through the./apibarrel asblog(slug?). - CLI:
initis now fully scriptable through the./apibarrel — the non-interactive installer (agent-docs cheat sheet, starter template,--remove-agents) lives inapi/initand returns a typed receipt (init.run|init.remove), with the CLI reduced to a thin parse → API call → render wrapper. Human output is emitted through an injectable logger, so a scriptedinit()stays silent while the CLI output is byte-identical for existing usage. - CLI:
theme buildis now fully scriptable through the./apibarrel — the ~1,000-line theme compiler (defineTheme extraction, CSS generation via@astryxdesign/core/theme, variant/type-declaration + icon-module generation, override validation) lives inapi/theme/buildand returns a typedtheme.buildreceipt, with the CLI reduced to a thin parse → API call → render wrapper. Human progress is emitted through an injectable logger, so a scriptedthemeBuild()stays silent while the generated CSS/JS/.d.ts, the--jsonenvelope, and human output stay byte-identical for existing usage. Watch mode remains a thin CLI loop. - CLI:
upgradeis now fully scriptable through the./apibarrel — the version-to-version pipeline (codemods + agent-docs refresh) lives inapi/upgradeand returns a typed receipt (upgrade.list|upgrade.status|upgrade.run), with the CLI reduced to a thin parse → API call → render wrapper. Human progress is emitted through an injectable logger, so a scriptedupgrade()stays silent while the CLI output and--jsonenvelopes are unchanged for existing usage. - Timestamp: new
tooltipEntriesprop renders the hover tooltip across several time zones and/or formats at once — one line per entry, each with an optionaltimezoneID(IANA id; omit it or pass'local'for the viewer's zone),format(every non-relativeTimestampFormatplus'full'), andlabel. The default is unchanged: with no entries the tooltip stays the single full absolute line in the viewer's zone. Configuring entries also attaches the tooltip to absolute formats, which previously had none — note that this gives those timestamps a tab stop and focus ring, as relative timestamps already have, so a column of them gains one tab stop per row.hasTooltip={false}still suppresses the tooltip, and an empty array counts as no configuration. Also correctsisTimezoneShown's documentation, which claimed it applied to thesystem_date_timeandsystem_timeformats; it never has, and those formats stay machine-readable. (#4188)
astryx theme build: component-override keys for multi-word components (TextInput, DateInput, NumberInput, DropdownMenu, SideNav, TopNav, etc.) now match the hyphenated class the component actually renders. The known-component registry used de-hyphenated keys, so overrides authored against them emitted dead selectors (.astryx-textinputinstead of.astryx-text-input) that silently never applied (#4109).
- CLI: blog reorganized into api/blog leaf shape — list/detail leaves projecting a shared RSS adapter (
_adapter.mjsowns all network fetch + feed parsing), withblog.mjskept as a dispatcher+barrel so the sameblogexport, the CLI wrapper, api/index.mjs, and the --json/human output stay byte-identical. - CLI:
buildreorganized into theapi/buildleaf shape —build.mjsis now a dispatcher + barrel that routes no-query →build.help(api/build/help/help.mjs) and a query →build.kit(api/build/kit/kit.mjs), with each leaf projecting its single{type, data}envelope. Pure reorganization: thebuildexport, the./apibarrel, and the CLI consumer are unchanged, and the--jsonand human output stay byte-identical for existing usage. - CLI:
componentreorganized into theapi/componentleaf shape over a shared_adapterresolver —component.mjsis now a dispatcher + barrel that routes to per-type leaves (list,detail,detail/props,detail/source,detail/showcase,detail/blocks), each a thin projection of a subject the adapter resolves once (core/external/scoped/integration ownership, ambiguity handling, and fuzzy search, deduped). Pure reorg: every--jsonenvelope and human output stays byte-identical across all modes. - CLI: discover reorganized into api/discover leaf shape (list, detail, detail/doc, search) behind a shared _adapter that owns external-package discovery and doc loading; discover.mjs is now a dispatcher+barrel keeping the same exports. Pure reorg —
--jsonand human output are byte-identical and api/index.mjs + the CLI consumer are untouched. Adds colocated leaf tests. - CLI: docs reorganized into api/docs leaf shape —
docs()inapi/docs/docs.mjsis now a dispatcher + barrel that routes by argument shape into three leaves (api/docs/list,api/docs/detail,api/docs/detail/section), each projecting into a single{ type, data }envelope. The discovery, overlay loading, and topic resolution shared by ≥2 leaves live inapi/docs/_adapter.mjs. Pure reorganization: thedocsexport,api/index.mjs, the CLI consumer, and all--jsonand human output are unchanged (byte-identical). - CLI: hook reorganized into api/hook leaf shape —
hook.mjsis now a dispatcher+barrel routing to colocated leaves (list/list.mjs→ hook.list,detail/detail.mjs→ hook.detail,detail/params/params.mjs→ hook.detail.params) over a shared_adapter.mjsresolver. Pure reorg:--jsonand human output are byte-identical across all modes, and thehookexport surface (api/index.mjs + CLI) is unchanged. - CLI: init reorganized into api/init leaf shape —
init.mjsis now a dispatcher + barrel that routes toapi/init/run/run.mjs(the default /--features/--allinstall path) andapi/init/remove/remove.mjs(the--remove-agentspath), with the shared plain-logger contract inapi/init/_adapter.mjs. Pure reorg:getNextSteps,noopInitLogger, and theInitOptions/InitLoggertypes stay re-exported from the barrel, so api/index.mjs, the CLI command, and the programmatic API are unchanged. Human and--jsonoutput are byte-identical. - CLI: layout reorganized into the api/layout leaf shape — a shared
_adapter.mjs(analyze/loadBlocks/formatIssueoverlib/xle) with thinexpand/,check/, andgrammar/leaves, plus alayout.mjsbarrel.api/index.mjsand the CLI are unchanged (they import via the barrel). Pure reorg:layout expand/check/grammar--jsonenvelopes and human output are byte-identical. - CLI: swizzle reorganized into api/swizzle leaf shape — the flat command splits into
api/swizzle/list(swizzle.list) andapi/swizzle/copy(swizzle.copyreceipt, incl.rewriteImports), with shared @astryxdesign/core discovery + component listing deduped inapi/swizzle/_adapter.mjs, andswizzle.mjsreduced to a dispatcher + barrel that keeps its existing exports (swizzle,rewriteImports). Pure reorganization with no behavior change: human output and every--jsonenvelope stay byte-identical, and the CLI command, the./apibarrel, and the centraltypes/swizzledeclarations are untouched. - CLI: template reorganized into api/template leaf shape (shared helpers preserved on the barrel). Pure reorg —
--jsonand human output stay byte-identical: shared discovery/IO moved toapi/template/_adapter.mjs, the command modes split intolist/show/skeleton/copyleaves, andtemplate.mjsbecomes a dispatcher + barrel that re-exports every previously-exported symbol (template, discoverTemplates, discoverAll, discoverAllWithErrors, discoverIntegrationTemplatesForOne, findShowcase, findRelatedBlocks, stripTemplateAssetRefs, listTemplates, extractComponents, and the DiscoveredTemplate/TemplateDiscoveryError types) so component/layout/search/init/discover/validate-integration and lib/project keep resolvingapi/template/template.mjsunchanged. - CLI:
theme add/listare reorganized into the fractalapi/theme/leaf shape — a shared_adapter.mjs(bundled-theme manifest reader + slug resolver) with thinadd/(copy →theme.addreceipt) andlist/(theme.list) leaves over it, plus atheme.mjsbarrel, mirroring thetheme buildextraction (#4462).themeList()is now exported from@astryxdesign/cli/apialongsidethemeAdd. Pure reorg:theme list/add--jsonenvelopes and human output are byte-identical, with new direct-API tests for both leaves. - CLI: upgrade reorganized into api/upgrade leaf shape — the flat pipeline is split into a dispatcher+barrel (
upgrade.mjs), a shared_adapter.mjs(version detection + agent-docs refresh + codemod selection/execution machinery), andlist/status/runleaves (upgrade.list|upgrade.status|upgrade.run). Pure reorg: the./apibarrel + CLI consumer are unchanged, and both the human output and--jsonenvelopes are byte-identical.
- Neutral theme: express the light
--color-borderas#00000014(translucent black) instead of the opaque#ebebeb. Same rendered color over a white surface, but it now blends over any background — matching the translucent dark-mode value.
Thanks to everyone who contributed to this release:
- @AKnassa
- @arham766
- @bhamodi
- @cixzhang
- @ernestt
- @freddymeta
- @HelloOjasMutreja
- @humbertovirtudes
- @josephfarina
- @kentonquatman
- @lexs
- @nynexman4464
Full Changelog: https://github.com/facebook/astryx/compare/v0.1.9...v0.2.0
mobx-react@10.0.0
-
1926c69f53168619d688f348aa587e8f3ae579ae#4671 Thanks @kubk! - Release MobX 7, mobx-react-lite 5, and mobx-react 10.Bundle sizes are down: ESM prod 17.02 KiB gzip -> 13.96 KiB gzip; a minimal tree-shaken example is 10.32 KiB gzip now.
It removes long-deprecated compatibility paths and keeps the React bindings split between
mobx-react-litefor function components andmobx-reactfor class-component support.MobX 7 is a cleanup release focused on the modern runtime and decorator model.
- MobX now always uses Proxy-backed observable objects and arrays. The ES5/non-proxy fallback has been removed.
configure({ useProxies: ... })is no longer supported.{ proxy: false }options forobservable,observable.object, andobservable.arrayare no longer supported.- Legacy decorators are no longer supported.
- Namespaced annotation and comparer properties now use named exports to reduce bundle size:
Removed API Replacement observable.refobservableRefobservable.shallowobservableShallowobservable.deepobservableDeepobservable.structobservableStructcomputed.structcomputedStructaction.boundactionBoundflow.boundflowBoundcomparer.identitycompareIdentitycomparer.defaultcompareDefaultcomparer.structuralcompareStructuralcomparer.shallowcompareShallow- The public
traceAPI and its related runtime support have been removed. UsetoJS,getDependencyTree,getObserverTree,spyormobx-logpackage for debugging.
mobx-react-lite 5 and mobx-react 10 require MobX 7 and React 18 or later.
mobx-react-literemains the function-component package.mobx-reactremains a thin wrapper aroundmobx-react-litethat adds class component and Stage 3@observerclass decorator support.- Keep function-component imports on
mobx-react-liteif you do not need class component support. - Use
mobx-reactwhen you need class components or@observerclass decorators. mobx-react-litesupports function components andforwardRef;mobx-reactdelegates function components tomobx-react-liteand handles classes itself.- Remove React batching imports, including the stale React Native batching deep import. React 18+ renderers handle batching.
The recommended public React binding surface for both packages is:
observerObserveruseLocalObservableenableStaticRenderingisUsingStaticRendering
The following APIs have been removed from the React binding packages:
Provider,inject, andMobXProviderContext; useReact.createContextdirectly.disposeOnUnmount; dispose reactions incomponentWillUnmountor return cleanup functions fromuseEffect.PropTypes; use TypeScript or the regularprop-typespackage.useObserver; wrap components withobserveror use<Observer>.useLocalStore; useuseLocalObservable.useAsObservableSource; synchronize values from props into local observable state explicitly.useStaticRendering; useenableStaticRendering.observerBatching,isObserverBatched,batchingForReactDom,batchingOptOut, andbatchingForReactNative; remove these imports because React 18+ renderers handle batching.- Deprecated
observer(fn, { forwardRef: true }); pass an already-createdReact.forwardRef(...)component toobserverinstead. - Legacy function-component
contextTypeshandling.
- Updated dependencies [
1926c69f53168619d688f348aa587e8f3ae579ae]:- mobx-react-lite@5.0.0
mobx-react-lite@5.0.0
-
1926c69f53168619d688f348aa587e8f3ae579ae#4671 Thanks @kubk! - Release MobX 7, mobx-react-lite 5, and mobx-react 10.Bundle sizes are down: ESM prod 17.02 KiB gzip -> 13.96 KiB gzip; a minimal tree-shaken example is 10.32 KiB gzip now.
It removes long-deprecated compatibility paths and keeps the React bindings split between
mobx-react-litefor function components andmobx-reactfor class-component support.MobX 7 is a cleanup release focused on the modern runtime and decorator model.
- MobX now always uses Proxy-backed observable objects and arrays. The ES5/non-proxy fallback has been removed.
configure({ useProxies: ... })is no longer supported.{ proxy: false }options forobservable,observable.object, andobservable.arrayare no longer supported.- Legacy decorators are no longer supported.
- Namespaced annotation and comparer properties now use named exports to reduce bundle size:
Removed API Replacement observable.refobservableRefobservable.shallowobservableShallowobservable.deepobservableDeepobservable.structobservableStructcomputed.structcomputedStructaction.boundactionBoundflow.boundflowBoundcomparer.identitycompareIdentitycomparer.defaultcompareDefaultcomparer.structuralcompareStructuralcomparer.shallowcompareShallow- The public
traceAPI and its related runtime support have been removed. UsetoJS,getDependencyTree,getObserverTree,spyormobx-logpackage for debugging.
mobx-react-lite 5 and mobx-react 10 require MobX 7 and React 18 or later.
mobx-react-literemains the function-component package.mobx-reactremains a thin wrapper aroundmobx-react-litethat adds class component and Stage 3@observerclass decorator support.- Keep function-component imports on
mobx-react-liteif you do not need class component support. - Use
mobx-reactwhen you need class components or@observerclass decorators. mobx-react-litesupports function components andforwardRef;mobx-reactdelegates function components tomobx-react-liteand handles classes itself.- Remove React batching imports, including the stale React Native batching deep import. React 18+ renderers handle batching.
The recommended public React binding surface for both packages is:
observerObserveruseLocalObservableenableStaticRenderingisUsingStaticRendering
The following APIs have been removed from the React binding packages:
Provider,inject, andMobXProviderContext; useReact.createContextdirectly.disposeOnUnmount; dispose reactions incomponentWillUnmountor return cleanup functions fromuseEffect.PropTypes; use TypeScript or the regularprop-typespackage.useObserver; wrap components withobserveror use<Observer>.useLocalStore; useuseLocalObservable.useAsObservableSource; synchronize values from props into local observable state explicitly.useStaticRendering; useenableStaticRendering.observerBatching,isObserverBatched,batchingForReactDom,batchingOptOut, andbatchingForReactNative; remove these imports because React 18+ renderers handle batching.- Deprecated
observer(fn, { forwardRef: true }); pass an already-createdReact.forwardRef(...)component toobserverinstead. - Legacy function-component
contextTypeshandling.
mobx@7.0.0
-
1926c69f53168619d688f348aa587e8f3ae579ae#4671 Thanks @kubk! - Release MobX 7, mobx-react-lite 5, and mobx-react 10.Bundle sizes are down: ESM prod 17.02 KiB gzip -> 13.96 KiB gzip; a minimal tree-shaken example is 10.32 KiB gzip now.
It removes long-deprecated compatibility paths and keeps the React bindings split between
mobx-react-litefor function components andmobx-reactfor class-component support.MobX 7 is a cleanup release focused on the modern runtime and decorator model.
- MobX now always uses Proxy-backed observable objects and arrays. The ES5/non-proxy fallback has been removed.
configure({ useProxies: ... })is no longer supported.{ proxy: false }options forobservable,observable.object, andobservable.arrayare no longer supported.- Legacy decorators are no longer supported.
- Namespaced annotation and comparer properties now use named exports to reduce bundle size:
Removed API Replacement observable.refobservableRefobservable.shallowobservableShallowobservable.deepobservableDeepobservable.structobservableStructcomputed.structcomputedStructaction.boundactionBoundflow.boundflowBoundcomparer.identitycompareIdentitycomparer.defaultcompareDefaultcomparer.structuralcompareStructuralcomparer.shallowcompareShallow- The public
traceAPI and its related runtime support have been removed. UsetoJS,getDependencyTree,getObserverTree,spyormobx-logpackage for debugging.
mobx-react-lite 5 and mobx-react 10 require MobX 7 and React 18 or later.
mobx-react-literemains the function-component package.mobx-reactremains a thin wrapper aroundmobx-react-litethat adds class component and Stage 3@observerclass decorator support.- Keep function-component imports on
mobx-react-liteif you do not need class component support. - Use
mobx-reactwhen you need class components or@observerclass decorators. mobx-react-litesupports function components andforwardRef;mobx-reactdelegates function components tomobx-react-liteand handles classes itself.- Remove React batching imports, including the stale React Native batching deep import. React 18+ renderers handle batching.
The recommended public React binding surface for both packages is:
observerObserveruseLocalObservableenableStaticRenderingisUsingStaticRendering
The following APIs have been removed from the React binding packages:
Provider,inject, andMobXProviderContext; useReact.createContextdirectly.disposeOnUnmount; dispose reactions incomponentWillUnmountor return cleanup functions fromuseEffect.PropTypes; use TypeScript or the regularprop-typespackage.useObserver; wrap components withobserveror use<Observer>.useLocalStore; useuseLocalObservable.useAsObservableSource; synchronize values from props into local observable state explicitly.useStaticRendering; useenableStaticRendering.observerBatching,isObserverBatched,batchingForReactDom,batchingOptOut, andbatchingForReactNative; remove these imports because React 18+ renderers handle batching.- Deprecated
observer(fn, { forwardRef: true }); pass an already-createdReact.forwardRef(...)component toobserverinstead. - Legacy function-component
contextTypeshandling.
979d267d569734dc3cb969ed1880ed68bb79f1b5#4677 Thanks @kubk! - Shorten minified error URL to reduce production bundle size.
v11.0.0
v11 delivers a ground-up observer lifecycle rewrite, making observation and cleanup more resilient across React 17, 18, and 19. Shared callback-ref handling, idempotent cleanup, and improved threshold behavior make hooks more predictable in real-world mounting and unmounting scenarios.
It also introduces a new Blume-powered documentation site with clearer guides and examples. Storybook and the README have been refreshed to make getting started easier.
Smaller improvements include private vulnerability reporting, stronger PR quality checks with Fallow, dependency updates, and expanded observer lifecycle tests.
- docs: use private vulnerability reporting by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/759
- Fix callback ref cleanup compatibility across React 17–19 by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/760
- fix: make observe cleanup idempotent by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/763
- fix: respect threshold before trigger once cleanup by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/762
- test: characterize hook observer lifecycle by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/764
- refactor: share callback-ref observation between hooks by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/765
- build(deps-dev): bump postcss from 8.5.6 to 8.5.10 by @dependabot[bot] in https://github.com/thebuilder/react-intersection-observer/pull/761
- Adopt Fallow as a PR quality gate by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/768
- feat: add Blume documentation site by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/770
- Update dependencies by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/771
- docs: enable vercel analytics by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/772
- Simplify and brand Storybook introduction by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/773
- Update README to simplify bundle size information by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/774
- Use responsive logo lockups in docs header by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/775
Full Changelog: https://github.com/thebuilder/react-intersection-observer/compare/v10.1.0...v11.0.0
create-vite@9.1.2
Please refer to CHANGELOG.md for details.
v8.2.0
Please refer to CHANGELOG.md for details.
v6.1.1
- @wangeditor-next/basic-modules@6.1.1
- @wangeditor-next/code-highlight@6.1.1
- @wangeditor-next/core@6.1.1
- @wangeditor-next/list-module@6.1.1
- @wangeditor-next/table-module@6.1.1
- @wangeditor-next/upload-image-module@6.1.1
- @wangeditor-next/video-module@6.1.1
Package versions
| Package | Version | Source |
|---|---|---|
@wangeditor-next/basic-modules |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/code-highlight |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/core |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/editor |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/editor-for-react |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/editor-for-vue |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/editor-for-vue2 |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/list-module |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/plugin-attachment |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/plugin-ctrl-enter |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/plugin-float-image |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/plugin-formula |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/plugin-link-card |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/plugin-markdown |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/plugin-mention |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/table-module |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/upload-image-module |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/video-module |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/yjs |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/yjs-for-react |
6.1.1 |
Source (tar.gz) |
@wangeditor-next/yjs-for-vue |
6.1.1 |
Source (tar.gz) |