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.
244 lines
9.6 KiB
244 lines
9.6 KiB
/* ── Provider — variant-shared base ─────────────────────────────────────── */
|
|
|
|
[data-checkbox] {
|
|
--_checkbox-box-size: var(--checkbox-size-md-box-size);
|
|
--_checkbox-indicator-size: var(--checkbox-size-md-indicator-size);
|
|
--_checkbox-indicator-stroke: var(--checkbox-size-md-indicator-stroke);
|
|
|
|
/* `--_checkbox-palette-*` are private TSC tokens emitted by the
|
|
* generator from `lib/recipes/base.ts > checkbox._palette-*`.
|
|
* Per-color cascade is config-owned via `declarations[]`. */
|
|
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex: 0 0 auto;
|
|
inline-size: var(--_checkbox-box-size);
|
|
block-size: var(--_checkbox-box-size);
|
|
padding: 0;
|
|
border: var(--checkbox-border-width) solid var(--checkbox-border-off);
|
|
border-radius: var(--checkbox-radius);
|
|
background: var(--checkbox-bg-off);
|
|
box-shadow: none;
|
|
cursor: pointer;
|
|
outline: none;
|
|
transition:
|
|
background var(--checkbox-transition-duration) var(--checkbox-transition-ease),
|
|
border-color var(--checkbox-transition-duration) var(--checkbox-transition-ease),
|
|
box-shadow var(--checkbox-transition-duration) var(--checkbox-transition-ease),
|
|
opacity var(--checkbox-transition-duration) var(--checkbox-transition-ease);
|
|
}
|
|
|
|
/* ── Sizes ──────────────────────────────────────────────────────────────── */
|
|
|
|
[data-checkbox][data-size='xs'] {
|
|
--_checkbox-box-size: var(--checkbox-size-xs-box-size);
|
|
--_checkbox-indicator-size: var(--checkbox-size-xs-indicator-size);
|
|
--_checkbox-indicator-stroke: var(--checkbox-size-xs-indicator-stroke);
|
|
}
|
|
|
|
[data-checkbox][data-size='sm'] {
|
|
--_checkbox-box-size: var(--checkbox-size-sm-box-size);
|
|
--_checkbox-indicator-size: var(--checkbox-size-sm-indicator-size);
|
|
--_checkbox-indicator-stroke: var(--checkbox-size-sm-indicator-stroke);
|
|
}
|
|
|
|
[data-checkbox][data-size='md'] {
|
|
--_checkbox-box-size: var(--checkbox-size-md-box-size);
|
|
--_checkbox-indicator-size: var(--checkbox-size-md-indicator-size);
|
|
--_checkbox-indicator-stroke: var(--checkbox-size-md-indicator-stroke);
|
|
}
|
|
|
|
[data-checkbox][data-size='lg'] {
|
|
--_checkbox-box-size: var(--checkbox-size-lg-box-size);
|
|
--_checkbox-indicator-size: var(--checkbox-size-lg-indicator-size);
|
|
--_checkbox-indicator-stroke: var(--checkbox-size-lg-indicator-stroke);
|
|
}
|
|
|
|
[data-checkbox][data-size='xl'] {
|
|
--_checkbox-box-size: var(--checkbox-size-xl-box-size);
|
|
--_checkbox-indicator-size: var(--checkbox-size-xl-indicator-size);
|
|
--_checkbox-indicator-stroke: var(--checkbox-size-xl-indicator-stroke);
|
|
}
|
|
|
|
/* ── Color subset cascade — config-owned by recipes/base.ts ──────────────
|
|
* Subset: primary | secondary | neutral | affirm. Per-color override
|
|
* blocks emitted by the generator at `[data-checkbox][data-color='X']`. */
|
|
|
|
/* ── Hover / focus ─────────────────────────────────────────────────────── */
|
|
|
|
[data-checkbox]:hover:not([data-disabled]):not([data-readonly]) {
|
|
background: var(--checkbox-bg-off-hover);
|
|
border-color: var(--checkbox-border-off-hover);
|
|
}
|
|
|
|
[data-checkbox]:focus-visible {
|
|
outline: var(--focus-ring-width) solid var(--focus-ring-color);
|
|
outline-offset: 0;
|
|
}
|
|
|
|
/* ── States: checked / indeterminate ─────────────────────────────────────
|
|
* Solid variant (default): filled with the colour palette. */
|
|
|
|
[data-checkbox][data-variant='solid'][data-state='checked'],
|
|
[data-checkbox][data-variant='solid'][data-state='indeterminate'],
|
|
[data-checkbox]:not([data-variant])[data-state='checked'],
|
|
[data-checkbox]:not([data-variant])[data-state='indeterminate'] {
|
|
background: var(--_checkbox-palette-solid);
|
|
border-color: var(--_checkbox-palette-solid);
|
|
--_checkbox-palette-text: var(--color-content-on-solid);
|
|
}
|
|
|
|
[data-checkbox][data-variant='solid'][data-state='checked']:hover:not([data-disabled]):not([data-readonly]),
|
|
[data-checkbox][data-variant='solid'][data-state='indeterminate']:hover:not([data-disabled]):not([data-readonly]),
|
|
[data-checkbox]:not([data-variant])[data-state='checked']:hover:not([data-disabled]):not([data-readonly]),
|
|
[data-checkbox]:not([data-variant])[data-state='indeterminate']:hover:not([data-disabled]):not([data-readonly]) {
|
|
background: var(--_checkbox-palette-solid-hover);
|
|
border-color: var(--_checkbox-palette-solid-hover);
|
|
}
|
|
|
|
/* Outline variant: transparent fill, border carries the active colour. */
|
|
|
|
[data-checkbox][data-variant='outline'][data-state='checked'],
|
|
[data-checkbox][data-variant='outline'][data-state='indeterminate'] {
|
|
background: transparent;
|
|
border-color: var(--_checkbox-palette-solid);
|
|
--_checkbox-palette-text: var(--_checkbox-palette-solid);
|
|
}
|
|
|
|
/* Ghost variant: minimal chrome, faint tint when active. */
|
|
|
|
[data-checkbox][data-variant='ghost'] {
|
|
border-color: transparent;
|
|
background: transparent;
|
|
}
|
|
|
|
[data-checkbox][data-variant='ghost']:hover:not([data-disabled]):not([data-readonly]) {
|
|
background: color-mix(in srgb, var(--_checkbox-palette-solid) 8%, transparent);
|
|
border-color: transparent;
|
|
}
|
|
|
|
[data-checkbox][data-variant='ghost'][data-state='checked'],
|
|
[data-checkbox][data-variant='ghost'][data-state='indeterminate'] {
|
|
background: color-mix(in srgb, var(--_checkbox-palette-solid) 18%, transparent);
|
|
border-color: transparent;
|
|
--_checkbox-palette-text: var(--_checkbox-palette-solid);
|
|
}
|
|
|
|
/* ── Invalid state (form validation) ────────────────────────────────────
|
|
* Threat-coloured border across ALL variants. Wins over the active color
|
|
* because invalid signals priority. */
|
|
|
|
[data-checkbox][data-invalid] {
|
|
border-color: var(--color-threat-element);
|
|
}
|
|
|
|
[data-checkbox][data-invalid]:focus-visible {
|
|
box-shadow: 0 0 0 2px var(--color-surface-default), 0 0 0 4px var(--color-threat-element);
|
|
}
|
|
|
|
/* ── Disabled / readonly ────────────────────────────────────────────────── */
|
|
|
|
[data-checkbox][data-disabled] {
|
|
background: var(--checkbox-bg-disabled);
|
|
border-color: var(--checkbox-border-disabled);
|
|
cursor: not-allowed;
|
|
opacity: var(--checkbox-disabled-opacity);
|
|
}
|
|
|
|
[data-checkbox][data-readonly] {
|
|
cursor: default;
|
|
}
|
|
|
|
/* ── Indicator ──────────────────────────────────────────────────────────── */
|
|
|
|
[data-checkbox-indicator] {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
inline-size: var(--_checkbox-indicator-size);
|
|
block-size: var(--_checkbox-indicator-size);
|
|
flex: 0 0 auto;
|
|
color: var(--_checkbox-palette-text);
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* SVG glyph from `$uix/eidos/components/svg`. Uses currentColor so it
|
|
* inherits the indicator's colour, which is set per-variant above. */
|
|
[data-checkbox-indicator] svg {
|
|
inline-size: 100%;
|
|
block-size: 100%;
|
|
stroke-width: var(--_checkbox-indicator-stroke);
|
|
}
|
|
|
|
/* ── Animation: stroke-dasharray draw on check + dash grow ─────────────── */
|
|
|
|
[data-checkbox-indicator] svg[data-svg='check'] path,
|
|
[data-checkbox-indicator] svg[data-svg='dash'] path {
|
|
stroke-dasharray: 100;
|
|
stroke-dashoffset: 100;
|
|
transition: stroke-dashoffset var(--checkbox-stroke-duration) var(--checkbox-stroke-ease);
|
|
}
|
|
|
|
[data-checkbox][data-state='checked'] [data-checkbox-indicator] svg[data-svg='check'] path,
|
|
[data-checkbox][data-state='indeterminate'] [data-checkbox-indicator] svg[data-svg='dash'] path {
|
|
stroke-dashoffset: 0;
|
|
}
|
|
|
|
/* ── Disabled indicator colour ──────────────────────────────────────────── */
|
|
|
|
[data-checkbox][data-disabled] [data-checkbox-indicator] {
|
|
color: var(--checkbox-indicator-color-disabled);
|
|
}
|
|
|
|
/* ── Group ──────────────────────────────────────────────────────────────── */
|
|
|
|
[data-checkbox-group] {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--checkbox-group-gap);
|
|
}
|
|
|
|
[data-checkbox-group][data-orientation='horizontal'] {
|
|
flex-direction: row;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
}
|
|
|
|
/* Grid layout when `columns` is set on the wrapper. The wrapper publishes
|
|
* `--_checkbox-group-columns` inline + `data-columns` for the selector. */
|
|
|
|
[data-checkbox-group][data-columns] {
|
|
display: grid;
|
|
grid-template-columns: repeat(var(--_checkbox-group-columns, 2), minmax(0, 1fr));
|
|
align-items: start;
|
|
}
|
|
|
|
[data-checkbox-group-label] {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
width: fit-content;
|
|
font-family: var(--checkbox-group-label-font-family);
|
|
font-size: var(--checkbox-group-label-font-size);
|
|
font-weight: var(--checkbox-group-label-font-weight);
|
|
line-height: var(--checkbox-group-label-line-height);
|
|
color: var(--checkbox-group-label-color);
|
|
}
|
|
|
|
[data-checkbox-group-label][data-disabled] {
|
|
color: var(--checkbox-group-label-color-disabled);
|
|
}
|
|
|
|
/* ── Reduced motion ─────────────────────────────────────────────────────────
|
|
* Honour the user's OS preference: skip the stroke draw + state
|
|
* transition. Indicator just snaps in / out. */
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
[data-checkbox] {
|
|
transition: none;
|
|
}
|
|
[data-checkbox-indicator] svg path {
|
|
transition: none;
|
|
}
|
|
}
|