Skip to content

Changelog

1.5.0

Minor changes

  • Canonical layouts (M7, COMPONENT_SPEC §16a; Compose ListDetailPaneScaffold, SupportingPaneScaffold, ThreePaneScaffold and their navigators, plus the m3.material.io feed): list-detail and supporting-pane layouts that show one pane below 840px of their own width, two from 840px and three (with an extra pane) from 1600px — m3.material.io's Breakpoints; pane-rule="compose" / paneRule="compose" follows Compose's calculatePaneScaffoldDirective, three panes from 1200px — sized by a container query on .m3e-layout, so they adapt inside a navigation suite's content area. Navigation between panes follows Compose's navigator (navigateTo, navigateBack with the four back behaviors, history awareness), moves panes on Compose's pane motion (spring 0.8 / 380, the default enter / exit transitions, interruptible) and moves focus to the new destination and back. A pane expansion drag handle (drag-handle / hasDragHandle) splits two panes and settles on anchors. New components/pane-scaffold-defaults.css tokens (partition spacer, default pane sizes, pane motion spring, feed margins / gap / column width), m3e-css layout.css (.m3e-layout, .m3e-pane-scaffold with --list-detail, --supporting-pane, --compose, __pane--primary|secondary|tertiary, __drag-handle; .m3e-feed with __item--wide) and vertical-drag-handle.css (.m3e-vertical-drag-handle), m3e-motion three-pane-scaffold ports (calculateThreePaneScaffoldValue, ThreePaneScaffoldNavigator, threePaneScaffoldDirective, threePaneScaffoldLayout, calculatePaneMotion, paneTransitions, ThreePaneScaffoldAnimation, pane expansion anchors, ListDetailPaneScaffoldRole, SupportingPaneScaffoldRole), m3e-elements <m3e-list-detail-layout>, <m3e-supporting-pane-layout> and the pane-scaffold-layout.js (PaneScaffoldLayout), pane-motion.js and pane-expansion.js entries, and m3e-react <ListDetailPaneScaffold>, <SupportingPaneScaffold>, <FeedLayout>, useListDetailPaneScaffoldNavigator, useSupportingPaneScaffoldNavigator.

    m3e-cssm3e-elementsm3e-motionm3e-reactm3e-tokensm3exp-web 1e86a0b

  • Navigation drawer (M7, COMPONENT_SPEC §15; Compose PermanentNavigationDrawer, DismissibleNavigationDrawer, ModalNavigationDrawer, their drawer sheets and NavigationDrawerItem): permanent, dismissible and modal drawers. Opening runs on the default spatial spring and closing on the fast effects spring (Compose's DrawerState), interruptible with the velocity kept; a drag on the open sheet (or the modal scrim) follows the pointer and settles with Compose's thresholds (50% of the width, 400dp/s) on its decay or 256ms tween; the modal drawer opens over the 32% scrim as a dialog (focus trap, Escape and scrim dismissal, focus return); arrow keys move between items. New components/navigation-drawer-defaults.css tokens (item and sheet literals, the inherited body-large label style, the scrim, springs, settle tween and thresholds Compose renders, plus the m3.material.io headline row and divider inset / color), m3e-css navigation-drawer.css (.m3e-navigation-drawer with --dismissible, --modal, --open, __sheet, __headline, __divider, __scrim, and .m3e-navigation-drawer-item with __icon, __label, __badge; added to the state-layer / focus-ring lists and the ripple.js triggers), m3e-motion DrawerAnimation, drawerSettlesOpen and exponentialDecayTarget (and an optional initial velocity on SpringAnimatable.animateTo), m3e-elements <m3e-navigation-drawer> plus the navigation-drawer-layout.js (NavigationDrawerLayout) entry and a badge attribute on <m3e-navigation-item>, and m3e-react <NavigationDrawer variant items selectedKey onSelectionChange isOpen onOpenChange header />.

    m3e-cssm3e-elementsm3e-motionm3e-reactm3e-tokensm3exp-web 00f2747

  • Navigation bar and rails (M7, COMPONENT_SPEC §13/§14; Compose ShortNavigationBar, WideNavigationRail, ModalWideNavigationRail): the wide navigation rail now animates between collapsed and expanded on Compose's springs (width, item spacing and icon position on the default spatial spring, label color on the default effects spring), interruptible and laid out once per frame; the new modal wide navigation rail opens over a scrim as a dialog (focus trap, Escape and scrim dismissal, focus return; hideOnCollapse slides it in). New components/navigation-defaults.css tokens (the springs, modal colors / shape and expandedHeaderTopPadding Compose renders), m3e-css .m3e-modal-wide-navigation-rail (the static rail classes are unchanged), m3e-motion WideNavigationRailAnimation, wideNavigationRailWidth and wideNavigationRailItemWidth, m3e-elements <m3e-short-navigation-bar>, <m3e-wide-navigation-rail>, <m3e-modal-wide-navigation-rail> and <m3e-navigation-item> plus the wide-navigation-rail-layout.js (WideNavigationRailLayout) entry, attachRipple's optional trigger, and m3e-react <ModalWideNavigationRail> (<WideNavigationRail isExpanded> now animates). Fidelity: the wide rail's selection indicator grows from the pill's start, as Compose's AnimatedNavigationItem places it; its labels stay on one line (ellipsized).

    m3e-cssm3e-elementsm3e-motionm3e-reactm3e-tokensm3exp-web a984af0

  • Navigation suite scaffold (M7, COMPONENT_SPEC §16; Compose NavigationSuiteScaffold, NavigationSuiteScaffoldLayout, NavigationSuite, NavigationSuiteScaffoldState): one set of destinations shown as the navigation the window size class calls for — a short navigation bar below 600px (horizontal items at compact height), a collapsed wide navigation rail from 600px and, by default, the expanded wide navigation rail from 1200px (m3.material.io guidance; Compose keeps the collapsed rail) — with the content beside or above it. Switching on resize keeps the selection, the item elements (bar ↔ rail share one <nav>, as Compose's movableContentOf keeps its items) and keyboard focus. Override with a fixed type (layout-type / layoutType, incl. navigation-drawer and none), expanded-from / expandedFrom (none / null: Compose's own rule), expanded-type / expandedType (a permanent drawer at large widths) or a function of the window size class. Show / hide animates on Compose's spring(0.9, 700) with its state semantics. New components/navigation-suite-defaults.css tokens (scaffold colors, primary action alignment / padding, the show / hide spring), m3e-css navigation-suite.css (.m3e-navigation-suite with --bar, --rail, --drawer, --none, --navigation-hidden, --primary-action-start / --primary-action-center, --adaptive for a no-JavaScript fallback, __content, __primary-action), m3e-motion NavigationSuiteScaffoldAnimation, navigationSuiteOffset, isNavigationBarType, NAVIGATION_SUITE_TYPES, NAVIGATION_SUITE_EXPANDED_FROM and the expandedFrom / expandedType options of navigationSuiteType (whose type now includes the expanded rail, the drawer and none), m3e-elements <m3e-navigation-suite> plus the navigation-suite-layout.js (NavigationSuiteLayout) entry, and m3e-react <NavigationSuiteScaffold items selectedKey onSelectionChange layoutType navigationSuiteType expandedFrom expandedType isNavigationHidden primaryAction>. React <NavigationDrawer> destinations gain isDisabled (the element already rendered disabled items).

    m3e-cssm3e-elementsm3e-motionm3e-reactm3e-tokensm3exp-web 90935e5

  • Tabs (M7, COMPONENT_SPEC §17; Compose PrimaryTabRow, SecondaryTabRow, PrimaryScrollableTabRow, SecondaryScrollableTabRow, Tab, LeadingIconTab): primary and secondary rows, fixed (equal tabs) or scrollable (52dp edge padding, tabs at least 90dp), with text, icon, icon + text (72dp) or leading-icon tabs. The indicator (primary: the selected tab's content width, at least 24dp, 3dp rounded; secondary: the whole tab) slides on the default spatial spring from its current position and velocity (Compose's TabIndicatorOffsetNode), and a scrollable row scrolls the selected tab to the centre; APG tabs with manual activation (arrow keys, Home / End, no wrapping; Space / Enter select) and role="tabpanel" wiring. New components/tabs-defaults.css tokens (the TabRowDefaults / Tab.kt values Compose renders: tab heights, paddings, edge padding, minimum widths, indicator defaults, divider, springs, label style and baseline placement), m3e-css tabs.css (.m3e-tabs with --primary, --secondary, --scrollable, --leading-icon, __list; .m3e-tab with __content, __icon, __label; .m3e-tab-panel; added to the state-layer / focus-ring lists and the ripple.js triggers), m3e-motion TabIndicatorAnimation, TabScrollAnimation, tabPositions, tabIndicatorTarget, tabIndicatorShift and scrollableTabOffset, m3e-elements <m3e-tabs>, <m3e-tab> and <m3e-tab-panel> plus the tabs-layout.js (TabsLayout) entry and RovingFocus.reset(), and m3e-react <Tabs variant scrollable iconPosition items selectedKey onSelectionChange>, <Tab> and <TabPanel>.

    m3e-cssm3e-elementsm3e-motionm3e-reactm3e-tokensm3exp-web 0fd53c5

  • Window size class utilities (M7, FOUNDATIONS §9; androidx window-core WindowSizeClass and Compose Material3 adaptive): new --m3e-sys-window-{width,height}-* tokens and the windowBreakpoints JS tokens (min-width 600 / 840 / 1200 / 1600, min-height 480 / 900), m3e-motion windowSizeClass, windowWidthSizeClass, windowHeightSizeClass, isWidthAtLeastBreakpoint, isHeightAtLeastBreakpoint, isAtLeastBreakpoint, sameWindowSizeClass, paneScaffoldDirective (Compose calculatePaneScaffoldDirective), navigationSuiteType (NavigationSuiteScaffoldDefaults.navigationSuiteType) and WINDOW_WIDTH_BREAKPOINTS / WINDOW_HEIGHT_BREAKPOINTS, m3e-elements observeWindowSizeClass and currentWindowSizeClass (viewport via matchMedia, or an element's content box via ResizeObserver) in a new window-size-class.js entry that also re-exports the classification, and the m3e-react useWindowSizeClass hook.

    m3e-elementsm3e-motionm3e-reactm3e-tokensm3exp-web 2c741a7

Patch changes

  • Canonical layouts: m3.material.io's pane counts are now the default (owner decision, COMPONENT_SPEC §16a) — two panes at large (1200–1599px), three only from extra-large (1600px), when an extra pane exists. Compose's calculatePaneScaffoldDirective (three panes from 1200px) becomes the opt-in: pane-rule="compose" on <m3e-list-detail-layout> / <m3e-supporting-pane-layout>, paneRule="compose" on <ListDetailPaneScaffold> / <SupportingPaneScaffold>, the .m3e-pane-scaffold--compose modifier for the CSS-only layout (replacing the unreleased --recommended modifier), and threePaneScaffoldDirective(sizeClass, { paneRule: 'compose' }) in m3e-motion, whose default is now 'recommended'.

    m3e-cssm3e-elementsm3e-motionm3e-react 16220b4