feat!: release 4.0.0 with split view and desktop styles - #210
Merged
Merged
Conversation
Measured against iOS 27 (simulator), Android 17 (Pixel 10) and Chrome 153: - iOS/macOS/Windows: 26pt continuous-corner cards, 20pt margins, 52pt rows with 17pt text, 17pt semibold section headers, secondary grey - Android/Linux/Fuchsia: each tile on its own card (20dp group ends, 4dp inner corners, 2dp gaps) on a surfaceContainer page, 16sp titles, tighter rows, check/cross switch thumbs - Web: white 8px cards with a light shadow, 14/13px text, 20px icons, chevrons on navigation tiles, near-black section titles, 680px column Adds tests for the new layout and updates the README screenshots and the example's iOS headers to sentence case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds CupertinoSettingsSwitch, a pure-Flutter copy of the iOS 26/27 UISwitch, measured on the iOS 27 simulator, and uses it in iOS-style switch tiles instead of CupertinoSwitch. - Rest: 63x28 continuous-corner track, 37x24 white pill thumb, 2pt inset, 22pt travel. OFF #C5C5C7/#5A5A5E, ON system green. - Pressed or dragged: the thumb springs into a 59.33x39.67 glass lens that overflows the track. It is painted with a CustomPainter only: a squeezed, lifted track image with flares, refracted bands, a hairline rim, a specular line and a soft shadow below. - Motion: spring press with a small overshoot, frosted phases, and a tinted thumb that fades to white after release. Drags follow the finger with rubber-banding and flip the value 1pt past the far end. Reduced motion skips the lens. - Horizontal drags only, so lists still scroll. Light haptic on iOS and macOS. Toggle semantics, keyboard activation, 50% opacity when disabled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
flutter create picked up an unrelated development team when the iOS runner was regenerated. Leave it unset so contributors choose their own team in Xcode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CLAUDE.md now only imports AGENTS.md, so Claude and Codex read the same file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- SettingsList.brightness now overrides the app brightness. - ApplicationType.both decides by the platform the app runs on (iOS and macOS read the CupertinoTheme), not by the platform field, which is null when auto-detecting. - crossAxisAlignment: start puts the content column at the start edge (RTL-aware); the spare width goes to the end. - The default padding uses the width the list gets (LayoutBuilder), not the screen width, so a list in a narrow pane fits the pane. - An empty SettingsSection renders nothing instead of crashing on iOS. - SettingsTile passes titleDescriptionPadding (not titlePadding) on iOS, and trailingPadding/descriptionPadding on iOS. Android and web now apply titlePadding. - Android and web disabled switches honor inactiveSwitchColor in every layout; the web switch next to a trailing widget drops the hard-coded blue active color. - Example: Flutter >=3.44 / Dart >=3.12, material_ui and cupertino_ui as direct dependencies. - CHANGELOG: 3.0.1 entry and the fixes above. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- README: prompts for coding agents (a hero prompt plus four task prompts) that point at llms.txt, and the 2026 look for each style. Correct brightness, crossAxisAlignment and split-pane padding, applicationType.both, where value/description/titleDescription show per style, switch-row taps, iOS system colors, the material_ui and cupertino_ui direct dependency note, SettingsSection.titlePadding, the SettingsTile padding params and CupertinoSettingsSwitch. - llms.txt: install and version choice, a minimal example that compiles, the full parameter reference, the platform to style table, SettingsThemeData, CupertinoSettingsSwitch, testing notes and rules for agents. - AGENTS.md: 4.0.0, Flutter 3.44 with material_ui/cupertino_ui imports, dart format, the 60% coverage gate, the public exports (with CupertinoSettingsSwitch), design specs per style, the test layout and the on-device integration test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DevicePlatform.linux now renders like GNOME Settings 51 (libadwaita 1.10) instead of the Android style. Fuchsia stays on the Android style. - Boxed lists: one card per section with 12px corners and the libadwaita 3-layer soft shadow (painted outside the card only, like CSS, so the translucent dark card does not show it), 54px rows, full-width 1px separators, text 14px in, 16px symbolic leading icons 12px before the title. - Page: AdwClamp-style content width (600sp maximum, easing in from the 400sp tightening threshold), 24px above the first group and between groups, 12px side margins. - Group titles in bold 14.67px, 34px tall, 6px above the card; 14.67px row titles and 12.22px subtitles at 55% opacity. titleDescription and description are both row subtitles. - Navigation rows end with a painted go-next-symbolic arrow (mirrored in RTL); values are dimmed labels before it. - Hover (3%) and pressed (8%) highlights with the 200ms libadwaita transition, a 2px accent keyboard focus ring that follows the card corners, Enter/Space activation, and merged row semantics. - Switch rows toggle from anywhere in the row, like AdwSwitchRow, and never call onPressed. - New public AdwaitaSettingsSwitch: the 46x26 GtkSwitch with a round 20px knob, #3584E4 accent, hover/pressed track colors, the dark-mode grey knob, drag, keyboard, focus ring, reduce motion and RTL. - Colors follow libadwaita: #FAFAFB/#FFFFFF light, #222226/white 8% dark, all text and icon colors derived from the GNOME foreground. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- New gallery screen: the Power panel of GNOME Settings 51 in the Linux style (power mode radio rows, switch, combo and navigation rows, flat header bar). - The web build reads `?platform=`, `?screen=gnome-power|cross-platform` and `?theme=light|dark` from the URL, so screenshots can open a style and screen directly. - The integration test accepts the Linux switch (AdwaitaSettingsSwitch) and covers the new screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DevicePlatform.macOS now renders like the grouped form of macOS 26/27 System Settings instead of the iOS style: #F7F7F7/#252525 cards with 12pt continuous corners on a white/#1E1E1E page, 36pt rows with 1pt separators inset 10pt, 13pt text, 13pt semibold headers, 11pt footers, a drawn chevron.right and the new public MacosSettingsSwitch (36x16, or 44x20 with MacosSettingsSwitchSize.large). The content column is at most 640pt wide. Windows keeps the iOS style. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README, llms.txt, CHANGELOG and AGENTS.md: Linux now maps to the GNOME style, where value, description and titleDescription show in it, which theme fields it uses, and the new public AdwaitaSettingsSwitch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A Notifications pane replica in the macOS style, with MacosIconBadge (colored squircle icons) and MacosPopupValue (pop-up button value) as example widgets, reachable from the gallery. - ?screen=macos&theme=dark (web) or --dart-define=SCREEN/THEME opens a screen directly in light or dark mode, for screenshots. - The example now has a macOS runner (flutter create --platforms=macos). - The integration test knows MacosSettingsSwitch and scrolls in short desktop windows; it passes on macOS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Windows used the iOS style. It now gets its own style, modelled on Windows 11 Settings (WinUI 3 theme resources and the Community Toolkit SettingsCard): - One card per tile: 4px corners, a 1px border, 4px apart, at least 68px tall (52 compact) with 16px padding; 20px icons, Body 14/20 titles, Caption 12/16 descriptions, the value in secondary text and a thin 13px chevron at the end. - Section headers in BodyStrong with the 1,30,0,6 margin; a 1000px column with 36px margins (16 below 641px) and 36 at the bottom. - Below 476px the content moves under the header, below 286px the icon hides, as the Toolkit does. - Clickable cards get the WinUI hover and pressed colors, the elevation border and the 2px + 1px keyboard focus ring; Enter and Space activate. - FluentSettingsSwitch, a public WinUI ToggleSwitch drawn in Flutter: 40x20, knob 12/14/17x14, accent #005FB8 / #60CDFF, drag, keyboard, focus ring, semantics, RTL and reduce motion. macOS stays on the iOS style. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- "Windows Display Settings" in the gallery: System > Display in the Windows style, with the page breadcrumb, Night light, Scale, resolution and orientation rows, and an integration test for it. - On the web, URL options open a screen directly for screenshots: ?screen=windows-display|cross-platform, ?platform=<DevicePlatform> and ?theme=light|dark. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README, llms.txt and AGENTS.md: Windows now has its own style (platform table, one line on the look, colors, where value and description show, switch-tile taps, theme fields) and FluentSettingsSwitch is exported. CHANGELOG: one entry for the new style. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README, llms.txt and AGENTS.md: macOS now has its own style, Windows keeps the iOS one. Adds the MacosSettingsSwitch API and a CHANGELOG entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pressing the switch (or a trailing widget) of a row that also has onPressed showed the row's pressed tint until release. Also document that a disabled macOS switch keeps a paler accent unless inactiveSwitchColor is set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved: - theme_provider.dart: keep both _adwaitaTheme and _fluentTheme. - settings_list.dart (calculateDefaultPadding): keep the Linux AdwClamp column and the Windows 1000 column with 36/16 margins and 32 bottom padding; both branches had split top/bottom padding, unified on the contentWidth = min(width, max) form. - Tests: Linux and Windows each get their own dispatch expectations, with cross-checks that the other style is absent; widget_test.dart wires adwaitaStyleTests, fluentStyleTests and fluentSwitchTests. - Example: gallery lists both replicas; one LaunchOptions (?platform=, ?screen=, ?theme=) and a launchScreens map in main.dart that can open every gallery screen; integration test covers both replicas and knows all four switch types. - CHANGELOG, README, llms.txt, AGENTS.md: merged into one text with iOS/macOS -> iOS, Windows -> Windows 11, Linux -> GNOME, Android/Fuchsia -> Android, web -> Chrome. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved: - Dispatchers (settings_section, settings_tile, theme_provider): macOS, Linux, iOS and Windows each get their own case; iOS no longer shares a case with macOS or Windows. Exports list all four switches. - settings_list.dart (calculateDefaultPadding): macOS 640 column with 12/0 top and 10 bottom padding added next to the Linux AdwClamp and Windows 1000/36 rules, on the shared contentWidth form. - Tests: re-applied the macOS expectations on top of the Linux and Windows ones, with cross-checks; widget_test.dart wires macosStyleTests too. - Example: `?screen=macos` joins the launchScreens map; LaunchOptions now also reads --dart-define SCREEN/PLATFORM/THEME, so one mechanism works on the web and on desktop. example/README documents it. Integration test helpers know MacosSettingsSwitch. - CHANGELOG, README, llms.txt, AGENTS.md: one text with iOS -> iOS, macOS -> macOS System Settings, Windows -> Windows 11, Linux -> GNOME, Android/Fuchsia -> Android, web -> Chrome. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dart 3.13's formatter (Flutter 3.47, what CI's stable channel uses) keeps a closure or list argument as a block when named arguments follow it; Dart 3.12's (Flutter 3.44) splits every argument instead, so the same code passed one check and failed the other. Put `variant:` before the test body and move the tile list into a local, so both formatters leave the files alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An iOS tile's description footer was as wide as the screen, so in a list narrower than the screen (a pane of a wide window) it overflowed the card column. It now takes the tile's own width and falls back to the screen width only when the width is unbounded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move the platform, brightness and theme resolution out of SettingsList into SettingsStyleConfig (internal), and publish the resolved config in a SettingsStyleScope. A page opened from a tile can then let the SettingsList in its body take the inputs it leaves unset from the list that opened it. A list's own scope doesn't inherit, so nested lists keep detecting their style. calculateBrightness keeps its behavior. Add SettingsContentColumnHint (internal) so a pane can tell the list that fills it to use the whole width or to keep space free at the end. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SettingsThemeData gets selectedTileColor, selectedTileTextColor, selectedTileIconColor and listPaneBackground, with defaults per style: iPad sidebar colors (#E2E6F0/#181D20, #0080F5/#13A4FF capsule with white text), Android surfaceDim list pane with the selected card in surfaceContainer, and Chrome's tinted primary menu pill. They are merged and copied like the other fields. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SettingsTile.navigation(destination:) opens a SettingsDestination without a Navigator.push of your own. In a SettingsList it pushes a Cupertino or Material route with the style's page header: the iOS 26 inline title and glass back button, Android's collapsing large title, or Chrome's page title. The list in the page takes the opener's platform, brightness and themes. SettingsSplitView shows the list and the selected page side by side, and a list with pushed pages when there is no room: - Two panes on iPads from 600pt wide, Android at 720dp wide with a 600dp smallest width, desktops by width, and the web above 980px. A breakpoint, a list pane width and a forced layout can override this. - List pane per style: iPad 320pt sidebar with capsule selection, the Android phone cards on surfaceDim (36.36%, no icons under 380dp), and Chrome's 266px menu. Detail pages fill the pane on iPad and Android and place the 680px column like Chrome on the web. - One detail Navigator and the list pane live under GlobalKeys, so the page, its state and pushed sub-pages survive folding, unfolding and rotation. The chosen page stays shown when the view collapses; the default one doesn't. - Back and Android predictive back go through the detail navigator first. The shown page is restored, the panes sit on each side of a vertical hinge, and the layout mirrors in RTL. - SettingsSplitController selects pages, clears the selection and reports whether two panes show; onDestinationChanged reports changes. Tests cover breakpoints for real devices, pane geometry and colors per style, selection, layout changes, back handling and its races, the controller, hinges, RTL, restoration and pages pushed from a plain SettingsList. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A "Split view" entry in the gallery (new "New in v4" section) shows SettingsSplitView with an iPad Settings, Android Settings or Chrome settings tree for the resolved style, and a Style tile that opens the platform picker to force another one. The app also takes --route '/split-view?style=android&page=display&theme=dark' to open the demo directly (the web uses #/split-view?...). The integration test opens the demo, selects a page through the controller and goes back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README: a "Pages and split view" section with the per-platform layout table and a controller example, API tables for SettingsDestination and SettingsSplitView, the destination parameter and the new theme fields. llms.txt gets the same API and do/don't rules. AGENTS.md lists the new exports and describes how lib/src/split works. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved: - lib/settings_ui.dart: export the four switches and the split view API. - settings_list.dart: the branch's SettingsStyleConfig resolution and content column hint on top of the per-style calculateDefaultPadding (macOS, Windows, GNOME rules and _startsWithHeader kept). - settings_tile.dart: destinations and the list-pane selection work in the dispatcher that has a case for every style. - Example: one launch mechanism. LaunchOptions reads screen, platform, page and theme from the web URL's query, the initial route (--route or #/..., whose path names the screen, so the branch's '/split-view?...' routes keep working with `platform` instead of `style`) or --dart-define. `split-view` joins launchScreens (now builders), and SplitViewScreen.fromQuery is gone. - CHANGELOG, README, llms.txt, AGENTS.md: split view docs merged with the macOS, Windows and GNOME styles; the next commit makes the split view work with those styles as documented. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
example/linux/ only had the generated plugin files, so `flutter run -d linux` couldn't work although the GNOME style is new in this release, and linux/flutter/ephemeral/ showed up in the package. Generated with `flutter create --platforms=linux --org com.example .` (application id com.example.example, like the other runners); the template's test/widget_test.dart is left out. Note the example changes in the CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Up and Down only move between the sidebar's rows and stop at the first and last ones (NSTableView, NavigationView and GtkListBox do); Down on the last row no longer jumps into the page (and, on macOS, no longer selects a control there). - A click on a sidebar row gives it the keyboard focus, so Tab and the arrow keys go on from the clicked row instead of the first one. Its focus ring stays hidden until a key is pressed. - A switch tile without onPressed in the macOS sidebar or the expanded Windows pane can be reached with Tab and toggled with Space: its switch takes the focus when the row can't. - The macOS sidebar list reaches 3pt up under the transparent toolbar strip, so the first row's focus ring isn't clipped; the rows stay where they were. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Switching between one and two panes rebuilds the navigators around the panes, and the new route or detail navigator took the focus: the next Tab started over from the first row. After the switch the focus goes back to the row it was on, to the card of the same tile when the new layout draws the row as a card (macOS, Windows), or to the tile of a page that one pane no longer shows. In one pane, Tab from a page opened over the list no longer jumps to the rows of the hidden list; it stays in the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`flutter test --coverage`, as CI runs it, leaves coverage/ untracked. .pubignore already keeps it out of the package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GNOME sidebar rows and Windows pane items showed their pressed fill from pointer down to pointer up. When the sidebar won the gesture before the tap's deadline no tap cancel came, so the row stayed pressed for the whole scroll. Like the GNOME and Windows cards, a row now lets go when a finger moves past the touch slop, or when the pointer leaves it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- After a round trip through one pane, the accent pill slid in from the item selected before it. A selected item that is built anew now tells the pane that the pill is there. - The page title and its breadcrumb wrapped without a limit, so a long or localized title in a narrow window at large text overflowed the page. They now stay on one line like WinUI's BreadcrumbBar: the crumbs nearest the start collapse into a "…" crumb that goes back to the last collapsed page (and reads its title to screen readers), and a title too long for the line ends in an ellipsis. - The compact rail's pane header added a side safe-area inset (a display cutout in phone landscape) inside the fixed 48px rail, which pushed the menu button out of the rail where it could not be seen or tapped. The header now only keeps clear of the top inset, like the items. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iew flows integration_test.dart failed on phones and the 800x600 macOS window (taps on tiles below the fold) and in every split view style but iPad and Android (it selected a 'display' page the other trees don't have). Scroll targets into view first, pick each style's page, check the gallery's new entries, and don't assume the Material 3 demo starts light. split_view_flows_test.dart runs the split view demo and the showcase in all six styles: pages, a nested page, back, switches, 2x text in dark mode, and resizing across the breakpoints with a nested page open (24 tests, about 4 minutes on macOS). A missed tap fails the test instead of letting back quit the app. AGENTS.md and the example README say how to run them: one file at a time on macOS, and not on web devices. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The GNOME sidebar width (180–280sp) and the collapse width (550sp) scaled those sizes with TextScaler.scale directly. Android 14 and later scale text non-linearly, so large sizes barely grew: at font scale 1.3 the sidebar stayed 25% of the window and its labels were cut off. The sp sizes now grow as much as GNOME's body text does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ssed The ring of a row focused by a click came back when the focus returned to it without the keyboard (after going back from the page it opened in one pane). It now stays hidden until any key is pressed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Screen readers read the switch of a macOS sidebar row with onPressed, and of every expanded Windows pane item, as just "switch, on": the switch was a node of its own with no label. Like the list tiles: - A row with onPressed keeps its switch as a separate node, labelled with the tile title (labelTileSwitch). - A Windows item without onPressed is one merged node, "Title, switch, on", like the macOS and GNOME sidebar rows already were. - A switch item in the Windows compact rail, which toggles on a tap and shows no switch, now says it is a switch and whether it is on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The GNOME content column scaled its 600sp maximum and 400sp threshold with TextScaler.scale directly. Android 14 and later scale text non-linearly, so those large sizes barely grew: at font scale 1.3 the column stayed about 600 wide while the text grew 30%. Like the GNOME split view, the sp sizes now grow as much as GNOME's body text does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The view closes the page of a SettingsSection tile that goes away, but it only learns about a tile in a CustomSettingsSection once that tile has built, so it can't tell such a tile was removed from one that scrolled out of a lazily built list. Document that, and that SettingsSplitController.clearSelection() closes the page, with a test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Sidebar keyboard: Up and Down stop at the first and last rows, a click focuses the row and its ring shows only after a key press. - Back: the split view's PopScope, the page's own PopScope for the back swipe, and routes pushed from the list pane in one pane (which keep one pane while open). - GNOME sp sizes follow the body text size; the Windows breadcrumb stays on one line and collapses its first crumbs into "…". - Switch tiles read as one node, "Title, switch, on"; iOS rows expose a tap only when they do something; a forced brightness works in all six styles; removed pages, and the CustomSettingsSection exception. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes to 3.x behavior go under Bug fixes (forced brightness in every style, disabled tiles and the keyboard, switch and row semantics, the iOS tile timer in widget tests). Fixes to the new split view and desktop styles are folded into their feature descriptions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The demo's Style tile pushes its own route and re-creates the split view with the same controller. In every style, in one pane and with two, back now closes only the picker, and picking a style doesn't trip the controller's one-view assert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…up to date
- Desktop sidebars: Up and Down stop at the first and last rows, a click
focuses the row (its ring shows after a key press), Tab reaches switch
rows in the macOS sidebar and the expanded Windows pane, and screen
readers hear the selected row.
- Back also covers the iOS back swipe, which a PopScope can veto; in one
pane a route a list tile pushed itself closes first, and the view stays
in one pane until it has closed.
- A shown page closes when its tile goes away; tiles in a
CustomSettingsSection need controller.clearSelection().
- The Windows breadcrumb stays on one line ("…" and an ellipsis).
- GNOME sizes are sp values that grow like body text, also with Android
14+ non-linear font scaling.
- A forced brightness works in every style; switch tiles read as
"Title, switch, on"; disabled tiles ignore the keyboard.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tiles that were not semantics containers merged into their section's node whenever their semantics didn't clash. On Android a section whose only tappable row sat among other rows was one node, so TalkBack read "Plain, Value, Disabled, Active" as one button; with no tappable row the whole section, title included, was one item. The web split view's menu did the same, and iOS and web cards only escaped it through their inner ListView. The Android, iOS and web tiles and the web menu item are now semantics containers: a button when they have onPressed (dimmed when disabled), a merged "Title, switch, on" node for switch tiles, plain text otherwise. They carry their own selected flag in a split view's list pane, which the dispatcher passes as semanticsSelected instead of wrapping them. Section titles are header nodes in every style (Windows' header was not a container, so its section node was the heading). Custom tiles get a node of their own (tileSemanticsNode), and iOS and macOS footers too: they were read before the section title, or before a switch row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README's short agent prompt points here, so the full steps live in one place: inspect the app first, propose sections and wait for the user's OK, build with settings_ui (split view on tablets, desktop and the web), wire rows to persisted state, add the store-required rows without inventing URLs, test every shipped style, run and screenshot, then summarize. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README opens with two images (phones and a tablet split view; the macOS, Windows, GNOME and web styles) and a short prompt that points coding agents at the recipe in llms.txt. The other task prompts move to doc/agent-prompts.md. pub.dev screenshots now show the 4.0 look, and the old v2/v3 README images stay in the repo but leave the package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
settings_ui 4.0.0. This includes #209 (the 2026 look and the new iOS switch), so merging this closes it too.
What's in it
material_ui/cupertino_ui(fix: migrate tomaterial_uiandcupertino_uipackages #207). Needs Flutter 3.44+. Apps still onpackage:flutter/material.dartstay on^3.0.1.CupertinoSettingsSwitch, an iOS 26 switch drawn in Flutter (feat!: match the 2026 iOS, Android and Chrome settings look #209).MacosSettingsSwitch), Windows 11 Settings (FluentSettingsSwitch) and GNOME Settings for Linux (AdwaitaSettingsSwitch,AdwaitaPanDownIcon). They were checked against real screenshots of each app.SettingsSplitViewputs the list and the selected page side by side on iPad, tablets, foldables, desktop and the web, with a native sidebar per style.SettingsTile.navigation(destination: SettingsDestination(...))also opens pages on phones without any Navigator code.brightnessworks in every styledoc/agent-prompts.mdllms.txtwith a build recipeAGENTS.mdChecks
flutter pub publish --dry-run: 0 warnings, 2 MB.Known issue: on iOS, VoiceOver frames can be off after the split view changes layout (rotate or resize). This is a Flutter engine bug, reproduced without this package, and it's noted in the README.
🤖 Generated with Claude Code