diff --git a/resources/css/components/toolbar.css b/resources/css/components/toolbar.css index 7e355791..a1fdedb7 100644 --- a/resources/css/components/toolbar.css +++ b/resources/css/components/toolbar.css @@ -24,9 +24,9 @@ * `` and `` draw their own ink from `data-md-color`/`data-md-variant`, not a * utility, so a toolbar's recolouring rules — vibrant's icon buttons, a standard toolbar's primary * ones (N-13), a docked FAB's flattened shadow — sit in this file's own `material.components` - * layer like everything else: each only overrides the single `color`/`background-color`/ - * `box-shadow` declaration button.css or fab.css puts on its own base selector, so a toolbar's - * more specific selector always wins without needing to sit outside the layer. + * layer like everything else, each more specific than the button.css or fab.css rule it overrides, + * whichever file an application imports first. The recolouring leaves a disabled button alone, so + * button.css's disabled colours still apply inside a toolbar. */ @layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility; @@ -72,18 +72,19 @@ color: var(--md-sys-color-on-primary-container); } - [data-md-toolbar][data-md-vibrant] [data-md-icon-button]:not([aria-pressed='true']) { + [data-md-toolbar][data-md-vibrant] [data-md-icon-button]:not([aria-pressed='true'], :disabled, [aria-disabled='true']) { color: var(--md-sys-color-on-primary-container); } - [data-md-toolbar][data-md-vibrant] [data-md-icon-button][aria-pressed='true'] { + [data-md-toolbar][data-md-vibrant] [data-md-icon-button][aria-pressed='true']:not(:disabled, [aria-disabled='true']) { background-color: var(--md-sys-color-surface-container); color: var(--md-sys-color-on-surface); } /* M3's colour list for a standard toolbar ends "Standard button (Primary)", as the vibrant list - ends "Standard button (On primary container)" — the row above (N-13). */ - [data-md-toolbar]:not([data-md-vibrant]) [data-md-icon-button]:not([aria-pressed='true']) { + ends "Standard button (On primary container)" — the row above (N-13). A disabled button keeps + button.css's disabled colours in either. */ + [data-md-toolbar]:not([data-md-vibrant]) [data-md-icon-button]:not([aria-pressed='true'], :disabled, [aria-disabled='true']) { color: var(--md-sys-color-primary); } diff --git a/tests/Feature/Components/AppBarTest.php b/tests/Feature/Components/AppBarTest.php index f0c596ca..5722a4b1 100644 --- a/tests/Feature/Components/AppBarTest.php +++ b/tests/Feature/Components/AppBarTest.php @@ -212,8 +212,16 @@ it('keeps a toolbar at the bottom clear of the navigation bar', function () { ->and($css->declarations('[data-md-toolbar][data-md-vertical][data-md-toolbar-place=\'end\'], [data-md-toolbar-group][data-md-vertical][data-md-toolbar-place=\'end\']')) ->toBe(['inset-inline-end' => 'calc(var(--md-sys-measurement-space300) + var(--material-safe-right, env(safe-area-inset-right)))']) // A standard toolbar's standard buttons are primary (N-13). - ->and($css->declarations('[data-md-toolbar]:not([data-md-vibrant]) [data-md-icon-button]:not([aria-pressed=\'true\'])')) + ->and($css->declarations('[data-md-toolbar]:not([data-md-vibrant]) [data-md-icon-button]:not([aria-pressed=\'true\'], :disabled, [aria-disabled=\'true\'])')) ->toBe(['color' => 'var(--md-sys-color-primary)']); + + // A disabled icon button keeps button.css's disabled ink in a toolbar of either colour. + foreach (['[data-md-toolbar]:not([data-md-vibrant]) [data-md-icon-button]', '[data-md-toolbar][data-md-vibrant] [data-md-icon-button]'] as $scope) { + preg_match_all('/'.preg_quote($scope, '/').'[^{]*\{[^}]*\bcolor:/', $css->css, $rules); + + expect($rules[0])->not->toBeEmpty() + ->each->toContain(":disabled, [aria-disabled='true']"); + } }); it('offers M3\'s three contrast levels, marking the one in force', function () {