Files
livewire-material/bin/fetch-symbols
T
Andreas Reinhold / reiniandClaude Fable 5.1 c22d693334 Ship Material Symbols in the 20 optical-size cut
M3 draws icons at 20 dp from the optical size 20 cut, whose strokes stay as
heavy as the 24 dp design's instead of thinning with the glyph (styles.md
§ Icons, the optical size axis). The package only shipped the 24 cut, so every
20 px icon was a scaled-down 24 (core audit C16). bin/fetch-symbols now checks
out both cuts from the same commit of google/material-design-icons and writes
the new one to resources/svg/symbols/{outlined-20,filled-20}: 4,135 symbols
each, the same names and the same normalisation as the 24 cut.

Plan step 10; finding C16.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 04:00:16 +02:00

87 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Refresh resources/svg/symbols from google/material-design-icons (Apache-2.0).
#
# Material Symbols Rounded at weight 400 and grade 0, outlined and filled, in two cuts:
# optical size 24 (the standard size) and optical size 20. M3 draws an icon at 20 dp or
# smaller from the 20 cut, whose strokes stay as heavy as the 24 dp design's instead of
# thinning as the glyph is scaled down (docs/reference/m3/styles.md § Icons, the optical
# size axis). Maintenance only: applications never run this, and bin/ is not part of the
# archive Composer installs.
#
# The repository is ~5 GB, so it is cloned without blobs and checked out sparsely:
# git downloads only the four files per symbol that are kept. The @material-symbols
# npm packages were not used because their SVGs are drawn at optical size 48, whose
# strokes are thinner than the 24px design.
set -euo pipefail
root="$(cd "$(dirname "$0")/.." && pwd)"
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
git clone --quiet --depth=1 --filter=blob:none --no-checkout \
https://github.com/google/material-design-icons.git "$work/repo"
cd "$work/repo"
git sparse-checkout set --no-cone \
'/symbols/web/*/materialsymbolsrounded/*_24px.svg' \
'/symbols/web/*/materialsymbolsrounded/*_20px.svg' \
'!/symbols/web/*/materialsymbolsrounded/*_wght[0-9]*' \
'!/symbols/web/*/materialsymbolsrounded/*_grad200*' \
'!/symbols/web/*/materialsymbolsrounded/*_gradN25*'
git checkout --quiet "$(git symbolic-ref --short HEAD)"
out="$root/resources/svg/symbols"
# The 24 cut keeps the folder names it has always had; the 20 cut is suffixed, so a
# name resolves to a folder without a lookup table (Support\SvgFile::symbol()).
folder() { # optical size, style
case "$1" in
24) echo "$out/$2" ;;
*) echo "$out/$2-$1" ;;
esac
}
for size in 24 20; do
for style in outlined filled; do
rm -rf "$(folder "$size" "$style")"
mkdir -p "$(folder "$size" "$style")"
done
done
# Google's files carry width="24" height="24" and no fill. Drop the size so CSS decides
# it, and paint in currentColor so an icon takes the colour of the text around it.
normalise() {
sed -E \
-e 's/ (width|height)="[0-9]+(px)?"//g' \
-e 's/<svg /<svg fill="currentColor" /' \
"$1"
}
missing=0
for dir in symbols/web/*/materialsymbolsrounded; do
name="$(basename "$(dirname "$dir")")"
for size in 24 20; do
outlined="$dir/${name}_${size}px.svg"
filled="$dir/${name}_fill1_${size}px.svg"
if [[ ! -f "$outlined" || ! -f "$filled" ]]; then
echo "skipped $name: no outlined and filled ${size}px pair" >&2
missing=$((missing + 1))
continue
fi
normalise "$outlined" > "$(folder "$size" outlined)/$name.svg"
normalise "$filled" > "$(folder "$size" filled)/$name.svg"
done
done
git rev-parse HEAD > "$out/SOURCE"
echo "$(ls "$out/outlined" | wc -l | tr -d ' ') symbols at optical size 24 and $(ls "$out/outlined-20" | wc -l | tr -d ' ') at 20 from google/material-design-icons@$(cut -c1-12 "$out/SOURCE"), $missing skipped"