Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike out potential TypeScript conversion #662

Merged
merged 9 commits into from
Feb 14, 2020
Merged

Spike out potential TypeScript conversion #662

merged 9 commits into from
Feb 14, 2020

Conversation

mxstbr
Copy link
Member

@mxstbr mxstbr commented Feb 10, 2020

This "reworks" @theme-ui/core to be written in TypeScript and export its own type definitions. Thankfully, microbundle has built-in support for TypeScript so we barely need to do any build system changes. I also checked in the generated index.d.ts file (normally we would not check this into git) to show what it looks like.

cc @hasparus the DefinitelyTyped maintainer for the theme-ui types. No action items right now, just wanted you to be aware of this effort 馃槈

This "reworks" `@theme-ui/core` to be written in TypeScript and export
its own type definitions.  Thankfully, `microbundle` has built-in support
for TypeScript so we barely need to do any build system changes. I also
checked in the generated `index.d.ts` file (normally we would not check
this into git) to show what it looks like.
@hasparus hasparus mentioned this pull request Feb 13, 2020
@mxstbr
Copy link
Member Author

mxstbr commented Feb 13, 2020

Here's where I am at: the core package is now written entirely in TypeScript, and generates a typedef file in the build process that (roughly) looks like the one that is in DefinitelyTyped right now, mostly because I copied all the custom types from there 馃槄

import React from 'react';
import { Theme } from './theme';
export declare const jsx: typeof React.createElement;
export declare const Context: React.Context<{
__EMOTION_VERSION__: string;
theme: Theme;
}>;
export declare const useThemeUI: () => {
__EMOTION_VERSION__: string;
theme: Theme;
};
export declare const merge: {
(a: any, b: any): unknown;
all(...args: any[]): object;
};
export interface ThemeProviderProps {
theme: Partial<Theme> | ((outerTheme: Theme) => Theme);
children?: React.ReactNode;
}
export declare function ThemeProvider({ theme, children }: ThemeProviderProps): React.FunctionComponentElement<{
context: any;
children: any;
}>;

/// <reference types="react" />
import * as CSS from 'csstype';
import { SystemStyleObject } from '@styled-system/css';
import { Theme as StyledSystemTheme } from 'styled-system';
/**
* The `sx` prop accepts a `SxStyleProp` object and properties that are part of
* the `Theme` will be transformed to their corresponding values. Other valid
* CSS properties are also allowed.
*/
export declare type SxStyleProp = SystemStyleObject;
export interface SxProps {
/**
* The sx prop lets you style elements inline, using values from your
* theme. To use the sx prop, add the custom pragma as a comment to the
* top of your module and import the jsx function.
*
* ```ts
* // @jsx jsx
*
* import { jsx } from 'theme-ui'
* ```
*/
sx?: SxStyleProp;
}
export interface IntrinsicSxElements {
p: JSX.IntrinsicElements['p'] & SxProps;
b: JSX.IntrinsicElements['b'] & SxProps;
i: JSX.IntrinsicElements['i'] & SxProps;
a: JSX.IntrinsicElements['a'] & SxProps;
h1: JSX.IntrinsicElements['h1'] & SxProps;
h2: JSX.IntrinsicElements['h2'] & SxProps;
h3: JSX.IntrinsicElements['h3'] & SxProps;
h4: JSX.IntrinsicElements['h4'] & SxProps;
h5: JSX.IntrinsicElements['h5'] & SxProps;
h6: JSX.IntrinsicElements['h6'] & SxProps;
img: JSX.IntrinsicElements['img'] & SxProps;
pre: JSX.IntrinsicElements['pre'] & SxProps;
code: JSX.IntrinsicElements['code'] & SxProps;
ol: JSX.IntrinsicElements['ol'] & SxProps;
ul: JSX.IntrinsicElements['ul'] & SxProps;
li: JSX.IntrinsicElements['li'] & SxProps;
blockquote: JSX.IntrinsicElements['blockquote'] & SxProps;
hr: JSX.IntrinsicElements['hr'] & SxProps;
table: JSX.IntrinsicElements['table'] & SxProps;
tr: JSX.IntrinsicElements['tr'] & SxProps;
th: JSX.IntrinsicElements['th'] & SxProps;
td: JSX.IntrinsicElements['td'] & SxProps;
em: JSX.IntrinsicElements['em'] & SxProps;
strong: JSX.IntrinsicElements['strong'] & SxProps;
div: JSX.IntrinsicElements['div'] & SxProps;
delete: JSX.IntrinsicElements['div'] & SxProps;
inlineCode: JSX.IntrinsicElements['div'] & SxProps;
thematicBreak: JSX.IntrinsicElements['div'] & SxProps;
root: JSX.IntrinsicElements['div'] & SxProps;
}
declare type ObjectOrArray<T> = T[] | {
[K: string]: T | ObjectOrArray<T>;
};
declare type StyledTags = keyof IntrinsicSxElements;
/**
* To use Theme UI color modes, color scales should include at least a text
* and background color. These values are used in the ColorMode component to
* set body foreground and background colors. Color modes should be defined as
* nested objects within a theme.colors.modes object. Each key in this object
* should correspond to a color mode name, where the name can be anything, but
* typically light and dark are used for applications with a dark mode. The
* initialColorModeName key is required to enable color modes and will be used as
* the name for the root color palette.
*/
export declare type ColorMode = {
[k: string]: CSS.ColorProperty | ObjectOrArray<CSS.ColorProperty>;
} & {
/**
* 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;
};
export interface Theme extends Omit<StyledSystemTheme, 'colors'> {
/**
* Enable/disable custom CSS properties/variables if lower browser
* support is required (for eg. IE 11).
*
* References: https://theme-ui.com/color-modes/#turn-off-custom-properties
*/
useCustomProperties?: boolean;
/**
* Provide a value here to enable color modes
*/
initialColorModeName?: string;
/**
* Define the colors that are available through this theme
*/
colors?: ColorMode & {
/**
* Nested color modes can provide overrides when used in conjunction with
* `Theme.initialColorModeName and `useColorMode()`
*/
modes?: {
[k: string]: ColorMode;
};
};
/**
* 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?: {
[P in StyledTags]?: SystemStyleObject;
};
}
export {};

@hasparus does this look okay-ish to you, both the types and the general build process of how this works (automatically)? Any thoughts/feedback?

Once we are happy with where the types & the build process are at, then we ship this conversion and start tackling the other packages from there. I will be opening a planning issue with a clear outline what needs to be converted so all the contributors can help with this 馃檹

@mxstbr mxstbr requested a review from jxnblk February 13, 2020 19:48
@@ -0,0 +1,143 @@
import * as CSS from 'csstype'
import { SystemStyleObject } from '@styled-system/css'
import { Theme as StyledSystemTheme } from 'styled-system'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing the plan is to eventually have the entire Theme interface defined in this repo, right?

Copy link
Member

@hasparus hasparus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hasparus does this look okay-ish to you, both the types and the general build process of how this works (automatically)? Any thoughts/feedback?

Wow. Hello, imposter syndrome, my old friend.

It looks great! I've left 3 notes for the future.


BTW This is super weird that I can post a review to a repo where I'm not a contributor.

packages/core/package.json Show resolved Hide resolved
packages/core/src/index.ts Outdated Show resolved Hide resolved
@@ -28,10 +31,13 @@ const parseProps = props => {
return next
}

export const jsx = (type, props, ...children) =>
export const jsx: typeof React.createElement = (type, props, ...children) =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although it isn't 100% correct (jsx handles sx and css props, createElement doesn't), focusing on this now would be bikeshedding.

Copy link
Member Author

@mxstbr mxstbr Feb 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to start submitting PRs to clean this up too 馃槈

hasparus and others added 2 commits February 14, 2020 10:00
@mxstbr mxstbr merged commit 3525f07 into master Feb 14, 2020
@mxstbr mxstbr deleted the typescript-spike branch February 14, 2020 18:55
@mxstbr mxstbr mentioned this pull request Feb 14, 2020
32 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants