Let a card's title take the heading level the page needs
<x-card> always titled itself with an <h3>, so a card straight under a page's <h1> skipped a level, which SealShare's download page did with no way round it from the application. `heading` takes h2 to h6, or div or p for a title that is not a heading, as <x-pane> and <x-app-bar> already do; h3 stays the default. The skill also says a card holds one subject, as M3 does (plan step 46). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d557dd9b49
commit
ff5349759b
@@ -476,7 +476,7 @@ The `illustration` slot draws the application's own artwork in place of the shap
|
|||||||
|
|
||||||
### `<x-card>`
|
### `<x-card>`
|
||||||
|
|
||||||
`variant`: `filled` (default, surface-container-highest), `elevated`, `outlined`; medium corner. Props `title`, `subtitle`, `separator`; slots `figure` (full-bleed media), `menu` (top-end), `actions` (end-aligned). Do not pass `bg-*`; use `variant`.
|
`variant`: `filled` (default, surface-container-highest), `elevated`, `outlined`; medium corner. Props `title`, `subtitle`, `separator`, `heading` (the title's element, `h3` by default: pass `h2` for a card straight under the page's `h1`); slots `figure` (full-bleed media), `menu` (top-end), `actions` (end-aligned). A card holds content and actions about one subject (M3); a table of many rows or a group of settings is a headed section, not a card. Do not pass `bg-*`; use `variant`.
|
||||||
|
|
||||||
A card or list item that opens something is a **row**: `data-md-list-row` on it and `data-md-list-open` on its one opener (the title link or a button). A press anywhere else on the row reaches the opener; its other controls keep their own presses. Never wrap a card in `<a>` or use a stretched link. A row answers with the state layer and one step of elevation; its corner does not move.
|
A card or list item that opens something is a **row**: `data-md-list-row` on it and `data-md-list-open` on its one opener (the title link or a button). A press anywhere else on the row reaches the opener; its other controls keep their own presses. Never wrap a card in `<a>` or use a stretched link. A row answers with the state layer and one step of elevation; its corner does not move.
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
`elevated` (surface-container-low at elevation 1) and `outlined` (surface, an outline-variant
|
`elevated` (surface-container-low at elevation 1) and `outlined` (surface, an outline-variant
|
||||||
edge); all with a medium corner. maryUI's props keep their meaning: `title`, `subtitle`,
|
edge); all with a medium corner. maryUI's props keep their meaning: `title`, `subtitle`,
|
||||||
`separator` (a divider under the header), and the `menu` (top-end, beside the title),
|
`separator` (a divider under the header), and the `menu` (top-end, beside the title),
|
||||||
`figure` (full-bleed media on top) and `actions` (end-aligned, under the content) slots.
|
`figure` (full-bleed media on top) and `actions` (end-aligned, under the content) slots. The title
|
||||||
|
is an `<h3>` unless `heading` names the level the page's outline needs (`h2` … `h6`, or `div`/`p`
|
||||||
|
for a title that is not a heading), so a card straight under a page's `<h1>` skips no level.
|
||||||
|
|
||||||
M3 draws two kinds of card a person can press, and they differ in the keyboard: on a
|
M3 draws two kinds of card a person can press, and they differ in the keyboard: on a
|
||||||
**non-actionable card with actionable elements** Tab moves through each control inside before
|
**non-actionable card with actionable elements** Tab moves through each control inside before
|
||||||
@@ -51,12 +53,14 @@
|
|||||||
'title' => null,
|
'title' => null,
|
||||||
'subtitle' => null,
|
'subtitle' => null,
|
||||||
'variant' => 'filled',
|
'variant' => 'filled',
|
||||||
|
'heading' => 'h3',
|
||||||
'separator' => false,
|
'separator' => false,
|
||||||
'actionable' => false,
|
'actionable' => false,
|
||||||
])
|
])
|
||||||
|
|
||||||
@php
|
@php
|
||||||
$variant = in_array($variant, ['filled', 'elevated', 'outlined'], true) ? $variant : 'filled';
|
$variant = in_array($variant, ['filled', 'elevated', 'outlined'], true) ? $variant : 'filled';
|
||||||
|
$heading = in_array($heading, ['h2', 'h3', 'h4', 'h5', 'h6', 'div', 'p'], true) ? $heading : 'h3';
|
||||||
$role = $actionable ? ($attributes->get('role') ?: 'button') : null;
|
$role = $actionable ? ($attributes->get('role') ?: 'button') : null;
|
||||||
$isRow = $actionable || $attributes->has('data-md-list-row');
|
$isRow = $actionable || $attributes->has('data-md-list-row');
|
||||||
|
|
||||||
@@ -87,7 +91,7 @@
|
|||||||
<div data-md-card-header-row>
|
<div data-md-card-header-row>
|
||||||
<div data-md-card-heading>
|
<div data-md-card-heading>
|
||||||
@if ($title)
|
@if ($title)
|
||||||
<h3 data-md-card-title>{{ $title }}</h3>
|
<{{ $heading }} data-md-card-title>{{ $title }}</{{ $heading }}>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($subtitle)
|
@if ($subtitle)
|
||||||
|
|||||||
@@ -93,3 +93,10 @@ it('rings the row from the card itself when actionable, or from a has() when its
|
|||||||
->and($css->declarations('[data-md-card][data-md-list-row] [data-md-list-open]:focus-visible'))
|
->and($css->declarations('[data-md-card][data-md-list-row] [data-md-list-open]:focus-visible'))
|
||||||
->toBe(['outline' => 'none']);
|
->toBe(['outline' => 'none']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('titles the card at the heading level the page\'s outline needs', function () {
|
||||||
|
expect((string) $this->blade('<x-card title="Shared files" heading="h2">Body</x-card>'))
|
||||||
|
->toContain('<h2 data-md-card-title>Shared files</h2>')
|
||||||
|
->and((string) $this->blade('<x-card title="Shared files" heading="span">Body</x-card>'))
|
||||||
|
->toContain('<h3 data-md-card-title>Shared files</h3>');
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user