From cbad3b14bbd498e96a610fb4d2fe74413c243137 Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Tue, 20 Feb 2024 16:28:15 +0100 Subject: [PATCH 1/5] Dont show setup controls if control is disabled or a function --- code/ui/blocks/src/components/ArgsTable/ArgControl.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx b/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx index be9b7e1c8a46..bc562ea5568e 100644 --- a/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx +++ b/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx @@ -13,10 +13,11 @@ import { RangeControl, TextControl, } from '../../controls'; -import type { Args, ArgType } from './types'; +import type { Args } from './types'; +import type { InputType } from '@storybook/types'; export interface ArgControlProps { - row: ArgType; + row: InputType; arg: any; updateArgs: (args: Args) => void; isHovered: boolean; @@ -65,7 +66,7 @@ export const ArgControl: FC = ({ row, arg, updateArgs, isHovere const onBlur = useCallback(() => setFocused(false), []); const onFocus = useCallback(() => setFocused(true), []); - if (!control || control.disable) + if (!control && row.type !== 'function') return isHovered ? ( Date: Tue, 20 Feb 2024 16:33:29 +0100 Subject: [PATCH 2/5] Dont show setup controls if control is disabled or a function --- .../blocks/src/components/ArgsTable/ArgControl.tsx | 12 ++++++------ code/ui/blocks/src/components/ArgsTable/types.ts | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx b/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx index bc562ea5568e..6d51fe88d318 100644 --- a/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx +++ b/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx @@ -13,11 +13,10 @@ import { RangeControl, TextControl, } from '../../controls'; -import type { Args } from './types'; -import type { InputType } from '@storybook/types'; +import type { Args, ArgType } from './types'; export interface ArgControlProps { - row: InputType; + row: ArgType; arg: any; updateArgs: (args: Args) => void; isHovered: boolean; @@ -66,8 +65,9 @@ export const ArgControl: FC = ({ row, arg, updateArgs, isHovere const onBlur = useCallback(() => setFocused(false), []); const onFocus = useCallback(() => setFocused(true), []); - if (!control && row.type !== 'function') - return isHovered ? ( + if (!control || control.disabled) { + const canBeSetup = control?.disabled !== true && row?.type?.name !== 'function'; + return isHovered && canBeSetup ? ( = ({ row, arg, updateArgs, isHovere ) : ( ); - + } // row.name is a display name and not a suitable DOM input id or name - i might contain whitespace etc. // row.key is a hash key and therefore a much safer choice const props = { name: key, argType: row, value: boxedValue.value, onChange, onBlur, onFocus }; diff --git a/code/ui/blocks/src/components/ArgsTable/types.ts b/code/ui/blocks/src/components/ArgsTable/types.ts index a8f3dd1d453e..b8d097e851ce 100644 --- a/code/ui/blocks/src/components/ArgsTable/types.ts +++ b/code/ui/blocks/src/components/ArgsTable/types.ts @@ -41,6 +41,9 @@ export interface ArgType { description?: string; defaultValue?: any; if?: Conditional; + type?: { + name?: string; + }; [key: string]: any; } From 9605d6978b982f8f1dd236ce2deb50ae5846a2a4 Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Tue, 20 Feb 2024 17:08:04 +0100 Subject: [PATCH 3/5] Remove type --- code/ui/blocks/src/components/ArgsTable/types.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/ui/blocks/src/components/ArgsTable/types.ts b/code/ui/blocks/src/components/ArgsTable/types.ts index b8d097e851ce..a8f3dd1d453e 100644 --- a/code/ui/blocks/src/components/ArgsTable/types.ts +++ b/code/ui/blocks/src/components/ArgsTable/types.ts @@ -41,9 +41,6 @@ export interface ArgType { description?: string; defaultValue?: any; if?: Conditional; - type?: { - name?: string; - }; [key: string]: any; } From f9b9958b129923fb440338adca08c6a8e7a1a9bf Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Wed, 21 Feb 2024 14:13:38 +0100 Subject: [PATCH 4/5] Only expand object control if data is plain object or array. --- code/ui/.storybook/preview.tsx | 1 - .../ui/blocks/src/controls/Object.stories.tsx | 32 +++++++++++++++++++ code/ui/blocks/src/controls/Object.tsx | 10 ++++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/code/ui/.storybook/preview.tsx b/code/ui/.storybook/preview.tsx index 1054d62a5d59..34d955269f75 100644 --- a/code/ui/.storybook/preview.tsx +++ b/code/ui/.storybook/preview.tsx @@ -260,7 +260,6 @@ export const decorators = [ ]; export const parameters = { - actions: { argTypesRegex: '^on.*' }, options: { storySort: (a, b) => a.title === b.title ? 0 : a.id.localeCompare(b.id, undefined, { numeric: true }), diff --git a/code/ui/blocks/src/controls/Object.stories.tsx b/code/ui/blocks/src/controls/Object.stories.tsx index d96844e51646..22aed6df6629 100644 --- a/code/ui/blocks/src/controls/Object.stories.tsx +++ b/code/ui/blocks/src/controls/Object.stories.tsx @@ -1,5 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react'; import { ObjectControl } from './Object'; +import { fn } from '@storybook/test'; export default { component: ObjectControl, @@ -53,3 +54,34 @@ export const Undefined: StoryObj = { value: undefined, }, }; + +class Person { + constructor( + public firstName: string, + public lastName: string + ) {} + + fullName() { + return `${this.firstName} ${this.lastName}`; + } +} + +/** + * We show a class collapsed as it might contain many methods. + * It is read-only as we can not construct the class. + */ +export const Class: StoryObj = { + args: { + value: new Person('Kasper', 'Peulen'), + }, +}; + +/** + * We show a function collapsed. Even if it is "object" like, such as "fn". + * It is read-only as we can not construct a function. + */ +export const Function: StoryObj = { + args: { + value: fn(), + }, +}; diff --git a/code/ui/blocks/src/controls/Object.tsx b/code/ui/blocks/src/controls/Object.tsx index d6c4d2328af0..f6c782164534 100644 --- a/code/ui/blocks/src/controls/Object.tsx +++ b/code/ui/blocks/src/controls/Object.tsx @@ -5,7 +5,7 @@ import React, { useCallback, useMemo, useState, useEffect, useRef } from 'react' import { styled, useTheme, type Theme } from '@storybook/theming'; import { Form, IconButton, Button } from '@storybook/components'; import { AddIcon, EyeCloseIcon, EyeIcon, SubtractIcon } from '@storybook/icons'; -import { JsonTree, getObjectType } from './react-editable-json-tree'; +import { JsonTree } from './react-editable-json-tree'; import { getControlId, getControlSetterButtonId } from './helpers'; import type { ControlProps, ObjectValue, ObjectConfig } from './types'; @@ -247,7 +247,6 @@ export const ObjectControl: FC = ({ name, value, onChange }) => { const theme = useTheme(); const data = useMemo(() => value && cloneDeep(value), [value]); const hasData = data !== null && data !== undefined; - const [showRaw, setShowRaw] = useState(!hasData); const [parseError, setParseError] = useState(null); const updateRaw: (raw: string) => void = useCallback( @@ -294,9 +293,12 @@ export const ObjectControl: FC = ({ name, value, onChange }) => { /> ); + const isObjectOrArray = + Array.isArray(value) || (typeof value === 'object' && value?.constructor === Object); + return ( - {['Object', 'Array'].includes(getObjectType(data)) && ( + {isObjectOrArray && ( { e.preventDefault(); @@ -309,6 +311,8 @@ export const ObjectControl: FC = ({ name, value, onChange }) => { )} {!showRaw ? ( !isObjectOrArray} data={data} rootName={name} onFullyUpdate={onChange} From d96be410f6aa952c9f65f9079debc5b86f49ee9b Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Thu, 22 Feb 2024 10:05:08 +0100 Subject: [PATCH 5/5] Use default expand settings when object or array --- code/ui/blocks/src/controls/Object.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ui/blocks/src/controls/Object.tsx b/code/ui/blocks/src/controls/Object.tsx index f6c782164534..28188f77165f 100644 --- a/code/ui/blocks/src/controls/Object.tsx +++ b/code/ui/blocks/src/controls/Object.tsx @@ -312,7 +312,7 @@ export const ObjectControl: FC = ({ name, value, onChange }) => { {!showRaw ? ( !isObjectOrArray} + isCollapsed={isObjectOrArray ? /* default value */ undefined : () => true} data={data} rootName={name} onFullyUpdate={onChange}