chore: update styled components typings

This commit is contained in:
Roman Hotsiy 2018-11-27 11:18:41 +02:00
parent af3eee1f52
commit 27d195ef38
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
19 changed files with 1647 additions and 488 deletions

View File

@ -4,16 +4,10 @@
*/
import * as React from 'react';
import styled, { StyledFunction } from 'styled-components';
import styled from '../src/styled-components';
function withProps<T, U extends HTMLElement = HTMLElement>(
styledFunction: StyledFunction<React.HTMLProps<U>>,
): StyledFunction<T & React.HTMLProps<U>> {
return styledFunction;
}
const DropDownItem = withProps<{ active: boolean }>(styled.li)`
${props => ((props as any).active ? 'background-color: #eee' : '')};
const DropDownItem = styled.li<{ active?: boolean }>`
${(props: any) => (props.active ? 'background-color: #eee' : '')};
padding: 13px 16px;
&:hover {
background-color: #eee;

View File

@ -1,7 +1,6 @@
import Dropdown from 'react-dropdown';
import { StyledComponentClass } from 'styled-components';
import styled, { withProps } from '../styled-components';
import styled from '../styled-components';
export interface DropdownOption {
label: string;
@ -14,17 +13,17 @@ export interface DropdownProps {
onChange: (val: DropdownOption) => void;
}
export const StyledDropdown = withProps<DropdownProps>(styled(Dropdown))`
export const StyledDropdown = styled(Dropdown)`
min-width: 100px;
display: inline-block;
position: relative;
width: auto;
font-family: ${props => props.theme.typography.headings.fontFamily};
.Dropdown-control {
.Dropdown-control {
font-family: ${props => props.theme.typography.headings.fontFamily};
position: relative;
font-size: .929em;
font-size: 0.929em;
width: 100%;
line-height: 1.5em;
vertical-align: middle;
@ -84,14 +83,14 @@ export const StyledDropdown = withProps<DropdownProps>(styled(Dropdown))`
padding: 0.4em;
&.is-selected {
background-color: rgba(0, 0, 0, 0.05)
background-color: rgba(0, 0, 0, 0.05);
}
&:hover {
background-color: rgba(38, 50, 56, 0.12)
background-color: rgba(38, 50, 56, 0.12);
}
}
` as StyledComponentClass<any, DropdownProps>;
`;
export const SimpleDropdown = styled(StyledDropdown)`
margin-left: 10px;
@ -105,7 +104,7 @@ export const SimpleDropdown = styled(StyledDropdown)`
background: transparent;
&:hover {
color: ${props => props.theme.colors.main};
color: ${props => props.theme.colors.primary.main};
box-shadow: none;
}
}

View File

@ -1,6 +1,6 @@
// import { transparentize } from 'polished';
import styled, { extensionsHook, withProps } from '../styled-components';
import styled, { extensionsHook } from '../styled-components';
import { deprecatedCss } from './mixins';
export const PropertiesTableCaption = styled.caption`
@ -10,7 +10,7 @@ export const PropertiesTableCaption = styled.caption`
color: ${props => props.theme.colors.text.secondary};
`;
export const PropertyCell = styled.td`
export const PropertyCell = styled.td<{ kind?: string }>`
border-left: 1px solid ${props => props.theme.schema.linesColor};
box-sizing: border-box;
position: relative;
@ -58,7 +58,7 @@ export const PropertyCellWithInner = styled(PropertyCell)`
padding: 0;
`;
export const PropertyNameCell = withProps<{ kind?: string }>(styled(PropertyCell))`
export const PropertyNameCell = styled(PropertyCell)`
vertical-align: top;
line-height: 20px;
white-space: nowrap;

View File

@ -1,5 +1,5 @@
import { SECTION_ATTR } from '../services/MenuStore';
import styled, { media, withProps } from '../styled-components';
import styled, { media, WithProps } from '../styled-components';
export const MiddlePanel = styled.div`
width: calc(100% - ${props => props.theme.rightPanel.width});
@ -12,17 +12,15 @@ export const MiddlePanel = styled.div`
`};
`;
export const Section = withProps<{ underlined?: boolean }>(
styled.div.attrs({
[SECTION_ATTR]: props => props.id,
} as any),
)`
export const Section = (styled.div as WithProps<'div', { underlined?: boolean }>).attrs(props => ({
[SECTION_ATTR]: props.id,
}))`
padding: ${props => props.theme.spacing.sectionVertical}px 0;
${media.lessThan('medium', true)`
padding: 0;
`}
${props =>
${(props: any) =>
(props.underlined &&
`
position: relative;

View File

@ -1,4 +1,4 @@
import styled, { withProps } from '../styled-components';
import styled from '../styled-components';
export const OneOfList = styled.ul`
margin: 0;
@ -15,7 +15,7 @@ export const OneOfLabel = styled.span`
}
`;
export const OneOfButton = withProps<{ active: boolean }>(styled.li)`
export const OneOfButton = styled.li<{ active: boolean }>`
display: inline-block;
margin-right: 10px;
font-size: 0.8em;

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import styled, { withProps } from '../styled-components';
import styled from '../styled-components';
const directionMap = {
left: '90deg',
@ -48,7 +48,7 @@ export const ShelfIcon = styled(IntShelfIcon)`
}
`;
export const Badge = withProps<{ type: string }>(styled.span)`
export const Badge = styled.span<{ type: string }>`
display: inline-block;
padding: 0 5px;
margin: 0;

View File

@ -11,7 +11,7 @@ export class ApiLogo extends React.Component<{ info: OpenAPIInfo }> {
if (!logoInfo || !logoInfo.url) {
return null;
}
const logoHref = logoInfo.href || (info.contact && info.contact.url);
// Use the english word logo if no alt text is provided
@ -24,12 +24,6 @@ export class ApiLogo extends React.Component<{ info: OpenAPIInfo }> {
alt={altText}
/>
);
return (
<LogoWrap>
{
logoHref ? LinkWrap(logoHref)(logo) : logo
}
</LogoWrap>
);
return <LogoWrap>{logoHref ? LinkWrap(logoHref)(logo) : logo}</LogoWrap>;
}
}

View File

@ -1,4 +1,4 @@
import styled, { withProps } from '../../styled-components';
import styled from '../../styled-components';
export const OperationEndpointWrap = styled.div`
cursor: pointer;
@ -14,7 +14,7 @@ export const ServerRelativeURL = styled.span`
text-overflow: ellipsis;
`;
export const EndpointInfo = withProps<{ expanded?: boolean; inverted?: boolean }>(styled.div)`
export const EndpointInfo = styled.div<{ expanded?: boolean; inverted?: boolean }>`
padding: 10px 30px 10px ${props => (props.inverted ? '10px' : '20px')};
border-radius: ${props => (props.inverted ? '0' : '4px 4px 0 0')};
background-color: ${props => (props.inverted ? 'transparent' : '#222d32')};
@ -33,12 +33,12 @@ export const EndpointInfo = withProps<{ expanded?: boolean; inverted?: boolean }
}
`;
export const HttpVerb = withProps<{ type: string }>(styled.span).attrs({
className: props => `http-verb ${props.type}`,
})`
export const HttpVerb = styled.span.attrs((props: { type: string }) => ({
className: `http-verb ${props.type}`,
}))<{ type: string }>`
font-size: 0.929em;
line-height: 20px;
background-color: ${props => props.theme.colors.http[props.type] || '#999999'};
background-color: ${(props: any) => props.theme.colors.http[props.type] || '#999999'};
color: #ffffff;
padding: 3px 10px;
text-transform: uppercase;
@ -46,7 +46,7 @@ export const HttpVerb = withProps<{ type: string }>(styled.span).attrs({
margin: 0;
`;
export const ServersOverlay = withProps<{ expanded: boolean }>(styled.div)`
export const ServersOverlay = styled.div<{ expanded: boolean }>`
position: absolute;
width: 100%;
z-index: 100;

View File

@ -1,10 +1,10 @@
import { observer } from 'mobx-react';
import * as React from 'react';
import styled, { withProps } from '../../styled-components';
import styled from '../../styled-components';
import { OpenAPIExternalDocumentation } from '../../types';
import { linksCss } from '../Markdown/styled.elements';
const LinkWrap = withProps<{ compact?: boolean }>(styled.div)`
const LinkWrap = styled.div<{ compact?: boolean }>`
${linksCss};
${({ compact }) => (!compact ? 'margin: 1em 0' : '')}
`;

View File

@ -1,9 +1,9 @@
import * as React from 'react';
import styled, { withProps } from '../../styled-components';
import styled from '../../styled-components';
import { Spinner } from './Spinner.svg';
const LoadingMessage = withProps<{ color: string }>(styled.div)`
const LoadingMessage = styled.div<{ color: string }>`
font-family: helvetica, sans;
width: 100%;
text-align: center;

View File

@ -1,6 +1,8 @@
import { headerCommonMixin, linkifyMixin } from '../../common-elements';
import { PrismDiv } from '../../common-elements/PrismDiv';
import styled, { css, extensionsHook, withProps } from '../../styled-components';
import styled, { css, extensionsHook, ResolvedThemeInterface } from '../../styled-components';
import { StyledComponent } from 'styled-components';
export const linksCss = css`
a {
@ -17,9 +19,11 @@ export const linksCss = css`
}
`;
export const StyledMarkdownBlock = withProps<{ compact?: boolean; inline?: boolean }>(
styled(PrismDiv),
)`
export const StyledMarkdownBlock = styled(PrismDiv as StyledComponent<
'div',
ResolvedThemeInterface,
{ compact?: boolean; inline?: boolean }
>)`
font-family: ${props => props.theme.typography.fontFamily};
font-weight: ${props => props.theme.typography.fontWeightRegular};

View File

@ -32,7 +32,7 @@ export class MediaTypeSamples extends React.Component<PayloadSamplesProps> {
}
if (examplesNames.length > 1) {
return (
<SmallTabs>
<SmallTabs defaultIndex={0}>
<TabList>
{examplesNames.map(name => (
<Tab key={name}> {examples[name].summary || name} </Tab>

View File

@ -7,9 +7,9 @@ export const SearchWrap = styled.div`
padding: 5px 0;
`;
export const SearchInput = styled.input.attrs({
export const SearchInput = styled.input.attrs(() => ({
className: 'search-input',
})`
}))`
width: calc(100% - ${props => props.theme.spacing.unit * 8}px);
box-sizing: border-box;
margin: 0 ${props => props.theme.spacing.unit * 4}px;

View File

@ -1,11 +1,13 @@
import * as classnames from 'classnames';
import { deprecatedCss, ShelfIcon } from '../../common-elements';
import styled, { css, withProps } from '../../styled-components';
import styled, { css, WithProps } from '../../styled-components';
export const OperationBadge = withProps<{ type: string }>(styled.span).attrs({
className: props => `operation-type ${props.type}`,
})`
export const OperationBadge = (styled.span as WithProps<'span', { type: string }>).attrs(
(props: any) => ({
className: `operation-type ${props.type}`,
}),
)`
width: 32px;
display: inline-block;
height: ${props => props.theme.typography.code.fontSize};
@ -57,7 +59,7 @@ export const OperationBadge = withProps<{ type: string }>(styled.span).attrs({
}
&.head {
background-color: ${props => props.theme.colors.http.head};
background-color: ${props => props.theme.colors.http.head};
}
`;
@ -71,7 +73,7 @@ function menuItemActiveBg(depth): string {
}
}
export const MenuItemUl = withProps<{ expanded: boolean }>(styled.ul)`
export const MenuItemUl = styled.ul<{ expanded: boolean }>`
margin: 0;
padding: 0;
@ -82,7 +84,7 @@ export const MenuItemUl = withProps<{ expanded: boolean }>(styled.ul)`
${props => (props.expanded ? '' : 'display: none;')};
`;
export const MenuItemLi = withProps<{ depth: number }>(styled.li)`
export const MenuItemLi = styled.li<{ depth: number }>`
list-style: none inside none;
overflow: hidden;
text-overflow: ellipsis;
@ -111,18 +113,19 @@ export const menuItemDepth = {
`,
};
export const MenuItemLabel = withProps<{
export interface MenuItemLabelType {
depth: number;
active: boolean;
deprecated?: boolean;
type?: string;
}>(styled.label).attrs({
}
export const MenuItemLabel = styled.label.attrs((props: MenuItemLabelType) => ({
role: 'menuitem',
className: props =>
classnames('-depth' + props.depth, {
active: props.active,
}),
})`
className: classnames('-depth' + props.depth, {
active: props.active,
}),
}))<MenuItemLabelType>`
cursor: pointer;
color: ${props =>
props.active ? props.theme.colors.primary.main : props.theme.colors.text.primary};
@ -151,7 +154,7 @@ export const MenuItemLabel = withProps<{
}
`;
export const MenuItemTitle = withProps<{ width?: string }>(styled.span)`
export const MenuItemTitle = styled.span<{ width?: string }>`
display: inline-block;
vertical-align: middle;
width: ${props => (props.width ? props.width : 'auto')};

View File

@ -3,7 +3,7 @@ import * as React from 'react';
import { MenuStore } from '../../services/MenuStore';
import { RedocNormalizedOptions, RedocRawOptions } from '../../services/RedocNormalizedOptions';
import styled, { media, withProps } from '../../styled-components';
import styled, { media } from '../../styled-components';
import { IS_BROWSER } from '../../utils/index';
import { OptionsContext } from '../OptionsProvider';
import { AnimatedChevronButton } from './ChevronSvg';
@ -21,7 +21,7 @@ export interface StickySidebarProps {
const stickyfill = Stickyfill && Stickyfill();
const StyledStickySidebar = withProps<{ open?: boolean }>(styled.div)`
const StyledStickySidebar = styled.div<{ open?: boolean }>`
width: ${props => props.theme.menu.width};
background-color: ${props => props.theme.menu.backgroundColor};
overflow: hidden;

View File

@ -4,7 +4,9 @@ import defaultTheme from '../theme';
export default class TestThemeProvider extends React.Component {
render() {
return <ThemeProvider theme={defaultTheme}>{this.props.children}</ThemeProvider>;
return (
<ThemeProvider theme={defaultTheme}>{React.Children.only(this.props.children)}</ThemeProvider>
);
}
}

View File

@ -5,15 +5,10 @@ import { ResolvedThemeInterface } from './theme';
export { ResolvedThemeInterface };
export type InterpolationFunction<P> = styledComponents.InterpolationFunction<P>;
export type StyledFunction<T> = styledComponents.ThemedStyledFunction<T, ResolvedThemeInterface>;
function withProps<T, U extends HTMLElement = HTMLElement>(
styledFunction: StyledFunction<React.HTMLProps<U>>,
): StyledFunction<T & React.HTMLProps<U>> {
return styledFunction;
}
type WithProps<
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
T extends object
> = styledComponents.ThemedStyledFunction<C, ResolvedThemeInterface, T>;
const {
default: styled,
@ -54,7 +49,7 @@ export const media = {
},
};
export { css, createGlobalStyle, keyframes, ThemeProvider, withProps };
export { css, createGlobalStyle, keyframes, ThemeProvider, WithProps };
export default styled;
export function extensionsHook(styledName: string) {

View File

@ -1,51 +1,21 @@
import * as styledComponents from 'styled-components';
// Styled components typings for using babel-plugin BEFORE typescript
// FIXME
declare module 'styled-components' {
type Attrs<P, A extends Partial<P>, T> = {
[K in keyof A]: ((props: ThemedStyledProps<P, T>) => A[K]) | A[K]
};
type KeyofBase = keyof any;
type Diff<T extends KeyofBase, U extends KeyofBase> = ({ [P in T]: P } & { [P in U]: never })[T];
type DiffBetween<T, U> = Pick<T, Diff<keyof T, keyof U>> & Pick<U, Diff<keyof U, keyof T>>;
interface ThemedStyledFunction<P, T, O = P> {
// adding "| string[]" for transpileTemplateLiterals and similar below
(
strings: TemplateStringsArray | string[],
...interpolations: Array<Interpolation<ThemedStyledProps<P, T>>>
): StyledComponentClass<P, T, O>;
<U>(
strings: TemplateStringsArray | string[],
...interpolations: Array<Interpolation<ThemedStyledProps<P & U, T>>>
): StyledComponentClass<P & U, T, O & U>;
attrs<U, A extends Partial<P & U> = {}>(
attrs: Attrs<P & U, A, T>,
): ThemedStyledFunction<DiffBetween<A, P & U>, T, DiffBetween<A, O & U>>;
// adding "withConfig" for transpileTemplateLiterals
withConfig(config: any): ThemedStyledFunction<P, T, O>;
}
export interface BaseThemedCssFunction<T> {
(
strings: TemplateStringsArray | string[],
...interpolations: SimpleInterpolation[]
): InterpolationValue[];
<P>(
strings: TemplateStringsArray | string[],
...interpolations: Array<Interpolation<ThemedStyledProps<P, T>>>
): Array<FlattenInterpolation<ThemedStyledProps<P, T>>>;
export interface ThemedStyledFunction<
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
T extends object,
O extends object = {},
A extends keyof any = never
> extends ThemedStyledFunctionBase<C, T, O, A> {
withConfig(config: any): any;
// tslint:enable:unified-signatures
}
interface ThemedStyledComponentsModule<T> {
keyframes(
strings: TemplateStringsArray | string[],
...interpolations: SimpleInterpolation[]
): Keyframes;
createGlobalStyle<P = {}>(
strings: TemplateStringsArray | string[],
...interpolations: Array<Interpolation<ThemedStyledProps<P, T>>>
): GlobalStyleClass<P, T>;
): Keyframes;
}
}

1924
yarn.lock

File diff suppressed because it is too large Load Diff