uui-docs/src/types.ts (130 lines of code) (raw):

import * as React from 'react'; import { IDemoApi } from './demoApi'; export interface DemoComponentProps<TProps = PropDocPropsUnknown> { DemoComponent: React.ComponentType<TProps> | React.NamedExoticComponent<TProps>; props: TProps; isPreview?: boolean; } export interface IComponentDocs<TProps> { name: string; component?: React.ComponentType<TProps> | React.NamedExoticComponent<TProps>; props?: PropDoc<TProps, keyof TProps>[]; contexts?: DemoContext<TProps>[]; getPropExamplesMap?: <TProp extends keyof TProps>(propName: TProp) => { [exampleName: string] : PropExampleObject<TProp> } } export interface DemoContext<TProps> { context: React.ComponentType<TProps>; name: string; } export interface IPropSamplesCreationContext<TProps = PropDocPropsUnknown> { getChangeHandler(name: string): (newValue: unknown) => void; getSelectedProps(): TProps; demoApi: IDemoApi; forceUpdate: () => void; } export type PropExampleObject<TProp> = { id?: string; name?: string; value: TProp; isDefault?: boolean; }; export type PropExample<TProp> = PropExampleObject<TProp> | TProp; export interface IPropDocEditor<TProp> { name: string; value: TProp; exampleId: string | undefined; examples: PropExampleObject<TProp>[]; onValueChange(newValue: TProp): void; onExampleIdChange(newExampleId: string | undefined): void; } export type TSharedPropEditorType = 'CssClassEditor' | 'JsonEditor' | 'JsonView' | 'LinkEditor' | 'NumEditor' | 'StringEditor' | 'StringWithExamplesEditor' | 'MultiUnknownEditor' | 'SingleUnknownEditor' | 'IconEditor' | 'CantResolve' ; export type TPropDocEditorType = React.FC<IPropDocEditor<any>> | TSharedPropEditorType; export interface PropDoc<TProps, TProp extends keyof TProps> { name: Extract<keyof TProps, string>; description?: string; isRequired: boolean; defaultValue?: TProps[TProp]; examples?: PropExample<TProps[TProp]>[] | ((ctx: IPropSamplesCreationContext<TProps>) => PropExample<TProps[TProp]>[]); editorType?: TPropDocEditorType; remountOnChange?: boolean; } export type PropDocPropsUnknown = Record<string, unknown>; export type PropDocUnknown = PropDoc<PropDocPropsUnknown, string>; export enum TSkin { UUI = 'uui', Electric = 'electric', Loveship = 'loveship', Promo = 'promo' } export enum TDocContext { Default = 'Default', Block = 'Block', FlexRow = 'FlexRow', Form = 'Form', PagePanel = 'PagePanel', RelativePanel = 'RelativePanel', Resizable = 'Resizable', TabButton = 'TabButton', Table = 'Table', VerticalTabButton = 'VerticalTabButton', OpenedPickerBody = 'OpenedPickerBody' } export type TDocsGenExportedType = Autogenerated_TDocsGenExportedTypeRef; export type IconBase<TIcon> = { id: string; icon: TIcon; name: string; path: string; }; /** * Include prop in current "iteration" only when condition is met. * It is based on the values of parent props and current prop value which is going to be iterated. */ export type TPreviewPropsItemMatrixCondition<TProps> = (parentProps: TProps, thisPropValue?: unknown) => boolean; type TPreviewPropsItemMatrixValues<TProps, TProp extends keyof TProps> = { /** Array of values to be directly passed to the component */ values: TProps[TProp][]; /** * exclude prop from current iteration based on the values of other props which are part of the same iteration */ condition?: TPreviewPropsItemMatrixCondition<TProps>; examples?: never; }; type TPreviewPropsItemMatrixExamples<TProps> = { /** * Array of example names or just a "*" which means all examples. * NOTE: it is NOT array of example ids, because ids are numeric and thus difficult to maintain. */ examples: string[] | '*'; /** * exclude prop from current iteration based on the values of other props which are part of the same iteration */ condition?: TPreviewPropsItemMatrixCondition<TProps>; values?: never; }; type TCellSize = // step=5 (until 200) | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 175 | 180 | 185 | 190 | 195 | 200 // step=10 (until 500) | 210 | 220 | 230 | 240 | 250 | 260 | 270 | 280 | 290 | 300 | 310 | 320 | 330 | 340 | 350 | 360 | 370 | 380 | 390 | 400 | 410 | 420 | 430 | 440 | 450 | 460 | 470 | 480 | 490 | 500 // etc. | 600 | 640 | 768 | 1280; /** * Cell 'width-height'. E.g.: `100-200` (means 100px width and 200px height) * * Each "render case" is displayed inside a preview cell. This is cell size. * * The total width is fixed to 1280px. * The total height is dynamic and depends on total amount of cells and the cell size. */ export type TPreviewCellSize = `${TCellSize}-${TCellSize}`; export type TPreviewPropsItemRenderCases = { id: string; context: TDocContext | undefined; cellSize: TPreviewCellSize | undefined; props: Record<string, unknown>[]; matrix: TNormalizedMatrix[]; }; export type TNormalizedMatrix = Record<string, { values: unknown[]; condition?: TPreviewPropsItemMatrixCondition<any> } >; export type TPreviewMatrix<T> = TComponentPreview<T>['matrix']; export type TComponentPreview<TProps, TProp extends keyof TProps = keyof TProps> = { /** Optional group ID. It will visually group list of previews in the Property Explorer. */ groupId?: string; /** A unique ID of the preview props which can be referenced by test automation */ id: string; /** TDocContext.Default will be used is nothing is passed */ context?: TDocContext; /** * A map of prop names to prop values/examples. * The component will be repeated more than once in order to render all possible combinations: all-props/all-values/all-examples. */ matrix: { [prop in TProp]?: TPreviewPropsItemMatrixValues<TProps, prop> | TPreviewPropsItemMatrixExamples<TProps> } | { [prop in TProp]?: TPreviewPropsItemMatrixValues<TProps, prop> | TPreviewPropsItemMatrixExamples<TProps> }[], /** * 'width-height' */ cellSize?: TPreviewCellSize | undefined; }; export type TComponentPreviewList<TProps> = TComponentPreview<TProps>[];