import React from "react"; import { Button, ClipboardButton } from "./buttons"; import EditorState from "./EditorState"; import { DebugPanel, InputPanel, OutputPanel } from "./panels"; import PrettierFormat from "./PrettierFormat"; import { shallowEqual } from "./helpers"; import * as urlHash from "./urlHash"; import formatMarkdown from "./markdown"; import * as util from "./util"; import getCodeSample from "./codeSamples"; import { Sidebar, SidebarCategory } from "./sidebar/components"; import SidebarOptions from "./sidebar/SidebarOptions"; import Option from "./sidebar/options"; import { Checkbox } from "./sidebar/inputs"; const CATEGORIES_ORDER = [ "Global", "Common", "JavaScript", "Markdown", "HTML", "Special" ]; const ENABLED_OPTIONS = [ "parser", "printWidth", "tabWidth", "useTabs", "semi", "singleQuote", "bracketSpacing", "jsxSingleQuote", "jsxBracketSameLine", "quoteProps", "arrowParens", "trailingComma", "proseWrap", "htmlWhitespaceSensitivity", "insertPragma", "requirePragma", "vueIndentScriptAndStyle" ]; const ISSUES_URL = "https://github.com/prettier/prettier/issues/new?body="; const MAX_LENGTH = 8000 - ISSUES_URL.length; // it seems that GitHub limit is 8195 const COPY_MESSAGE = "\n"; class Playground extends React.Component { constructor(props) { super(); const original = urlHash.read(); const defaultOptions = util.getDefaults( props.availableOptions, ENABLED_OPTIONS ); const options = Object.assign(defaultOptions, original.options); const content = original.content || getCodeSample(options.parser); this.state = { content, options }; this.handleOptionValueChange = this.handleOptionValueChange.bind(this); this.setContent = content => this.setState({ content }); this.clearContent = this.setContent.bind(this, ""); this.resetOptions = () => this.setState({ options: defaultOptions }); this.enabledOptions = orderOptions(props.availableOptions, ENABLED_OPTIONS); this.rangeStartOption = props.availableOptions.find( opt => opt.name === "rangeStart" ); this.rangeEndOption = props.availableOptions.find( opt => opt.name === "rangeEnd" ); } componentDidUpdate(_, prevState) { const { content, options } = this.state; if ( !shallowEqual(prevState.options, this.state.options) || prevState.content !== content ) { urlHash.replace({ content, options }); } } handleOptionValueChange(option, value) { this.setState(state => { const options = Object.assign({}, state.options); if (option.type === "int" && isNaN(value)) { delete options[option.name]; } else { options[option.name] = value; } const content = state.content === "" || state.content === getCodeSample(state.options.parser) ? getCodeSample(options.parser) : state.content; return { options, content }; }); } getMarkdown(formatted, reformatted, full) { const { content, options } = this.state; const { availableOptions, version } = this.props; return formatMarkdown( content, formatted, reformatted || "", version, window.location.href, options, util.buildCliArgs(availableOptions, options), full ); } render() { const { worker } = this.props; const { content, options } = this.state; return ( {editorState => ( {({ formatted, debug }) => { const fullReport = this.getMarkdown( formatted, debug.reformatted, true ); const showFullReport = encodeURIComponent(fullReport).length < MAX_LENGTH; return (
{editorState.showAst ? ( ) : null} {editorState.showDoc ? ( ) : null} {editorState.showSecondFormat ? ( ) : null}
Copy config JSON
Copy link this.getMarkdown(formatted, debug.reformatted) } > Copy markdown (showFullReport ? "" : fullReport)} > Report issue
); }}
)}
); } } function orderOptions(availableOptions, order) { const optionsByName = {}; for (const option of availableOptions) { optionsByName[option.name] = option; } return order.map(name => optionsByName[name]); } function getReportLink(reportBody) { return `${ISSUES_URL}${encodeURIComponent(reportBody)}`; } function getSecondFormat(formatted, reformatted) { return formatted === "" ? "" : formatted === reformatted ? "✓ Second format is unchanged." : reformatted; } export default Playground;