Changelog
The @kyralabs packages are released together under one version. Each change below
appears once, with the packages whose changelog lists it. Breaking changes wait for 2.0: see
Migrating to 2.0.
1.8.0
Minor changes
-
Date pickers (COMPONENT_SPEC §27, M10): Compose's
DatePicker(calendar with month paging and the year grid, switchable to the date input),DateRangePicker(a scrolling month list with the range band, switchable to start / end inputs) andDatePickerDialog, plus m3.material.io's docked date picker. m3e-tokens generates the date picker's Compose values, state layers, docked values and motion (date-picker-defaults.css); m3e-css addsdate-picker.css; m3e-motion ports the calendar model,DatePickerState/DateRangePickerState, the input's pattern, parser and validator anddrawRangeBackground(checked against a JVM run of the vendored Kotlin); m3e-elements adds<m3e-date-picker>,<m3e-date-range-picker>,<m3e-docked-date-picker>, their layout entries and the lazily loadeddate-fieldentry; m3e-react addsDatePicker,DateRangePicker,DockedDatePickerandDatePickerDialog. -
Time pickers (COMPONENT_SPEC §28, M10): Compose's dial
TimePicker(baseline and vibrant, vertical and horizontal),TimeInput(baseline, vibrant, uncontained with the side column) and the expressiveTimeScrollwheels, with the updated AM/PM toggle buttons. m3e-tokens generates the vibrant, side column, scroll field, dialog and motion values (time-picker-defaults.css); m3e-css addstime-picker.css(dial, fields, wheels and the.m3e-time-picker-dialogsurface); m3e-motion portsTimePickerState/AnalogTimePickerState,CircularLayout's placement,TimeInputTransformationandScrollField's paging (checked against a JVM run of the vendored Kotlin); m3e-elements adds<m3e-time-picker>,<m3e-time-input>,<m3e-time-scroll>and the sharedtime-picker-layoutentry; m3e-react addsTimePicker,TimeInput,TimeScroll,TimePickerModeToggle,TimePickerDialogandVibrantTimePickerDialog. -
API review fixes (M11, D16: additive; every old name keeps working, is
@deprecatedand goes in 2.0). m3e-elements: the inner inputs' nativeinput/changeno longer reach the host of<m3e-time-input>,<m3e-docked-date-picker>and the date pickers' input mode, nor the input's nativeselectthe host of<m3e-search>, so host listeners see only the element'sCustomEvent; every element with events exports anM3e<Name>EventMapwith typedaddEventListener/removeEventListener(type-only) and its detail types (OpenChangeDetail,ExpandedChangeDetail,ValueDetail, …);<m3e-button-group>firesselection-changeand takesdisallow-empty-selection(change,selection-requireddeprecated),<m3e-list selection-mode>(selectiondeprecated), carousel items fire a bubblingaction(item-clickdeprecated),<m3e-slider variant orientation>(centered,verticaldeprecated),<m3e-side-sheet back-button>(thebackattribute deprecated),<m3e-bottom-sheet open>withopen-change, the time pickers'selection-changedetail gainsvalue;SelectableDates,YearRange,DatePickerDisplayModeandSideSheetVariantOptionare exported; the helpers shared with m3e-react are tagged@internal. m3e-css: two-rows top app bars read the public--m3e-comp-top-app-bar-container-collapsed-height/-expanded-height. m3e-react:FabMenu isOpen,isExpandedonFloatingToolbar,SearchBarandExtendedFab,scrollBehavior="exit-always"on the toolbars,DatePicker/DateRangePicker showHeadline(the old names warn once in development),onDisplayModeChange(next)/onModeToggle(next)on the time pickers, and type exports for the prop types it used without exporting (SliderSize,SheetValue,BadgeValue,RoundedPolygon,IconButtonStyle, …); the D4*Propstypes are@deprecatedandfabClassName({ size: 'small' })warns like<Fab size="small">.
Patch changes
-
Accessibility audit fixes (M11 hardening; no API change). The date pickers' fields, the chip sets' input chips and the lists get ids that are unique across bundles: the element entries and m3e-react (which bundles the same layouts) shared counters starting at 1, so an element and a React docked date picker on one page both made
id="m3e-date-field-1"and the second label focused the first field. The modal date picker's month arrows each get their own 48dp slot, as Compose'sIconButtons inMonthsNavigationdo (they overlapped, leaving "previous month" 40 × 48), and today's day and the current year keep a full 48dp target inside their outline. The baseline filter chip's check slot no longer animates its width underprefers-reduced-motion(--m3e-comp-selectable-chip-icon-shrink-durationis 0ms there; the fade stays). In forced colors an enabled slider's inactive track is a CanvasText outline instead of GrayText, which now means disabled only. A bottom sheet's overflowing, focusable content is arole="group"named like its sheet, in both layers. -
Package READMEs (M11 docs; no code change). m3e-react lists every component and hook, grouped by COMPONENT_SPEC section, with the D4 deprecations and the props renamed in 1.8, and its usage example now imports
material-symbols.css(without it, icons render as their names). m3e-elements documents<m3e-bottom-sheet>(open,value,value-change,open-change) and the top app bar (attachTopAppBarScrolland the public--m3e-comp-top-app-bar-container-{collapsed,expanded}-heightproperties). m3e-css lists every component file with its class, which ones need JavaScript, and its deprecated classes. -
Source register, category (a) (M11): values that the pinned sources already settle, now cited instead of marked
TODO(verify). The navigation drawer divider usesoutline-variant, matching Compose'sDividerTokens.Colorand the m3.material.io token DB, which deprecates the drawer's own divider token for the standalone divider token (SOURCES #33). The docked date picker's year arrows are labelled "Previous year" / "Next year", the wording in m3.material.io Date pickers › Accessibility (SOURCES #89). Citations only, with no value change, for #50, #57, #63, #64, #69, #76 and #77. -
Bundle and d.ts build (M11 hardening; no API or behavior change). m3e-elements emits its declarations with one
tscpass and bundles the.d.tsfiles per entry, so its build no longer needs a 4 GB heap (it fits 512 MB) and every public type path and exported type stays the same. m3e-react bundles the m3e-elements code it uses from source, so m3e-motion and m3e-shapes are imported once instead of also being inlined a second time (m3e-react (all) −1.9 kB, dist 778 → 540 KB). Element classes declarestatic propertiesin a pure form, so bundlers drop element classes a page imports without registering them; module-level constants in m3e-motion (app-bar-scroll,menu-position) and m3e-shapes (TwoPi) no longer leave code behind in every import.
1.7.0
Minor changes
-
Badges (M9, COMPONENT_SPEC §34; Compose
BadgeandBadgedBox): the 6dp dot and the 16dp large badge (label small, 4dp padding, up to four characters) in the error colors, placed on the anchor's top-end corner asBadgedBoxplaces them (the dot 6dp inside it, a large badge 12dp before the end and 2dp above the top; mirrored in RTL), with a CSS hook for thebadgeBounds()rulers that navigation items and tabs will use. m3e-react<Badge count max>writes counts above 999 as999+(m3e-motionbadgeText) and<BadgedBox badge>wraps the anchor. The badge carries visually hidden text that joins the accessible name of its item ("New notification" for the dot, the count otherwise, orlabel); the visible digits arearia-hidden. Newcomponents/badge-defaults.csstokens (theBadge.ktvalues Compose renders) and m3e-cssbadge.css. No custom element: navigation bar, rail, suite and tab badges follow separately. -
Bottom sheets (M9, COMPONENT_SPEC §30): Compose's
ModalBottomSheet(a native modal<dialog>named "Bottom Sheet" over the 0.32 scrim; the page inert and its scroll locked, Tab kept inside, focus on the drag handle and back to the opener; Escape partially expands an expanded sheet, else hides it, as the scrim does) andBottomSheet(the standard sheet, fixed to the bottom of its positioned container, with theBottomSheetScaffoldpeek height as an option). The sheet is surface-container-low with extra-large top corners, at most 640dp wide, centered and flush with the bottom; it opens partially expanded (half the container, or the whole sheet when it is shorter) or, withskipPartiallyExpanded, expanded. Show / expand run on the default spatial spring, hide / partially expand on the fast effects spring (both jump under reduced motion), the scrim on the default effects spring; drags settle with Compose's thresholds (56dp from the anchor behind, 125dp/s, a dampened fling near Hidden) on the default spatial spring started at the release velocity. The drag handle is a 32 × 48dp button with its built-in "Drag handle" tooltip: a click expands a partially expanded sheet and dismisses an expanded one; ArrowUp / ArrowDown expand and collapse it. Newcomponents/bottom-sheet-defaults.csstokens, m3e-cssbottom-sheet.css, m3e-motion's N-anchor anchored-draggable model (DraggableAnchors,computeTarget,AnchoredDraggableAnimation; reference-tested against the androidx anchored-draggable and sheet tests and against the navigation drawer's two-anchor target selection) andSheetState, the m3e-elements<m3e-bottom-sheet>andbottom-sheet-layout(BottomSheetLayout) entries, and m3e-react<BottomSheet>and<ModalBottomSheet>. The navigation drawer's pointer drags now run on the drag helper it shares with the sheets (no change in behavior). -
Carousel (M9, COMPONENT_SPEC §36): the multi-browse, uncontained and center-aligned hero carousels of Compose Material3, the start-aligned hero, and a CSS-only full-screen layout. m3e-motion ports Compose's carousel math (Arrangement, keylines, Strategy, snap positions and the per-item mask and translation), checked against the Compose host tests and a JVM reference; items grow and shrink as they scroll, masked with extra-large corners, and snap natively one at a time to their keylines (the uncontained layout scrolls freely). Every item is a tab stop and the arrow keys move between them (WAI-ARIA carousel and slides); link and button items show the state layer and ripple; reduced motion keeps every item at one size. New
components/carousel-defaults.csstokens, m3e-csscarousel.css, the m3e-elements<m3e-carousel>/<m3e-carousel-item>andcarousel-layout(CarouselLayout) entries, and m3e-react<Carousel>/<CarouselItem>. -
Dialogs (M9, COMPONENT_SPEC §29): the alert dialog (Compose
AlertDialog: an optional centered icon, a headline, supporting text and the dismiss / confirm buttons, end-aligned and stacked with the confirm button on top when they do not fit, in a 280–560dp surface-container-high surface with extra-large corners and no shadow), custom content (ComposeBasicAlertDialog) and the full-screen dialog (m3.material.io; Compose has none: a 56dp header with a close button, the headline and the confirming action, filling the window below 600dp and laid out as a basic dialog from 600dp, the header taking surface-container while the content scrolls). Each is a native<dialog>opened withshowModal(): the page is inert, the page scroll locks, Tab stays inside, focus starts on the first control and returns to the opener; Escape, the 32% scrim and the close button ask to close (cancelable, as Compose'sonDismissRequest). The alert dialog has thealertdialogrole and is named by its headline and described by its text; the others are plain dialogs named by the headline or "Dialog". Motion: the scrim fades on the default effects spring; the dialog slides in and its surface grows as Material Web's dialog does (fades only under reduced motion). Newcomponents/dialog-defaults.csstokens (theAlertDialog.ktvalues Compose renders, the modal scrim fade, Material Web 2.5.0's dialog motion and the m3.material.io full-screen dialog), m3e-cssdialog.css, the m3e-elements<m3e-dialog>anddialog-layout(DialogLayout) entries, and m3e-react<AlertDialog>,<BasicAlertDialog>and<FullScreenDialog>. Shared helper:base/modal.tsgainsModalSession(scroll lock, Tab trap, Escape, initial focus and focus return) for the modals that follow. -
Badges on navigation destinations and tabs (M9 B2; COMPONENT_SPEC §13, §14, §16, §17, §34):
badge(the dot for""/true, a count with999+above 999, or short text) andbadge-label/badgeLabel(the visually hidden text, read after the label: "Inbox 8", "Chat New notification") on<m3e-navigation-item>and<m3e-tab>, and on the ReactNavigationDestination(short navigation bar, wide and modal rails, navigation suite, the legacy bar and rail) andTabItem/<Tab>. A ComposeBadgesits on the destination's icon (BadgedBox, asNavigationSuiteScaffoldbuilds it) and at the end of a tab's label (on the icon when the label is hidden), kept inside narrow items and tabs like Compose'sbadgeBounds()(CSS for the navigation items, TabsLayout for tabs; a leading-icon tab's badge is not clamped, asLeadingIconTabhas no bounds). The navigation suite's drawer type keeps showingbadgeas trailing text. m3e-motion addsbadgeValueText,badgeLabelTextand theBadgeValuetype. -
Pull to refresh (M9, COMPONENT_SPEC §38): Compose Material3's
PullToRefreshBox. A touch or pen pull down at the top of a scroll container (overscroll contained) brings the indicator down, half the drag and slowing past the 80dp threshold; a release past it asks for a refresh, and the indicator rests at the threshold while the app refreshes. m3e-motion ports Compose's pull math and arrow (checked against a JVM reference). The default indicator is Compose's arrow then a circular progress; the loading indicator variant drives contained loading indicators. Mouse drags never pull: a visible Refresh button is the keyboard path. Newcomponents/pull-to-refresh-defaults.csstokens, m3e-csspull-to-refresh.css, the m3e-elements<m3e-pull-to-refresh>andpull-to-refresh-layout(PullToRefreshLayout) entries, and m3e-react<PullToRefresh>. -
Segmented button (M9, COMPONENT_SPEC §37), deprecated from the start (DECISIONS D4: shipped until 2.0 for migration; use the connected button group): Compose Material3's
SingleChoiceSegmentedButtonRow/MultiChoiceSegmentedButtonRowwithSegmentedButtonon native radios and checkboxes (no custom element). Equal-width buttons overlapping by their 1dp outline in a 48dp row, full corners on the outer ends, secondary container when selected; the check fades and scales in on the springs while the label slides aside, and leaves at once; an icon shown while unselected cross-fades with it. Newcomponents/segmented-button-defaults.csstokens (theSegmentedButton.ktvalues Compose renders), m3e-csssegmented-button.css(with the state-layer, focus-ring andripple.jshooks), and m3e-reactSingleChoiceSegmentedButtonRow,MultiChoiceSegmentedButtonRowandSegmentedButton, marked@deprecatedand warning once in development. -
Side sheets (M9, COMPONENT_SPEC §31; D8: Compose has no side sheet, m3.material.io is the only reference and every value is
TODO(verify)against it). The standard side sheet is an<aside>at the end of a flex row that takes its width from the row while open, so the content beside it shrinks; the modal side sheet is a native modal<dialog>at the window's end edge over the 0.32 scrim (the page inert and its scroll locked, Tab kept inside, focus on its first button and back to the opener);adaptiveis modal below 600dp (the medium window size class) and standard from it. From the m3.material.io token DB and Specs: 256dp wide by default and at most 400dp, surface (standard) or surface-container-low with 16dp start corners and a level 1 shadow (modal), adetachedoption inset by 16dp with all corners rounded, an optional divider in outline, a header with an optional back button, the title-large headline and the required close button, and optional start-aligned bottom actions. The sheets open on the default spatial spring and close on the fast effects spring, the navigation drawer's motion mirrored to the end edge (no drags); the close button, Escape and the scrim ask to close. Newcomponents/side-sheet-defaults.csstokens, m3e-cssside-sheet.css, the m3e-elements<m3e-side-sheet>andside-sheet-layout(SideSheetLayout) entries, and m3e-react<SideSheet>. -
Snackbar (M9, COMPONENT_SPEC §32): Compose's
Snackbar(inverse surface, extra-small corners, the level 3 shadow; the text, then an inverse-primary text-button action and a dismiss icon button with its built-in "Dismiss" tooltip at the end, or the action under the text; 48dp for one line, 68dp for two, at most 600dp wide; the padding-basedisSnackbarStylingFixEnabledlayout) and its host (Compose'sSnackbarHost/SnackbarHostState): one snackbar at a time from a first-in, first-out queue,showSnackbar()resolving with'action-performed'or'dismissed', 4s / 10s / indefinite durations (indefinite with an action), the timer paused while hovered or focused, Escape dismissing the focused snackbar,focus()to reach it from an app shortcut, focus returned when it leaves; the current snackbar scales and fades in on the fast springs while the previous one fades out. The host is a polite live region fixed to the bottom center of the window, raised by--m3e-comp-snackbar-host-bottom-offset(above a FAB). Newcomponents/snackbar-defaults.csstokens, m3e-csssnackbar.css, the m3e-elements<m3e-snackbar-host>andsnackbar-layout(SnackbarHostState,SnackbarHostController) entries, and m3e-reactuseSnackbarHostState(),<SnackbarHost>and<Snackbar>. -
Tooltips (M9, COMPONENT_SPEC §33; Compose
PlainTooltip,RichTooltipandTooltipBox): plain tooltips (inverse surface, up to 200dp) and rich tooltips (subhead, supporting text and a text-button action, up to 320dp, level 2 shadow), with Compose's opt-in caret. Compose's behavior: mouse hover shows a tooltip at once and it stays while the anchor or the tooltip is hovered, hiding 1.5 s after the pointer leaves both (m3.material.io); the anchor'saria-describedbypoints at the tooltip unless its text equals the anchor's accessible name (then the tooltip isaria-hidden); a rich tooltip with an action is a non-modal dialog; a touch long press shows it until the press ends (at least 1.5 s); keyboard focus shows it until focus leaves; Escape and a click outside hide it; one tooltip at a time (the global mutex and its priorities);show()hides a non-persistent tooltip after 1.5 s. Placement portsTooltipPositionProviderImpl(above by default, flipped below at the window top; below, left, right, start, end) and the caret placement, measured from the anchor's 48dp minimum interactive bounds; the tooltip scales in from 0.8 on the fast spatial spring and fades on the fast effects spring. Newcomponents/tooltip-defaults.csstokens (theTooltip.kt/internal/BasicTooltip.ktvalues Compose renders), m3e-motiontooltipPosition/tooltipCaret, m3e-csstooltip.css, the m3e-elements<m3e-tooltip>andtooltip-popup(TooltipController,TooltipPopup) entries, and m3e-react<TooltipTrigger>,<PlainTooltip>and<RichTooltip>. Shared helper: the menu popup's popover, spring and reposition engine moves intoAnchoredPopup, whichMenuPopupnow extends (no change to menus).
Patch changes
-
Button group (M9 follow-up T2, fidelity fix): the overflow ("More options") icon button now has the plain tooltip Compose builds into
ButtonGroupDefaults.OverflowIndicator— the button's name (overflow-label/overflowLabel), above it, shown on hover, keyboard focus or a long press and hidden 1.5s after the pointer leaves, as every tooltip does. It repeats the button's name, so it isaria-hiddenand not anaria-describedbytarget.<m3e-button-group>renders the.m3e-tooltipafter the overflow button and imports thetooltip-popupentry when that button first renders; m3e-react's<ButtonGroup>uses<TooltipTrigger>+<PlainTooltip>.
1.6.1
Patch changes
-
Chip set: the arrow keys now wrap from the last chip to the first and back (mirrored in RTL), in
<m3e-chip-set>and m3e-react's<ChipSet>(both runChipSetLayout), matching<InputChipGroup>(React Aria TagGroup). Previously they stopped at the ends. Home / End and the single tab stop are unchanged. -
@kyralabs/m3e-motion@1.6.1
- @kyralabs/m3e-shapes@1.6.1
Older releases: 1.6.0 , 1.5.0 , 1.4.0 , 1.3.0 , 1.2.0 , 1.1.0 , 1.0.1 , 1.0.0 .