UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

214 lines (187 loc) 6.26 kB
@import "../style/base.css"; @layer components { .input { /* Identity */ --color-black: var(--input-color-black, inherit); --color-dark: var(--input-color-dark, inherit); --color-vivid: var(--input-color-vivid, inherit); --color-light: var(--input-color-light, inherit); --color-white: var(--input-color-white, inherit); /* Box */ box-sizing: border-box; width: 100%; margin: var(--input-spacing, var(--space-small)) 0; border-radius: var(--input-radius, var(--radius-xsmall)); border: var(--input-border, var(--stroke-normal)) solid var(--color-vivid); padding: var(--input-padding, var(--space-small)) var(--input-padding, var(--space-small)); flex-grow: var(--grow-greedy); /* Style — Inputs always use the un-variant extremes: `bg=white / text=black` (4 steps apart, * maximum readability). Variant tints surface as borders and validity colours only. */ color: var(--color-black); background: var(--color-white); transition: all 120ms ease-in-out; cursor: default; outline: var(--input-border, var(--stroke-focus)) solid transparent; outline-offset: calc(0px - var(--input-border, var(--stroke-normal))); box-shadow: none; /* Typography */ font-family: var(--input-font, var(--font-body)); font-weight: var(--input-weight, var(--weight-normal)); font-size: var(--input-size, var(--size-normal)); line-height: var(--input-leading, var(--leading-normal)); /* Content */ justify-content: start; align-items: center; /* Variants. */ &.select { /* Select inputs have pointer cursor, down arrow image. */ cursor: pointer; appearance: none; background-repeat: no-repeat; background-size: var(--input-icon-size, var(--size-icon)); padding-right: 2.5em; background-position: right var(--input-padding, var(--space-small)) center; background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iY3VycmVudENvbG9yIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMS40NyA0LjcyYS43NS43NSAwIDAgMSAxLjA2IDBsMy43NSAzLjc1YS43NS43NSAwIDAgMS0xLjA2IDEuMDZMMTIgNi4zMSA4Ljc4IDkuNTNhLjc1Ljc1IDAgMCAxLTEuMDYtMS4wNmwzLjc1LTMuNzVabS0zLjc1IDkuNzVhLjc1Ljc1IDAgMCAxIDEuMDYgMEwxMiAxNy42OWwzLjIyLTMuMjJhLjc1Ljc1IDAgMSAxIDEuMDYgMS4wNmwtMy43NSAzLjc1YS43NS43NSAwIDAgMS0xLjA2IDBsLTMuNzUtMy43NWEuNzUuNzUgMCAwIDEgMC0xLjA2WiIgY2xpcC1ydWxlPSJldmVub2RkIiAvPjwvc3ZnPgo="); /* Placeholder colour if contains checked empty option. */ &:has(.empty:checked) { color: var(--color-dark); } /* Success border if contains a checked value option. */ &:has(.value:checked) { border-color: var(--vivid-green); } } &.text { /* Text inputs have text cursor, selection, placeholder. */ cursor: text; resize: none; &::selection { color: var(--color-white); background-color: var(--color-focus); } &::placeholder { color: var(--color-dark); } /* Success border if valid and has content. */ &:valid:not(:placeholder-shown) { border-color: var(--vivid-green); } /* Error border if invalid and not empty. */ &:invalid:not(:placeholder-shown) { border-color: var(--vivid-red); } &.multiline { /* Textarea has pre-spacing and field-sizing for auto-resizing. */ white-space: pre-wrap; word-break: break-word; field-sizing: content; min-height: calc(1lh * attr(rows number, 2)); } } &.button, &.label { /* Button and label inputs have a pointer cursor and clip overlong labels. */ cursor: pointer; overflow: hidden; white-space: nowrap; /* Success border if contains a checked control or valid text. */ &:has(.checkbox:checked, .radio:checked, .option:checked, .text:valid:not(:placeholder-shown)) { border-color: var(--vivid-green); } /* Error border if contains invalid text. */ &:has(.text:invalid:not(:placeholder-shown)) { border-color: var(--vivid-red); } } &.button { justify-content: center; } /* Error if aria invalid or contains aria invalid. */ &[aria-invalid="true"], &:has([aria-invalid="true"]) { border-color: var(--vivid-red); } /* Important pseudo-classes */ &.disabled, &:disabled, &:has(.disabled, :disabled) { opacity: var(--input-disabled-opacity, 0.5); cursor: default; } &.focus, &:focus, &:focus-within, &:has(.focus) { border-color: var(--color-focus); outline-color: var(--color-focus); } /* Children */ > .input { /* Nested inputs don't double up border or padding. */ padding: 0; border: 0; margin: 0; outline: 0; } && > [data-slot="icon"] { inline-size: var(--input-icon-size, var(--size-icon)); block-size: var(--input-icon-size, var(--size-icon)); flex: none; } &.wrapper { position: relative; /* Absolutely position any slotted element and center it vertically. */ & > [data-slot] { position: absolute; inset-block: 0; display: flex; align-items: center; justify-content: center; inline-size: calc(var(--input-padding, var(--space-small)) + var(--input-icon-size, var(--size-icon))); pointer-events: none; } /* First [data-slot] child anchors to the left. */ & > [data-slot]:first-child { inset-inline-start: 0; } /* Last [data-slot] child anchors to the right. */ & > [data-slot]:last-child { inset-inline-end: 0; } /* Push the inner .input left padding to clear the left slot. */ &:has(> [data-slot]:first-child) > .input { padding-inline-start: var(--input-icon-size, var(--size-icon)); } /* Push the inner .input right padding to clear the right slot. */ &:has(> [data-slot]:last-child) > .input { padding-inline-end: var(--input-icon-size, var(--size-icon)); } } } .placeholder { color: var(--color-dark); } .checkbox, .radio { display: block; width: calc(var(--input-icon-size, var(--size-icon)) - 4px); height: calc(var(--input-icon-size, var(--size-icon)) - 4px); margin: 2px; flex: 0 0 auto; accent-color: var(--color-vivid); cursor: inherit; outline: none; font-size: inherit; line-height: inherit; } } @layer overrides { .input { &:first-child { margin-top: 0; } &:last-child { margin-bottom: 0; } } }