From 4052e028fd9ed345e56ccbd21b00cee9189a7264 Mon Sep 17 00:00:00 2001 From: Levi Thomason Date: Wed, 5 Dec 2018 15:52:27 -0800 Subject: [PATCH 1/2] docs(prettier): add prettier support --- .prettierrc.json | 1 + docs/src/components/CodeSnippet.tsx | 84 +++-- .../ComponentExample/ComponentExample.tsx | 199 +++++------ .../ComponentProp/ComponentPropEnum.tsx | 4 +- .../ComponentTable/ComponentTable.tsx | 4 +- docs/src/components/Editor/Editor.tsx | 115 ++---- .../ExampleSnippet/ExampleSnippet.tsx | 70 +++- .../components/Button/Usage/index.tsx | 2 +- .../ChatMessageExampleStyled.shorthand.tsx | 6 +- .../Chat/Types/ChatMessageExampleStyled.tsx | 6 +- .../PopupExamplePosition.shorthand.tsx | 4 +- .../Popup/Variations/PopupExamplePosition.tsx | 4 +- .../Portal/Types/PortalExample.shorthand.tsx | 6 +- .../components/Portal/Types/PortalExample.tsx | 6 +- .../PortalExampleControlled.shorthand.tsx | 6 +- .../Portal/Types/PortalExampleControlled.tsx | 6 +- docs/src/index.ejs | 21 +- docs/src/utils/formatCode.ts | 24 ++ docs/src/views/Accessibility.tsx | 220 ++++++------ docs/src/views/IntegrateCustomComponents.tsx | 177 ++++------ docs/src/views/Introduction.tsx | 33 +- docs/src/views/QuickStart.tsx | 42 ++- docs/src/views/Theming.tsx | 188 +++------- docs/src/views/ThemingExamples.tsx | 331 +++++++++--------- package.json | 4 +- .../teams/components/Menu/menuItemStyles.ts | 20 +- types/global.d.ts | 4 + webpack.config.ts | 3 +- yarn.lock | 72 +--- 29 files changed, 755 insertions(+), 907 deletions(-) create mode 100644 docs/src/utils/formatCode.ts diff --git a/.prettierrc.json b/.prettierrc.json index 79e50a4981..6799f36619 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,5 +1,6 @@ { "$schema": "http://json.schemastore.org/prettierrc", + "htmlWhitespaceSensitivity": "ignore", "printWidth": 100, "tabWidth": 2, "semi": false, diff --git a/docs/src/components/CodeSnippet.tsx b/docs/src/components/CodeSnippet.tsx index aa8704ead3..357a5c3239 100644 --- a/docs/src/components/CodeSnippet.tsx +++ b/docs/src/components/CodeSnippet.tsx @@ -1,50 +1,66 @@ +import * as _ from 'lodash' import * as React from 'react' + +import formatCode from '../utils/formatCode' import Editor, { EDITOR_BACKGROUND_COLOR } from './Editor' export interface CodeSnippetProps { + fitted?: boolean label?: string mode?: 'jsx' | 'html' | 'sh' value: string style?: React.CSSProperties } -const CodeSnippet = ({ label, value, mode = 'jsx', style, ...rest }: CodeSnippetProps) => ( -
+const formatters = { + sh: (val: string = ''): string => val.replace(/^/g, '$ '), + html: (val: string = ''): string => formatCode(val, 'html'), + jsx: (val: string = ''): string => formatCode(val, 'babylon'), +} + +const CodeSnippet = ({ fitted, label, value, mode = 'jsx', ...rest }: CodeSnippetProps) => { + const format = formatters[mode] + const formattedValue = format(value) + // remove eof line break, they are not helpful for snippets + .replace(/\n$/, '') + + return (
- {label || mode} +
+ {label || mode} +
+
- -
-) + ) +} export default CodeSnippet diff --git a/docs/src/components/ComponentDoc/ComponentExample/ComponentExample.tsx b/docs/src/components/ComponentDoc/ComponentExample/ComponentExample.tsx index 3c5782a653..ee42bf791a 100644 --- a/docs/src/components/ComponentDoc/ComponentExample/ComponentExample.tsx +++ b/docs/src/components/ComponentDoc/ComponentExample/ComponentExample.tsx @@ -2,14 +2,13 @@ import * as _ from 'lodash' import PropTypes from 'prop-types' import * as React from 'react' import { RouteComponentProps, withRouter } from 'react-router' -import { html } from 'js-beautify' import * as copyToClipboard from 'copy-to-clipboard' import SourceRender from 'react-source-render' import { Divider, Form, Grid, Menu, Segment, Visibility } from 'semantic-ui-react' import { Provider, themes } from '@stardust-ui/react' import { examplePathToHash, getFormattedHash, knobsContext, scrollToAnchor } from 'docs/src/utils' -import { callable, doesNodeContainClick, pxToRem, constants } from 'src/lib' +import { callable, pxToRem, constants } from 'src/lib' import Editor, { EDITOR_BACKGROUND_COLOR, EDITOR_GUTTER_COLOR } from 'docs/src/components/Editor' import { babelConfig, importResolver } from 'docs/src/components/Playground/renderConfig' import ComponentControls from '../ComponentControls' @@ -19,6 +18,8 @@ import SourceCodeManager, { SourceCodeType } from './SourceCodeManager' import { ThemeInput, ThemePrepared } from 'src/themes/types' import { mergeThemeVariables } from '../../../../../src/lib/mergeThemes' import { ThemeContext } from '../../../context/theme-context' +import CodeSnippet from '../../CodeSnippet' +import formatCode from '../../../utils/formatCode' export interface ComponentExampleProps extends RouteComponentProps { title: React.ReactNode @@ -52,16 +53,17 @@ const codeTypeApiButtonLabels: { [key in SourceCodeType]: string } = { shorthand: 'Shorthand API', } +const disabledStyle = { opacity: 0.5, pointerEvents: 'none' } + /** * Renders a `component` and the raw `code` that produced it. * Allows toggling the the raw `code` code block. */ class ComponentExample extends React.Component { - private componentRef: React.Component - private sourceCodeMgr: SourceCodeManager - private anchorName: string - private kebabExamplePath: string - private KnobsComponent: any + sourceCodeMgr: SourceCodeManager + anchorName: string + kebabExamplePath: string + KnobsComponent: any state = { knobs: {}, @@ -78,11 +80,11 @@ class ComponentExample extends React.Component { + clearActiveState = () => { this.setState({ showCode: false, showRtl: false, @@ -129,31 +131,27 @@ class ComponentExample extends React.Component { + isActiveState = () => { const { showCode, showVariables } = this.state return showCode || showVariables } - private isActiveHash = () => this.anchorName === getFormattedHash(this.props.location.hash) - - private clickedOutsideComponent = (e: Event): boolean => { - return !doesNodeContainClick((this.componentRef as any).ref, e) - } + isActiveHash = () => this.anchorName === getFormattedHash(this.props.location.hash) - private updateHash = () => { + updateHash = () => { if (this.isActiveState()) this.setHashAndScroll() else if (this.isActiveHash()) this.removeHash() } - private setHashAndScroll = () => { + setHashAndScroll = () => { const { history, location } = this.props history.replace(`${location.pathname}#${this.anchorName}`) scrollToAnchor() } - private removeHash = () => { + removeHash = () => { const { history, location } = this.props history.replace(location.pathname) @@ -161,12 +159,12 @@ class ComponentExample extends React.Component { + handleDirectLinkClick = () => { this.setHashAndScroll() copyToClipboard(window.location.href) } - private handleMouseLeave = () => { + handleMouseLeave = () => { this.setState({ isHovering: false, handleMouseLeave: undefined, @@ -174,7 +172,7 @@ class ComponentExample extends React.Component { + handleMouseMove = () => { this.setState({ isHovering: true, handleMouseLeave: this.handleMouseLeave, @@ -182,25 +180,13 @@ class ComponentExample extends React.Component { - if (shouldShowCode !== this.state.showCode) { - this.setState({ showCode: shouldShowCode }, this.updateHash) - } - } - - handleShowCodeInactive = (e: Event) => { - if (this.clickedOutsideComponent(e)) { - this.handleShowCode(false) - } - } - - private handleShowRtlClick = e => { + handleShowRtlClick = e => { e.preventDefault() this.setState(prevState => ({ showRtl: !prevState.showRtl })) } - private handleShowCodeClick = e => { + handleShowCodeClick = e => { e.preventDefault() const { showCode } = this.state @@ -208,7 +194,7 @@ class ComponentExample extends React.Component { + handleShowVariablesClick = e => { e.preventDefault() const { showVariables } = this.state @@ -216,7 +202,7 @@ class ComponentExample extends React.Component { + handleShowTransparentClick = e => { e.preventDefault() const { showTransparent } = this.state @@ -224,36 +210,36 @@ class ComponentExample extends React.Component { + handlePass = () => { const { title } = this.props if (title) _.invoke(this.context, 'onPassed', null, this.props) } - private copyJSX = () => { + copyJSX = () => { copyToClipboard(this.state.sourceCode) this.setState({ copiedCode: true }) setTimeout(() => this.setState({ copiedCode: false }), 1000) } - private resetJSX = () => { + resetJSX = () => { if (this.sourceCodeMgr.originalCodeHasChanged && confirm('Lose your changes?')) { this.sourceCodeMgr.resetToOriginalCode() this.updateAndRenderSourceCode() } } - private getKnobsFilename = () => `./${this.props.examplePath}.knobs.tsx` + getKnobsFilename = () => `./${this.props.examplePath}.knobs.tsx` - private getKebabExamplePath = () => { + getKebabExamplePath = () => { if (!this.kebabExamplePath) this.kebabExamplePath = _.kebabCase(this.props.examplePath) return this.kebabExamplePath } - private hasKnobs = () => _.includes(knobsContext.keys(), this.getKnobsFilename()) + hasKnobs = () => _.includes(knobsContext.keys(), this.getKnobsFilename()) - private renderExampleFromCode = (): JSX.Element => { + renderExampleFromCode = (): JSX.Element => { const { sourceCode } = this.state if (sourceCode == null) { @@ -263,7 +249,7 @@ class ComponentExample extends React.Component{({ element }) => element} } - private renderElement = (element: React.ReactElement) => { + renderElement = (element: React.ReactElement) => { const { showRtl, componentVariables, themeName } = this.state const theme = themes[themeName] @@ -277,7 +263,7 @@ class ComponentExample extends React.Component{element} } - private renderMissingExample = (): JSX.Element => { + renderMissingExample = (): JSX.Element => { const missingExamplePath = `./docs/src/examples/${this.sourceCodeMgr.currentPath}.tsx` return ( @@ -287,7 +273,7 @@ class ComponentExample extends React.Component { + handleKnobChange = knobs => { this.setState(prevState => ({ knobs: { ...prevState.knobs, @@ -296,7 +282,7 @@ class ComponentExample extends React.Component { + getKnobsComponent = () => { if (typeof this.KnobsComponent !== 'undefined') { return this.KnobsComponent } @@ -306,35 +292,35 @@ class ComponentExample extends React.Component { + getKnobsValue = () => { const Knobs = this.getKnobsComponent() return Knobs ? { ...Knobs.defaultProps, ...this.state.knobs } : null } - private renderKnobs = () => { + renderKnobs = () => { const Knobs = this.getKnobsComponent() return Knobs ? : null } - private getDisplayName = () => this.props.examplePath.split('/')[1] + getDisplayName = () => this.props.examplePath.split('/')[1] - private handleChangeCode = (sourceCode: string) => { + handleChangeCode = (sourceCode: string) => { this.sourceCodeMgr.currentCode = sourceCode this.updateAndRenderSourceCode() } - private updateAndRenderSourceCode = () => { + updateAndRenderSourceCode = () => { this.setState({ sourceCode: this.sourceCodeMgr.currentCode }) } - private setApiCodeType = (codeType: SourceCodeType) => { + setApiCodeType = (codeType: SourceCodeType) => { this.sourceCodeMgr.codeType = codeType this.updateAndRenderSourceCode() } - private renderApiCodeMenu = (): JSX.Element => { + renderApiCodeMenu = (): JSX.Element => { const { sourceCode } = this.state const lineCount = sourceCode && sourceCode.match(/^/gm)!.length @@ -370,7 +356,23 @@ class ComponentExample extends React.Component { + canBePrettified = () => { + const { sourceCode } = this.state + + try { + return sourceCode !== formatCode(sourceCode) + } catch (err) { + return false + } + } + + handleFormat = () => { + const { sourceCode } = this.state + + this.handleChangeCode(formatCode(sourceCode)) + } + + renderCodeEditorMenu = (): JSX.Element => { const { copiedCode } = this.state const { originalCodeHasChanged, currentPath } = this.sourceCodeMgr const codeEditorStyle: React.CSSProperties = { @@ -392,8 +394,20 @@ class ComponentExample extends React.Component + + {({ error }) => ( + + )} + { + renderJSX = () => { const { showCode, sourceCode } = this.state if (!showCode) return null @@ -426,19 +440,13 @@ class ComponentExample extends React.Component {this.renderCodeEditorMenu()} - + ) } - private renderError = () => { + renderError = () => { return ( {({ error }) => @@ -452,49 +460,23 @@ class ComponentExample extends React.Component { + renderHTML = () => { const { showCode } = this.state if (!showCode) return null return ( - {({ markup }) => { - // add new lines between almost all adjacent elements - // moves inline elements to their own line - const preFormattedHTML = markup.replace(/><(?!\/i|\/label|\/span)/g, '>\n<') - - const beautifiedHTML = html(preFormattedHTML, { - indent_size: 2, - indent_char: ' ', - wrap_attributes: 'auto', - wrap_attributes_indent_size: 2, - end_with_newline: false, - }) - - return ( -
- - HTML - -
- -
-
- ) - }} + {({ markup }) => ( +
+ + +
+ )}
) } - private renderVariables = () => { + renderVariables = () => { const { showVariables } = this.state if (!showVariables) return undefined @@ -547,7 +529,7 @@ class ComponentExample extends React.Component (e, { value }) => { + handleVariableChange = (component, variable) => (e, { value }) => { this.setState(state => ({ componentVariables: { ...state.componentVariables, @@ -556,7 +538,7 @@ class ComponentExample extends React.Component (this.componentRef = c!)} - > + {/* Ensure anchor links don't occlude card shadow effect */}
{ {exceeds && }
- {_.map(sliced, value => {value})} + {_.map(sliced, value => ( + {value} + ))} {exceeds && !showAll && '...'}
diff --git a/docs/src/components/ComponentDoc/ComponentTable/ComponentTable.tsx b/docs/src/components/ComponentDoc/ComponentTable/ComponentTable.tsx index fcb71afbe4..f4dfc36730 100644 --- a/docs/src/components/ComponentDoc/ComponentTable/ComponentTable.tsx +++ b/docs/src/components/ComponentDoc/ComponentTable/ComponentTable.tsx @@ -13,7 +13,9 @@ const ComponentTable: any = ({ props }) => ( - {_.map(props, propDef => )} + {_.map(props, propDef => ( + + ))}
) diff --git a/docs/src/components/Editor/Editor.tsx b/docs/src/components/Editor/Editor.tsx index a7278f19a1..44f66a07ce 100644 --- a/docs/src/components/Editor/Editor.tsx +++ b/docs/src/components/Editor/Editor.tsx @@ -8,7 +8,6 @@ import 'brace/mode/html' import 'brace/mode/jsx' import 'brace/mode/sh' import 'brace/theme/tomorrow_night' -import { doesNodeContainClick, EventStack } from 'src/lib' const parentComponents = [] @@ -46,35 +45,28 @@ const semanticUIReactCompleter = { languageTools.addCompleter(semanticUIReactCompleter) export interface EditorProps extends AceEditorProps { - id: string - value?: string - mode?: 'html' | 'jsx' | 'sh' - onClick?: () => void - onOutsideClick?: (e: Event) => void active?: boolean - showCursor?: boolean highlightGutterLine?: boolean + mode?: 'html' | 'jsx' | 'sh' + value?: string + showCursor?: boolean } export const EDITOR_BACKGROUND_COLOR = '#1D1F21' export const EDITOR_GUTTER_COLOR = '#26282d' class Editor extends React.Component { - private static readonly refName = 'aceEditor' - private clickSubscription = EventStack.noSubscription + editorRef: any + name = `docs-editor-${_.uniqueId()}` - public static propTypes = { - id: PropTypes.string.isRequired, + static propTypes = { value: PropTypes.string.isRequired, mode: PropTypes.oneOf(['html', 'jsx', 'sh']), - onClick: PropTypes.func, - onOutsideClick: PropTypes.func, active: PropTypes.bool, showCursor: PropTypes.bool, } - public static defaultProps = { - id: '', + static defaultProps = { value: '', mode: 'jsx', theme: 'tomorrow_night', @@ -84,6 +76,7 @@ class Editor extends React.Component { enableBasicAutocompletion: true, enableLiveAutocompletion: true, editorProps: { $blockScrolling: Infinity }, + setOptions: { fixedWidthGutter: true, showFoldWidgets: false }, showPrintMargin: false, tabSize: 2, maxLines: Infinity, @@ -93,7 +86,12 @@ class Editor extends React.Component { showCursor: true, } - public componentWillReceiveProps(nextProps: EditorPropsWithDefaults) { + componentDidMount() { + const { showCursor } = this.props + this.setCursorVisibility(showCursor) + } + + componentWillReceiveProps(nextProps) { const previousPros = this.props const { active, showCursor } = nextProps @@ -101,90 +99,21 @@ class Editor extends React.Component { this.setCursorVisibility(showCursor) } - if (active !== previousPros.active) { - if (active) { - this.editor.focus() // focus editor when editor is active - this.addDocumentListener() - } else { - this.removeDocumentListener() - } + // focus editor when editor it becomes active + if (active !== previousPros.active && active) { + this.editorRef.editor.focus() } } - public componentDidMount() { - const { active, showCursor } = this.props as EditorPropsWithDefaults + setCursorVisibility = visible => { + const cursor = this.editorRef.editor.renderer.$cursorLayer.element - this.setCursorVisibility(showCursor) - - if (active) { - this.addDocumentListener() - } + cursor.style.display = visible ? '' : 'none' } - public componentWillUnmount() { - this.removeDocumentListener() - } - - public render() { - const { id, onClick, ...rest } = this.props - - return ( -
- -
- ) - } - - private handleDocumentClick = (e: Event) => { - const { onOutsideClick } = this.props - if (!doesNodeContainClick(this.container, e) && onOutsideClick) { - onOutsideClick(e) - } - } - - private addDocumentListener() { - this.clickSubscription.unsubscribe() - this.clickSubscription = EventStack.subscribe('click', this.handleDocumentClick) - } - - private removeDocumentListener() { - this.clickSubscription.unsubscribe() - } - - private get editor() { - return this.safeCall(() => (this.refs[Editor.refName] as any).editor) - } - - private get renderer() { - return this.safeCall(() => this.editor.renderer) - } - - private get cursor(): HTMLElement { - return this.safeCall(() => this.renderer.$cursorLayer.element) - } - - private get container(): HTMLElement { - return this.safeCall(() => this.renderer.container) - } - - private setCursorVisibility(visible: boolean): void { - this.safeCall(() => { - this.cursor.style.display = visible ? '' : 'none' - }) - } - - private safeCall(cb: () => T, logError?: boolean): T | undefined { - try { - return cb() - } catch (error) { - if (logError) { - console.error(`Editor.tsx:safeCall error: ${error}`) - } - return undefined - } + render() { + return (this.editorRef = c)} /> } } export default Editor - -export type EditorPropsWithDefaults = EditorProps & (typeof Editor.defaultProps) diff --git a/docs/src/components/ExampleSnippet/ExampleSnippet.tsx b/docs/src/components/ExampleSnippet/ExampleSnippet.tsx index 7d44e943d4..165f08c71b 100644 --- a/docs/src/components/ExampleSnippet/ExampleSnippet.tsx +++ b/docs/src/components/ExampleSnippet/ExampleSnippet.tsx @@ -1,24 +1,56 @@ import * as React from 'react' -import CodeSnippet, { CodeSnippetProps } from '../CodeSnippet' +import reactElementToJSXString from 'react-element-to-jsx-string' +import CodeSnippet from '../CodeSnippet' -const ExampleSnippet = ({ - render, - style, - ...rest -}: CodeSnippetProps & { +export type ExampleSnippetProps = { + value?: string render?: () => React.ReactNode -}) => ( -
- - {render &&
{render()}
} -
-) +} + +const rootStyle = { + background: 'white', + marginBottom: '2rem', + boxShadow: '0 0 2px rgba(0, 0, 0, 0.2)', +} + +const renderedStyle = { + padding: '1rem', +} + +const ExampleSnippet = ({ render = () => null, value }: ExampleSnippetProps) => { + let renderHasFunction + + const element = render() + const string = + value || + reactElementToJSXString(element, { + showDefaultProps: false, + showFunctions: true, + functionValue: fn => (renderHasFunction = true), + }) + + if (process.env.NODE_ENV !== 'production') { + if (renderHasFunction && !value) { + throw new Error( + [ + "This ExampleSnippet's render prop output includes function.", + ' A helpful JSX string cannot be generated for functions.', + ' Please define a `value` string prop that displays readable code to the user.', + '\n\n', + 'RENDERED:', + '\n\n', + string, + ].join(''), + ) + } + } + + return ( +
+ + {element &&
{element}
} +
+ ) +} export default ExampleSnippet diff --git a/docs/src/examples/components/Button/Usage/index.tsx b/docs/src/examples/components/Button/Usage/index.tsx index 9485fe95c6..73cb8987fc 100644 --- a/docs/src/examples/components/Button/Usage/index.tsx +++ b/docs/src/examples/components/Button/Usage/index.tsx @@ -6,7 +6,7 @@ const Usage = () => ( diff --git a/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.shorthand.tsx b/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.shorthand.tsx index 78f4acdb40..84f895029f 100644 --- a/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.shorthand.tsx +++ b/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.shorthand.tsx @@ -8,9 +8,11 @@ const janeAvatar = { const content = (
- Sure! Try one of these places:
+ Sure! Try one of these places: +
www.goodFood1.com,
- www.goodFood2.com or
+ www.goodFood2.com or +
www.goodFood3.com
) diff --git a/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.tsx b/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.tsx index 332dad7599..110553fd61 100644 --- a/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.tsx +++ b/docs/src/examples/components/Chat/Types/ChatMessageExampleStyled.tsx @@ -8,9 +8,11 @@ const janeAvatar = { const content = (
- Sure! Try one of these places:
+ Sure! Try one of these places: +
www.goodFood1.com,
- www.goodFood2.com or
+ www.goodFood2.com or +
www.goodFood3.com
) diff --git a/docs/src/examples/components/Popup/Variations/PopupExamplePosition.shorthand.tsx b/docs/src/examples/components/Popup/Variations/PopupExamplePosition.shorthand.tsx index 03421b0325..d3d4e44603 100644 --- a/docs/src/examples/components/Popup/Variations/PopupExamplePosition.shorthand.tsx +++ b/docs/src/examples/components/Popup/Variations/PopupExamplePosition.shorthand.tsx @@ -12,7 +12,9 @@ const PopupWithButton = props => { content={{ content: (

- The popup is rendered {position} the trigger
aligned to the {align}. + The popup is rendered {position} the trigger +
+ aligned to the {align}.

), }} diff --git a/docs/src/examples/components/Popup/Variations/PopupExamplePosition.tsx b/docs/src/examples/components/Popup/Variations/PopupExamplePosition.tsx index 1624a03b6d..64de34d011 100644 --- a/docs/src/examples/components/Popup/Variations/PopupExamplePosition.tsx +++ b/docs/src/examples/components/Popup/Variations/PopupExamplePosition.tsx @@ -13,7 +13,9 @@ const PopupArrowExample = props => { content={{ content: (

- The popup is rendered {position} the trigger
aligned to the {align}. + The popup is rendered {position} the trigger +
+ aligned to the {align}.

), }} diff --git a/docs/src/examples/components/Portal/Types/PortalExample.shorthand.tsx b/docs/src/examples/components/Portal/Types/PortalExample.shorthand.tsx index 84589f8d69..fa47e224a9 100644 --- a/docs/src/examples/components/Portal/Types/PortalExample.shorthand.tsx +++ b/docs/src/examples/components/Portal/Types/PortalExample.shorthand.tsx @@ -45,7 +45,11 @@ class PortalExamplePortal extends React.Component { Event Log -
{log.map((e, i) => 
{e}
)}
+
+            {log.map((e, i) => (
+              
{e}
+ ))} +
) diff --git a/docs/src/examples/components/Portal/Types/PortalExample.tsx b/docs/src/examples/components/Portal/Types/PortalExample.tsx index 9d3ef90b1e..cc642bb397 100644 --- a/docs/src/examples/components/Portal/Types/PortalExample.tsx +++ b/docs/src/examples/components/Portal/Types/PortalExample.tsx @@ -42,7 +42,11 @@ class PortalExamplePortal extends React.Component { Event Log -
{log.map((e, i) => 
{e}
)}
+
+            {log.map((e, i) => (
+              
{e}
+ ))} +
) diff --git a/docs/src/examples/components/Portal/Types/PortalExampleControlled.shorthand.tsx b/docs/src/examples/components/Portal/Types/PortalExampleControlled.shorthand.tsx index 97aa049f27..e4b40bc9e4 100644 --- a/docs/src/examples/components/Portal/Types/PortalExampleControlled.shorthand.tsx +++ b/docs/src/examples/components/Portal/Types/PortalExampleControlled.shorthand.tsx @@ -30,7 +30,11 @@ class PortalExampleControlled extends React.Component { Event Log -
{log.map((e, i) => 
{e}
)}
+
+            {log.map((e, i) => (
+              
{e}
+ ))} +
Event Log -
{log.map((e, i) => 
{e}
)}
+
+            {log.map((e, i) => (
+              
{e}
+ ))} +
- + + + - + - - + + + diff --git a/docs/src/utils/formatCode.ts b/docs/src/utils/formatCode.ts new file mode 100644 index 0000000000..0c87458b26 --- /dev/null +++ b/docs/src/utils/formatCode.ts @@ -0,0 +1,24 @@ +import prettier from 'prettier/standalone' +import prettierConfig from '../../../.prettierrc.json' + +delete prettierConfig.$schema +delete prettierConfig.overrides + +// Heads up! +// Please use this function directly and don't reexport it in utils. +// https://github.com/prettier/prettier/issues/4959 + +const formatCode = (code, parser = 'babylon') => { + if (!code) return '' + + const formatted = prettier.format(code, { + ...prettierConfig, + // a narrower print width is more friendly to doc examples + parser, + plugins: window.prettierPlugins, + }) + + return formatted.replace(/^; ( to the screen reader user only can be added to the label:

-> ', - ].join('\n')} + value={` + + `} />

@@ -111,11 +114,13 @@ export default () => ( {code('aria-*')} attributes:

", - " Download", - '', - ].join('\n')} + mode="html" + value={` + + `} />

Basic rules for semantically correct HTML:

@@ -156,7 +161,6 @@ export default () => (

Similarly, the controls

- {' '}

@@ -211,8 +215,9 @@ export default () => ( {link( 'Focus Zone from Office UI Fabric', 'https://developer.microsoft.com/en-us/fabric#/components/focuszone', - )}. This component allows to wrap any focusable component/element and adds arrow key - navigation functionality. + )} + . This component allows to wrap any focusable component/element and adds arrow key navigation + functionality.

There are two basic use cases for Focus Zone:

    @@ -228,9 +233,11 @@ export default () => (
`, `}`].join( - '\n', - )} + value={` + const App = () => ( + + ) + `} />

{code('FocusZone')} operates based on DOM structure to:

    @@ -308,40 +315,38 @@ export default () => (

    Example: Menu component
    ', - '}', - ].join('\n')} + value={` + const items = [ + {key: "editorials", content: "Editorials"} , + {key: "review", content: "Reviews" }, + {key: "events", content: "Upcoming Events" }, + ] + + const menu = + `} />

    - Default accessibility behaviour for {code('Menu')} component is {code('MenuBehavior')} ({code( - 'MenuItemBehavior', - )}{' '} - for the menu items). These behaviours add appropriate ARIA roles by default: + Default accessibility behaviour for {code('Menu')} component is {code('MenuBehavior')} ( + {code('MenuItemBehavior')} for the menu items). These behaviours add appropriate ARIA roles by + default:

    Rendered HTML:

    ', - ' ', - ' ', - ' ', - '
', - ].join('\n')} + value={` + + `} /> @@ -353,17 +358,19 @@ export default () => ( following example:

', ' Editorials', ' ', ' )'].join( - '\n', - )} + value={` + + Editorials + + `} />

Rendered HTML:

', - ' ', - '', - ].join('\n')} + value={` + + `} />

Notice that Stardust only applies role only on the {code('

  • ')} element which it rendered. @@ -374,51 +381,49 @@ export default () => (

    Proper accessible menu implementation in this case would be:

    ', - ' ', - ' ', - ')', - ].join('\n')} + value={` + + + + `} />

    This way, Stardust will generate a child component based on the provided content string and will apply the role to it:

    ', - '', - 'export default MenuExamplePrimary', - ].join('\n')} + value={` + import React from 'react' + import { Menu } from '@stardust-ui/react' + + const items = [ + { key: 'editorials', content: 'Editorials' }, + { key: 'review', content: 'Reviews' }, + { key: 'events', content: 'Upcoming Events' }, + ] + + const MenuExamplePrimary = () => + + export default MenuExamplePrimary + `} />

    And this is the HTML that will be rendered:

    ', - ' ', - ' ', - ' ', - '', - ].join('\n')} + value={` + + `} /> @@ -429,15 +434,13 @@ export default () => (

    ', - ' ', - ' Conversation', - ' ', - '
    ', - ')', - ].join('\n')} + value={` + + + Conversation + + + `} />

    @@ -485,17 +488,18 @@ export default () => (

    Example:

    ', ')'].join( - '\n', - )} + value={` + ', - ].join('\n')} + mode="html" + value={` + + `} />
    diff --git a/docs/src/views/IntegrateCustomComponents.tsx b/docs/src/views/IntegrateCustomComponents.tsx index e65bdd7803..ffd91383b4 100644 --- a/docs/src/views/IntegrateCustomComponents.tsx +++ b/docs/src/views/IntegrateCustomComponents.tsx @@ -44,17 +44,17 @@ export default () => ( for adapting your custom component to the Stardust's styling and theming mechanisms.

    {`, - ` const { classes } = stardust`, - ` return `, - ` }`, - `})`, - ].join('\n')} + value={` + import { createComponent } from '@stardust-ui/react' + + const StyledButton = createComponent({ + displayName: 'StyledButton', + render: ({stardust, className, children}) => { + const { classes } = stardust + return + } + }) + `} />

    Let's go step by step throughout all bits of the createComponent method. @@ -66,28 +66,7 @@ export default () => ( component.

    ({`, - ` backgroundColor: siteVariables.brand,`, - ` color: variables.color,`, - ` }),`, - ` },`, - ` },`, - ` }}`, - `>`, - ` Provider styled button `, - '', - ].join('\n')} - render={() => ( + value={` ( StyledButton: { root: ({ props, variables, theme: { siteVariables } }) => ({ backgroundColor: siteVariables.brand, - color: (variables as any).color, + color: variables.color, }), }, }, @@ -107,7 +86,7 @@ export default () => ( > Provider styled button - )} + `} />

    The second argument of the createComponent config param is the{' '} @@ -117,9 +96,8 @@ export default () => (

    • - stardust - the object containing the evaluated theming props ( - classes - + stardust - the object containing the evaluated theming props ( + classes and rtl).
    • @@ -142,11 +120,6 @@ export default () => ( } /> `, - ` Inline styled button`, - ``, - ].join('\n')} render={() => ( Inline styled button @@ -156,24 +129,22 @@ export default () => ( The same can be achieved with adding styles in the componentStyles part of the{' '} theme in the Provider. ({`, - ` ':hover': {`, - ` backgroundColor: "yellow"`, - ` }`, - ` }),`, - ` },`, - ` },`, - ` }}`, - `>`, - ` Inline styled button`, - '', - ].join('\n')} + render={() => ( + + Inline styled button + + )} />

      For more advanced theming scenarios, please take a look in the Styles section on the{' '} @@ -189,31 +160,31 @@ export default () => ( /> Let's consider that the following theme was passed to the Provider. ({`, - ` color: variables.color,`, - ` }),`, - ` },`, - ` },`, - ` }}`, - `>`, - ` ...`, - '', - ].join('\n')} + value={` + ({ + color: variables.color + }), + }, + }, + }} + > + ... + + `} /> Then we can use the variables prop for changing the color inside the{' '} StyledButton. `, - ` Inline styled button`, - ``, - ].join('\n')} + value={` + + Inline styled button + + `} render={() => ( ( The alternative approach with defining componentVariables inside the{' '} theme would like like this: ({`, - ` color: variables.color,`, - ` }),`, - ` },`, - ` },`, - ` }}`, - `>`, - ` ...`, - '', - ].join('\n')} + value={` + ({ + color: variables.color + }), + }, + }, + }} + > + ... + + `} />

      For more advanced theming scenarios, please take a look in the Variables section on the{' '} diff --git a/docs/src/views/Introduction.tsx b/docs/src/views/Introduction.tsx index a500b64e90..1dc09de676 100644 --- a/docs/src/views/Introduction.tsx +++ b/docs/src/views/Introduction.tsx @@ -1,43 +1,12 @@ import * as _ from 'lodash' -import PropTypes from 'prop-types' import * as React from 'react' import { NavLink } from 'react-router-dom' +import { Container, Header, Segment } from 'semantic-ui-react' -import Editor from 'docs/src/components/Editor' -import { Container, Divider, Grid, Header, Icon, Label, Segment } from 'semantic-ui-react' import Logo from '../components/Logo/Logo' const pkg = require('package.json') -const Comparison: any = ({ jsx, html }) => ( - - - - - - - - - - - - - - - - - -) - -Comparison.propTypes = { - jsx: PropTypes.string, - html: PropTypes.string, -} - const Introduction = () => ( diff --git a/docs/src/views/QuickStart.tsx b/docs/src/views/QuickStart.tsx index 855ffc3986..e8671b8fe8 100644 --- a/docs/src/views/QuickStart.tsx +++ b/docs/src/views/QuickStart.tsx @@ -28,33 +28,31 @@ export default () => (

      `, - ` `, - ` ,`, - ` document.getElementById('root'),`, - `)`, - ].join('\n')} + value={` + import React from 'react' + import ReactDOM from 'react-dom' + import { Provider, themes } from '@stardust-ui/react' + + import App from './App' + + ReactDOM.render( + + + , + document.getElementById('root'), + ) + `} />
      Usage

      That's it. You can now use Stardust UI components in your app.

      (`, - ` `, - ` Branding`, - `
  • `, - ``, - ].join('\n')} render={() => ( - +
    Branding @@ -76,15 +55,11 @@ export default () => (

    You can define component variables on a single instance of a component.

    `, - ``, - ].join('\n')} render={() => ( -
    + <> -
    + )} /> @@ -93,19 +68,8 @@ export default () => ( the Provider.

    `, - ``, - '', - ``, - ` `, - ` `, - ` `, - ` `, - ``, - ].join('\n')} render={() => ( -
    + <> @@ -115,7 +79,7 @@ export default () => ( -
    + )} />

    @@ -141,21 +105,12 @@ export default () => (

    You can define styles on a single component instance.

    - This is green text`} - render={() => This is green text} - /> + This is green text} />

    Every slot (named part) of every component also accepts styles that are applied to the root element of the slot.

    `, - ].join('\n')} render={() => (
    + )} />

    @@ -228,24 +162,24 @@ export default () => (

    `, - ` ... `, - `
    `, - ].join('\n')} + value={` + + ... + + `} />

    @@ -259,29 +193,21 @@ export default () => ( how we can use them in our components.

    `, - `
    `, - ` `, - ` `, - `
    `, - `
    `, - ].join('\n')} render={() => ( - +
    @@ -306,27 +232,21 @@ export default () => ( `, - ` `, - ` `, - ``, - ].join('\n')} render={() => ( - +
    diff --git a/docs/src/views/ThemingExamples.tsx b/docs/src/views/ThemingExamples.tsx index d35db5c187..000427b1ee 100644 --- a/docs/src/views/ThemingExamples.tsx +++ b/docs/src/views/ThemingExamples.tsx @@ -17,9 +17,9 @@ export default () => ( some parameterizable standard themes or you can create your own.

    - Startdust theme is constructed around CSS-like style objects ( - styles - ) and variables. + Startdust theme is constructed around CSS-like style objects ( + styles) and{' '} + variables.

    Stardust supports four levels of theming:

      @@ -42,24 +42,24 @@ export default () => (

      If you do not need any custom theming, just import some components and start using them.

      `, - ` `, - ` <>`, - `
    `, - `
    `, - `)`, - ``, - `export default provider`, - ].join('\n')} + value={` + import React from 'react' + import { Button, Divider, Icon, Label, Provider } from '@stardust-ui/react' + + const theme = { + siteVariables: { + brand: 'darkred', + brand04: '#8F5873', + gray08: '#A8516E8C', + gray06: '#f4c2c2', + gray03: '#757575', + }, + componentVariables: { + Button: { + height: '24px', + minWidth: '24px', + borderRadius: '8px', + color: 'darkred', + secondaryColor: '#ffffff', + secondaryBorderColor: 'transparent', + secondaryBackgroundColor: '#6699CC', + secondaryBackgroundColorHover: '#91A3B0', + }, + }, + componentStyles: { + Button: { + icon: { + fontSize: '12px', + }, + }, + }, + } + + const provider = () => ( + +
    +
    +
    + ) + + export default provider + `} render={() => (
    ( using nested providers and overwrite the needed styles.

    `, - ` /* Default theming */`, - `
    `, - ` `, - ` Branding`, - ``, - ` /* First nested theming */`, - ` `, - `
    `, - `
    `, - ``, - `
    `, - ` `, - `
    `, - `
    `, - `
    `, - ].join('\n')} + value={` +
    + /* Default theming */ +
    + + Branding + + /* First nested theming */ + +
    +
    + +
    +
    +
    +
    + + `} render={() => (
    diff --git a/package.json b/package.json index 1960ea1159..5fc391b956 100644 --- a/package.json +++ b/package.json @@ -120,12 +120,11 @@ "inquirer": "^6.0.0", "jest": "^23.6.0", "jest-axe": "^3.1.0", - "js-beautify": "^1.6.14", "leven": "^2.1.0", "lint-staged": "^7.0.2", "merge2": "^1.2.2", "normalize.css": "^8.0.0", - "prettier": "1.12.0", + "prettier": "^1.15.3", "raw-loader": "^0.5.1", "react": "^16.0.0", "react-ace": "^5.1.2", @@ -133,6 +132,7 @@ "react-docgen-typescript": "^1.12.0", "react-document-title": "^2.0.3", "react-dom": "^16.0.0", + "react-element-to-jsx-string": "^14.0.2", "react-hot-loader": "^4.1.3", "react-router": "^4.1.2", "react-router-dom": "^4.1.2", diff --git a/src/themes/teams/components/Menu/menuItemStyles.ts b/src/themes/teams/components/Menu/menuItemStyles.ts index 1edd76b8c7..675c3039e5 100644 --- a/src/themes/teams/components/Menu/menuItemStyles.ts +++ b/src/themes/teams/components/Menu/menuItemStyles.ts @@ -26,14 +26,14 @@ const getActionStyles = ({ background: v.defaultBackgroundColor, } : primary - ? { - color: v.primaryActiveColor, - background: v.primaryActiveBackgroundColor, - } - : { - color, - background: v.defaultActiveBackgroundColor, - } + ? { + color: v.primaryActiveColor, + background: v.primaryActiveBackgroundColor, + } + : { + color, + background: v.defaultActiveBackgroundColor, + } const itemSeparator: ComponentSlotStyleFunction = ({ props, @@ -211,8 +211,8 @@ const menuItemStyles: ComponentSlotStylesInput Date: Wed, 5 Dec 2018 17:49:43 -0800 Subject: [PATCH 2/2] docs: add changelog entry [ci skip] --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19d913f989..7bd68e5e0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Features - `Ref` components uses `forwardRef` API by default @layershifter ([#491](https://github.com/stardust-ui/react/pull/491)) +### Documentation +- Add `prettier` support throughout the docs @levithomason ([#568](https://github.com/stardust-ui/react/pull/568)) + ## [v0.14.0](https://github.com/stardust-ui/react/tree/v0.14.0) (2018-12-05) [Compare changes](https://github.com/stardust-ui/react/compare/v0.13.3...v0.14.0)