You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/components/fab/fab.css

132 lines
5.3 KiB

/*
* Fab (Floating Action Button) recipe.
*
* The composed <Button> paints the chrome (variant fill, intent colour, focus
* ring, icon slot). This recipe owns only the FAB-specific treatment, layered
* on the same `<button>` (it carries `data-button` + `data-fab`):
*
* 1. prominent elevation, lifting on hover;
* 2. the FAB size scale (its own sm/md/lg — larger than a control);
* 3. the circular icon form vs the extended pill (`data-extended`);
* 4. floating placement, fixed to the viewport (`data-placement`).
*
* The dimensional rules out-specify Button's `[data-button][data-size]` (0,2,0)
* by also matching `[data-fab]` (≥ 0,3,0), so they win regardless of which
* code-split chunk loads first.
*
* Elevation drives Button's OWN `--button-shadow` token (its `[data-button]`
* rule already renders + transitions `box-shadow`), so the FAB shadow composes
* with Button's `outline` focus ring instead of fighting its box-shadow rule on
* a specificity tie. The `[data-button][data-fab]` prefix (0,2,0) wins over any
* `[data-button]` setter regardless of code-split load order.
*
* The hover lift uses the `translate` property, NOT `transform` — Button's
* active press-squeeze animates `transform: scale(...)`, so a transform here
* would clobber it; `translate` composes cleanly alongside it. Button transitions
* `transform` but not `translate`, so we re-declare its transition list + add
* `translate` for the lift to animate.
*/
/* The FAB's size / icon / offset / elevation / lift scale (`--fab-*`) is declared
* in the recipe (`base.ts > fab`) and generated to `:root` — this file only
* CONSUMES it (the values are NOT literals here). The scale is deliberately off
* the control-height ladder (Material 40 / 56 / 72); the shadow tops out at
* `--shadow-overlay`, so the hover affordance is the `--fab-lift` translate. */
[data-button][data-fab] {
--button-shadow: var(--fab-shadow);
transition:
background var(--button-transition-duration) var(--button-transition-ease),
border-color var(--button-transition-duration) var(--button-transition-ease),
color var(--button-transition-duration) var(--button-transition-ease),
box-shadow var(--button-transition-duration) var(--button-transition-ease),
transform var(--button-transition-duration) var(--button-transition-ease),
translate var(--button-transition-duration) var(--button-transition-ease);
}
[data-button][data-fab]:hover:not([data-disabled]):not(:active) {
translate: 0 calc(-1 * var(--fab-lift));
}
[data-button][data-fab][data-disabled] {
--button-shadow: none;
}
/* ── Size (diameter + glyph) ─────────────────────────────────────────── */
[data-button][data-fab][data-fab-size='sm'] {
block-size: var(--fab-size-sm);
font-size: var(--fab-icon-sm);
}
[data-button][data-fab][data-fab-size='md'] {
block-size: var(--fab-size-md);
font-size: var(--fab-icon-md);
}
[data-button][data-fab][data-fab-size='lg'] {
block-size: var(--fab-size-lg);
font-size: var(--fab-icon-lg);
}
/* Circular icon-only form: width = height. Overrides Button's iconOnly
* `inline-size: var(--_button-height)` (which would size to the control
* height, not the FAB diameter). */
[data-button][data-fab][data-fab-size='sm']:not([data-extended]) {
inline-size: var(--fab-size-sm);
}
[data-button][data-fab][data-fab-size='md']:not([data-extended]) {
inline-size: var(--fab-size-md);
}
[data-button][data-fab][data-fab-size='lg']:not([data-extended]) {
inline-size: var(--fab-size-lg);
}
/* Extended pill: height = diameter, width hugs the content with comfortable
* inline padding + a gap between the icon and the label. */
[data-button][data-fab][data-extended] {
inline-size: auto;
padding-inline: var(--space-5);
gap: var(--space-2);
}
/* The visible glyph follows the FAB's font-size (1em icon). */
[data-fab] [data-button-icon] {
font-size: 1em;
}
/* ── Floating placement (fixed to the viewport) ──────────────────────── */
/*
* `static` = no positioning (the consumer places the FAB). The four corners
* pin to their edges, padded by `--fab-offset` + the matching safe-area inset
* so the FAB clears notches / home indicators.
*/
[data-fab][data-placement='bottom-end'],
[data-fab][data-placement='bottom-start'],
[data-fab][data-placement='top-end'],
[data-fab][data-placement='top-start'] {
position: fixed;
z-index: var(--fab-z);
}
[data-fab][data-placement='bottom-end'] {
inset-block-end: calc(var(--fab-offset) + env(safe-area-inset-bottom, 0px));
inset-inline-end: calc(var(--fab-offset) + env(safe-area-inset-right, 0px));
}
[data-fab][data-placement='bottom-start'] {
inset-block-end: calc(var(--fab-offset) + env(safe-area-inset-bottom, 0px));
inset-inline-start: calc(var(--fab-offset) + env(safe-area-inset-left, 0px));
}
[data-fab][data-placement='top-end'] {
inset-block-start: calc(var(--fab-offset) + env(safe-area-inset-top, 0px));
inset-inline-end: calc(var(--fab-offset) + env(safe-area-inset-right, 0px));
}
[data-fab][data-placement='top-start'] {
inset-block-start: calc(var(--fab-offset) + env(safe-area-inset-top, 0px));
inset-inline-start: calc(var(--fab-offset) + env(safe-area-inset-left, 0px));
}
@media (prefers-reduced-motion: reduce) {
[data-button][data-fab]:hover:not([data-disabled]):not(:active) {
translate: none;
}
}

Powered by TurnKey Linux.