Skip to content

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) and DatePickerDialog, 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 adds date-picker.css; m3e-motion ports the calendar model, DatePickerState / DateRangePickerState, the input's pattern, parser and validator and drawRangeBackground (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 loaded date-field entry; m3e-react adds DatePicker, DateRangePicker, DockedDatePicker and DatePickerDialog.

    m3e-cssm3e-elementsm3e-motionm3e-reactm3e-tokensm3exp-web 324ebea

  • 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 expressive TimeScroll wheels, 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 adds time-picker.css (dial, fields, wheels and the .m3e-time-picker-dialog surface); m3e-motion ports TimePickerState / AnalogTimePickerState, CircularLayout's placement, TimeInputTransformation and ScrollField'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 shared time-picker-layout entry; m3e-react adds TimePicker, TimeInput, TimeScroll, TimePickerModeToggle, TimePickerDialog and VibrantTimePickerDialog.

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

  • API review fixes (M11, D16: additive; every old name keeps working, is @deprecated and goes in 2.0). m3e-elements: the inner inputs' native input / change no longer reach the host of <m3e-time-input>, <m3e-docked-date-picker> and the date pickers' input mode, nor the input's native select the host of <m3e-search>, so host listeners see only the element's CustomEvent; every element with events exports an M3e<Name>EventMap with typed addEventListener / removeEventListener (type-only) and its detail types (OpenChangeDetail, ExpandedChangeDetail, ValueDetail, …); <m3e-button-group> fires selection-change and takes disallow-empty-selection (change, selection-required deprecated), <m3e-list selection-mode> (selection deprecated), carousel items fire a bubbling action (item-click deprecated), <m3e-slider variant orientation> (centered, vertical deprecated), <m3e-side-sheet back-button> (the back attribute deprecated), <m3e-bottom-sheet open> with open-change, the time pickers' selection-change detail gains value; SelectableDates, YearRange, DatePickerDisplayMode and SideSheetVariantOption are 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, isExpanded on FloatingToolbar, SearchBar and ExtendedFab, 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 *Props types are @deprecated and fabClassName({ size: 'small' }) warns like <Fab size="small">.

    m3e-cssm3e-elementsm3e-reactm3exp-web 41ec979

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's IconButtons in MonthsNavigation do (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 under prefers-reduced-motion (--m3e-comp-selectable-chip-icon-shrink-duration is 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 a role="group" named like its sheet, in both layers.

    m3e-cssm3e-elementsm3e-reactm3e-tokensm3exp-web 93ab234

  • 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 (attachTopAppBarScroll and the public --m3e-comp-top-app-bar-container-{collapsed,expanded}-height properties). m3e-css lists every component file with its class, which ones need JavaScript, and its deprecated classes.

    m3e-cssm3e-elementsm3e-react 0c1ac46

  • Source register, category (a) (M11): values that the pinned sources already settle, now cited instead of marked TODO(verify). The navigation drawer divider uses outline-variant, matching Compose's DividerTokens.Color and 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.

    m3e-cssm3e-elementsm3e-tokensm3exp-web e829f59

  • Bundle and d.ts build (M11 hardening; no API or behavior change). m3e-elements emits its declarations with one tsc pass and bundles the .d.ts files 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 declare static properties in 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.

    m3e-elementsm3e-motionm3e-reactm3e-shapesm3exp-web 08b128b

1.7.0

Minor changes

  • Badges (M9, COMPONENT_SPEC §34; Compose Badge and BadgedBox): 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 as BadgedBox places 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 the badgeBounds() rulers that navigation items and tabs will use. m3e-react <Badge count max> writes counts above 999 as 999+ (m3e-motion badgeText) 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, or label); the visible digits are aria-hidden. New components/badge-defaults.css tokens (the Badge.kt values Compose renders) and m3e-css badge.css. No custom element: navigation bar, rail, suite and tab badges follow separately.

    m3e-cssm3e-motionm3e-reactm3e-tokensm3exp-web 88fb764

  • 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) and BottomSheet (the standard sheet, fixed to the bottom of its positioned container, with the BottomSheetScaffold peek 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, with skipPartiallyExpanded, 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. New components/bottom-sheet-defaults.css tokens, m3e-css bottom-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) and SheetState, the m3e-elements <m3e-bottom-sheet> and bottom-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).

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

  • 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.css tokens, m3e-css carousel.css, the m3e-elements <m3e-carousel> / <m3e-carousel-item> and carousel-layout (CarouselLayout) entries, and m3e-react <Carousel> / <CarouselItem>.

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

  • 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 (Compose BasicAlertDialog) 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 with showModal(): 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's onDismissRequest). The alert dialog has the alertdialog role 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). New components/dialog-defaults.css tokens (the AlertDialog.kt values Compose renders, the modal scrim fade, Material Web 2.5.0's dialog motion and the m3.material.io full-screen dialog), m3e-css dialog.css, the m3e-elements <m3e-dialog> and dialog-layout (DialogLayout) entries, and m3e-react <AlertDialog>, <BasicAlertDialog> and <FullScreenDialog>. Shared helper: base/modal.ts gains ModalSession (scroll lock, Tab trap, Escape, initial focus and focus return) for the modals that follow.

    m3e-cssm3e-elementsm3e-reactm3e-tokensm3exp-web 690a736

  • Badges on navigation destinations and tabs (M9 B2; COMPONENT_SPEC §13, §14, §16, §17, §34): badge (the dot for "" / true, a count with 999+ above 999, or short text) and badge-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 React NavigationDestination (short navigation bar, wide and modal rails, navigation suite, the legacy bar and rail) and TabItem / <Tab>. A Compose Badge sits on the destination's icon (BadgedBox, as NavigationSuiteScaffold builds 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's badgeBounds() (CSS for the navigation items, TabsLayout for tabs; a leading-icon tab's badge is not clamped, as LeadingIconTab has no bounds). The navigation suite's drawer type keeps showing badge as trailing text. m3e-motion adds badgeValueText, badgeLabelText and the BadgeValue type.

    m3e-cssm3e-elementsm3e-motionm3e-reactm3exp-web 84b9625

  • 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. New components/pull-to-refresh-defaults.css tokens, m3e-css pull-to-refresh.css, the m3e-elements <m3e-pull-to-refresh> and pull-to-refresh-layout (PullToRefreshLayout) entries, and m3e-react <PullToRefresh>.

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

  • 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 / MultiChoiceSegmentedButtonRow with SegmentedButton on 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. New components/segmented-button-defaults.css tokens (the SegmentedButton.kt values Compose renders), m3e-css segmented-button.css (with the state-layer, focus-ring and ripple.js hooks), and m3e-react SingleChoiceSegmentedButtonRow, MultiChoiceSegmentedButtonRow and SegmentedButton, marked @deprecated and warning once in development.

    m3e-cssm3e-elementsm3e-reactm3e-tokensm3exp-web f0cea30

  • 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); adaptive is 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), a detached option 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. New components/side-sheet-defaults.css tokens, m3e-css side-sheet.css, the m3e-elements <m3e-side-sheet> and side-sheet-layout (SideSheetLayout) entries, and m3e-react <SideSheet>.

    m3e-cssm3e-elementsm3e-reactm3e-tokensm3exp-web 45f8177

  • 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-based isSnackbarStylingFixEnabled layout) and its host (Compose's SnackbarHost / 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). New components/snackbar-defaults.css tokens, m3e-css snackbar.css, the m3e-elements <m3e-snackbar-host> and snackbar-layout (SnackbarHostState, SnackbarHostController) entries, and m3e-react useSnackbarHostState(), <SnackbarHost> and <Snackbar>.

    m3e-cssm3e-elementsm3e-reactm3e-tokensm3exp-web 6ab93f3

  • Tooltips (M9, COMPONENT_SPEC §33; Compose PlainTooltip, RichTooltip and TooltipBox): 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's aria-describedby points at the tooltip unless its text equals the anchor's accessible name (then the tooltip is aria-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 ports TooltipPositionProviderImpl (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. New components/tooltip-defaults.css tokens (the Tooltip.kt / internal/BasicTooltip.kt values Compose renders), m3e-motion tooltipPosition / tooltipCaret, m3e-css tooltip.css, the m3e-elements <m3e-tooltip> and tooltip-popup (TooltipController, TooltipPopup) entries, and m3e-react <TooltipTrigger>, <PlainTooltip> and <RichTooltip>. Shared helper: the menu popup's popover, spring and reposition engine moves into AnchoredPopup, which MenuPopup now extends (no change to menus).

    m3e-cssm3e-elementsm3e-motionm3e-reactm3e-tokensm3exp-web 937129f

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 is aria-hidden and not an aria-describedby target. <m3e-button-group> renders the .m3e-tooltip after the overflow button and imports the tooltip-popup entry when that button first renders; m3e-react's <ButtonGroup> uses <TooltipTrigger> + <PlainTooltip>.

    m3e-elementsm3e-reactm3exp-web 0bd8c65

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 run ChipSetLayout), matching <InputChipGroup> (React Aria TagGroup). Previously they stopped at the ends. Home / End and the single tab stop are unchanged.

    m3e-cssm3e-elementsm3e-reactm3e-tokensm3exp-web fe964d5

  • @kyralabs/m3e-motion@1.6.1

    • @kyralabs/m3e-shapes@1.6.1

    m3e-react

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 .