-
Notifications
You must be signed in to change notification settings - Fork 671
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Typescript support #121
Comments
i'd like to help with this as i'm having an issue with no type definitions. I've bodge a fix locally but adding an |
I think we'd be open to add definition files for TS, if anyone wants to start a small PR for the core package. A rewrite is probably out of scope for the time being, but we'd like to make sure this works well for TS users generally |
Also happy to help start on type definitions! |
I started on something here. PRs or help welcome- I've never contributed to DT before. |
@erikdstock I can help you to get your first PR through to DT, if you like! 🙂 Can you make a PR against your own repo to open the code for comments? here are some quick remarks:
Emotion definitions: declare module 'react' {
interface DOMAttributes<T> {
css?: InterpolationWithTheme<any>
}
}
declare global {
namespace JSX {
/**
* Do we need to modify `LibraryManagedAttributes` too,
* to make `className` props optional when `css` props is specified?
*/
interface IntrinsicAttributes {
css?: InterpolationWithTheme<any>
}
}
} |
Thanks @sebald - On advice from a friend who has written lots of types I'd moved from working on these in pure theory in the DT repo to actually beginning to use them in a project (or rather, attempting a migration from Edit: by supporting the export const jsx: typeof React.createElement
interface SxProps {
sx: SystemStyleObject
}
type SxComponent = React.ComponentClass<SxProps>
export const Box: SxComponent
export const Container: SxComponent
export const Flex: SxComponent
export const Header: SxComponent
export const Styled: { [k: string]: SxComponent } |
Not that I know of. Which is actually kinda annoying. I am currently working on a code base using emotion and the |
Alright, I've got a start here. |
Hi @erikdstock 👋 Would be super cool to have the types! Anything we can do to help you? |
Hi @LekoArts - I'd love to keep working on this but got sidetracked as I didn't have an immediate use case for theme-ui. Is there a way we could collaborate on this through the branch I started and then submit it as one PR? I've never added a package to DT before so don't know how to determine when it is 'done.' |
I never added a package to DT, too! Maybe also @sebald , @IniZio or @PaulieScanlon can help with that – together we should be able to get this shipped 💪 |
Activating the bat signal on Twitter sounds like a good idea. |
I could stand up a simple hello world gatsby site, which we'd add types to through real use (filling the site with nonsense), and then we could move the typings into a @types pr. This was based on some advice I got early on that it's best to add types through real use than simply trying to catalog them. |
@erikdstock I really hope this doesn't step on any toes, but I was in urgent need of yarn add @types/theme-ui Since most of it was your work your name is down as the main contributor. I've got a few other types for the other libraries and I may not get around to doing a PR for them for a few days at least. If anyone wants to use them as a starting point or create a PR please feel free. Code is available here. |
I personally think that's really cool, thanks for writing the definitions. I'd say: Let's just try the package and see if we encounter issues. What is still missing in the definitions in your opinion @ifiokjr ? Anyone interested in putting this information into the docs? |
@LekoArts we should add a Also right now the code supports nested tags: const Success = () => (
<div
sx={{
'body > div': {
':hover': {
color: 'red',
},
},
}}
/>
); But not when the nested tag is within a media query: const Failure = () => (
<div
sx={{
'@media only screen and (max-width: 600px)': {
'body > div': {
':hover': {
color: 'red',
},
},
},
}}
/>
); |
Hi and thank you @ifiokjr! not stepping on my toes at all, it was a side project that I couldn't follow through with- but i'll be happy to help maintain in the future. Glad my start was of some help. |
Hey @ifiokjr, thanks for the types! It's working pretty well but I found some parts that are either not implemented yet or I didn't figure out how to use them. Can I use the ColorMode and InitializeColorMode components? I had to do this little trick to make it work: import * as themeUi from 'theme-ui'
const _ColorMode = require('theme-ui').ColorMode
const _InitializeColorMode = require('theme-ui').InitializeColorMode
declare module 'theme-ui' {
export const ColorMode = _ColorMode
export const InitializeColorMode = _InitializeColorMode
} I also can't seem to make <Styled.a href="/">Test</Styled.a> Generates the following error: Property 'href' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<SxProps, any, any>> & Readonly & Readonly<{ children?: ReactNode; }>'. Is there anyway to make this work? |
@sleepyfran I've added a PR here DefinitelyTyped/DefinitelyTyped#37578 Test it out by copying the file contents from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d2f29c7d1eae3eee7a33b94cd6147a5c7aee95cd/types/theme-ui/index.d.ts into declare module 'theme-ui' {
// New declaration here
} and remove the current |
Wow, that was fast, thanks @ifiokjr! Just checked it with the revision and it's working perfectly. |
Theme.colors.modes, ColorModes, doesn't appear to be typed correctly. I'm getting an error when trying to define my different theme.colors.modes. Shouldn't the ColorModes would something like this work?
|
@sbardian (& everyone else)- as this issue is now technically resolved with the addition of That said I do think you are right @sbardian - would you be able to make a PR? |
Will do! thanks @erikdstock |
Fantastic @ifiokjr . I had the same issue, installed the |
@sbardian @erikdstock Hey guys, thanks so much for the theme-ui typings. I've got a quick question... Right now, I'm able to use the /** @jsx jsx */
import { Button as BlueprintButton, IButtonProps } from '@blueprintjs/core';
import { ButtonHTMLAttributes, FunctionComponent } from 'react';
import { jsx } from 'theme-ui';
export const Button: FunctionComponent<IButtonProps & ButtonHTMLAttributes<HTMLButtonElement>> = props => (
<BlueprintButton
{...props}
sx={{
lineHeight: '1em',
boxSizing: 'border-box',
boxShadow: 'unset',
backgroundImage: 'none',
variant: `buttons.${props.intent}.default`,
'&:active, &:focus': {
variant: `buttons.${props.intent}.active`,
outline: 'none',
},
'&:hover': {
variant: `buttons.${props.intent}.hover`,
},
}}
/>
); Any thoughts on what might be going on? |
@jonavila I chased that down at one point a while ago and discovered it's not limited to theme-ui or sx, it's an issue with Emotion's object styles, too. If I remember right, emotion-js/emotion#1267 is what's up. TL;DR: it currently accepts any string to allow for nested selectors. |
@jonavila @wKovacs64 would it be advisable to narrow the type for the sx prop? I recently made my own library inspired by |
@erikdstock That seems to work better, but maybe with the caveat that you can't type check when nesting more than one level deep? Also, unrelated but missing in the types is the I'll create an issue in DefinitelyTyped |
Using |
Some fixes were mentioned here, some in the recently closed issues. It would be awesome if those would get PR'ed upstream to DefinitelyTyped so that everyone can benefit from them :) Like |
There's a bunch of changes in v0.3 (https://theme-ui.com/migrating). Since tracking issues in DT may be a bit cumbersome, we could try to list needed changes here alongside problems @LekoArts mentioned. An incomplete list of current issues I know about. Ping me or copy-paste it to add more?
BTW @jxnblk, I do realize I may sound like a door-to-door salesman (or like this), but would you be open to adopt TypeScript in simpler packages in the monorepo? @theme-ui/preset-future is a good example.
I'd be happy to help. |
There's no "question" issue template, so I'll ask it here, because it's a bit connected. Are get and merge public API? They're mentioned in the docs, but they're described as used internally. |
@hasparus Could you add
|
I’ve been thinking about it, @isBatak. Are you using this in an app, or building a library? |
I'm using it for Maybe you could add a doc comment above those props:
|
Isn’t what you’re doing possible with jsx pragma or spreading received sx prop? |
yes, it is... I'm doing that in higher-order components, spreading |
Would it be okay for you to wait for more input on this? I'd use an assertion and lock the version of theme-ui if I were you. I can think of few reasons not to include
I am not super strongly opposed to the idea. I'd just try to avoid doing it. |
I could leave without I found another problem...
I get this TS error:
It seems like Also, it would be cool if we could do this
...and get correct typings for |
FWIW The
|
I am not sure Reakit has correctly typed
Andrew Branch from TypeScript team has a nice blogpost about it: https://blog.andrewbran.ch/polymorphic-react-components/ color problemBoxOwnProps extends SpaceProps and ColorProps, but it has nothing to do with BoxProps adds ComponentProps<"div">. export interface BoxProps extends Assign<React.ComponentProps<'div'>, BoxOwnProps> Notice that your error persists if you change IHeaderProps to ColorBoxProps export interface ColorBoxProps {
color: object;
} Changing BoxOwnProps to BoxProps should fix it for you. export interface IHeaderProps extends BoxProps {
title?: string;
}
export const Header = forwardRef<HTMLDivElement, BoxProps>(({ title, sx, ...rest }, ref) => {
return (
<Flex
ref={ref}
sx={{ alignItems: 'center', px: 7, pt: 5, pb: '12px', borderBottom: '1px solid', ...sx }}
{...rest}
/>
);
}); |
As of pseudocode: import { css, get } from '@theme-ui/css'
const myVariant = ({ theme, variant, __myThemeKey }) =>
css(get(theme, __myThemeKey + '.' + variant, get(theme, variant))) It would still work when @jxnblk removes or renames |
@isBatak Not sure if it will help you, but instead of example componentimport { Link as BaseLink, LinkProps as BaseLinkProps } from 'my-router-of-choice';
export interface LinkProps extends BaseLinkProps {
variant?: "button";
}
export const Link = ({ variant, ...rest }: LinkProps) => {
const { theme } = useThemeUI();
const variantStyles = variant === "button" ? theme.buttons.primary : {};
return <BaseLink sx={variantStyles} {...rest} />;
}; theme.tsxdeclare module "theme-ui" {
export interface Theme {
useCustomProperties?: boolean;
forms: {
textarea: themeUi.SxStyleProp;
};
}
// app-level code: narrow the type of value returned from context to
// exactly my theme shape
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export function useThemeUI(): { theme: typeof theme };
}
const makeTheme = <T extends themeUi.Theme>(t: T): T => t;
export const theme = makeTheme({
// redacted
buttons: {
primary: {
// redacted
},
}); |
@hasparus thx for everything :D And @jxnblk thx for clearing out things with |
@hasparus The current types have the following:
For whatever reason in my environment, the
This is what styled-components do for their typing of the Thoughts? |
Is it worth adding types to DefinitelyTyped for Since it's a wrapper around Polished I was able to get it working by adding this to my local definitions file.
|
It is certainly not needed for savvy TypeScript users, @allanpope :) |
hey @jonavila 👋 I took a quick look at it to figure out why it's done this way. I think theme-ui JSX handling is inspired by what emotion does. Merging We add this prop to the first parameter of React.createElement and it just won't be handled. export const jsx: typeof React.createElement; So this is why adding I think we could go two ways:
I think this is connected with #633 and a quick description how to tell TypeScript about your JSX pragma (regardless of framework) could be a nice addition to the README (some day?). |
Good point on Automatic Type Acquisition @hasparus I've made a pr for @theme-ui/color. Turns out a few of the Polished JS functions were renamed in Theme UI, so was worth doing. |
👋 We are working on converting the entire theme-ui codebase to TypeScript and automatically generating the typedefs from the code to make TypeScript support a first-class citizen. Thanks to your excellent typedefs in DefinitelyTyped, this is turning out to be much simpler than I thought! 💯 We would love to have some more 👀 from y'all with way more TypeScript experience here: #662 (comment) The plan is to ship the conversion of the |
The initial spike #662 was merged! 🎉 We would love your help to convert the codebase to TypeScript, so I opened up a coordination issue: #668 Please chime in there if you have some time to spare to convert some packages 🙏 I am going to close this issue now. Thank so much to all of you for working on this since the initial release, we can't wait to ship first class TypeScript support now 💜 |
@jxnblk Is it possible to add a |
I used rebass before and really like this new idea, especially since it allows even more flexibility.
Not sure if you prefer adding definition files only or refactoring into typescript? I can make pr for either approach 🤔
The text was updated successfully, but these errors were encountered: