Skip to content

Add TypeScript components generation support. - #1956

Merged
alexcjohnson merged 13 commits into
devfrom
typescript-component-generator
Apr 27, 2022
Merged

alexcjohnson merged 13 commits into
devfrom
typescript-component-generator

Conversation

@T4rk1n

@T4rk1n T4rk1n commented Mar 3, 2022 •

Copy link
Copy Markdown
Contributor

Add typescript component support for Dash components, custom replacement for react-docgen.

Use with dash-generate-components CLI.

Requires npm modules installed as devDependencies:

  • typescript

Contributor Checklist

  • I have run the tests locally and they passed. (refer to testing section in contributing)
  • I have added tests, or extended existing tests, to cover any new features or bugs fixed in this PR

optionals

@T4rk1n
T4rk1n requested a review from alexcjohnson as a code owner March 3, 2022 17:03
@T4rk1n
T4rk1n force-pushed the typescript-component-generator branch 8 times, most recently from 8d4f7f4 to 8d520b1 Compare March 7, 2022 14:31
@T4rk1n

T4rk1n commented Mar 7, 2022

Copy link
Copy Markdown
Contributor Author

@alexcjohnson Ready for review, thank you.

@T4rk1n
T4rk1n force-pushed the typescript-component-generator branch 2 times, most recently from 6210fd4 to a4fca7d Compare March 8, 2022 16:48
@T4rk1n

T4rk1n commented Mar 8, 2022 •

Copy link
Copy Markdown
Contributor Author

Component template: https://github.com/T4rk1n/dash-typescript-component-template

It install Dash from this PR, there's an issue with the setup and the installation is not complete but it generates the component.

@T4rk1n
T4rk1n force-pushed the typescript-component-generator branch from 33a4726 to c4ff36b Compare March 18, 2022 20:52
@snehilvj

Copy link
Copy Markdown

I want to refactor the dash-mantine-components library with typescript support. Is there any estimate as to when this will be merged into dev?

@T4rk1n

T4rk1n commented Mar 22, 2022

Copy link
Copy Markdown
Contributor Author

@snehilvj

The current solution requires that all components in a package are in TypeScript, we would like to more easily migrate existing libraries by combining the extract-meta script with the new ts compiler for .tsx files only. I am working on that and then I think it's good.

@T4rk1n
T4rk1n force-pushed the typescript-component-generator branch from c4ff36b to f3f0da3 Compare March 25, 2022 14:52
@snehilvj

Copy link
Copy Markdown

@T4rk1n I had one more request. Will this change support imported prop types? So for example many a times react components accept common props such as style, class_name, padding props (p, px, py, pr, pt, etc.), margin props (m, mx, my, etc). It would be nice if these props can be defined in one module and imported in all the components.

@T4rk1n

T4rk1n commented Mar 25, 2022 •

Copy link
Copy Markdown
Contributor Author

@snehilvj
The generator will work with imported types from local files and libraries, you don't have to define the props in the component file. I would recommend against using local .d.ts files for the prop types as editors will include them without exports but the compiler will not pick them if the file is not imported in the component files.

You can use all the typescript type utilities to combine & manipulate the prop types. Like if you want to wrap the props of an html element but remove the onEvent props and other props that are not json compatible, you can do something like this for an audio component wrapper:

./src/props.ts

import React from 'react'

export type DashComponentProps = {
    /**
     * Unique ID to identify this component in Dash callbacks.
     */
    id?: string;
    /**
     * Update props to trigger callbacks.
     */
    setProps: (props: Record<string, any>) => void;
}

type InvalidHtmlProps =
    | 'dangerouslySetInnerHTML'
    | 'defaultChecked'
    | 'defaultValue'
    | 'suppressContentEditableWarning'
    | 'suppressHydrationWarning'
    | 'ref'
    | 'key'
    | 'async';

type EventsProps = keyof Omit<React.DOMAttributes<any>, 'children'>;
type AriaProps = keyof React.AriaAttributes;
export type HtmlOmittedProps = InvalidHtmlProps | EventsProps | AriaProps;

type SourceProps = Omit<React.SourceHTMLAttributes<any>, HtmlOmittedProps>;

export type AudioProps = Omit<React.AudioHTMLAttributes<any>, HtmlOmittedProps> & Partial<{
    sources: JSX.Element[] | SourceProps[];
    /**
     * Set to true to play the audio source.
     */
    play: boolean;
    status: 'playing' | 'paused' | 'stopped';
    /**
     * READONLY: true when the audio can be played.
     */
    can_play: boolean;
    /**
     * READONLY: true when the audio has been download completely.
     */
    can_play_through: boolean;
}> & DashComponentProps;

Then import it in the component:

./src/components/Audio.tsx

import React from 'react'
import { AudioProps } from '../props';


const Audio = (props: AudioProps) => {
    // Remove the custom props & keep the rest to give to the html component.
    const { sources, play, status, can_play, can_play_throught, setProps, ...audioProps } = props;
    return (
        <audio {...audioProps}>
            // ...
        </audio>
    )
}

export default Audio;

@snehilvj

Copy link
Copy Markdown

You made me cry. 😭 Thanks for all the efforts @T4rk1n.

@rohitranjan017

Copy link
Copy Markdown

@T4rk1n , I tried using https://github.com/T4rk1n/dash-typescript-component-template but, it is not generating the python class file in the example_component directory. How can I run the python-dash app with the typescript component?

@rohitranjan017

Copy link
Copy Markdown

I realized that the metadata.json file is empty and hence the python class is not being generate? @T4rk1n , could you please comment on this?

@T4rk1n
T4rk1n force-pushed the typescript-component-generator branch from 824afde to 033a4dd Compare April 7, 2022 13:42
@T4rk1n

T4rk1n commented Apr 7, 2022

Copy link
Copy Markdown
Contributor Author

@rohitranjan017 There were a few errors in the template because it was not up to date with the latest development here. I updated the template and this branch, should work now if you generate again from the template.

@T4rk1n
T4rk1n force-pushed the typescript-component-generator branch from 033a4dd to 36ef5d2 Compare April 20, 2022 18:27
Comment thread dash/development/_py_components_generation.py
Comment thread dash/extract-meta.js
Comment thread dash/extract-meta.js Outdated
@T4rk1n
T4rk1n force-pushed the typescript-component-generator branch from 70b99ae to efb54ce Compare April 25, 2022 14:14
@alexcjohnson

Copy link
Copy Markdown
Collaborator

@T4rk1n this is looking great! My only real questions about it are about how folks will learn to use it:

  • Are you still thinking of merging your template into the main dash-component-boilerplate as an option?
  • What if someone using the JS build pipeline wants to add a TS component to their package? What instructions can we give them? Is it sufficient to say something like "add this tsconfig file, add these deps to your package.json, and modify your webpack config like this"?

@T4rk1n

T4rk1n commented Apr 26, 2022

Copy link
Copy Markdown
Contributor Author

Are you still thinking of merging your template into the main dash-component-boilerplate as an option?

I think for now I'd like to keep them separated, the original boilerplate has more stuff in it and the component it generates is a class component while the new template is structured differently and generates a functional component.

@alexcjohnson alexcjohnson left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

💃 Excellent work!

I think for now I'd like to keep them separated, the original boilerplate has more stuff in it and the component it generates is a class component while the new template is structured differently and generates a functional component.

We don't need to deal with this before merging this PR, but if the original has unnecessary things in it or is out-of-date we should update it. I think it would be a mistake to split component creation into two different cookiecutters, because it would give people a false impression that JS/TS is a difficult transition, also it'd be more for us to maintain and more for users to learn about.

@T4rk1n
T4rk1n force-pushed the typescript-component-generator branch from 5769545 to c469c72 Compare April 27, 2022 13:19
@T4rk1n
T4rk1n force-pushed the typescript-component-generator branch from c469c72 to de009db Compare April 27, 2022 13:40
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.

4 participants