/* eslint-disable max-lines */ import * as SelectPrimitive from "@radix-ui/react-select"; import * as LabelPrimitive from "@radix-ui/react-label"; import { styled } from "../../theme"; import { pxToRem } from "../../utils"; import { Text, typographyVariants } from "../text"; import { Flex } from "../flex"; import { Box } from "../box"; import type { SpaceTokenKey } from "../../theme/spacings"; import type { CSS } from "../../theme"; const FIELDSET_BORDER_WIDTH = pxToRem(1); const FIELDSET_BORDER_WIDTH_FOCUS = pxToRem(2); const LEGEND_PADDING: SpaceTokenKey = "$1"; const SELECT_INPUT_HEIGHT = pxToRem(56); const enabledLegendStyle = { maxWidth: "100%", px: LEGEND_PADDING, }; const enabledLabelStyle = { top: 0, ...typographyVariants.body5, }; const visibleValueStyle: CSS = { opacity: 1, visibility: "visible" }; export const StyledRoot = styled(SelectPrimitive.Root, {}); export const StyledIcon = styled(SelectPrimitive.SelectIcon, { transform: "rotate(0deg)", }); export const StyledLabel = styled(LabelPrimitive.Root, { position: "absolute", color: "$off-white-72-opaque", top: "50%", transform: "translateY(-50%)", left: "$4", transition: `all 200ms cubic-bezier(0, 0, 0.2, 1) 20ms, color 0s`, variants: { error: { true: { color: "$light-red", }, }, filled: { true: { ...enabledLabelStyle, }, }, }, ...typographyVariants.body3, }); export const StyledValue = styled(SelectPrimitive.Value); export const StyledExtraContainer = styled(Flex, { alignItems: "center", gap: "$2", }); export const StyledFieldSet = styled("fieldset", { height: SELECT_INPUT_HEIGHT, width: "100%", border: `${FIELDSET_BORDER_WIDTH} solid $off-white-18-opaque`, borderRadius: "$xs", variants: { error: { true: { border: `${FIELDSET_BORDER_WIDTH_FOCUS} solid $light-red`, }, }, }, }); export const StyledLegend = styled("legend", { visibility: "hidden", maxWidth: "0", height: 0, transition: `max-width 50ms, padding-left 50ms, padding-right 50ms, margin-left 50ms, cubic-bezier(0.0, 0, 0.2, 1) 30ms`, whiteSpace: "nowrap", ml: "$4", ...typographyVariants.body5, variants: { filled: { true: { ...enabledLegendStyle, marginLeft: `calc($4 - ${FIELDSET_BORDER_WIDTH} - ${LEGEND_PADDING})`, }, }, }, }); export const StyledTrigger = styled(SelectPrimitive.SelectTrigger, { position: "absolute", display: "flex", width: "100%", height: SELECT_INPUT_HEIGHT, top: 0, justifyContent: "space-between", pr: "$4", "> span": { pl: "$4", pt: "$4", flex: 1, opacity: 0, visibility: "hidden", color: "$off-white-72-opaque", transition: "opacity 200ms cubic-bezier(0, 0, 0.2, 1) 30ms", overflowX: "hidden", textOverflow: "ellipsis", ...typographyVariants.body3, }, "div[data-value-container='true']": { overflow: "hidden", textOverflow: "ellipsis", display: "inline-block", width: "100%", textWrap: "nowrap", }, [`& ${StyledIcon}`]: { svg: { color: "$light-off-white", }, }, "&:focus": { "> span": { ...visibleValueStyle, }, [`& ${StyledLabel}`]: { ...enabledLabelStyle, }, }, '&&[data-state="open"]': { [`& ${StyledLabel}`]: { ...enabledLabelStyle, }, [`& ${StyledIcon}`]: { transform: "rotate(-180deg)", svg: { color: "$light-off-white", }, }, "> span": { ...visibleValueStyle, }, }, variants: { filled: { true: { "> span": { ...visibleValueStyle, }, }, }, error: { true: { '&&[data-state="open"]': { [`& ${StyledLegend}`]: { ...enabledLegendStyle, marginLeft: `calc($4 - ${FIELDSET_BORDER_WIDTH_FOCUS} - ${LEGEND_PADDING})`, }, }, }, }, }, }); export const StyledWrapper = styled(Box, { width: "100%", height: "100%", position: "relative", "&[data-disabled]": { opacity: "$disabled", "> *": { cursor: "not-allowed", }, }, [`:where(${StyledTrigger}:hover:not([disabled]) + ${StyledFieldSet})`]: { border: `${FIELDSET_BORDER_WIDTH} solid $off-white-36-opaque`, }, "&:focus-within": { [`& ${StyledFieldSet}`]: { border: `${FIELDSET_BORDER_WIDTH_FOCUS} solid $off-white-36-opaque`, }, [`& ${StyledLegend}`]: { ...enabledLegendStyle, marginLeft: `calc($4 - ${FIELDSET_BORDER_WIDTH_FOCUS} - ${LEGEND_PADDING})`, }, }, }); export const StyledIconContainer = styled(Flex, { gap: "$2", alignItems: "center", }); export const StyledPortal = styled(SelectPrimitive.Portal, { backgroundColor: "$off-white-3-opaque", boxShadow: "$card", borderRadius: "$xs", }); export const StyledContent = styled(SelectPrimitive.Content, { overflow: "hidden", width: "var(--radix-select-trigger-width)", }); export const StyledViewport = styled(SelectPrimitive.Viewport); export const StyledGroup = styled(SelectPrimitive.Group, { maxHeight: pxToRem(252), width: "100%", }); export const StyledItem = styled(SelectPrimitive.Item, { position: "relative", display: "flex", gap: "$2", userSelect: "none", minHeight: pxToRem(56), color: "$off-white-72-opaque", p: "$3 $4", alignItems: "center", "&[data-highlighted]": { outline: "none", backgroundColor: "$off-white-9-opaque", color: "$light-off-white", }, "> span": { overflowWrap: "anywhere", textSizeAdjust: "100%", }, variants: { extraPosition: { right: { width: "100%", flexDirection: "row-reverse", justifyContent: "space-between", }, left: {}, }, }, ...typographyVariants.body4, }); export const StyledItemText = styled(SelectPrimitive.ItemText); export const StyledExtraInfo = styled(Text, { display: "block", color: "$off-white-72-opaque", mt: "$2", ml: "$4", variants: { error: { true: { color: "$light-red", }, }, }, });