From 71cf7dc504ba2d0d3e1d307729410bf69bf396e0 Mon Sep 17 00:00:00 2001 From: Erik Stockmeier Date: Thu, 4 Jul 2019 10:55:34 -0400 Subject: [PATCH] wip --- types/theme-ui/index.d.ts | 145 ++++++++++++++----------------- types/theme-ui/package.json | 3 + types/theme-ui/theme-ui-tests.ts | 87 +++++++++++++++++++ 3 files changed, 156 insertions(+), 79 deletions(-) diff --git a/types/theme-ui/index.d.ts b/types/theme-ui/index.d.ts index 2671c6c5c730e3..32d8049da63c5e 100644 --- a/types/theme-ui/index.d.ts +++ b/types/theme-ui/index.d.ts @@ -1,56 +1,60 @@ +// TypeScript Version: 3.1 // Type definitions for theme-ui 0.2 // Project: https://github.com/system-ui/theme-ui#readme // Definitions by: Erik Stockmeier // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped import * as StyledSystem from "styled-system"; -import { SystemStyleObject } from 'styled-system__css'; +import { SystemStyleObject } from '@styled-system/css'; import * as React from "react"; import * as Emotion from "@emotion/core"; import * as CSS from 'csstype'; export {}; -type Omit = Pick>; -export type ObjectOrArray = T[] | { [K: string]: T | ObjectOrArray }; +type Omit = Pick> +type ObjectOrArray = T[] | { [K: string]: T | ObjectOrArray } +type Object = {[k: string]: T | Object} -export interface Theme extends StyledSystem.Theme { - /** Provide a value here to enable color modes */ - initialColorMode?: string; - colors?: StyledSystem.Theme['colors'] & { - /** Body background color */ - background: CSS.ColorProperty; - /** Body foreground color */ - text: CSS.ColorProperty; - /** Primary brand color for links, buttons, etc. */ - primary: CSS.ColorProperty; - /** A secondary brand color for alternative styling */ - secondary: CSS.ColorProperty; - /** A faint color for backgrounds, borders, and accents that do not require high contrast with the background color */ - muted: CSS.ColorProperty; - /** A contrast color for emphasizing UI */ - accent: CSS.ColorProperty; - /** Nested color modes can provide overrides when used in conjunction with `Theme.initialColorMode and `useColorMode()` */ - modes: { - [k: string]: Omit; - }; - }; - - /** - * Styles for elements rendered in MDX can be added to the theme.styles object. - * This is the primary, low-level way to control typographic and other styles in markdown content. - * Styles within this object are processed with @styled-system/css - * and have access to base theme values like colors, fonts, etc. - */ - styles?: { - [k: string]: SystemStyleObject; - }; -} +export const ThemeProvider: typeof Emotion.ThemeContext.Provider; +type SSColors = StyledSystem.Theme["colors"] +type ColorModes = { + [k: string]: Partial> + } -interface Components {} - +// TODO: Are Theme.colors.background, text, etc really required? +export interface Theme extends StyledSystem.Theme { + /** Provide a value here to enable color modes */ + initialColorMode?: string + colors?: {[k: string]: CSS.ColorProperty | ObjectOrArray} & { + /** Body background color */ + background: CSS.ColorProperty + /** Body foreground color */ + text: CSS.ColorProperty + /** Primary brand color for links, buttons, etc. */ + primary: CSS.ColorProperty + /** A secondary brand color for alternative styling */ + secondary: CSS.ColorProperty + /** A faint color for backgrounds, borders, and accents that do not require high contrast with the background color */ + muted: CSS.ColorProperty + /** A contrast color for emphasizing UI */ + accent: CSS.ColorProperty + /** Nested color modes can provide overrides when used in conjunction with `Theme.initialColorMode and `useColorMode()` */ + modes?: ColorModes + } + + /** + * Styles for elements rendered in MDX can be added to the theme.styles object. + * This is the primary, low-level way to control typographic and other styles in markdown content. + * Styles within this object are processed with @styled-system/css + * and have access to base theme values like colors, fonts, etc. + */ + styles?: { + [k: string]: SystemStyleObject + } +} /** * A React renderer with awareness of the `sx` prop. * Requires the [custom @jsx jsx pragma](https://theme-ui.com/sx-prop) declaration @@ -58,57 +62,40 @@ interface Components {} */ export const jsx: typeof React.createElement; -// TODO: Verify -export const ThemeProvider: React.FC<{theme: Theme}> +interface SxProps { + sx: SystemStyleObject; +} + +type SxComponent = React.ComponentClass; +export const Box: SxComponent; +export const Container: SxComponent; +export const Flex: SxComponent; +export const Header: SxComponent; +export const Footer: SxComponent; +export const Layout: SxComponent; +export const Main: SxComponent; +export const Styled: { [k: string]: SxComponent }; + // TODO: ??? maybe this extra type isn't needed? Maybe SystemStyleObject is enough? -/** +/** [this doc from styled-system__css] * The `SystemStyleObject` extends [style props](https://emotion.sh/docs/object-styles) * such that properties that are part of the `Theme` will be transformed to * their corresponding values. Other valid CSS properties are also allowed. * */ -export interface SxObject extends SystemStyleObject {} - -// TODO: Verify -interface ThemeUIContext {theme: Theme, components: Components} - -// TODO: Verify -export const Context: React.Context - -// TODO: Verify -export const useThemeUI: () => typeof React.useContext; +// export interface SxObject extends SystemStyleObject {} -/*~ TODO: There's some nested providers stuff here that makes useColorMode and other things a little harder - * to track down- see src/provider.js - */ -export const useColorMode: (initialMode: string) => [string, (colorMode: string) => void] - -// /*~ If this module has methods, declare them as functions like so. -// */ -// export function myMethod(a: string): string; -// export function myOtherMethod(a: number): number; +// // TODO: Verify +// interface ThemeUIContext {theme: Theme, components: any} -// /*~ You can declare types that are available via importing the module */ -// export interface someType { -// name: string; -// length: number; -// extras?: string[]; -// } +// // TODO: Verify +// export const Context: React.Context -// /*~ You can declare properties of the module using const, let, or var */ -// export const myField: number; +// // TODO: Verify +// export const useThemeUI: () => typeof React.useContext; -// /*~ If there are types, properties, or methods inside dotted names -// *~ of the module, declare them inside a 'namespace'. +// /*~ TODO: There's some nested providers stuff here that makes useColorMode and other things a little harder +// * to track down- see src/provider.js // */ -// export namespace subProp { -// /*~ For example, given this definition, someone could write: -// *~ import { subProp } from 'yourModule'; -// *~ subProp.foo(); -// *~ or -// *~ import * as yourMod from 'yourModule'; -// *~ yourMod.subProp.foo(); -// */ -// function foo(): void; -// } +// export const useColorMode: (initialMode: string) => [string, (colorMode: string) => void] diff --git a/types/theme-ui/package.json b/types/theme-ui/package.json index 208aa420357d4d..99b2887160b916 100644 --- a/types/theme-ui/package.json +++ b/types/theme-ui/package.json @@ -1,7 +1,10 @@ { + "version": "0.2.0", + "name": "@types/theme-ui", "private": true, "dependencies": { "@emotion/core": "^10.0.14", + "@types/styled-system__css": "^5.0.0", "csstype": "^2.6.5" } } diff --git a/types/theme-ui/theme-ui-tests.ts b/types/theme-ui/theme-ui-tests.ts index e69de29bb2d1d6..e9211cc0105f7d 100644 --- a/types/theme-ui/theme-ui-tests.ts +++ b/types/theme-ui/theme-ui-tests.ts @@ -0,0 +1,87 @@ +import * as React from 'react'; +import { ThemeProvider, Theme, jsx, Box } from 'theme-ui'; + + +// Test the `Theme` validates as per the Theme Spec: +// https://styled-system.com/theme-specification +// https://system-ui.com/theme/ +export const themeA: Theme = { + borders: ['1px solid red', '2px solid red'], + borderStyles: { + primary: { + border: '3px solid red', + }, + disabled: { + border: '1px solid gray', + }, + }, + borderWidths: [0, 1, 3], + buttons: { + primary: { + color: 'blue', + }, + danger: { + color: 'red', + }, + }, + breakpoints: ['40em', '52em', '64em'], + colors: { + black: 'hsl(0, 0%, 0%)', + background: 'red', + text: 'black', + primary: 'red', + secondary: 'black', + muted: '#fff', + accent: '#000', + blacks: ['hsla(0, 0%, 0%, .9)', 'hsla(0, 0%, 0%, .1)'], + }, + colorStyles: { + warning: { + color: 'black', + backgroundColor: 'orange', + }, + }, + fonts: { + normal: 'apple-system, BlinkMacSystemFont, sans-serif', + mono: 'Consolas, Courier, monospace', + }, + fontWeights: [100, 400, 700], + fontSizes: [12, 14, 16], + heights: [0, '50vh', '100vh'], + letterSpacings: [-1, 1, 3], + lineHeights: [1, 1.25, 2], + maxHeights: ['50vh', '100vh'], + maxWidths: ['50%', '100%'], + minHeights: ['50vh', '100vh'], + minWidths: ['50%', '100%'], + opacity: [0, 0.25, 0.5, 0.75], + radii: [0, 3, 9], + shadows: ['1 1 3px -1 gray', '1 2 6px -1 gray'], + sizes: [0, '33%', '50%', '100%'], + space: [12, 14, 16], + textStyles: { + caps: { + textTransform: 'uppercase', + letterSpacing: '0.2em', + }, + }, + zIndices: [-1, 0, 1, 9999], +}; + +// Some properties can be formatted differently +export const themeB: Theme = { + space: ['12px', '14px', '16px'], + fontSizes: ['12px', '14px', '16px'], + lineHeights: ['14px', '14.5px', '16.5px'], +}; + +export const themeC: Theme = { + space: { + small: 12, + medium: '14px', + }, + fontSizes: { + small: 12, + medium: '14px', + }, +};