Skip to content

v0.9.3

Latest

Choose a tag to compare

@YuKongA YuKongA released this 04 Jul 08:18
c36fab7

English | 中文

Highlights

  • New: Tooltip component — plain and rich tooltips shown on hover (desktop/web), long press (touch), or programmatically via TooltipState, with six anchor positions, automatic flipping, an optional caret, and single-tooltip-at-a-time behavior.
  • New: Badge / BadgedBox components — an error-colored dot or short-text pill, plus a new badge slot on NavigationBarItem, FloatingNavigationBarItem, and NavigationRailItem.
  • NavigationRail gains expand/collapse — a new NavigationRailState (via rememberNavigationRailState()) drives an animated transition between the compact rail and a 240dp expanded rail with pill-shaped items and a built-in toggle; the old display-mode API is removed (see Breaking Changes).
  • Snackbar redesigned — inverse-surface tone by default (dark bar in light theme, light bar in dark theme), smooth-corner background with a soft shadow, a filled pill-style action button, and layout-driven stack animations.
  • TabRow redesigned — unselected tabs now draw a subtle outline, and the selection indicator snaps to the selected tab instead of tweening.
  • PullToRefresh reworkedisRefreshing is now the source of truth in both directions: setting it to true shows the indicator programmatically, and the stuck-refresh bug is fixed (#345).
  • Smoother interaction feedback — the default press/hover indication now animates with spring physics (folme springs) instead of a 120ms linear tween, and press feedback stays visible on fast clicks over hover (web/desktop).
  • miuix-squircle fixes & perf — content taller than the GPU texture limit no longer renders transparent; the SDF mask uploads as an ALPHA_8 texture, is sampled with hardware linear filtering, and per-frame allocations were removed.
  • Icons — new extended Home icon (all five weights), new built-in Close and Sidebar icons, and an optical realignment pass across the 62 extended icons.

⚠️ Breaking Changes

1. NavigationRail: display-mode API removed, replaced by an expandable-rail state API

NavigationRail was reworked into an expandable rail. The following were removed with no deprecation shims:

  • the mode: NavigationRailDisplayMode parameter
  • the NavigationRailDisplayMode enum and the LocalNavigationRailDisplayMode CompositionLocal
  • NavigationRailDefaults.TextOnlyFontSize, TextOnlyVerticalPadding, SelectedPressedAlpha, UnselectedPressedAlpha, UnselectedAlpha

A new state: NavigationRailState? = null parameter is inserted as the second parameter (right after modifier), so fully positional call sites passing header or later arguments no longer compile — use named arguments.

// Old
NavigationRail(
    mode = NavigationRailDisplayMode.IconAndText,
) { /* items */ }

// New — classic fixed rail (always icon + label)
NavigationRail { /* items */ }

// New — expandable rail with a built-in toggle
val railState = rememberNavigationRailState()
NavigationRail(
    state = railState,
    expandedWidth = NavigationRailDefaults.ExpandedWidth, // 240.dp
) { /* items */ }

The classic rail (state = null) always renders icon + label; the icon-only and text-only presets have no direct replacement. By design, the selected item in the classic layout is now flat (no bold/alpha tint) — the expanded layout's pill is the selection visual — and press feedback comes from LocalIndication.

2. Navigation bars: TextOnly display mode removed

NavigationBarDisplayMode.TextOnly and NavigationBarDefaults.TextFontSize were removed: navigation items now anchor badges to their icon, and a text-only item has no icon to anchor to. The enum keeps IconAndText, IconOnly, and IconWithSelectedLabel. Exhaustive when branches over the enum need updating.

3. Snackbar: SnackbarColors gained a required actionContainerColor

The SnackbarColors data class has a new fifth constructor property actionContainerColor: Color (background of the new pill-style action button) with no default value. Direct constructions must add it; the SnackbarDefaults.snackbarColors() factory keeps compiling unchanged (the new parameter is trailing with a default).

// Old
SnackbarColors(
    containerColor = …,
    contentColor = …,
    actionContentColor = …,
    dismissActionContentColor = …,
)

// New
SnackbarColors(
    containerColor = …,
    contentColor = …,
    actionContentColor = …,
    dismissActionContentColor = …,
    actionContainerColor = …, // background of the action pill
)

Note the redesigned default appearance: snackbarColors() defaults switched to an inverse-surface palette, SnackbarDefaults.CornerRadius changed 12dp → 16dp, and InsideMargin changed to PaddingValues(all = 12.dp). Unstyled snackbars look substantially different after upgrading; pass explicit colors/values to keep the old look.

4. TextButton: textStyle parameter inserted mid-signature

textStyle: TextStyle? = null was inserted between insideMargin and interactionSource. Only fully positional call sites that pass interactionSource or indication positionally are affected; named-argument call sites compile unchanged.

5. PullToRefresh (behavioral): isRefreshing is now the source of truth in both directions

No signature changed, but the state-sync contract did:

  • Setting isRefreshing = true while the indicator is idle now shows the indicator programmatically (previously a silent no-op) — enabling refresh-on-entry patterns.
  • Releasing a pull while isRefreshing is already true now joins the in-progress refresh instead of invoking onRefresh a second time.
  • A sub-frame true → false pulse no longer latches the indicator in the refreshing state forever (#345).

Adjust any code that relied on the old edge-triggered semantics.

Binary compatibility note: several public functions gained defaulted parameters (SnackbarDefaults.snackbarColors, NavigationRail, folmeSpring), which changes their compiled signatures. Libraries precompiled against 0.9.2 should be recompiled against 0.9.3.

What's Changed

New Features

Improvements

Components

  • library: redesign Snackbar component by @YuKongA in f6f9342e
  • library: Rework Snackbar stack animations to layout-driven motion by @YuKongA in 6c440321
  • library: redesign TabRow with outlined unselected tabs by @YuKongA in efd47bd6
  • library: Rework NavigationRail expand animation to layout-phase reads by @YuKongA in 14cea47d
  • library: use spring-based animations for indication by @YuKongA in #355
  • library: Animate caption bar inset in FloatingNavigationBar by @YuKongA in 6979e70b
  • library: Drop no-op status bar inset from FloatingNavigationBar by @YuKongA in a0f7fa35
  • library: cut redundant overscroll placement and per-frame math by @YuKongA in 99b4fc3d

miuix-squircle

  • library: restore squircle clip/surface scroll perf on normal nodes by @YuKongA in f7aea863
  • library: upload the squircle SDF mask as an ALPHA_8 texture by @YuKongA in bdebeaa9
  • library: sample squircle SDF with hardware linear filtering by @YuKongA in 94c98f3e
  • library: avoid per-frame Rect alloc in squircle band/corner clip by @YuKongA in 8c95716d

Bug Fixes

  • library: rework PullToRefresh isRefreshing sync, fix stuck refresh by @YuKongA in ab8552d9
  • library: fix squircle clip/surface transparency on tall content by @YuKongA in f1082146
  • library: Fix slider edge feedback and synchronize haptic logic by @wxxsfxyzm in #367
  • library: keep persistent tooltip open when cursor moves onto it by @YuKongA in 8bbd8983
  • library: fix tooltip twitch when dismissed during enter animation by @YuKongA in b36a2fa2
  • library: keep press feedback on fast clicks over hover (web) by @YuKongA in 49ac701c

Example & Docs

  • example: preload web CJK fonts up front, drop lazy text wrappers by @YuKongA in d3f557ab
  • example: web: improve loading experience with progress and dark mode by @YuKongA in 6c658e15
  • example: web: improve LazyWebFontFamily support by @YuKongA in 61202bbd
  • example: Keep icon page search bar padding at 0dp on wide screens by @YuKongA in 8c1beb7c
  • example: Update aboutlibraries.json by @YuKongA in 0a495150
  • docs: drop removed text-only mode from navigation docs by @YuKongA in d2c2c078

Dependencies

  • library: replace jetbrains navigationevent with androidx by @YuKongA in 17583a86
  • fix(deps): update dependency androidx.navigation3:navigation3-runtime to v1.1.4 by @renovate in #364
  • fix(deps): update androidx.navigation3 to v1.1.3 by @renovate in #351
  • fix(deps): update dependency androidx.test.uiautomator:uiautomator to v2.4.0 by @renovate in #365
  • fix(deps): update about.libraries to v15.0.3 by @renovate in #363
  • fix(deps): update about.libraries to v15.0.2 by @renovate in #359
  • fix(deps): update about.libraries to v15.0.1 by @renovate in #358
  • fix(deps): update about.libraries to v15 by @renovate in #356
  • chore(deps): update dependency androidx.baselineprofile to v1.5.0-alpha07 by @renovate in #362
  • chore(deps): update gradle to v9.6.1 by @renovate in #360
  • chore(deps): update gradle to v9.6.0 by @renovate in #354
  • fix(deps): update dependency com.diffplug.spotless:spotless-plugin-gradle to v8.8.0 by @renovate in #366
  • fix(deps): update spotless to v8.7.0 by @renovate in #348
  • fix(deps): update composektlintrules to v0.6.2 by @renovate in #352
  • fix(deps): update composektlintrules to v0.6.1 by @renovate in #347
  • fix(deps): update composektlintrules to v0.6.0 by @renovate in #344
  • chore(deps): update actions/checkout action to v7 by @renovate in #353

Full Changelog: v0.9.2...v0.9.3


亮点

  • 新增:Tooltip 组件 — 普通与富文本工具提示,支持悬停(桌面/网页)、长按(触屏)或通过 TooltipState 编程触发;六个锚定方位自动翻转、可选尖角、全局同一时刻仅显示一个。
  • 新增:Badge / BadgedBox 组件 — 错误色圆点或短文本药丸角标;NavigationBarItemFloatingNavigationBarItemNavigationRailItem 新增 badge 插槽。
  • NavigationRail 支持展开 / 收起 — 新的 NavigationRailStaterememberNavigationRailState())驱动侧栏在紧凑布局与 240dp 展开布局(药丸样式条目 + 内置切换按钮)之间动画过渡;原显示模式 API 已移除(见破坏性更改)。
  • Snackbar 重设计 — 默认反色表面配色(浅色主题深色条 / 深色主题浅色条)、平滑圆角背景与柔和投影、药丸样式操作按钮、布局驱动的堆叠动画。
  • TabRow 重设计 — 未选中标签改为细描边样式,选择指示器改为直接切换而非补间动画。
  • PullToRefresh 重构isRefreshing 成为双向数据源:置 true 可编程式展示刷新指示器,并修复卡死在刷新态的问题 (#345)。
  • 交互反馈更顺滑 — 默认按压 / 悬停指示动画由 120ms 线性补间改为弹簧物理(folme 弹簧);快速点击时按压反馈不再被悬停态吞掉(网页/桌面)。
  • miuix-squircle 修复与性能 — 修复超过 GPU 纹理上限的超高内容渲染透明的问题;SDF 遮罩改用 ALPHA_8 纹理上传、硬件线性过滤采样,并消除每帧分配。
  • 图标 — 扩展图标集新增 Home(全部五个字重)、内置基础图标新增 CloseSidebar,并对 62 个扩展图标完成光学对齐。

⚠️ 破坏性更改

1. NavigationRail:显示模式 API 移除,替换为可展开侧栏状态 API

NavigationRail 重构为可展开侧栏。以下 API 被直接移除(无弃用过渡):

  • mode: NavigationRailDisplayMode 参数
  • NavigationRailDisplayMode 枚举与 LocalNavigationRailDisplayMode CompositionLocal
  • NavigationRailDefaults.TextOnlyFontSizeTextOnlyVerticalPaddingSelectedPressedAlphaUnselectedPressedAlphaUnselectedAlpha

新增的 state: NavigationRailState? = null 参数插入在第二位(紧随 modifier),因此以位置参数传入 header 及之后参数的调用将无法编译——请改用具名参数。

//
NavigationRail(
    mode = NavigationRailDisplayMode.IconAndText,
) { /* items */ }

// 新 — 经典固定侧栏(始终图标 + 标签)
NavigationRail { /* items */ }

// 新 — 可展开侧栏(内置切换按钮)
val railState = rememberNavigationRailState()
NavigationRail(
    state = railState,
    expandedWidth = NavigationRailDefaults.ExpandedWidth, // 240.dp
) { /* items */ }

经典侧栏(state = null)始终渲染图标 + 标签;仅图标与仅文本预设没有直接替代。按新设计语言,经典布局下选中项不再加粗 / 透明度着色(展开布局的药丸即选中视觉),按压反馈改由 LocalIndication 提供。

2. 导航栏:TextOnly 显示模式移除

NavigationBarDisplayMode.TextOnlyNavigationBarDefaults.TextFontSize 已移除:导航项现在将角标锚定到图标上,而仅文本条目没有图标可供锚定。枚举保留 IconAndTextIconOnlyIconWithSelectedLabel。对该枚举做穷举 when 的代码需要更新。

3. SnackbarSnackbarColors 新增必填属性 actionContainerColor

SnackbarColors 数据类新增第五个构造属性 actionContainerColor: Color(新药丸样式操作按钮的背景色),无默认值。直接构造 SnackbarColors(...) 的代码必须补上该参数;SnackbarDefaults.snackbarColors() 工厂函数保持源码兼容(新参数位于末尾且带默认值)。

//
SnackbarColors(
    containerColor = …,
    contentColor = …,
    actionContentColor = …,
    dismissActionContentColor = …,
)

//
SnackbarColors(
    containerColor = …,
    contentColor = …,
    actionContentColor = …,
    dismissActionContentColor = …,
    actionContainerColor = …, // 操作按钮药丸的背景色
)

另请注意默认外观已重设计:snackbarColors() 的默认值切换为反色表面配色,SnackbarDefaults.CornerRadius 由 12dp 改为 16dp,InsideMargin 改为 PaddingValues(all = 12.dp)。未自定义样式的 Snackbar 升级后观感会明显不同;如需保留旧观感请显式传入颜色与尺寸。

4. TextButtontextStyle 参数插入签名中部

textStyle: TextStyle? = null 插入在 insideMargininteractionSource 之间。仅影响以位置参数传入 interactionSource / indication 的完全位置式调用;具名参数调用不受影响。

5. PullToRefresh(行为变更):isRefreshing 成为双向数据源

签名未变,但状态同步契约改变:

  • 指示器空闲时置 isRefreshing = true 现在会编程式展示刷新指示器(此前静默忽略)——支持进入页面即刷新等模式。
  • isRefreshing 已为 true 时松开下拉手势会并入进行中的刷新,不再第二次调用 onRefresh
  • 亚帧级的 true → false 脉冲不再导致指示器永久卡死在刷新态 (#345)。

依赖旧的边沿触发语义的代码需要调整。

二进制兼容性说明:若干公开函数新增了带默认值的参数(SnackbarDefaults.snackbarColorsNavigationRailfolmeSpring),其编译后签名发生变化。基于 0.9.2 预编译的库需针对 0.9.3 重新编译。

更新内容

新功能

改进

组件

  • library: redesign Snackbar component by @YuKongA in f6f9342e
  • library: Rework Snackbar stack animations to layout-driven motion by @YuKongA in 6c440321
  • library: redesign TabRow with outlined unselected tabs by @YuKongA in efd47bd6
  • library: Rework NavigationRail expand animation to layout-phase reads by @YuKongA in 14cea47d
  • library: use spring-based animations for indication by @YuKongA in #355
  • library: Animate caption bar inset in FloatingNavigationBar by @YuKongA in 6979e70b
  • library: Drop no-op status bar inset from FloatingNavigationBar by @YuKongA in a0f7fa35
  • library: cut redundant overscroll placement and per-frame math by @YuKongA in 99b4fc3d

miuix-squircle

  • library: restore squircle clip/surface scroll perf on normal nodes by @YuKongA in f7aea863
  • library: upload the squircle SDF mask as an ALPHA_8 texture by @YuKongA in bdebeaa9
  • library: sample squircle SDF with hardware linear filtering by @YuKongA in 94c98f3e
  • library: avoid per-frame Rect alloc in squircle band/corner clip by @YuKongA in 8c95716d

Bug 修复

  • library: rework PullToRefresh isRefreshing sync, fix stuck refresh by @YuKongA in ab8552d9
  • library: fix squircle clip/surface transparency on tall content by @YuKongA in f1082146
  • library: Fix slider edge feedback and synchronize haptic logic by @wxxsfxyzm in #367
  • library: keep persistent tooltip open when cursor moves onto it by @YuKongA in 8bbd8983
  • library: fix tooltip twitch when dismissed during enter animation by @YuKongA in b36a2fa2
  • library: keep press feedback on fast clicks over hover (web) by @YuKongA in 49ac701c

示例与文档

  • example: preload web CJK fonts up front, drop lazy text wrappers by @YuKongA in d3f557ab
  • example: web: improve loading experience with progress and dark mode by @YuKongA in 6c658e15
  • example: web: improve LazyWebFontFamily support by @YuKongA in 61202bbd
  • example: Keep icon page search bar padding at 0dp on wide screens by @YuKongA in 8c1beb7c
  • example: Update aboutlibraries.json by @YuKongA in 0a495150
  • docs: drop removed text-only mode from navigation docs by @YuKongA in d2c2c078

依赖更新

  • library: replace jetbrains navigationevent with androidx by @YuKongA in 17583a86
  • fix(deps): update dependency androidx.navigation3:navigation3-runtime to v1.1.4 by @renovate in #364
  • fix(deps): update androidx.navigation3 to v1.1.3 by @renovate in #351
  • fix(deps): update dependency androidx.test.uiautomator:uiautomator to v2.4.0 by @renovate in #365
  • fix(deps): update about.libraries to v15.0.3 by @renovate in #363
  • fix(deps): update about.libraries to v15.0.2 by @renovate in #359
  • fix(deps): update about.libraries to v15.0.1 by @renovate in #358
  • fix(deps): update about.libraries to v15 by @renovate in #356
  • chore(deps): update dependency androidx.baselineprofile to v1.5.0-alpha07 by @renovate in #362
  • chore(deps): update gradle to v9.6.1 by @renovate in #360
  • chore(deps): update gradle to v9.6.0 by @renovate in #354
  • fix(deps): update dependency com.diffplug.spotless:spotless-plugin-gradle to v8.8.0 by @renovate in #366
  • fix(deps): update spotless to v8.7.0 by @renovate in #348
  • fix(deps): update composektlintrules to v0.6.2 by @renovate in #352
  • fix(deps): update composektlintrules to v0.6.1 by @renovate in #347
  • fix(deps): update composektlintrules to v0.6.0 by @renovate in #344
  • chore(deps): update actions/checkout action to v7 by @renovate in #353

完整更新日志: v0.9.2...v0.9.3