diff --git a/package.json b/package.json index 5a9f1b5..ec502c2 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "react-dom": "^16.13.1", "react-scripts": "^3.4.1", "reakit": "^1.1.2", + "reakit-utils": "^0.13.1", "theme-ui": "^0.3.1", "ts-loader": "^8.0.1", "tsdx": "^0.13.2", diff --git a/src/Button.stories.tsx b/src/Button.stories.tsx index 8e79f77..b0468fb 100644 --- a/src/Button.stories.tsx +++ b/src/Button.stories.tsx @@ -1,8 +1,7 @@ -import React from 'react' +import React, { useReducer, useRef, useEffect, forwardRef, Ref } from 'react' import { ThemeProvider } from 'theme-ui' import { withA11y } from '@storybook/addon-a11y' import { withKnobs, text, color, boolean } from '@storybook/addon-knobs' -import { Checkbox, useCheckboxState } from 'reakit' import Button from '.' @@ -46,8 +45,55 @@ export function TheSXProp() { ) } -export function TheAsProp() { - const checkbox = useCheckboxState() +export function TheAsPropWithIntrinsicElement() { + const ref = useRef(null) + const [checked, toggle] = useReducer((value) => !value, false) + + useEffect(() => { + console.warn( + `TheAsPropWithIntrinsicElement: Detects properly type of \`ref\` from \`as\``, + ref.current + ) + }, []) + + return ( + + + + ) +} + +const Link = forwardRef(function Link( + { children, ...props }: JSX.IntrinsicElements['a'], + ref: Ref +) { + return ( + + {children} + + ) +}) + +export function TheAsPropWithCustomElement() { + const ref = useRef(null) + const [checked, toggle] = useReducer((value) => !value, false) + + useEffect(() => { + console.warn( + `TheAsPropWithCustomElement: Detects properly type of \`ref\` from \`as\``, + ref.current + ) + }, []) return ( - - {checkbox.state ? '😄 Happy' : '😞 Sad'} - + ) } diff --git a/src/index.tsx b/src/index.tsx index 14b8276..297db2e 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,12 +4,17 @@ import { Button as ThemeAwareButton, ButtonProps as ThemeAwareProps, } from 'theme-ui' +import { As, Props, Component } from '@vtex-components/types' -type Props = A11yProps & ThemeAwareProps +type ButtonProps = Props -function Button({ as, ...props }: Props, ref: Ref) { - return +const Button = ( + { as = ThemeAwareButton, ...props }: ButtonProps, + ref: Ref +) => { + return } -export { A11yProps, ThemeAwareProps } -export default forwardRef(Button) +export { ButtonProps, A11yProps, ThemeAwareProps } + +export default forwardRef(Button) as Component diff --git a/src/typings.d.ts b/src/typings.d.ts index e3ec8c5..f9abb28 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -15,3 +15,27 @@ declare module '*.svg' { export default svgUrl export { svgComponent as ReactComponent } } + +declare module '@vtex-components/types' { + import { PropsWithoutRef } from 'react' + import { As, PropsWithAs } from 'reakit-utils/types' + + export { As } + + export type Props = PropsWithAs< + PropsWithoutRef, + T + > + + export type AsOf = T extends Props ? TAs : never + + export type BasePropsOf = T extends Props + ? TProps + : never + + export type Component> = { + >( + props: Props> + ): JSX.Element + } +}