Files
Andreas Reinhold / reiniandClaude Opus 5 3083fe28b2 Move the file picker's rules out of the field into file.css
<x-file> marks its field root data-md-file, and the tonal
::file-selector-button with its hover and disabled states moves from
field.css to components/file.css on the state tokens (plan step 36). A
browser test pins the field's 56px box and 16px padding and the pill.

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

63 lines
3.0 KiB
CSS

/*
* <x-file>: the browser's file input in the text field's chrome
* (resources/views/components/file.blade.php).
*
* The chrome is the field's (components/field.css); this file restyles only what the browser
* draws. Its "No file chosen" line is transparent, because it can be neither truncated nor wrapped
* and the caller shows what was chosen; its `::file-selector-button` is a tonal pill — a 32px
* button in secondary-container with label-large, 16px padding, 12px before the line — so it reads
* as the thing to press, with M3's hover state layer and disabled opacities (tokens/state.css). In
* a filled field the button sits under the floating label, 28px tall.
*
* The field's root carries `data-md-file`.
*/
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
@import './field.css';
@layer material.components {
/* `<x-file>`: the browser's own "No file chosen" line is transparent (the caller shows what was
chosen), and its button is a tonal pill — the thing to press. */
input[type='file'][data-md-field-control] {
align-self: center;
color: transparent;
cursor: pointer;
}
input[type='file'][data-md-field-control]::file-selector-button {
height: 32px;
margin-inline-end: 12px;
padding-inline: var(--md-sys-measurement-space200);
border: 0;
border-radius: var(--md-sys-shape-corner-full);
background-color: var(--md-sys-color-secondary-container);
color: var(--md-sys-color-on-secondary-container);
cursor: pointer;
font: var(--md-sys-typescale-label-lg);
letter-spacing: var(--md-sys-typescale-label-lg-tracking);
transition: background-color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast);
}
@media (hover: hover) {
input[type='file'][data-md-field-control]:hover::file-selector-button {
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) calc(var(--md-sys-state-hover-state-layer-opacity) * 100%), var(--md-sys-color-secondary-container));
}
}
input[type='file'][data-md-field-control]:disabled::file-selector-button {
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity) * 100%), transparent);
color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity) * 100%), transparent);
cursor: default;
}
/* A file picker's button is taller than a line of text: it sits lower, and a little smaller. */
[data-md-field][data-md-variant='filled']:has([data-md-field-label]) input[type='file'][data-md-field-control] {
padding-block: 22px var(--md-sys-measurement-space75);
}
[data-md-field][data-md-variant='filled'] input[type='file'][data-md-field-control]::file-selector-button {
height: 28px;
}
}