/** @jsxRuntime classic */ /** @jsx jsx */ import { type ElementType, type ReactNode, createContext, useContext } from 'react' import { jsx, forwardRefWithAs, useTheme } from '@keystone-ui/core' // todo - these also exist at ../../types export type SizeType = 'small' | 'medium' export type ShapeType = 'square' | 'round' /** * What is this thing? * ------------------------------ * We expose primitive components for adorning inputs with icons and buttons. * There's some awkard requirements surrounding size and shape that's best to * consolidate in one place. */ const AdornmentContext = createContext<{ shape: ShapeType, size: SizeType }>({ shape: 'square', size: 'medium', }) const useAdornmentContext = () => useContext(AdornmentContext) // Adornment Wrapper // ------------------------------ export type AdornmentWrapperProps = { children: ReactNode shape: ShapeType size: SizeType } export const AdornmentWrapper = ({ children, shape, size }: AdornmentWrapperProps) => { return (
{children}
) } // Adornment Element // ------------------------------ const alignmentPaddingMap = { left: 'marginLeft', right: 'marginRight', } type AdornmentProps = { align: 'left' | 'right' as?: ElementType } export const Adornment = forwardRefWithAs<'div', AdornmentProps>( ({ align, as: Tag = 'div', ...props }, ref) => { const { shape, size } = useAdornmentContext() const { controlSizes } = useTheme() const { indicatorBoxSize, paddingX } = controlSizes[size] // optical alignment shifts towards the middle of the container with the large // border radius on "round" inputs. use padding rather than margin to optimise // the hit-area of interactive elements const offsetStyles = shape === 'round' ? { [alignmentPaddingMap[align]]: paddingX / 4, } : null return ( ) } )