/** * The shared style vocabulary (milestone 23, ruling 3; replaces the Tailwind * class constants of milestone 18, ruling 10). * * Every interactive element must carry `focusRing` or `insetFocusRing`; that * is the milestone-9 accessibility floor. Compose at the call site with * `stylex.props(styles.button, extra)` instead of re-spelling a variant. */ import * as stylex from "@stylexjs/stylex"; import { colors } from "./tokens.stylex"; const FOCUS = ":focus-visible"; const DISABLED = ":disabled"; /** The half-fade loop a placeholder runs while its data is in flight. */ const pulseFrames = stylex.keyframes({ "50%": { opacity: 0.5 }, }); export const styles = stylex.create({ /** The ring drawn outside the element. */ focusRing: { outlineWidth: { default: null, [FOCUS]: 2 }, outlineStyle: { default: null, [FOCUS]: "solid" }, outlineColor: { default: null, [FOCUS]: colors.focus }, outlineOffset: { default: null, [FOCUS]: 2 }, }, /** The ring drawn inside the element, for controls flush against a panel edge. */ insetFocusRing: { outlineWidth: { default: null, [FOCUS]: 2 }, outlineStyle: { default: null, [FOCUS]: "solid" }, outlineColor: { default: null, [FOCUS]: colors.focus }, outlineOffset: { default: null, [FOCUS]: -2 }, }, input: { marginTop: "0.25rem", width: "100%", borderRadius: "0.25rem", borderWidth: 1, borderStyle: "solid", borderColor: colors.borderStrong, backgroundColor: colors.surfaceRaised, color: colors.text, paddingInline: "0.75rem", paddingBlock: "0.5rem", }, smallInput: { borderRadius: "0.25rem", borderWidth: 1, borderStyle: "solid", borderColor: colors.borderStrong, backgroundColor: colors.surfaceRaised, color: colors.text, paddingInline: "0.5rem", paddingBlock: "0.375rem", fontSize: "0.875rem", lineHeight: "1.25rem", }, button: { borderRadius: "0.25rem", borderWidth: 1, borderStyle: "solid", borderColor: colors.borderStrong, paddingInline: "0.75rem", paddingBlock: "0.375rem", fontSize: "0.875rem", lineHeight: "1.25rem", }, smallButton: { borderRadius: "0.25rem", borderWidth: 1, borderStyle: "solid", borderColor: colors.borderStrong, paddingInline: "0.5rem", paddingBlock: "0.25rem", fontSize: "0.875rem", lineHeight: "1.25rem", }, largeButton: { borderRadius: "0.25rem", borderWidth: 1, borderStyle: "solid", borderColor: colors.borderStrong, paddingInline: "0.75rem", paddingBlock: "0.5rem", fontWeight: 500, }, primaryButton: { borderRadius: "0.25rem", borderStyle: "none", backgroundColor: colors.primary, color: colors.primaryText, paddingInline: "0.75rem", paddingBlock: "0.375rem", fontSize: "0.875rem", lineHeight: "1.25rem", fontWeight: 500, opacity: { default: 1, [DISABLED]: 0.5 }, }, largePrimaryButton: { borderRadius: "0.25rem", borderStyle: "none", backgroundColor: colors.primary, color: colors.primaryText, paddingInline: "0.75rem", paddingBlock: "0.5rem", fontWeight: 500, opacity: { default: 1, [DISABLED]: 0.5 }, }, rowButton: { borderRadius: "0.25rem", borderStyle: "none", backgroundColor: "transparent", paddingInline: "0.5rem", paddingBlock: "0.25rem", fontSize: "0.875rem", lineHeight: "1.25rem", color: colors.primaryOnSurface, }, linkButton: { borderStyle: "none", backgroundColor: "transparent", padding: 0, fontSize: "0.875rem", lineHeight: "1.25rem", fontWeight: 500, color: colors.primaryOnSurface, }, dangerLinkButton: { borderStyle: "none", backgroundColor: "transparent", padding: 0, fontSize: "0.875rem", lineHeight: "1.25rem", fontWeight: 500, color: colors.danger, opacity: { default: 1, [DISABLED]: 0.5 }, }, retryButton: { marginTop: "0.75rem", borderRadius: "0.25rem", borderWidth: 1, borderStyle: "solid", borderColor: colors.dangerBorder, backgroundColor: "transparent", paddingInline: "0.75rem", paddingBlock: "0.375rem", fontSize: "0.875rem", lineHeight: "1.25rem", fontWeight: 500, color: colors.dangerText, }, /** Marks an element as waiting on data. Carries no colour of its own. */ pulse: { animationName: pulseFrames, animationDuration: "2s", animationTimingFunction: "cubic-bezier(0.4, 0, 0.6, 1)", animationIterationCount: "infinite", }, /** Digits of equal width, so a column of counts does not jitter as it updates. */ tabularNums: { fontVariantNumeric: "tabular-nums", }, /** * A learned name is runtime state, not something the operator typed, so it * reads muted wherever it appears. The Clients page adds the outlined tag, * where the client is named once; the query tables leave it off rather than * repeat it on every row. The tag is real text — a screen reader announces * it — because colour alone is not an affordance. */ learnedName: { color: colors.textMuted, }, learnedTag: { marginLeft: "0.5rem", borderWidth: 1, borderStyle: "solid", borderColor: colors.border, borderRadius: "0.25rem", paddingInline: "0.375rem", paddingBlock: "0.125rem", fontSize: "0.75rem", lineHeight: "1rem", color: colors.textMuted, }, /** For a value the operator reads character by character: a domain, an IP, a URL. */ mono: { fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace", }, /** * Visible to a screen reader only; the element keeps its place in the a11y tree. * * Apply it to a block container. `overflow` has no effect on a table box, and * `height` on one is a minimum, so a `