From ec08774c0b7f9b4c74879aff502ba7a32fef7fdd Mon Sep 17 00:00:00 2001 From: Radek Podrazky Date: Mon, 3 Aug 2020 10:40:58 +0200 Subject: [PATCH 1/3] feat(ArgValue): pretiffy output of values in PropsTable Ref #11681 --- .../src/blocks/ArgsTable/ArgRow.stories.tsx | 36 ++++++++++ .../src/blocks/ArgsTable/ArgValue.tsx | 71 +++++++++++++++++-- 2 files changed, 101 insertions(+), 6 deletions(-) diff --git a/lib/components/src/blocks/ArgsTable/ArgRow.stories.tsx b/lib/components/src/blocks/ArgsTable/ArgRow.stories.tsx index f5e803da3200..6277a3f00646 100644 --- a/lib/components/src/blocks/ArgsTable/ArgRow.stories.tsx +++ b/lib/components/src/blocks/ArgsTable/ArgRow.stories.tsx @@ -262,6 +262,42 @@ Func.args = { }, }; +const enumeration = + '"search" | "arrow-to-bottom" | "arrow-to-right" | "bell" | "check" | "check-circle"'; + +export const Enum = Template.bind({}); +Enum.args = { + ...baseArgs, + row: { + key: 'enum', + name: 'Some enum', + type: { required: true }, + table: { + type: { + summary: enumeration, + }, + }, + }, +}; + +const long_enumeration = + '"search" | "arrow-to-bottom" | "arrow-to-right" | "bell" | "check" | "check-circle" | "chevron-up" | "chevron-down" | "chevron-left" | "chevron-right" | "envelope" | "exchange" | "file" | "file-check" | "file-import" | "file-pdf" | "file-times" | "pencil" | "question" | "question-circle" | "sitemap" | "user" | "times" | "plus" | "exclamation-triangle" | "trash-alt" | "long-arrow-up" | "long-arrow-down" | "long-arrow-left" | "long-arrow-right" | "external-link-alt" | "sticky-note" | "chart-line" | "spinner-third"'; + +export const LongEnum = Template.bind({}); +LongEnum.args = { + ...baseArgs, + row: { + key: 'longEnum', + name: 'Long enum', + type: { required: true }, + table: { + type: { + summary: long_enumeration, + }, + }, + }, +}; + export const Markdown = Template.bind({}); Markdown.args = { ...baseArgs, diff --git a/lib/components/src/blocks/ArgsTable/ArgValue.tsx b/lib/components/src/blocks/ArgsTable/ArgValue.tsx index d166c887a739..96e0079445d1 100644 --- a/lib/components/src/blocks/ArgsTable/ArgValue.tsx +++ b/lib/components/src/blocks/ArgsTable/ArgValue.tsx @@ -19,10 +19,35 @@ interface ArgSummaryProps { value: PropSummaryValue; } -const Text = styled.span(({ theme }) => ({ +const ITEMS_BEFORE_EXPANSION = 8; + +const Summary = styled.div<{ isExpanded?: boolean }>(({ isExpanded }) => ({ + display: 'flex', + flexDirection: isExpanded ? 'column' : 'row', + flexWrap: 'wrap', + alignItems: 'flex-start', + marginBottom: '-4px', +})); + +const Text = styled.span<{}>(codeCommon, ({ theme }) => ({ + flex: 0, fontFamily: theme.typography.fonts.mono, fontSize: theme.typography.size.s1, wordBreak: 'break-word', + margin: 0, + marginRight: '4px', + marginBottom: '4px', + paddingTop: '2px', + paddingBottom: '2px', + lineHeight: '13px', +})); + +const ExpandButton = styled.button<{}>(({ theme }) => ({ + fontFamily: theme.typography.fonts.mono, + color: theme.color.secondary, + marginBottom: '4px', + background: 'none', + border: 'none', })); const Expandable = styled.div<{}>(codeCommon, ({ theme }) => ({ @@ -72,18 +97,52 @@ const calculateDetailWidth = memoize(1000)((detail: string): string => { return `${Math.max(...lines.map((x) => x.length))}ch`; }); +const uniq = (arr: string[]): string[] => + arr.filter((value, index, self) => self.indexOf(value) === index); + +const getSummaryItems = (summary: string) => { + if (!summary) return [summary]; + const splittedItems = summary.split('|'); + const summaryItems = splittedItems.map((value) => value.trim()); + + return uniq(summaryItems); +}; + +const renderSummaryItems = (summaryItems: string[], isExpanded = true) => { + let items = summaryItems; + if (!isExpanded) { + items = summaryItems.slice(0, ITEMS_BEFORE_EXPANSION); + } + + return items.map((item) => ); +}; + const ArgSummary: FC = ({ value }) => { const { summary, detail } = value; const [isOpen, setIsOpen] = useState(false); + const [isExpanded, setIsExpanded] = useState(false); + + if (summary === undefined || summary === null) return null; // summary is used for the default value // below check fixes not displaying default values for boolean typescript vars - const summaryAsString = - summary !== undefined && summary !== null && typeof summary.toString === 'function' - ? summary.toString() - : summary; + const summaryAsString = typeof summary.toString === 'function' ? summary.toString() : summary; + if (detail == null) { - return ; + const summaryItems = getSummaryItems(summaryAsString); + const itemsCount = summaryItems.length; + const hasManyItems = itemsCount > ITEMS_BEFORE_EXPANSION; + + return hasManyItems ? ( + + {renderSummaryItems(summaryItems, isExpanded)} + setIsExpanded(!isExpanded)}> + {isExpanded ? 'Show less...' : `Show ${itemsCount - ITEMS_BEFORE_EXPANSION} more...`} + + + ) : ( + {renderSummaryItems(summaryItems)} + ); } return ( From 61ee8b0833d2bb9906ec0160b85ce43d6c38c25a Mon Sep 17 00:00:00 2001 From: Radek Podrazky Date: Tue, 4 Aug 2020 10:22:27 +0200 Subject: [PATCH 2/3] feat(ArgsTable): add prop for default expansion of args --- lib/components/src/blocks/ArgsTable/ArgRow.tsx | 9 +++++---- lib/components/src/blocks/ArgsTable/ArgValue.tsx | 14 ++++++++++---- .../src/blocks/ArgsTable/ArgsTable.stories.tsx | 10 ++++++++++ lib/components/src/blocks/ArgsTable/ArgsTable.tsx | 13 +++++++++++-- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/lib/components/src/blocks/ArgsTable/ArgRow.tsx b/lib/components/src/blocks/ArgsTable/ArgRow.tsx index cc94fe884e5a..fdf95425cfdf 100644 --- a/lib/components/src/blocks/ArgsTable/ArgRow.tsx +++ b/lib/components/src/blocks/ArgsTable/ArgRow.tsx @@ -14,6 +14,7 @@ export interface ArgRowProps { updateArgs?: (args: Args) => void; compact?: boolean; expandable?: boolean; + initialExpandedArgs?: boolean; } const Name = styled.span({ fontWeight: 'bold' }); @@ -64,7 +65,7 @@ const StyledTd = styled.td<{ expandable: boolean }>(({ theme, expandable }) => ( })); export const ArgRow: FC = (props) => { - const { row, updateArgs, compact, expandable } = props; + const { row, updateArgs, compact, expandable, initialExpandedArgs } = props; const { name, description } = row; const table = (row.table || {}) as TableAnnotation; const type = table.type || row.type; @@ -88,20 +89,20 @@ export const ArgRow: FC = (props) => { {table.jsDocTags != null ? ( <> - + ) : ( - + )} )} {compact ? null : ( - + )} {updateArgs ? ( diff --git a/lib/components/src/blocks/ArgsTable/ArgValue.tsx b/lib/components/src/blocks/ArgsTable/ArgValue.tsx index 96e0079445d1..d797d8f6a36f 100644 --- a/lib/components/src/blocks/ArgsTable/ArgValue.tsx +++ b/lib/components/src/blocks/ArgsTable/ArgValue.tsx @@ -9,6 +9,7 @@ import { codeCommon } from '../../typography/shared'; interface ArgValueProps { value?: PropSummaryValue; + initialExpandedArgs?: boolean; } interface ArgTextProps { @@ -17,6 +18,7 @@ interface ArgTextProps { interface ArgSummaryProps { value: PropSummaryValue; + initialExpandedArgs?: boolean; } const ITEMS_BEFORE_EXPANSION = 8; @@ -117,11 +119,11 @@ const renderSummaryItems = (summaryItems: string[], isExpanded = true) => { return items.map((item) => ); }; -const ArgSummary: FC = ({ value }) => { +const ArgSummary: FC = ({ value, initialExpandedArgs }) => { const { summary, detail } = value; const [isOpen, setIsOpen] = useState(false); - const [isExpanded, setIsExpanded] = useState(false); + const [isExpanded, setIsExpanded] = useState(initialExpandedArgs || false); if (summary === undefined || summary === null) return null; // summary is used for the default value @@ -170,6 +172,10 @@ const ArgSummary: FC = ({ value }) => { ); }; -export const ArgValue: FC = ({ value }) => { - return value == null ? : ; +export const ArgValue: FC = ({ value, initialExpandedArgs }) => { + return value == null ? ( + + ) : ( + + ); }; diff --git a/lib/components/src/blocks/ArgsTable/ArgsTable.stories.tsx b/lib/components/src/blocks/ArgsTable/ArgsTable.stories.tsx index 5786bc68b385..46f9e2ca644a 100644 --- a/lib/components/src/blocks/ArgsTable/ArgsTable.stories.tsx +++ b/lib/components/src/blocks/ArgsTable/ArgsTable.stories.tsx @@ -23,6 +23,8 @@ const htmlElementSubsection = { subcategory: 'HTMLElement' }; const stringType = ArgRow.String.args.row; const numberType = ArgRow.Number.args.row; +const longEnumType = ArgRow.LongEnum.args.row; + const Template = (args) => ; export const Normal = Template.bind({}); @@ -129,3 +131,11 @@ Error.args = { export const Empty = Template.bind({}); Empty.args = { rows: {} }; + +export const WithDefaultExpandedArgs = Template.bind({}); +WithDefaultExpandedArgs.args = { + rows: { + longEnumType, + }, + initialExpandedArgs: true, +}; diff --git a/lib/components/src/blocks/ArgsTable/ArgsTable.tsx b/lib/components/src/blocks/ArgsTable/ArgsTable.tsx index 6333723619c7..98c1fcad9f71 100644 --- a/lib/components/src/blocks/ArgsTable/ArgsTable.tsx +++ b/lib/components/src/blocks/ArgsTable/ArgsTable.tsx @@ -233,6 +233,7 @@ export interface ArgsTableRowProps { resetArgs?: (argNames?: string[]) => void; compact?: boolean; inAddonPanel?: boolean; + initialExpandedArgs?: boolean; } export interface ArgsTableErrorProps { @@ -297,7 +298,15 @@ export const ArgsTable: FC = (props) => { ); } - const { rows, args, updateArgs, resetArgs, compact, inAddonPanel } = props as ArgsTableRowProps; + const { + rows, + args, + updateArgs, + resetArgs, + compact, + inAddonPanel, + initialExpandedArgs, + } = props as ArgsTableRowProps; const groups = groupRows(pickBy(rows, (row) => !row?.table?.disable)); @@ -321,7 +330,7 @@ export const ArgsTable: FC = (props) => { if (!compact) colSpan += 2; const expandable = Object.keys(groups.sections).length > 0; - const common = { updateArgs, compact, inAddonPanel }; + const common = { updateArgs, compact, inAddonPanel, initialExpandedArgs }; return ( From 054947afc1ef607c22895d7e8d3224c75e163d97 Mon Sep 17 00:00:00 2001 From: Radek Podrazky Date: Wed, 5 Aug 2020 10:34:17 +0200 Subject: [PATCH 3/3] refactor: replace uniq with lodash --- lib/components/src/blocks/ArgsTable/ArgValue.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/components/src/blocks/ArgsTable/ArgValue.tsx b/lib/components/src/blocks/ArgsTable/ArgValue.tsx index d797d8f6a36f..9a08b8e8d2e8 100644 --- a/lib/components/src/blocks/ArgsTable/ArgValue.tsx +++ b/lib/components/src/blocks/ArgsTable/ArgValue.tsx @@ -1,6 +1,7 @@ import React, { FC, useState } from 'react'; import { styled } from '@storybook/theming'; import memoize from 'memoizerific'; +import uniq from 'lodash/uniq'; import { PropSummaryValue } from './types'; import { WithTooltipPure } from '../../tooltip/WithTooltip'; import { Icons } from '../../icon/icon'; @@ -99,9 +100,6 @@ const calculateDetailWidth = memoize(1000)((detail: string): string => { return `${Math.max(...lines.map((x) => x.length))}ch`; }); -const uniq = (arr: string[]): string[] => - arr.filter((value, index, self) => self.indexOf(value) === index); - const getSummaryItems = (summary: string) => { if (!summary) return [summary]; const splittedItems = summary.split('|');