Files
livewire-material/resources/views/components/icon.blade.php
T
Andreas Reinhold / reiniandClaude Opus 5 bdbb76a0bd Size icons and shapes with a prop instead of a Tailwind class
<x-icon size> writes --md-icon-size (24px by default) and takes the optical-size-20
cut for 20px or less, as M3 asks; mirror-rtl flips a directional symbol. <x-shape
size> writes --md-shape-size. Both draw from plain-CSS stylesheets in
material.components, gathered in components.css until all.css replaces it; a
caller's size class still wins while the other components are rewritten.
Plan steps 35 and 36, the prop every component rewrite depends on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 13:49:24 +02:00

60 lines
2.8 KiB
PHP

{{-- A Material Symbol (Rounded, weight 400, grade 0), inline.
`name` is Google's name for it, underscores and all (`arrow_back`), as listed on
fonts.google.com/icons; every symbol Google publishes is available, and an unknown name
throws. `filled` draws the filled state, which in M3 means active or selected.
`optical` is the cut the glyph is drawn from, `24` (the default) or `20`; anything else
falls back to 24, and `filled` combines with either. M3's optical size axis redraws a
symbol so its strokes look equally heavy at every size, which means an icon drawn at
20px or smaller uses the 20 cut: scaling the 24 cut down to 20px instead makes its
strokes about a sixth too thin (docs/reference/m3/styles.md § Icons). The cut and the
size are separate decisions, so a caller that draws `size-5` passes `optical="20"`
with it; the components that size their own icons do that for you.
Decorative by default and hidden from screen readers, because nearly every icon sits
beside words that already say what it means. Pass `label` when the icon alone carries
the meaning.
`size` is the drawn size in px (`16`, `18`, `20`, `24`, `32`, `40`, `48` , any whole number
from 8 to 256; 24 when left out), written as `--md-icon-size` and drawn by
resources/css/components/icon.css. An icon given a size of 20 or less takes the 20 cut
unless `optical` says otherwise, which is M3's rule. A size class from the caller still
works while the components that pass one are rewritten (plan step 36): a utility outranks
the package's layer.
`mirror-rtl` flips a directional symbol (an arrow, a chevron) in a right-to-left document,
as M3's bidirectionality rules ask; symbols that mean the same in both directions do not
take it. --}}
@props([
'name',
'filled' => false,
'label' => null,
'optical' => null,
'size' => null,
'mirrorRtl' => false,
])
@php
$size = filter_var($size, FILTER_VALIDATE_INT, ['options' => ['min_range' => 8, 'max_range' => 256]]) ?: null;
$optical = match (true) {
in_array((string) $optical, ['20', '24'], true) => (int) $optical,
$size !== null && $size <= 20 => 20,
default => 24,
};
$attributes = $attributes
->merge(array_filter([
'data-md-icon' => true,
'data-md-mirror-rtl' => $mirrorRtl ? true : null,
'style' => $size !== null ? "--md-icon-size: {$size}px" : null,
'aria-hidden' => $label === null ? 'true' : null,
'aria-label' => $label,
'role' => $label === null ? null : 'img',
'focusable' => 'false',
], fn ($value): bool => $value !== null));
@endphp
{{ \NoNameWeb\LivewireMaterial\Support\SvgFile::symbol($name, (bool) $filled, $attributes, $optical) }}