From c827be8897ac248bc458f73ea79f98db576e51dd Mon Sep 17 00:00:00 2001 From: atanasster Date: Mon, 9 Mar 2020 02:35:09 -0400 Subject: [PATCH] fix: tests with updated components --- .../extract-component.test.ts.snap | 972 +++++++++--------- .../__snapshots__/follow-imports.test.ts.snap | 10 +- .../extract-component/node-modules-source.js | 2 +- 3 files changed, 466 insertions(+), 518 deletions(-) diff --git a/core/instrument/test/__snapshots__/extract-component.test.ts.snap b/core/instrument/test/__snapshots__/extract-component.test.ts.snap index 9c04615ff..fd5bfd1d5 100644 --- a/core/instrument/test/__snapshots__/extract-component.test.ts.snap +++ b/core/instrument/test/__snapshots__/extract-component.test.ts.snap @@ -167,82 +167,119 @@ export const Button = React.forwardRef((props, ref) => ( exports[`extract-component node-modules-source.js 1`] = ` Object { - "from": "@component-controls/block-components", + "from": "@component-controls/components", "importedName": "Subtitle", "loc": Object { "end": Object { "column": 1, - "line": 56, + "line": 80, }, "start": Object { "column": 23, - "line": 46, + "line": 67, }, }, "name": "Button", "repository": Object { - "browse": "https://github.com/ccontrols/component-controls/tree/master/ui/block-components/dist/index.js", + "browse": "https://github.com/ccontrols/component-controls/tree/master/ui/components/dist/index.js", "docs": "https://github.com/ccontrols/component-controls/tree/master#readme", "issues": "https://github.com/ccontrols/component-controls/issues", }, - "request": "/Users/atanasster/component-controls/node_modules/@component-controls/block-components/dist/index.js", + "request": "/Users/atanasster/component-controls/node_modules/@component-controls/components/dist/index.js", "source": "'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -var React = _interopDefault(require('react')); var styled = _interopDefault(require('@emotion/styled')); -var tslib = require('tslib'); var themeUi = require('theme-ui'); -var components = require('@component-controls/components'); -var global = require('global'); -var qs = _interopDefault(require('qs')); -var copy = _interopDefault(require('copy-to-clipboard')); -var core = require('@component-controls/core'); -var editors = require('@component-controls/editors'); +var React = _interopDefault(require('react')); +var Octicon = require('@primer/octicons-react'); +var Octicon__default = _interopDefault(Octicon); +var tslib = require('tslib'); +var AnimateHeight = _interopDefault(require('react-animate-height')); var MarkdownToJSX = _interopDefault(require('markdown-to-jsx')); -var react = require('@mdx-js/react'); -var dracula = _interopDefault(require('prism-react-renderer/themes/dracula')); +var Highlight = require('prism-react-renderer'); +var Highlight__default = _interopDefault(Highlight); var duotoneDark = _interopDefault(require('prism-react-renderer/themes/duotoneDark')); var duotoneLight = _interopDefault(require('prism-react-renderer/themes/duotoneLight')); -var github = _interopDefault(require('prism-react-renderer/themes/github')); -var nightowl = _interopDefault(require('prism-react-renderer/themes/nightOwl')); -var nightOwlLight = _interopDefault(require('prism-react-renderer/themes/nightOwlLight')); -var oceanicNext = _interopDefault(require('prism-react-renderer/themes/oceanicNext')); -var palenight = _interopDefault(require('prism-react-renderer/themes/palenight')); -var shadesOfPurple = _interopDefault(require('prism-react-renderer/themes/shadesOfPurple')); -var ultramin = _interopDefault(require('prism-react-renderer/themes/ultramin')); -var vsDark = _interopDefault(require('prism-react-renderer/themes/vsDark')); -var jsStringEscape = _interopDefault(require('js-string-escape')); -var specification = require('@component-controls/specification'); +var TooltipTrigger = _interopDefault(require('react-popper-tooltip')); +var copy = _interopDefault(require('copy-to-clipboard')); +var reactTabs = require('react-tabs'); +var presets = require('@theme-ui/presets'); var polished = require('polished'); -var Highlight = require('prism-react-renderer'); -var Highlight__default = _interopDefault(Highlight); -const StyledHeading = styled(themeUi.Heading)(({ - theme -}) => { - var _a; - - return { - fontWeight: 400, - paddingBottom: \`\${(_a = theme === null || theme === void 0 ? void 0 : theme.space) === null || _a === void 0 ? void 0 : _a[3]}px\` - }; +const StyledContainer = styled.div\` + position: relative; +\`; +const StyledFlex = styled.div\` + display: flex; + position: absolute; + flex-direction: row-reverse; + width: 100%; +\`; + +const ActionColors = disabled => ({ + backgroundColor: 'highlight', + color: disabled ? '#ddd' : 'background', + cursor: disabled ? 'not-allowed' : undefined, + px: 2, + py: 1, + lineHeight: 1, + borderRadius: 0, + border: 'none' }); + +const ActionBar = ({ + actionItems +}) => themeUi.jsx(StyledContainer, null, themeUi.jsx(StyledFlex, null, actionItems.filter(({ + hidden +}) => !hidden).map(({ + title, + onClick, + disabled +}, index) => themeUi.jsx(themeUi.Box, { + key: \`\${typeof title === 'string' ? title : 'item'}_\${index}\`, + sx: { + ml: 1, + fontSize: 1, + a: ActionColors(disabled), + button: ActionColors(disabled) + } +}, typeof title === 'string' ? themeUi.jsx(themeUi.Button, { + onClick: onClick, + disabled: disabled +}, title) : title)))); + const Subtitle = _a => { var { children } = _a, rest = tslib.__rest(_a, [\\"children\\"]); - return React.createElement(StyledHeading, Object.assign({ + return React.createElement(themeUi.Heading, Object.assign({ as: \\"h3\\", - color: \\"fadedText\\" + color: \\"fadedText\\", + css: { + fontWeight: 400 + } }, rest), children); }; +const Collapsible = _a => { + var { + children, + isOpen + } = _a, + rest = tslib.__rest(_a, [\\"children\\", \\"isOpen\\"]); + + return React.createElement(AnimateHeight, Object.assign({}, rest, { + height: isOpen ? 'auto' : 0 + }), children); +}; + +/** @jsx jsx */ const SpacedBlockContainer = styled.div(() => ({ position: 'relative', margin: '25px 0 40px 0' @@ -256,329 +293,91 @@ const BlockContainer = ({ children, title, actions -}) => React.createElement(SpacedBlockContainer, null, title && React.createElement(Subtitle, null, title), actions && React.createElement(components.ActionBar, { - actionItems: actions -}), React.createElement(FramedBlockContainer, null, children)); - -/** @jsx jsx */ -const StyledTR = styled.tr(({ - theme -}) => { - var _a; - - return Object.assign({}, (_a = theme === null || theme === void 0 ? void 0 : theme.styles) === null || _a === void 0 ? void 0 : _a.tr); -}); -const StyledTD = styled.td(({ - theme -}) => { - var _a; - - return Object.assign({}, (_a = theme === null || theme === void 0 ? void 0 : theme.styles) === null || _a === void 0 ? void 0 : _a.td); -}); - -const InvalidType = () => themeUi.jsx(\\"span\\", null, \\"Invalid Type\\"); - -const PropertyEditorRow = ({ - prop, - name, - setControlValue, - clickControl, - storyId }) => { - const InputType = editors.getPropertyEditor(prop.type) || InvalidType; - - const onChange = (propName, value) => { - if (setControlValue && storyId) { - setControlValue(storyId, propName, value); - } - }; + const [isOpen, setIsOpen] = React.useState(true); + const id = title ? title.toLowerCase().replace(/\\\\s/g, '-') : undefined; //workaround for storybook iframe url - const onClick = () => { - if (clickControl && storyId) { - clickControl(storyId, name); - } - }; - - return themeUi.jsx(StyledTR, null, themeUi.jsx(StyledTD, null, !prop.hideLabel ? prop.label || name : null), themeUi.jsx(StyledTD, null, themeUi.jsx(themeUi.Flex, { + const url = (window.location != window.parent.location ? document.referrer : document.location.href) || ''; + return themeUi.jsx(SpacedBlockContainer, { + id: id + }, themeUi.jsx(themeUi.Flex, { sx: { - flexDirection: 'column', - alignItems: 'left', - flexBasis: '100%' - } - }, themeUi.jsx(InputType, { - prop: prop, - name: name, - onChange: onChange, - onClick: onClick - })))); -}; - -const StyleTable = styled.table(({ - theme -}) => { - var _a; - - return { - '&&': Object.assign(Object.assign({}, (_a = theme === null || theme === void 0 ? void 0 : theme.styles) === null || _a === void 0 ? void 0 : _a.table), { - tbody: { - boxShadow: 'none' - }, - 'th:last-of-type, td:last-of-type': { - width: '70%' - } - }) - }; -}); -const DEFAULT_GROUP_ID = 'Other'; - -const PropGroupTable = ({ - controls, - storyId, - setControlValue, - clickControl -}) => React.createElement(StyleTable, { - className: \\"component-controls-table\\" -}, React.createElement(\\"tbody\\", null, controls && Object.keys(controls).map((key, index) => ({ - name: key, - property: Object.assign(Object.assign({}, controls[key]), { - order: controls[key].order === undefined ? index : controls[key].order - }) -})).sort((a, b) => { - const aOrder = a.property.order || 0; - const bOrder = b.property.order || 0; - return aOrder - bOrder; -}).map(p => React.createElement(PropertyEditorRow, { - storyId: storyId, - key: \`prop_editor_row_\${storyId}_\${p.name}\`, - prop: p.property, - name: p.name, - setControlValue: setControlValue, - clickControl: clickControl -})))); - -const ControlsTable = props => { - const [copied, setCopied] = React.useState(false); - const { - controls, - title, - storyId, - setControlValue, - extraActions = [] - } = props; - - if (controls && Object.keys(controls).length) { - const onReset = e => { - e.preventDefault(); - - if (setControlValue && storyId) { - const values = core.resetControlValues(controls); - setControlValue(storyId, undefined, values); + flexDirection: 'row', + alignItems: 'center', + pb: 2, + ':hover': { + a: { + visibility: 'visible' + } } - }; - - const onCopy = e => { - e.preventDefault(); - setCopied(true); - const { - location - } = global.document; - const query = qs.parse(location.search, { - ignoreQueryPrefix: true - }); - const values = core.getControlValues(controls); - Object.keys(values).forEach(key => { - query[\`controls-\${key}\`] = values[key]; - }); - copy(\`\${location.origin + location.pathname}?\${qs.stringify(query, { - encode: false - })}\`); - global.window.setTimeout(() => setCopied(false), 1500); - }; - - const groupped = Object.keys(controls).filter(k => { - const p = controls[k]; - return p.type && !p.hidden; - }).reduce((acc, k) => { - const groupId = controls[k].groupId || DEFAULT_GROUP_ID; - return Object.assign(Object.assign({}, acc), { - [groupId]: Object.assign(Object.assign({}, acc[groupId]), { - [k]: controls[k] - }) - }); - }, {}); - const groupedItems = Object.keys(groupped).sort().map(key => { - return { - label: key, - controls: groupped[key] - }; - }); - - if (groupedItems.length === 0) { - return null; } - - const actionItems = [...extraActions.map(item => ({ - title: item.title, - onClick: e => { - e.preventDefault(); - item.onAction(props); + }, id && themeUi.jsx(themeUi.Link, { + sx: { + position: 'absolute', + left: -4, + px: 2, + visibility: 'hidden', + ':hover': { + visibility: 'visible' } - })), { - title: 'reset', - onClick: onReset - }, { - title: copied ? 'copied' : 'copy', - onClick: onCopy - }]; - return React.createElement(BlockContainer, { - actions: actionItems, - title: title - }, groupedItems.length === 1 ? React.createElement(PropGroupTable, Object.assign({}, props, { - controls: groupedItems[0].controls - })) : React.createElement(components.Tabs, null, React.createElement(components.TabList, null, groupedItems.map(item => React.createElement(components.Tab, { - key: \`tab_\${item.label}\` - }, item.label))), groupedItems.map(item => React.createElement(components.TabPanel, { - key: \`tab_panel_\${item.label}\` - }, React.createElement(PropGroupTable, Object.assign({}, props, { - controls: item.controls - })))))); - } - - return null; -}; - -/* eslint-disable react/display-name */ -const Markdown = ({ - children, - components -}) => React.createElement(react.MDXProvider, { - components: components -}, React.createElement(MarkdownToJSX, null, children)); - -const getArgumentsUsage = args => { - return args.reduce((acc, a) => { - var _a; - - if (Array.isArray(a.value)) { - return [...acc, ...getArgumentsUsage(a.value)]; - } - - const usage = (_a = a.usage) === null || _a === void 0 ? void 0 : _a.map(u => ({ - name: a.value, - loc: u - })); - - if (usage) { - return [...acc, ...usage]; + }, + href: \`\${url.split('#')[0]}#\${id}\` + }, themeUi.jsx(Octicon__default, { + icon: Octicon.Link + })), title && themeUi.jsx(Subtitle, { + css: { + paddingRight: 10 } - - return acc; - }, []); + }, title), themeUi.jsx(themeUi.Link, { + \\"aria-label\\": isOpen ? 'Collapse this block' : 'Expand this block', + css: { + cursor: 'pointer' + }, + onClick: () => setIsOpen(!isOpen) + }, themeUi.jsx(Octicon__default, { + icon: isOpen ? Octicon.ChevronDown : Octicon.ChevronRight + }))), themeUi.jsx(Collapsible, { + isOpen: isOpen + }, actions && themeUi.jsx(ActionBar, { + actionItems: actions + }), themeUi.jsx(FramedBlockContainer, null, children)), !isOpen && themeUi.jsx(themeUi.Divider, null)); }; -const stringifyValue = (type, value) => { - switch (type) { - case specification.ControlTypes.TEXT: - return \`\\"\${jsStringEscape(value)}\\"\`; - - case specification.ControlTypes.OBJECT: - if (value) { - return \`{ \${Object.keys(value).map(key => { - const obj = value[key]; - return \`\${key}: \${stringifyValue(obj.type, obj.value)}\`; - }).join(', ')} }\`; - } - - return ''; - - default: - if (Array.isArray(value)) { - return \`[\${stringifyValue(specification.ControlTypes.OPTIONS, value.join(', '))}]\`; - } +const ExternalLink = props => React.createElement(themeUi.Link, Object.assign({}, props, { + target: \\"_blank\\", + rel: \\"noopener noreferrer\\" +})); - return typeof value === 'string' ? \`\\"\${jsStringEscape(value)}\\"\` : value; +const FlexContainer = ({ + align = 'center', + children +}) => React.createElement(themeUi.Flex, { + css: { + alignItems: align, + justifyContent: align, + flexDirection: 'column', + flexBasis: '100%' } -}; - -const replaceString = (s, newStr, start, length) => s.substr(0, start) + newStr + s.substr(start + length); - -const mergeControlValues = (source, args, controls) => { - const locations = getArgumentsUsage(args); - const lines = source.split('\\\\n'); //sort locations in reverse order, so to replace source backwards - - locations.sort((a, b) => { - if (a.loc.loc.start.line === b.loc.loc.start.line) { - return b.loc.loc.start.column - a.loc.loc.start.column; - } - - return b.loc.loc.start.line - a.loc.loc.start.line; - }).forEach(l => { - const { - start, - end - } = l.loc.loc; - const val = controls[l.name]; - - if (val && val.value !== val.defaultValue) { - const value = val.value; - let strValue = stringifyValue(val.type, value); - - if (l.loc.name) { - if (l.loc.name.name === l.name) { - strValue = \`\${l.loc.name.name}: \${strValue}\`; - } - } - - if (start.line === end.line) { - lines[start.line] = replaceString(lines[start.line], strValue, start.column, end.column - start.column); - } else { - const startLine = lines[start.line]; - const endLine = lines[end.line]; - - if (startLine !== undefined && endLine !== undefined) { - lines[start.line - 1] = replaceString(lines[start.line - 1], strValue, start.column, lines[start.line - 1].length - start.column); - - if (end.line - start.line > 1) { - lines.splice(start.line, end.line - start.line - 1); - } - - lines[end.line - 1] = lines[end.line - 1].slice(end.column); - } - } - } - }); - return lines.join('\\\\n'); -}; +}, children); /** @jsx jsx */ /** - * Source component used to display source code - * + * Syntax highlighter component */ -const Source = ({ +const SyntaxHighlighter = ({ children = '', language = 'jsx', theme: customTheme, renderFn, - actions, dark = false, - title + style: propStyle, + as = 'span' }) => { - const [copied, setCopied] = React.useState(false); - - const onCopy = e => { - e.preventDefault(); - setCopied(true); - copy(children); - window.setTimeout(() => setCopied(false), 1500); - }; + if (typeof children !== 'string') { + console.error('Invalid children roperty passed to Source: must be a string'); + } - const actionsItems = Array.isArray(actions) ? [...actions] : []; - actionsItems.push({ - title: copied ? 'copied' : 'copy', - onClick: onCopy - }); const theme = customTheme ? customTheme : dark ? duotoneDark : duotoneLight; const renderProps = typeof renderFn === 'function' ? props => renderFn(props, { theme @@ -590,11 +389,14 @@ const Source = ({ getTokenProps }) => themeUi.jsx(themeUi.Styled.pre, { className: \`\${className}\`, - style: Object.assign(Object.assign({}, style), { - padding: '10px 10px', + style: Object.assign(Object.assign(Object.assign({}, style), { + padding: '3px 5px', + display: 'inline', margin: 0 - }) - }, tokens.map((line, i) => themeUi.jsx(\\"div\\", Object.assign({}, getLineProps({ + }), propStyle) + }, tokens.map((line, i) => themeUi.jsx(themeUi.Box, Object.assign({ + as: as + }, getLineProps({ line, key: i })), line.map((token, key) => themeUi.jsx(\\"span\\", Object.assign({}, getTokenProps({ @@ -608,196 +410,286 @@ const Source = ({ const props = Object.assign(Object.assign({}, Highlight.defaultProps), { theme }); - return themeUi.jsx(BlockContainer, { - actions: actionsItems, - title: title - }, themeUi.jsx(Highlight__default, Object.assign({}, props, { + return themeUi.jsx(Highlight__default, Object.assign({}, props, { code: children, language: language - }), renderProps)); + }), renderProps); }; -const getArgumentsLocations = args => { - return args.reduce((acc, a) => { - if (Array.isArray(a.value)) { - return [...acc, ...getArgumentsLocations(a.value)]; - } - - const locs = []; - - if (a.loc) { - locs.push(a.loc); - } - - if (a.usage) { - locs.push(...a.usage.map(u => u.loc)); - } - - return [...acc, { - name: a.value, - locs - }]; - }, []); +/* eslint-disable react/display-name */ +const defaultComponents = { + code: SyntaxHighlighter }; +/** + * MDX display component that works at run time + * uses \`markdown-to-jsx\` to compile MDX + */ -const TaggedSource = _a => { +const Markdown = ({ + children, + components +}) => React.createElement(MarkdownToJSX, { + options: { + forceBlock: true, + overrides: Object.assign(Object.assign({}, defaultComponents), components) + } +}, children); + +const SPACING = 8; + +const match = (requested, actual, value, fallback = 0) => actual.split('-')[0] === requested ? value : fallback; + +const Wrapper = styled.div(({ + placement, + borderColor, + hidden +}) => ({ + display: hidden ? 'none' : 'inline-block', + background: 'white', + marginTop: \`\${match('bottom', placement, SPACING + 2, 0)}px\`, + marginLeft: \`\${match('right', placement, SPACING + 2, 0)}px\`, + marginRight: \`\${match('left', placement, SPACING + 2, 0)}px\`, + filter: \` + drop-shadow(0px 5px 5px rgba(0,0,0,0.05)) + drop-shadow(0 1px 3px rgba(0,0,0,0.1)) +\`, + borderRadius: 8, + fontSize: 12, + border: \`1px solid \${borderColor}\` +})); +const Arrow = styled.div(({ + placement, + borderColor +}) => ({ + position: 'absolute', + borderStyle: 'solid', + background: 'white', + marginBottom: \`\${match('top', placement, '0', SPACING)}px\`, + marginTop: \`\${match('bottom', placement, '0', SPACING)}px\`, + marginRight: \`\${match('left', placement, '0', SPACING)}px\`, + marginLeft: \`\${match('right', placement, '0', SPACING)}px\`, + bottom: \`\${match('top', placement, SPACING * -1, 'auto')}px\`, + top: \`\${match('bottom', placement, SPACING * -1, 'auto')}px\`, + right: \`\${match('left', placement, SPACING * -1, 'auto')}px\`, + left: \`\${match('right', placement, SPACING * -1, 'auto')}px\`, + borderBottomWidth: \`\${match('top', placement, '0', SPACING)}px\`, + borderTopWidth: \`\${match('bottom', placement, '0', SPACING)}px\`, + borderRightWidth: \`\${match('left', placement, '0', SPACING)}px\`, + borderLeftWidth: \`\${match('right', placement, '0', SPACING)}px\`, + borderTopColor: match('top', placement, borderColor, 'transparent'), + borderBottomColor: match('bottom', placement, borderColor, 'transparent'), + borderLeftColor: match('left', placement, borderColor, 'transparent'), + borderRightColor: match('right', placement, borderColor, 'transparent') +})); +const Popover = _a => { var { - args, - theme + trigger, + placement = 'bottom', + modifiers, + tooltip, + children, + tooltipShown, + onVisibilityChange } = _a, - rest = tslib.__rest(_a, [\\"args\\", \\"theme\\"]); - - const tags = args ? getArgumentsLocations(args) : undefined; - return themeUi.jsx(Source, Object.assign({ - theme: theme - }, rest, { - renderFn: ({ - className, - style, - tokens, - getLineProps, - getTokenProps - }, { - theme - }) => { - if (tags) { - tags.forEach((tag, index) => { - let color; - const colorIdx = index % (theme.styles.length - 1); - const style = theme.styles[colorIdx]; - color = style.style.color || theme.plain.color || '#fff'; - tag.color = color; - }); - } - - return themeUi.jsx(themeUi.Styled.pre, { - className: \`\${className}\`, - style: Object.assign(Object.assign({}, style), { - padding: '10px 10px', - margin: 0 - }) - }, tokens.map((line, i) => themeUi.jsx(\\"div\\", Object.assign({}, getLineProps({ - line, - key: i - })), (() => { - let column = 0; - return line.map((token, key) => { - const tokenTrim = token.content.trim(); - const param = tags ? tags.find(tag => { - if (tag.name === tokenTrim) { - return tag.locs.find(loc => loc.start.line === i && loc.start.column >= column && loc.start.column <= column + token.content.length); - } - - return false; - }) : null; - column += token.content.length; - - if (param) { - const splitToken = getTokenProps({ - token, - key - }).children.split(/(\\\\s+)/); - return splitToken.map(s => s.trim().length ? themeUi.jsx(\\"span\\", Object.assign({}, getTokenProps({ - token, - key - }), { - sx: { - display: 'inline-block', - //@ts-ignore - backgroundColor: polished.transparentize(0.8, param.color), - paddingLeft: 1, - paddingRight: 1, - //@ts-ignore - border: \`1px solid \${param.color}\` - } - }), s) : s); - } - - return themeUi.jsx(\\"span\\", Object.assign({}, getTokenProps({ - token, - key - }), { - sx: { - display: 'inline-block' - } - })); - }); - })()))); + props = tslib.__rest(_a, [\\"trigger\\", \\"placement\\", \\"modifiers\\", \\"tooltip\\", \\"children\\", \\"tooltipShown\\", \\"onVisibilityChange\\"]); + + const borderColor = 'lightgrey'; + return React.createElement(TooltipTrigger, { + placement: placement, + trigger: trigger, + modifiers: modifiers, + tooltipShown: tooltipShown, + onVisibilityChange: onVisibilityChange, + tooltip: tooltipProps => { + const { + getTooltipProps, + getArrowProps, + tooltipRef, + arrowRef + } = tooltipProps; + + const _a = getTooltipProps(), + { + hidden + } = _a, + containerProps = tslib.__rest(_a, [\\"hidden\\"]); + + return React.createElement(Wrapper, Object.assign({ + placement: placement, + borderColor: borderColor, + hidden: hidden, + ref: tooltipRef + }, containerProps), React.createElement(Arrow, Object.assign({ + placement: placement, + borderColor: borderColor, + ref: arrowRef + }, getArrowProps())), typeof tooltip === 'function' ? tooltip(tooltipProps) : tooltip); } - })); + }, ({ + getTriggerProps, + triggerRef + }) => React.createElement(themeUi.Box, Object.assign({ + ref: triggerRef + }, getTriggerProps(), props, { + css: { + display: 'inline-block' + } + }), children)); }; -const themes = { - 'nightowl-light': nightOwlLight, - nightowl, - github, - 'vs-dark': vsDark, - 'oceanic-next': oceanicNext, - palenight, - ultramin, - 'duotone-light': duotoneLight, - 'duotone-dark': duotoneDark, - dracula, - 'shades-of-purple': shadesOfPurple -}; -const ViewStyleNext = { - values: 'tags', - tags: 'values' -}; -const StorySource = _a => { +/** + * Source component used to display source code + * + */ + +const Source = _a => { var { - controls, - fileSource, - children, - args, - actions = [] + children = '', + actions, + title, + as = 'div' } = _a, - rest = tslib.__rest(_a, [\\"controls\\", \\"fileSource\\", \\"children\\", \\"args\\", \\"actions\\"]); - - const [viewStyle, setViewStyle] = React.useState('tags'); - const [showFileSource, setShowFileSource] = React.useState(false); - - const onMergeValues = () => setViewStyle(ViewStyleNext[viewStyle]); - - const onShowFileSource = () => setShowFileSource(!showFileSource); + props = tslib.__rest(_a, [\\"children\\", \\"actions\\", \\"title\\", \\"as\\"]); - const allActions = [...actions]; - - if (fileSource) { - allActions.push({ - title: showFileSource ? 'story code' : 'file code', - onClick: onShowFileSource - }); - } + const [copied, setCopied] = React.useState(false); - if (args && args.length) { - allActions.push({ - title: ViewStyleNext[viewStyle], - onClick: onMergeValues - }); - } + const onCopy = e => { + e.preventDefault(); + setCopied(true); + copy(children); + window.setTimeout(() => setCopied(false), 1500); + }; - let source; + const actionsItems = Array.isArray(actions) ? [...actions] : []; + actionsItems.push({ + title: copied ? 'copied' : 'copy', + onClick: onCopy + }); + return themeUi.jsx(BlockContainer, { + actions: actionsItems, + title: title + }, themeUi.jsx(SyntaxHighlighter, Object.assign({ + as: as + }, props, { + style: { + padding: '16px 10px 10px', + display: 'block' + } + }), children)); +}; - if (!showFileSource) { - let code = typeof children === 'string' ? children : ''; +const TabsContainer = styled.div\` + \${({ + theme +}) => { + var _a, _b, _c; - if (viewStyle === 'values' && args && controls) { - code = mergeControlValues(code, args, controls); + return \` + .react-tabs { + -webkit-tap-highlight-color: transparent; + } + .react-tabs__tab-list { + margin: 0 0 10px; + padding: 0; + } + .react-tabs__tab { + font-size: 13px; + font-weight: bold; + display: inline-block; + border-bottom: none; + bottom: -1px; + position: relative; + list-style: none; + padding: 4px 15px; + cursor: pointer; + color: \${(_a = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _a === void 0 ? void 0 : _a.fadedText}; + } + .react-tabs__tab--selected { + border-bottom: 3px solid \${(_b = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _b === void 0 ? void 0 : _b.accent}; + color: \${(_c = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _c === void 0 ? void 0 : _c.accent}; + } + .react-tabs__tab--disabled { + color: GrayText; + cursor: default; + } + .react-tabs__tab:focus { + box-shadow: 0 0 5px hsl(208, 99%, 50%); + border-color: hsl(208, 99%, 50%); + outline: none; } + .react-tabs__tab:focus:after { + content: \\"\\"; + position: absolute; + height: 5px; + left: -4px; + right: -4px; + bottom: -5px; + background: #fff; + } + .react-tabs__tab-panel { + display: none; + } + .react-tabs__tab-panel.react-tabs__tab-panel--selected { + display: block; + } + \`; +}} +\`; - source = code; - } else { - source = fileSource || ''; - } +const Tabs = props => React.createElement(TabsContainer, null, React.createElement(reactTabs.Tabs, Object.assign({}, props))); - return React.createElement(TaggedSource, Object.assign({}, rest, { - args: viewStyle === 'tags' && !showFileSource ? args : undefined, - actions: allActions - }), source); +const ThemeContext = React.createContext({}); +const ThemeProvider = ({ + children, + dark +}) => { + const theme = Object.assign(Object.assign({}, presets.polaris), { + styles: Object.assign(Object.assign({}, presets.polaris.styles), { + table: { + margin: 0, + borderCollapse: 'collapse', + fontSize: '14px', + lineHeight: '20px', + textAlign: 'left', + width: '100%', + borderSpacing: '0px' + }, + td: { + padding: '16px 20px' + }, + tr: { + borderBottom: '1px solid rgba(0, 0, 0, 0.1)' + } + }), + buttons: { + primary: { + color: '#333', + bg: '#f3f3f3', + borderRadius: 5, + boxShadow: 'rgba(0, 0, 0, 0.1) 0px 0px 0px 1px inset' + }, + secondary: { + bg: 'highlight' + } + }, + colors: Object.assign(Object.assign({}, presets.polaris.colors), { + highlight: '#339793', + accent: '#1EA7FD', + fadedText: polished.lighten(0.25, presets.polaris.colors.text), + lightenPrimary: '#F6F9FC' + }) + }); + return React.createElement(ThemeContext.Provider, { + value: { + theme, + dark + } + }, React.createElement(themeUi.ThemeProvider, { + theme: theme + }, children)); }; -const StyledHeading$1 = styled(themeUi.Heading)(() => ({ +const StyledHeading = styled(themeUi.Heading)(() => ({ fontWeight: 900, paddingBottom: '25px' })); @@ -807,19 +699,73 @@ const Title = _a => { } = _a, rest = tslib.__rest(_a, [\\"children\\"]); - return React.createElement(StyledHeading$1, Object.assign({ + return React.createElement(StyledHeading, Object.assign({ as: \\"h1\\" }, rest), children); }; +const Toggle = _a => { + var { + checked = false, + onChange, + labels = { + true: 'True', + false: 'False' + } + } = _a, + rest = tslib.__rest(_a, [\\"checked\\", \\"onChange\\", \\"labels\\"]); + + return themeUi.jsx(themeUi.Box, Object.assign({}, rest), themeUi.jsx(themeUi.Label, { + sx: { + display: 'flex', + flexDirection: 'row', + alignItems: 'center' + } + }, themeUi.jsx(themeUi.Text, { + sx: { + paddingRight: 1 + } + }, checked ? labels.true : labels.false), themeUi.jsx(themeUi.Checkbox, { + checked: checked, + onClick: () => onChange && onChange(!checked) + }))); +}; +Toggle.displayName = 'Toggle'; + +Object.defineProperty(exports, 'Tab', { + enumerable: true, + get: function () { + return reactTabs.Tab; + } +}); +Object.defineProperty(exports, 'TabList', { + enumerable: true, + get: function () { + return reactTabs.TabList; + } +}); +Object.defineProperty(exports, 'TabPanel', { + enumerable: true, + get: function () { + return reactTabs.TabPanel; + } +}); +exports.ActionBar = ActionBar; +exports.Arrow = Arrow; exports.BlockContainer = BlockContainer; -exports.ControlsTable = ControlsTable; +exports.Collapsible = Collapsible; +exports.ExternalLink = ExternalLink; +exports.FlexContainer = FlexContainer; exports.Markdown = Markdown; +exports.Popover = Popover; exports.Source = Source; -exports.StorySource = StorySource; exports.Subtitle = Subtitle; +exports.Tabs = Tabs; +exports.ThemeContext = ThemeContext; +exports.ThemeProvider = ThemeProvider; exports.Title = Title; -exports.themes = themes; +exports.Toggle = Toggle; +exports.Wrapper = Wrapper; ", } `; diff --git a/core/instrument/test/__snapshots__/follow-imports.test.ts.snap b/core/instrument/test/__snapshots__/follow-imports.test.ts.snap index 4c4fe5d1d..5e9a6249d 100644 --- a/core/instrument/test/__snapshots__/follow-imports.test.ts.snap +++ b/core/instrument/test/__snapshots__/follow-imports.test.ts.snap @@ -10,11 +10,11 @@ Object { "loc": Object { "end": Object { "column": 1, - "line": 91, + "line": 92, }, "start": Object { "column": 28, - "line": 42, + "line": 43, }, }, "originalFilePath": "/Users/atanasster/component-controls/node_modules/@component-controls/storybook/dist/index.js", @@ -29,6 +29,7 @@ var blocks = require('@component-controls/blocks'); var blocks$1 = require('@storybook/addon-docs/blocks'); require('polished'); require('@storybook/theming'); +require('@component-controls/components'); var ThemeProvider = require('./ThemeProvider.js'); var tslib = require('tslib'); var coreEvents = require('@storybook/core-events'); @@ -232,11 +233,11 @@ Object { "loc": Object { "end": Object { "column": 1, - "line": 91, + "line": 92, }, "start": Object { "column": 28, - "line": 42, + "line": 43, }, }, "originalFilePath": "/Users/atanasster/component-controls/node_modules/@component-controls/storybook/dist/index.js", @@ -251,6 +252,7 @@ var blocks = require('@component-controls/blocks'); var blocks$1 = require('@storybook/addon-docs/blocks'); require('polished'); require('@storybook/theming'); +require('@component-controls/components'); var ThemeProvider = require('./ThemeProvider.js'); var tslib = require('tslib'); var coreEvents = require('@storybook/core-events'); diff --git a/core/instrument/test/examples/extract-component/node-modules-source.js b/core/instrument/test/examples/extract-component/node-modules-source.js index ebde2223b..6335dfd4c 100644 --- a/core/instrument/test/examples/extract-component/node-modules-source.js +++ b/core/instrument/test/examples/extract-component/node-modules-source.js @@ -1 +1 @@ -import { Subtitle as Button } from '@component-controls/block-components'; +import { Subtitle as Button } from '@component-controls/components';