Skip to content

Commit

Permalink
feat: copy table added to props table
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed May 8, 2020
1 parent 67a287f commit 6b91c0a
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 22 deletions.
1 change: 0 additions & 1 deletion core/loader/src/typings.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion ui/blocks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Some of the guiding design goals for this library:

# List of components

<react-docgen-typescript path="./src" exclude="index.ts,repositoryActions.tsx,StoryContext.tsx,utils.ts,ComponentsContext.tsx,context.tsx,argument-utils.ts,channel.ts,SinglePropsTable.tsx" />
<react-docgen-typescript path="./src" exclude="index.ts,repositoryActions.tsx,StoryContext.tsx,utils.ts,ComponentsContext.tsx,context.tsx,argument-utils.ts,channel.ts,BasePropsTable.tsx" />

<!-- START-REACT-DOCGEN-TYPESCRIPT -->

Expand Down
1 change: 1 addition & 0 deletions ui/blocks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@storybook/csf": "^0.0.1",
"copy-to-clipboard": "^3.2.1",
"global": "^4.3.2",
"js-string-escape": "^1.0.1",
"react": "^16.8.3",
"react-dom": "^16.8.3",
"react-table": "^7.0.0",
Expand Down
7 changes: 5 additions & 2 deletions ui/blocks/src/ControlsTable/controlsActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,22 @@ export const useControlsActions = (props: UseControlsActionsProps) => {
};
return [
{
title: copied ? 'copied' : 'copy',
title: copied ? 'values copied' : 'copy values',
onClick: onCopy,
id: 'copy',
group: 'controls',
id: 'copy_controls',
'aria-label': 'copy control values',
},
{
title: 'reset',
onClick: onReset,
group: 'controls',
id: 'reset',
'aria-label': 'reset control values to their initial value',
},
{
title: 'randomize',
group: 'controls',
onClick: () => {
if (setControlValue && controls && storyId) {
setControlValue(storyId, undefined, randomizeData(controls));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/* eslint-disable react/display-name */
/** @jsx jsx */
import { jsx, Text, Flex, Styled, Box } from 'theme-ui';
import { FC, useContext, useMemo } from 'react';
import { FC, useContext, useMemo, MouseEvent, useState } from 'react';
import { window } from 'global';
import jsStringEscape from 'js-string-escape';
import copy from 'copy-to-clipboard';
import {
Story,
StoryComponent,
ComponentControls,
ComponentControl,
PropType,
} from '@component-controls/specification';
Expand All @@ -17,6 +19,7 @@ import {
Markdown,
ActionContainer,
Tag,
ActionItems,
} from '@component-controls/components';
import {
getPropertyEditor,
Expand All @@ -34,7 +37,7 @@ interface PropRow {
control: ComponentControl;
}

export interface SinglePropsTableProps {
export interface BasePropsTableProps {
story?: Story;
component?: StoryComponent;
extraColumns: Column[];
Expand All @@ -44,19 +47,20 @@ export interface SinglePropsTableProps {
type GroupingProps = Partial<
Pick<TableProps, 'groupBy' | 'hiddenColumns' | 'expanded'>
>;
export const SinglePropsTable: FC<SinglePropsTableProps> = ({
export const BasePropsTable: FC<BasePropsTableProps> = ({
story,
component,
extraColumns,
tableProps,
}) => {
const { setControlValue, clickControl } = useContext(BlockControlsContext);
const { info = { props: undefined } } = component || {};
const { controls = {} } = story || {};
const propControls: ComponentControls = visibleControls(controls);
const { controls: storyControls = {} } = story || {};
const controls = visibleControls(storyControls);
// check if we should display controls in the PrpsTable
// at least one control's name should exist as a property name
const hasControls = !!Object.keys(propControls).length;
const hasControls = !!Object.keys(controls).length;
const propControls = { ...controls };
const { columns, rows, groupProps } = useMemo(() => {
const parents = new Set();
const keys = info.props ? Object.keys(info.props) : [];
Expand All @@ -72,7 +76,16 @@ export const SinglePropsTable: FC<SinglePropsTableProps> = ({
parents.add(parentName);
return {
name: key,
prop: { ...prop, description, label, parentName, required },
prop: {
...prop,
type: {
label,
required,
...prop.type,
},
description: description ?? prop.description,
parentName,
},
control,
};
});
Expand Down Expand Up @@ -287,16 +300,51 @@ export const SinglePropsTable: FC<SinglePropsTableProps> = ({
<Table {...groupProps} {...tableProps} columns={columns} data={rows} />
</ConrolsContextProvider>
);
const controlsActions = useControlsActions({
controls,
setControlValue,
storyId: story?.id,
const actions: ActionItems = [];
const [copied, setCopied] = useState(false);
const onCopy = (e: MouseEvent<HTMLButtonElement>) => {
const quotedValue = (value: string) => `"${jsStringEscape(value)}"`;
e.preventDefault();
const csvRows = rows
.map(row => {
const r = [
quotedValue(row.name),
quotedValue(row.prop.type.raw ?? row.prop.type.name),
quotedValue(row.prop.defaultValue ?? ''),
quotedValue(row.prop.description ?? ''),
];
if (hasControls) {
const value = row.control?.value;
if (Array.isArray(value) || typeof value === 'object') {
r.push(quotedValue(JSON.stringify(value)));
} else {
r.push(quotedValue((value as string) ?? ''));
}
}
return r.join(',');
})
.join('\n');
setCopied(true);
copy(csvRows);
window.setTimeout(() => setCopied(false), 1500);
};
actions.push({
title: copied ? 'copied' : 'copy table',
onClick: onCopy,
id: 'copy_table',
'aria-label': 'copy table as csv',
});
if (!hasControls) {
return table;
}

actions.push.apply(
actions,
useControlsActions({
controls,
setControlValue,
storyId: story?.id,
}),
);
return (
<ActionContainer actions={controlsActions}>
<ActionContainer actions={actions}>
<Box
sx={{
pt: 4,
Expand Down
4 changes: 2 additions & 2 deletions ui/blocks/src/PropsTable/PropsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ComponentsBlockContainerProps,
} from '../BlockContainer/components/ComponentsBlockContainer';

import { SinglePropsTable } from './SinglePropsTable';
import { BasePropsTable } from './BasePropsTable';

export interface PropsTableOwnProps {
/**
Expand All @@ -29,7 +29,7 @@ export const PropsTable: FC<PropsTableProps> = ({
return (
<ComponentsBlockContainer visibleOnControlsOnly={true} {...props}>
{(component, { story }, tableProps) => (
<SinglePropsTable
<BasePropsTable
component={component}
story={story}
extraColumns={extraColumns}
Expand Down
1 change: 1 addition & 0 deletions ui/blocks/src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
declare module 'global';
declare module '@theme-ui/presets';
declare module 'js-string-escape';

0 comments on commit 6b91c0a

Please sign in to comment.