diff --git a/core/docz-theme-default/src/components/ui/Props.tsx b/core/docz-theme-default/src/components/ui/Props/PropsRaw.tsx similarity index 86% rename from core/docz-theme-default/src/components/ui/Props.tsx rename to core/docz-theme-default/src/components/ui/Props/PropsRaw.tsx index fd77b47f6..f8653df62 100644 --- a/core/docz-theme-default/src/components/ui/Props.tsx +++ b/core/docz-theme-default/src/components/ui/Props/PropsRaw.tsx @@ -16,11 +16,11 @@ const Wrapper = styled.div` const Title = styled.div` display: flex; - border-bottom: 1px solid ${get('colors.sidebarBg')}; + border-bottom: 1px solid ${get('colors.propsBg')}; ` const PropName = styled.span` - background: ${get('colors.sidebarBg')}; + background: ${get('colors.propsBg')}; color: ${get('colors.primary')}; padding: 5px 10px; border-radius: 4px 4px 0 0; @@ -33,8 +33,8 @@ const PropName = styled.span` ` const PropType = styled(PropName)` - color: ${get('colors.blockquoteColor')}; - background: ${get('colors.sidebarBg')}; + color: ${get('colors.propsText')}; + background: ${get('colors.propsBg')}; font-weight: 400; ` @@ -48,11 +48,10 @@ const PropRequired = styled(PropType)` flex: 1; text-align: right; background: transparent; - color: ${get('colors.blockquoteColor')}; opacity: 0.5; ` -export const Props: React.SFC = ({ +export const PropsRaw: React.SFC = ({ props, getPropType, }) => { @@ -61,7 +60,7 @@ export const Props: React.SFC = ({ const Paragraph = useMemo( () => styled(components.P || 'p')` font-size: 16px; - color: ${get('colors.sidebarTex')}; + color: ${get('colors.sidebarText')}; `, [] ) diff --git a/core/docz-theme-default/src/components/ui/Props/PropsTable.tsx b/core/docz-theme-default/src/components/ui/Props/PropsTable.tsx new file mode 100644 index 000000000..70804c34c --- /dev/null +++ b/core/docz-theme-default/src/components/ui/Props/PropsTable.tsx @@ -0,0 +1,148 @@ +import * as React from 'react' +import { useMemo } from 'react' +import { PropsComponentProps, useComponents } from 'docz' +import styled from 'styled-components' + +import { get } from '@utils/theme' + +const breakpoint = '600px' + +const Container = styled.div` + border: 1px solid ${get('colors.border')}; + border-radius: 4px; + overflow: hidden; + background: ${get('colors.propsBg')}; + color: ${get('colors.propsText')}; +` + +const Line = styled.div` + padding: 8px 0; + + @media (min-width: ${breakpoint}) { + padding: O; + } + + & + & { + border-top: 1px solid ${get('colors.border')}; + } +` + + +const Column = styled.div` + min-width: 0; + padding: 2px 15px; + word-wrap: break-word; + + @media (min-width: ${breakpoint}) { + padding: 8px 15px; + } +` + +const ColumnName = styled(Column)` + @media (min-width: ${breakpoint}) { + flex-basis: 25%; + } +` + +const ColumnType = styled(Column)` + @media (min-width: ${breakpoint}) { + flex-basis: 50%; + } +` + +const ColumnValue = styled(Column)` + @media (min-width: ${breakpoint}) { + flex-basis: 25%; + } +` + +const Content = styled.div` + display: flex; + flex-direction: column; + font-family: ${get('fonts.mono')}; + + @media (min-width: ${breakpoint}) { + flex-wrap: nowrap; + flex-direction: row; + } +` + +const PropName = styled.span` + color: ${get('colors.primary')}; + font-weight: bold; +` + +const PropType = styled.span` + font-size: 0.9em; +` + +const PropDefaultValue = styled.span` + font-size: 0.9em; +` + +const PropRequired = styled.span` + font-size: 0.8em; + opacity: 0.8; +` + +export const PropsTable: React.SFC = ({ + props, + getPropType, +}) => { + const entries = Object.entries(props) + const components = useComponents() + const Paragraph = useMemo( + () => styled(components.P || 'p')` + margin: 0; + font-size: 16px; + color: ${get('colors.blockquoteColor')}; + padding: 0 15px 8px 15px; + `, + [] + ) + + return ( + + {entries.map(([key, prop]) => { + if (!prop.type && !prop.flowType) return null + return ( + + + + + {key} + + + + + {getPropType(prop)} + + + + {prop.defaultValue && ( + + {prop.defaultValue.value === "''" ? ( + = [Empty String] + ) : ( + = {prop.defaultValue.value.replace(/\'/g, '"')} + )} + + )} + {prop.required && ( + + required + + )} + + + {prop.description && ( + + {prop.description} + + )} + + ) + })} + + ) +} diff --git a/core/docz-theme-default/src/components/ui/Props/index.tsx b/core/docz-theme-default/src/components/ui/Props/index.tsx new file mode 100644 index 000000000..f5c9f9db3 --- /dev/null +++ b/core/docz-theme-default/src/components/ui/Props/index.tsx @@ -0,0 +1,76 @@ +import * as React from 'react' +import { useState, useMemo } from 'react' +import { PropsComponentProps, useComponents } from 'docz' +import styled from 'styled-components' +import { PropsRaw } from './PropsRaw' +import { PropsTable } from './PropsTable' + +const Container = styled.div` + margin: 20px 0; +` + +export const Props: React.SFC = ({ + title, + isRaw, + isToggle, + ...props +}) => { + const [isOpen, setIsOpen] = useState(true); + + const components = useComponents() + const Title = useMemo( + () => styled(components.H3 || 'h3')` + padding: 8px 0; + position: relative; + ${!isRaw ? 'margin-bottom: 0;' : ''} + ${!isOpen || isRaw + ? 'border-bottom: 1px solid rgba(0, 0, 0, 0.1);' + : ''} + + ${isToggle ? ` + cursor: pointer; + padding-right: 40px; + + &::after { + content: ''; + position: absolute; + top: 50%; + right: 16px; + transform: translateY(-50%) ${isOpen ? 'rotate(-135deg)' : 'rotate(45deg)'}; + ${!isOpen ? 'margin-top: -2px;' : ''} + width: 8px; + height: 8px; + border-bottom: 2px solid; + border-right: 2px solid; + } + `: ''} + `, + [isOpen] + ) + + const titleProps = isToggle ? { + onClick: () => setIsOpen(open => !open), + onkeydown: () => setIsOpen(open => !open), + role: 'button', + tabindex: 0, + } : {} + + return ( + + {(!!title || isToggle) && ( + + {title || 'Component props'} + + )} + {isOpen && ( +
+ {isRaw ? ( + + ): ( + + )} +
+ )} +
+ ) +} diff --git a/core/docz-theme-default/src/styles/colors.ts b/core/docz-theme-default/src/styles/colors.ts index b7561198c..aa298d22f 100644 --- a/core/docz-theme-default/src/styles/colors.ts +++ b/core/docz-theme-default/src/styles/colors.ts @@ -1,4 +1,5 @@ export const white = '#FFFFFF' +export const grayUltraLight = '#FCFBFA' export const grayExtraLight = '#F5F6F7' export const grayLight = '#CED4DE' export const gray = '#7D899C' diff --git a/core/docz-theme-default/src/styles/modes.ts b/core/docz-theme-default/src/styles/modes.ts index 4c8fef63e..4c412bba9 100644 --- a/core/docz-theme-default/src/styles/modes.ts +++ b/core/docz-theme-default/src/styles/modes.ts @@ -23,6 +23,8 @@ export const light = { blockquoteBg: colors.grayExtraLight, blockquoteBorder: colors.grayLight, blockquoteColor: colors.gray, + propsText: colors.gray, + propsBg: colors.grayUltraLight, } export const dark = { @@ -48,4 +50,6 @@ export const dark = { blockquoteBg: colors.grayDark, blockquoteBorder: colors.gray, blockquoteColor: colors.gray, + propsText: colors.grayLight, + propsBg: colors.dark, } diff --git a/core/docz/src/components/Props.tsx b/core/docz/src/components/Props.tsx index 66d240d7d..6a9d986bb 100644 --- a/core/docz/src/components/Props.tsx +++ b/core/docz/src/components/Props.tsx @@ -64,6 +64,9 @@ export type ComponentWithDocGenInfo = ComponentType & { } export interface PropsProps { + title?: Node, + isRaw?: boolean, + isToggle?: boolean, of: ComponentWithDocGenInfo } @@ -88,11 +91,19 @@ export const getPropType = (prop: Prop) => { } export interface PropsComponentProps { + title?: Node, + isRaw?: boolean, + isToggle?: boolean, props: Record - getPropType(prop: Prop): string + getPropType(prop: Prop): string, } -export const Props: SFC = ({ of: component }) => { +export const Props: SFC = ({ + title, + isToggle, + isRaw, + of: component, +}) => { const components = useComponents() const { props: stateProps } = React.useContext(doczState.context) const PropsComponent = components.props @@ -110,5 +121,13 @@ export const Props: SFC = ({ of: component }) => { if (!props) return null if (!PropsComponent) return null - return + return ( + + ) }