|
| 1 | +import * as React from 'react' |
| 2 | +import { StyledComponent } from '@emotion/styled' |
| 3 | +import { InterpolationWithTheme } from '@emotion/core' |
| 4 | +import { SxStyleProp } from 'theme-ui' |
| 5 | +import { SpaceProps, ColorProps, MarginProps } from 'styled-system' |
| 6 | +import { ResponsiveStyleValue } from '@theme-ui/css' |
| 7 | + |
| 8 | +type Assign<T, U> = { |
| 9 | + [P in keyof (T & U)]: P extends keyof T |
| 10 | + ? T[P] |
| 11 | + : P extends keyof U |
| 12 | + ? U[P] |
| 13 | + : never |
| 14 | +} |
| 15 | + |
| 16 | +type ForwardRef<T, P> = React.ForwardRefExoticComponent< |
| 17 | + React.PropsWithoutRef<P> & React.RefAttributes<T> |
| 18 | +> |
| 19 | + |
| 20 | +export interface BoxOwnProps extends SpaceProps, ColorProps { |
| 21 | + as?: React.ElementType |
| 22 | + variant?: string |
| 23 | + css?: InterpolationWithTheme<any> |
| 24 | +} |
| 25 | +export interface BoxProps |
| 26 | + extends Assign<React.ComponentProps<'div'>, BoxOwnProps> {} |
| 27 | +/** |
| 28 | + * Use the Box component as a layout primitive to add margin, padding, and colors to content. |
| 29 | + * @see https://theme-ui.com/components/box |
| 30 | + */ |
| 31 | +export const Box: StyledComponent<React.ComponentProps<'div'>, BoxOwnProps, {}> |
| 32 | + |
| 33 | +export type FlexStyleProps = BoxOwnProps |
| 34 | +export type FlexProps = BoxProps |
| 35 | +/** |
| 36 | + * Use the Flex component to create flexbox layouts. |
| 37 | + * @see https://theme-ui.com/components/flex |
| 38 | + */ |
| 39 | +export const Flex: StyledComponent< |
| 40 | + React.ComponentProps<'div'>, |
| 41 | + FlexStyleProps, |
| 42 | + {} |
| 43 | +> |
| 44 | + |
| 45 | +export interface GridProps extends BoxProps { |
| 46 | + /** |
| 47 | + * Minimum width of child elements |
| 48 | + */ |
| 49 | + width?: ResponsiveStyleValue<string | number> |
| 50 | + /** |
| 51 | + * Number of columns to use for the layout (cannot be used in conjunction with the width prop) |
| 52 | + */ |
| 53 | + columns?: ResponsiveStyleValue<number> |
| 54 | + /** |
| 55 | + * Space between child elements |
| 56 | + */ |
| 57 | + gap?: ResponsiveStyleValue<string | number> |
| 58 | +} |
| 59 | +/** |
| 60 | + * CSS grid layout component to arrange direct child elements in a tiled grid layout. |
| 61 | + * @see https://theme-ui.com/components/grid |
| 62 | + */ |
| 63 | +export const Grid: ForwardRef<HTMLDivElement, GridProps> |
| 64 | + |
| 65 | +export interface ButtonProps |
| 66 | + extends Assign<React.ComponentPropsWithRef<'button'>, BoxOwnProps> {} |
| 67 | +/** |
| 68 | + * Primitive button component with variants |
| 69 | + * @see https://theme-ui.com/components/button |
| 70 | + */ |
| 71 | +export const Button: ForwardRef<HTMLButtonElement, ButtonProps> |
| 72 | + |
| 73 | +export interface LinkProps |
| 74 | + extends Assign<React.ComponentPropsWithRef<'a'>, BoxOwnProps> {} |
| 75 | +/** |
| 76 | + * Link variants can be defined in the `theme.links` object. |
| 77 | + * By default the Link component will use styles defined in `theme.styles.a`. |
| 78 | + * @see https://theme-ui.com/components/link |
| 79 | + */ |
| 80 | +export const Link: ForwardRef<HTMLAnchorElement, LinkProps> |
| 81 | + |
| 82 | +export type TextProps = BoxProps |
| 83 | +/** |
| 84 | + * Primitive typographic component. |
| 85 | + * |
| 86 | + * Text style variants can be defined in the theme.text object. |
| 87 | + * @see https://theme-ui.com/components/text |
| 88 | + */ |
| 89 | +export const Text: ForwardRef<HTMLDivElement, BoxProps> |
| 90 | + |
| 91 | +export interface HeadingProps |
| 92 | + extends Assign<React.ComponentPropsWithRef<'h2'>, BoxOwnProps> {} |
| 93 | +/** |
| 94 | + * Primitive heading component, defaults to <h2>. |
| 95 | + * |
| 96 | + * Text style variants can be defined in the theme.text object. |
| 97 | + * The Heading component uses theme.text.heading as its default variant style. |
| 98 | + * @see https://theme-ui.com/components/heading |
| 99 | + */ |
| 100 | +export const Heading: ForwardRef<HTMLHeadingElement, HeadingProps> |
| 101 | + |
| 102 | +export interface ImageProps |
| 103 | + extends Assign<React.ComponentProps<'img'>, BoxOwnProps> {} |
| 104 | +/** |
| 105 | + * Image style variants can be defined in the theme.images object. |
| 106 | + * @see https://theme-ui.com/components/image/ |
| 107 | + */ |
| 108 | +export const Image: ForwardRef<HTMLImageElement, ImageProps> |
| 109 | + |
| 110 | +export type CardProps = BoxProps |
| 111 | +/** |
| 112 | + * Card style variants can be defined in the `theme.cards` object. |
| 113 | + * By default the Card component uses the `theme.cards.primary` variant. |
| 114 | + * @see https://theme-ui.com/components/card |
| 115 | + */ |
| 116 | +export const Card: ForwardRef<HTMLDivElement, CardProps> |
| 117 | + |
| 118 | +export interface LabelProps |
| 119 | + extends Assign<React.ComponentProps<'label'>, BoxOwnProps> {} |
| 120 | +/** |
| 121 | + * Label variants can be defined in `theme.forms` |
| 122 | + * and the component uses the `theme.forms.label` variant by default. |
| 123 | + * @see https://theme-ui.com/components/label/ |
| 124 | + */ |
| 125 | +export const Label: ForwardRef<HTMLLabelElement, LabelProps> |
| 126 | + |
| 127 | +export interface InputProps |
| 128 | + extends Assign<React.ComponentProps<'input'>, BoxOwnProps> {} |
| 129 | +/** |
| 130 | + * Input variants can be defined in `theme.forms` |
| 131 | + * and the component uses the `theme.forms.input` variant by default. |
| 132 | + * @see https://theme-ui.com/components/input/ |
| 133 | + */ |
| 134 | +export const Input: ForwardRef<HTMLInputElement, InputProps> |
| 135 | + |
| 136 | +export interface SelectProps |
| 137 | + extends Assign<React.ComponentProps<'select'>, BoxOwnProps> {} |
| 138 | +/** |
| 139 | + * Select variants can be defined in `theme.forms` |
| 140 | + * and the component uses the `theme.forms.select` variant by default. |
| 141 | + * @see https://theme-ui.com/components/select/ |
| 142 | + */ |
| 143 | +export const Select: ForwardRef<HTMLSelectElement, SelectProps> |
| 144 | + |
| 145 | +export interface TextareaProps |
| 146 | + extends Assign<React.ComponentProps<'textarea'>, BoxOwnProps> {} |
| 147 | +/** |
| 148 | + * Form textarea component |
| 149 | + * |
| 150 | + * Textarea variants can be defined in `theme.forms` |
| 151 | + * and the component uses the `theme.forms.textarea` variant by default. |
| 152 | + * @see https://theme-ui.com/components/textarea/ |
| 153 | + */ |
| 154 | +export const Textarea: ForwardRef<HTMLTextAreaElement, TextareaProps> |
| 155 | + |
| 156 | +export interface RadioProps |
| 157 | + extends Assign<React.ComponentProps<'input'>, BoxOwnProps> {} |
| 158 | +/** |
| 159 | + * Form radio input component |
| 160 | + * |
| 161 | + * Radio variants can be defined in `theme.forms` and the |
| 162 | + * component uses the `theme.forms.radio variant` by default. |
| 163 | + * @see https://theme-ui.com/components/radio/ |
| 164 | + */ |
| 165 | +export const Radio: ForwardRef<HTMLInputElement, RadioProps> |
| 166 | + |
| 167 | +export interface CheckboxProps |
| 168 | + extends Assign<React.ComponentProps<'input'>, BoxOwnProps> {} |
| 169 | +/** |
| 170 | + * Form checkbox input component |
| 171 | + * |
| 172 | + * Checkbox variants can be defined in `theme.forms` and the |
| 173 | + * component uses the `theme.forms.checkbox` variant by default. |
| 174 | + * @see https://theme-ui.com/components/checkbox/ |
| 175 | + */ |
| 176 | +export const Checkbox: ForwardRef<HTMLInputElement, CheckboxProps> |
| 177 | + |
| 178 | +export interface SliderProps |
| 179 | + extends Assign<React.ComponentProps<'input'>, BoxOwnProps> {} |
| 180 | +/** |
| 181 | + * Range input element |
| 182 | + * |
| 183 | + * Slider variants can be defined in the `theme.forms` object. |
| 184 | + * The Slider component uses `theme.forms.slider` as its default variant style. |
| 185 | + * @see https://theme-ui.com/components/slider/ |
| 186 | + */ |
| 187 | +export const Slider: ForwardRef<HTMLInputElement, SliderProps> |
| 188 | + |
| 189 | +export interface FieldOwnProps extends MarginProps { |
| 190 | + /** |
| 191 | + * Text for Label component |
| 192 | + */ |
| 193 | + label: string |
| 194 | + /** |
| 195 | + * Used for the for, id, and name attributes |
| 196 | + */ |
| 197 | + name: string |
| 198 | +} |
| 199 | +export type FieldProps<T extends React.ElementType> = FieldOwnProps & |
| 200 | + Omit<React.ComponentProps<T>, 'as' | keyof FieldOwnProps> & { |
| 201 | + /** |
| 202 | + * form control to render, default Input |
| 203 | + */ |
| 204 | + as?: T |
| 205 | + } |
| 206 | + |
| 207 | +// `T` is far from unnecessary. We derive component props from it. |
| 208 | +// tslint:disable-next-line no-unnecessary-generics |
| 209 | +export function Field< |
| 210 | + T extends React.ElementType = React.ElementType<InputProps> |
| 211 | +>(props: FieldProps<T>): JSX.Element |
| 212 | + |
| 213 | +export interface ProgressProps |
| 214 | + extends Assign<React.ComponentProps<'progress'>, BoxOwnProps> {} |
| 215 | +/** |
| 216 | + * @see https://theme-ui.com/components/progress/ |
| 217 | + */ |
| 218 | +export const Progress: ForwardRef<HTMLProgressElement, ProgressProps> |
| 219 | + |
| 220 | +export interface DonutProps |
| 221 | + extends Omit< |
| 222 | + React.SVGProps<SVGSVGElement>, |
| 223 | + 'opacity' | 'color' | 'css' | 'sx' | 'max' | 'min' |
| 224 | + >, |
| 225 | + BoxOwnProps { |
| 226 | + value: number |
| 227 | + min?: number |
| 228 | + max?: number |
| 229 | + title?: string |
| 230 | + size?: string | number |
| 231 | +} |
| 232 | +/** |
| 233 | + * Single value SVG donut chart |
| 234 | + * @see https://theme-ui.com/components/donut/ |
| 235 | + */ |
| 236 | +export const Donut: ForwardRef<SVGSVGElement, DonutProps> |
| 237 | + |
| 238 | +export interface SpinnerProps |
| 239 | + extends Omit< |
| 240 | + React.SVGProps<SVGSVGElement>, |
| 241 | + 'opacity' | 'color' | 'css' | 'sx' |
| 242 | + >, |
| 243 | + BoxOwnProps { |
| 244 | + size?: number | string |
| 245 | +} |
| 246 | +export const Spinner: ForwardRef<SVGSVGElement, SpinnerProps> |
| 247 | + |
| 248 | +export interface AvatarProps extends ImageProps { |
| 249 | + size?: number | string |
| 250 | +} |
| 251 | +export const Avatar: ForwardRef<HTMLImageElement, AvatarProps> |
| 252 | + |
| 253 | +export type BadgeProps = BoxProps |
| 254 | +export const Badge: ForwardRef<HTMLDivElement, BadgeProps> |
| 255 | + |
| 256 | +interface CloseProps extends Omit<IconButtonProps, 'children'> {} |
| 257 | +/** |
| 258 | + * Button with close (×) icon. |
| 259 | + * |
| 260 | + * The Close component renders as a <button> element by default. |
| 261 | + * Pass any button attributes as props to the component. |
| 262 | + * |
| 263 | + * Close component variants can be defined in the theme.buttons object. |
| 264 | + * The Close component uses theme.buttons.close as its default variant style. |
| 265 | + */ |
| 266 | +export const Close: ForwardRef<HTMLButtonElement, CloseProps> |
| 267 | + |
| 268 | +export type AlertProps = BoxProps |
| 269 | +/** |
| 270 | + * Component for displaying messages, notifications, or other application state. |
| 271 | + * |
| 272 | + * Alert variants can be defined in `theme.alerts`. |
| 273 | + * The Alert component uses `theme.alerts.primary` as its default variant. |
| 274 | + */ |
| 275 | +export const Alert: ForwardRef<HTMLDivElement, AlertProps> |
| 276 | + |
| 277 | +export type DividerProps = BoxProps |
| 278 | +/** |
| 279 | + * The Divider component reuses styles from `theme.styles.hr` as its default variant. |
| 280 | + */ |
| 281 | +export const Divider: ForwardRef<HTMLDivElement, DividerProps> |
| 282 | + |
| 283 | +export interface EmbedProps extends BoxProps { |
| 284 | + ratio?: number |
| 285 | + src?: React.IframeHTMLAttributes<any>['src'] |
| 286 | + frameBorder?: React.IframeHTMLAttributes<any>['frameBorder'] |
| 287 | + allowFullScreen?: React.IframeHTMLAttributes<any>['allowFullScreen'] |
| 288 | + allow?: React.IframeHTMLAttributes<any>['allow'] |
| 289 | +} |
| 290 | +/** |
| 291 | + * Responsive iframe for video embeds. |
| 292 | + * |
| 293 | + * Embed variants can be defined anywhere in the theme object. |
| 294 | + * |
| 295 | + * @see https://theme-ui.com/components/embed |
| 296 | + */ |
| 297 | +export const Embed: ForwardRef<HTMLIFrameElement, EmbedProps> |
| 298 | + |
| 299 | +export interface AspectRatioProps extends BoxProps { |
| 300 | + ratio?: number |
| 301 | +} |
| 302 | +/** |
| 303 | + * Component for maintaining a fluid-width aspect ratio |
| 304 | + * @see https://theme-ui.com/components/aspect-ratio |
| 305 | + */ |
| 306 | +export const AspectRatio: ForwardRef<HTMLDivElement, AspectRatioProps> |
| 307 | + |
| 308 | +export interface AspectImageProps extends ImageProps { |
| 309 | + ratio?: number |
| 310 | +} |
| 311 | +/** |
| 312 | + * Image component constrained by as aspect ratio. |
| 313 | + * @see https://theme-ui.com/components/aspect-image |
| 314 | + */ |
| 315 | +export const AspectImage: ForwardRef<HTMLImageElement, AspectImageProps> |
| 316 | + |
| 317 | +export type ContainerProps = BoxProps |
| 318 | +/** |
| 319 | + * Centered, max-width layout component |
| 320 | + * |
| 321 | + * Container variants can be defined in the `theme.layout` object. |
| 322 | + * The Container component uses `theme.layout.container` as its default variant style. |
| 323 | + * @see https://theme-ui.com/components/container |
| 324 | + */ |
| 325 | +export const Container: ForwardRef<HTMLDivElement, ContainerProps> |
| 326 | + |
| 327 | +export type NavLinkProps = LinkProps |
| 328 | +/** |
| 329 | + * Link component for use in navigation |
| 330 | + * |
| 331 | + * NavLink variants can be defined in the `theme.links` object. |
| 332 | + * By default the NavLink component will use styles defined in `theme.links.nav`. |
| 333 | + * @see https://theme-ui.com/components/nav-link |
| 334 | + */ |
| 335 | +export const NavLink: ForwardRef<HTMLAnchorElement, NavLinkProps> |
| 336 | + |
| 337 | +export type MessageProps = BoxProps |
| 338 | +/** |
| 339 | + * Styled Box component for callouts and inline messages |
| 340 | + * |
| 341 | + * Message variants can be defined in the theme.messages object. |
| 342 | + * @see https://theme-ui.com/components/message |
| 343 | + */ |
| 344 | +export const Message: ForwardRef<HTMLDivElement, MessageProps> |
| 345 | + |
| 346 | +export interface IconButtonProps |
| 347 | + extends Assign<React.ComponentPropsWithRef<'button'>, BoxOwnProps> {} |
| 348 | +/** |
| 349 | + * Transparent button for SVG icons |
| 350 | + * |
| 351 | + * IconButton variants can be defined in the `theme.buttons` object. |
| 352 | + * By default the IconButton component will use styles defined in `theme.buttons.icon`. |
| 353 | + * |
| 354 | + * @see https://theme-ui.com/components/icon-button |
| 355 | + */ |
| 356 | +export const IconButton: ForwardRef<HTMLButtonElement, BoxProps> |
| 357 | + |
| 358 | +export type MenuButtonProps = IconButtonProps |
| 359 | +/** |
| 360 | + * MenuButton variants can be defined in the `theme.buttons` object. |
| 361 | + * By default the MenuButton component will use styles defined in `theme.buttons.menu`. |
| 362 | + * |
| 363 | + * @see https://theme-ui.com/components/menu-button |
| 364 | + */ |
| 365 | +export const MenuButton: ForwardRef<HTMLButtonElement, MenuButtonProps> |
0 commit comments