diff --git a/src/ui/components/Button.js b/src/ui/components/Button.js index 3eafc752b..50efe03c7 100644 --- a/src/ui/components/Button.js +++ b/src/ui/components/Button.js @@ -186,6 +186,9 @@ type Props = { * Name of the icon dispalyed next to the text */ icon?: string, + /** + * Size of the icon in pixels. + */ iconSize?: number, /** * For toggle buttons, if the button is selected @@ -203,6 +206,9 @@ type Props = { * Whether the button should render depressed into its socket */ depressed?: boolean, + /** + * Style of the icon. `filled` is the default + */ iconVariant?: 'filled' | 'outline', }; @@ -211,41 +217,7 @@ type State = { }; /** - * Simple button. - * - * **Usage** - * - * ```jsx - * import {Button} from 'flipper'; - * - * ``` - * - * @example Default button - * - * @example Primary button - * - * @example Success button - * - * @example Warning button - * - * @example Danger button - * - * @example Default solid button - * - * @example Primary solid button - * - * @example Success solid button - * - * @example Warning solid button - * - * @example Danger solid button - * - * @example Compact button - * - * @example Large button - * - * @example Disabled button - * + * A simple button, used in many parts of the application. */ class Button extends React.Component< Props & {windowIsFocused: boolean}, diff --git a/src/ui/components/ButtonGroup.js b/src/ui/components/ButtonGroup.js index bf0f0256b..a38ae83cd 100644 --- a/src/ui/components/ButtonGroup.js +++ b/src/ui/components/ButtonGroup.js @@ -21,12 +21,13 @@ const ButtonGroupContainer = styled('div')({ /** * Group a series of buttons together. * - * @example List of buttons + * ```jsx * * * * * + * ``` */ export default class ButtonGroup extends Component<{ children: React$Node, diff --git a/src/ui/components/ButtonNavigationGroup.js b/src/ui/components/ButtonNavigationGroup.js index 39fb76f51..ac0eeb937 100644 --- a/src/ui/components/ButtonNavigationGroup.js +++ b/src/ui/components/ButtonNavigationGroup.js @@ -8,10 +8,17 @@ import ButtonGroup from './ButtonGroup.js'; import Button from './Button.js'; +/** + * Button group to navigate back and forth. + */ export default function ButtonNavigationGroup(props: {| + /** Back button is enabled */ canGoBack: boolean, + /** Forwards button is enabled */ canGoForward: boolean, + /** Callback when back button is clicked */ onBack: () => void, + /** Callback when forwards button is clicked */ onForward: () => void, |}) { return ( diff --git a/src/ui/components/Checkbox.js b/src/ui/components/Checkbox.js index 3fc8f2994..8bfb9fa12 100644 --- a/src/ui/components/Checkbox.js +++ b/src/ui/components/Checkbox.js @@ -9,7 +9,9 @@ import {PureComponent} from 'react'; import styled from '../styled/index.js'; type CheckboxProps = { + /** Whether the checkbox is checked. */ checked: boolean, + /** Called when a state change is triggered */ onChange: (checked: boolean) => void, }; @@ -19,6 +21,9 @@ const CheckboxContainer = styled('input')({ verticalAlign: 'middle', }); +/** + * A checkbox to toggle UI state + */ export default class Checkbox extends PureComponent { onChange = (e: SyntheticInputEvent) => { this.props.onChange(e.target.checked); diff --git a/src/ui/components/ContextMenu.js b/src/ui/components/ContextMenu.js index 3e3b3e3d8..604ee6893 100644 --- a/src/ui/components/ContextMenu.js +++ b/src/ui/components/ContextMenu.js @@ -12,12 +12,23 @@ import PropTypes from 'prop-types'; type MenuTemplate = Array; type Props = { + /** List of items in the context menu. Used for static menus. */ items?: MenuTemplate, + /** Function to generate the menu. Called right before the menu is showed. Used for dynamic menus. */ buildItems?: () => MenuTemplate, + /** Nodes that should have a context menu */ children: React$Node, + /** The component that is used to wrap the children. Defaults to `FlexColumn`. */ component: React.ComponentType | string, }; +/** + * Native context menu that is shown on secondary click. + * Uses [Electron's context menu API](https://electronjs.org/docs/api/menu-item) + * to show menu items. + * + * Separators can be added by `{type: 'separator'}` + */ export default class ContextMenu extends React.Component { static defaultProps = { component: FlexColumn, diff --git a/src/ui/components/ContextMenuProvider.js b/src/ui/components/ContextMenuProvider.js index 65946d969..ccf3f188d 100644 --- a/src/ui/components/ContextMenuProvider.js +++ b/src/ui/components/ContextMenuProvider.js @@ -17,6 +17,10 @@ const Container = styled('div')({ display: 'contents', }); +/** + * Flipper's root is already wrapped with this component, so plugins should not + * need to use this. ContextMenu is what you probably want to use. + */ export default class ContextMenuProvider extends Component<{| children: React$Node, |}> { diff --git a/src/ui/components/Dropdown.js b/src/ui/components/Dropdown.js deleted file mode 100644 index 273179b63..000000000 --- a/src/ui/components/Dropdown.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2018-present Facebook. - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * @format - */ - -import ContextMenu from './ContextMenu.js'; - -const invariant = require('invariant'); - -export default class Dropdown extends ContextMenu { - trigger: string = 'onClick'; - - ref: ?HTMLElement; - - getCoordinates(): {top: number, left: number} { - const {ref} = this; - invariant(ref, 'expected ref'); - - const rect = ref.getBoundingClientRect(); - return { - left: rect.left, - top: rect.top, - }; - } - - setRef = (ref: ?HTMLElement) => { - this.ref = ref; - }; - - render() { - return {this.props.children}; - } -} diff --git a/src/ui/components/ErrorBlock.js b/src/ui/components/ErrorBlock.js index 09781db2f..bf7f9c577 100644 --- a/src/ui/components/ErrorBlock.js +++ b/src/ui/components/ErrorBlock.js @@ -18,8 +18,13 @@ export const ErrorBlockContainer = styled(CodeBlock)({ padding: 10, }); +/** + * Displaying error messages in a red box. + */ export default class ErrorBlock extends React.Component<{ + /** Error message to display. Error object's `stack` or `message` property is used. */ error: Error | string | void, + /** Additional className added to the container. */ className?: string, }> { render() { diff --git a/src/ui/components/ErrorBoundary.js b/src/ui/components/ErrorBoundary.js index f77a19788..38c3ed15d 100644 --- a/src/ui/components/ErrorBoundary.js +++ b/src/ui/components/ErrorBoundary.js @@ -10,7 +10,6 @@ import {Component} from 'react'; import Heading from './Heading.js'; import Button from './Button.js'; import View from './View.js'; -import LogManager from '../../fb-stubs/Logger.js'; import styled from '../styled/index.js'; const ErrorBoundaryContainer = styled(View)({ @@ -24,10 +23,13 @@ const ErrorBoundaryStack = styled(ErrorBlock)({ }); type ErrorBoundaryProps = { + /** Function to dynamically generate the heading of the ErrorBox. */ buildHeading?: (err: Error) => string, + /** Heading of the ErrorBox. Used as an alternative to `buildHeading`. */ heading?: string, - logger?: LogManager, + /** Whether the stacktrace of the error is shown in the error box */ showStack?: boolean, + /** Code that might throw errors that will be catched */ children?: React$Node, }; @@ -35,6 +37,9 @@ type ErrorBoundaryState = {| error: ?Error, |}; +/** + * Boundary catching errors and displaying an ErrorBlock instead. + */ export default class ErrorBoundary extends Component< ErrorBoundaryProps, ErrorBoundaryState, @@ -45,7 +50,7 @@ export default class ErrorBoundary extends Component< } componentDidCatch(err: Error) { - this.props.logger && console.error(err.toString(), 'ErrorBoundary'); + console.error(err.toString(), 'ErrorBoundary'); this.setState({error: err}); } diff --git a/src/ui/components/File.js b/src/ui/components/File.js index 1061adeda..d0053ceeb 100644 --- a/src/ui/components/File.js +++ b/src/ui/components/File.js @@ -11,13 +11,20 @@ const React = require('react'); const fs = require('fs'); type FileProps = {| + /** Path to the file in the file system */ src: string, + /** Initial content that should be shown while the file is loading */ buffer?: ?string, + /** Encoding to parse the contents of the file. Defaults to UTF-8. */ encoding: string, - onError?: (err: Error) => React.Element<*>, - onLoading?: () => React.Element<*>, + /** Content that should be rendered, when the file loading failed. */ + onError?: (err: Error) => React.Element, + /** Content that should be rendered, while the file is loaded. */ + onLoading?: () => React.Element, + /** Callback when the data is successfully loaded. */ onData?: (content: string) => void, - onLoad: (content: string) => React.Element<*>, + /** Content that should be rendered, when the file is successfully loaded. This ususally should render the file's contents. */ + onLoad: (content: string) => React.Element, |}; type FileState = {| @@ -26,6 +33,9 @@ type FileState = {| content: string, |}; +/** + * Wrapper for loading file content from the file system. + */ export default class File extends Component { constructor(props: FileProps, context: Object) { super(props, context); diff --git a/src/ui/components/FileList.js b/src/ui/components/FileList.js index c270c778d..ffc9281c4 100644 --- a/src/ui/components/FileList.js +++ b/src/ui/components/FileList.js @@ -29,9 +29,13 @@ export type FileListFile = {| export type FileListFiles = Array; type FileListProps = { + /** Path to the folder */ src: string, + /** Content to be rendered in case of an error */ onError?: ?(err: Error) => React$Node, + /** Content to be rendered while loading */ onLoad?: () => void, + /** Content to be rendered when the file list is loaded */ onFiles: (files: FileListFiles) => React$Node, }; @@ -40,6 +44,10 @@ type FileListState = {| error: ?Error, |}; +/** + * List the contents of a folder from the user's file system. The file system is watched for + * changes and this list will automatically update. + */ export default class FileList extends Component { constructor(props: FileListProps, context: Object) { super(props, context); diff --git a/src/ui/components/FlexBox.js b/src/ui/components/FlexBox.js index 418fcfd1d..1353d98b7 100644 --- a/src/ui/components/FlexBox.js +++ b/src/ui/components/FlexBox.js @@ -8,7 +8,15 @@ import View from './View.js'; import styled from '../styled/index.js'; -export default styled(View)(({shrink}) => ({ +type Props = { + /** Flexbox's shrink property. Set to `0`, to disable shrinking. */ + shrink: number, +}; + +/** + * A container using flexbox to layout its children + */ +export default styled(View)(({shrink}: Props) => ({ display: 'flex', flexShrink: shrink == null || shrink ? 1 : 0, })); diff --git a/src/ui/components/FlexCenter.js b/src/ui/components/FlexCenter.js index c383909b3..c5636a70b 100644 --- a/src/ui/components/FlexCenter.js +++ b/src/ui/components/FlexCenter.js @@ -8,6 +8,9 @@ import View from './View.js'; import styled from '../styled/index.js'; +/** + * A container dispalying its children horizontally and vertically centered. + */ export default styled(View)({ display: 'flex', alignItems: 'center', diff --git a/src/ui/components/FlexColumn.js b/src/ui/components/FlexColumn.js index e87715e9d..f1612c645 100644 --- a/src/ui/components/FlexColumn.js +++ b/src/ui/components/FlexColumn.js @@ -8,6 +8,9 @@ import FlexBox from './FlexBox.js'; import styled from '../styled/index.js'; +/** + * A container dispalying its children in a column + */ export default styled(FlexBox)({ flexDirection: 'column', }); diff --git a/src/ui/components/FlexRow.js b/src/ui/components/FlexRow.js index 2bf3fdc4b..aef09ac77 100644 --- a/src/ui/components/FlexRow.js +++ b/src/ui/components/FlexRow.js @@ -8,6 +8,9 @@ import FlexBox from './FlexBox.js'; import styled from '../styled/index.js'; +/** + * A container dispalying its children in a row + */ export default styled(FlexBox)({ flexDirection: 'row', }); diff --git a/src/ui/components/Glyph.js b/src/ui/components/Glyph.js index 6a3154d0f..ac7aec384 100644 --- a/src/ui/components/Glyph.js +++ b/src/ui/components/Glyph.js @@ -28,7 +28,7 @@ const ColoredIconCustom = styled('div')(props => ({ WebkitMaskSize: '100% 100%', })); -export function ColoredIcon( +function ColoredIcon( props: {| name: string, src: string, diff --git a/src/ui/components/Heading.js b/src/ui/components/Heading.js index 088ed4981..d7ea685cb 100644 --- a/src/ui/components/Heading.js +++ b/src/ui/components/Heading.js @@ -25,19 +25,6 @@ const SmallHeading = styled('div')({ /** * A heading component. - * - * @example Heading 1 - * I'm a heading - * @example Heading 2 - * I'm a heading - * @example Heading 3 - * I'm a heading - * @example Heading 4 - * I'm a heading - * @example Heading 5 - * I'm a heading - * @example Heading 6 - * I'm a heading */ export default function Heading(props: { /** diff --git a/src/ui/components/InlineContextMenu.js b/src/ui/components/InlineContextMenu.js deleted file mode 100644 index d4b40f604..000000000 --- a/src/ui/components/InlineContextMenu.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright 2018-present Facebook. - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * @format - */ - -import ContextMenu from './ContextMenu.js'; - -export default class InlineContextMenu extends ContextMenu { - render() { - return {this.props.children}; - } -} diff --git a/src/ui/components/ResizeSensor.js b/src/ui/components/ResizeSensor.js index b18b79f62..04abf8d60 100644 --- a/src/ui/components/ResizeSensor.js +++ b/src/ui/components/ResizeSensor.js @@ -19,7 +19,11 @@ const IFrame = styled('iframe')({ left: 0, }); +/** + * Listener for resize events. + */ export default class ResizeSensor extends Component<{ + /** Callback when resize happened */ onResize: (e: UIEvent) => void, }> { iframe: ?HTMLIFrameElement; diff --git a/src/ui/components/Select.js b/src/ui/components/Select.js index b7364882e..18bb8fbcf 100644 --- a/src/ui/components/Select.js +++ b/src/ui/components/Select.js @@ -7,12 +7,19 @@ import {Component} from 'react'; +/** + * Dropdown to select from a list of options + */ export default class Select extends Component<{ + /** Additional className added to the element */ className?: string, + /** Additional className added to the element */ options: { [key: string]: string, }, + /** Callback when the selected value changes */ onChange: (key: string) => void, + /** Selected key */ selected?: ?string, }> { onChange = (event: Object) => { diff --git a/src/ui/components/Tab.js b/src/ui/components/Tab.js index 297bf60f3..d374f16e1 100644 --- a/src/ui/components/Tab.js +++ b/src/ui/components/Tab.js @@ -4,6 +4,7 @@ * LICENSE file in the root directory of this source tree. * @format */ + export default function Tab(props: {| /** * Label of this tab to show in the tab list. diff --git a/src/ui/components/Tooltip.js b/src/ui/components/Tooltip.js index cd3b4072c..0ab84bf18 100644 --- a/src/ui/components/Tooltip.js +++ b/src/ui/components/Tooltip.js @@ -18,7 +18,9 @@ const TooltipContainer = styled('div')({ }); type TooltipProps = { + /** Content shown in the tooltip */ title: React$Node, + /** Component that will show the tooltip */ children: React$Node, options?: TooltipOptions, }; diff --git a/src/ui/components/data-inspector/ManagedDataInspector.js b/src/ui/components/data-inspector/ManagedDataInspector.js index ea6b2bcb9..f60396b6b 100644 --- a/src/ui/components/data-inspector/ManagedDataInspector.js +++ b/src/ui/components/data-inspector/ManagedDataInspector.js @@ -54,28 +54,6 @@ type ManagedDataInspectorState = {| * * If you require lower level access to the state then use `DataInspector` * directly. - * - * @example Plain object - * - * @example Expanded root - * - * @example Editable - * {}} data={{ - * a: '', - * b: [1, 2, 3, 4], - * c: {foo: 'bar'}, - * d: 4, - * }} /> */ export default class ManagedDataInspector extends PureComponent< ManagedDataInspectorProps, diff --git a/src/ui/components/searchable/Searchable.js b/src/ui/components/searchable/Searchable.js index 08fc8433d..ab75bb7fa 100644 --- a/src/ui/components/searchable/Searchable.js +++ b/src/ui/components/searchable/Searchable.js @@ -390,4 +390,8 @@ const Searchable = ( } }; +/** + * Higher-order-component that allows adding a searchbar on top of the wrapped + * component. See SearchableManagedTable for usage with a table. + */ export default Searchable; diff --git a/src/ui/components/searchable/SearchableTable.js b/src/ui/components/searchable/SearchableTable.js index b742d6513..1426b46f1 100644 --- a/src/ui/components/searchable/SearchableTable.js +++ b/src/ui/components/searchable/SearchableTable.js @@ -17,10 +17,10 @@ import deepEqual from 'deep-equal'; type Props = {| ...ManagedTableProps, ...SearchableProps, + /** Reference to the table */ innerRef?: (ref: React.ElementRef<*>) => void, + /** Filters that are added to the filterbar by default */ defaultFilters: Array, - filter: empty, - filterValue: empty, |}; type State = { @@ -103,4 +103,8 @@ class SearchableManagedTable extends PureComponent { } } +/** + * Table with filter and searchbar, supports all properties a ManagedTable + * and Searchable supports. + */ export default Searchable(SearchableManagedTable); diff --git a/src/ui/index.js b/src/ui/index.js index f1ae73371..c75df1280 100644 --- a/src/ui/index.js +++ b/src/ui/index.js @@ -17,7 +17,7 @@ export {default as ButtonGroup} from './components/ButtonGroup.js'; export {colors, darkColors, brandColors} from './components/colors.js'; // -export {default as Glyph, ColoredIcon} from './components/Glyph.js'; +export {default as Glyph} from './components/Glyph.js'; // export {default as LoadingIndicator} from './components/LoadingIndicator.js'; @@ -86,8 +86,6 @@ export { default as ContextMenuProvider, } from './components/ContextMenuProvider.js'; export {default as ContextMenu} from './components/ContextMenu.js'; -export {default as InlineContextMenu} from './components/InlineContextMenu.js'; -export {default as Dropdown} from './components/Dropdown.js'; // file export type {FileListFile, FileListFiles} from './components/FileList.js'; diff --git a/website/generate-uidocs.js b/website/generate-uidocs.js index df042c4b5..755a744fc 100644 --- a/website/generate-uidocs.js +++ b/website/generate-uidocs.js @@ -95,9 +95,9 @@ function generateMarkdown(component) { } // escape pipes and new lines because they will break tables - type = type.replace(/\n/g, ' ').replace(/\|/g, '|'); + type = type.replace(/\n/g, ' ').replace(/\|/g, '⎮'); description = description - ? description.replace(/\n/g, ' ').replace(/\|/g, '|') + ? description.replace(/\n/g, ' ').replace(/\|/g, '⎮') : ''; props += `| \`${prop}\` | \`${type}\` | ${description} |\n`;