diff --git a/editor/src/components/inspector/controls/select-control.tsx b/editor/src/components/inspector/controls/select-control.tsx index bde06840abe0..6aa5a15517d3 100644 --- a/editor/src/components/inspector/controls/select-control.tsx +++ b/editor/src/components/inspector/controls/select-control.tsx @@ -28,7 +28,7 @@ export interface DEPRECATEDSelectControlOptions extends DEPRECATEDGenericControl export interface SelectOption { value: any - icon?: IcnProps + icon?: Omit label?: string style?: React.CSSProperties options?: SelectOption[] diff --git a/editor/src/components/inspector/fill-hug-fixed-control.tsx b/editor/src/components/inspector/fill-hug-fixed-control.tsx index 3897163367f3..faf7642c5607 100644 --- a/editor/src/components/inspector/fill-hug-fixed-control.tsx +++ b/editor/src/components/inspector/fill-hug-fixed-control.tsx @@ -56,7 +56,7 @@ import { fixedSizeDimensionHandlingText } from '../text-editor/text-handling' import { when } from '../../utils/react-conditionals' import type { LayoutPinnedPropIncludingCenter } from '../../core/layout/layout-helpers-new' import { isLayoutPinnedProp, type LayoutPinnedProp } from '../../core/layout/layout-helpers-new' -import type { AllElementProps } from '../editor/store/editor-state' +import type { AllElementProps, EditorState } from '../editor/store/editor-state' import { jsExpressionValue, emptyComments } from '../../core/shared/element-template' import type { EditorDispatch, EditorAction } from '../editor/action-types' import { @@ -76,6 +76,7 @@ import { isConversionForbidden, } from '../canvas/canvas-strategies/strategies/group-conversion-helpers' import { notice } from '../common/notice' +import createCachedSelector from 're-reselect' export const FillFixedHugControlId = (segment: 'width' | 'height'): string => `hug-fixed-fill-${segment}` @@ -106,18 +107,47 @@ export function selectOptionLabel(mode: FixedHugFillMode): string { } } -function selectOption(mode: FixedHugFillMode): SelectOption { - return { - value: mode, - label: selectOptionLabel(mode), +export function selectOptionIconType( + mode: FixedHugFillMode, + dimension: 'width' | 'height', +): string { + switch (mode) { + case 'fill': + return `fill-${dimension}` + case 'fixed': + return `fixed-${dimension}` + case 'hug': + return `hug-${dimension}` + case 'hug-group': + return `hug-${dimension}` + case 'computed': + return `fixed-${dimension}` + case 'detected': + return `fixed-${dimension}` + default: + assertNever(mode) } } -const fixedHugFillOptionsSelector = createSelector( +const selectOption = + (dimension: 'width' | 'height') => + (mode: FixedHugFillMode): SelectOption => { + return { + value: mode, + label: selectOptionLabel(mode), + icon: { + category: 'layout/commands', + type: selectOptionIconType(mode, dimension), + }, + } + } + +const fixedHugFillOptionsSelector = createCachedSelector( metadataSelector, pathTreesSelector, selectedViewsSelector, - (metadata, pathTrees, selectedViews) => { + (_: MetadataSubstate, dimension: 'width' | 'height') => dimension, + (metadata, pathTrees, selectedViews, dimension) => { const applicableOptions: Array = [ ...intersection( selectedViews.map((selectedView) => @@ -126,9 +156,9 @@ const fixedHugFillOptionsSelector = createSelector( ), ] - return applicableOptions.map(selectOption) + return applicableOptions.map(selectOption(dimension)) }, -) +)((_, dimension: 'width' | 'height') => dimension) export const FillHugFixedControlOld = React.memo(() => { const onlyGroupChildrenSelected = useEditorState( @@ -503,7 +533,7 @@ export const FixedHugDropdown = React.memo((props: { dimension: 'width' | 'heigh const fixedHugFillOptions = useEditorState( Substores.metadata, - fixedHugFillOptionsSelector, + (store) => fixedHugFillOptionsSelector(store, dimension), 'FixedHugDropdown fixedHugFillOptions', ) @@ -511,7 +541,7 @@ export const FixedHugDropdown = React.memo((props: { dimension: 'width' | 'heigh return ( { const renderCountAfter = renderResult.getNumberOfRenders() // if this breaks, GREAT NEWS but update the test please :) - expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`700`) + expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`706`) expect(renderResult.getRenderInfo()).toMatchSnapshot() }) @@ -127,7 +127,7 @@ describe('React Render Count Tests -', () => { const renderCountAfter = renderResult.getNumberOfRenders() // if this breaks, GREAT NEWS but update the test please :) - expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`745`) + expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`751`) expect(renderResult.getRenderInfo()).toMatchSnapshot() }) @@ -183,7 +183,7 @@ describe('React Render Count Tests -', () => { const renderCountAfter = renderResult.getNumberOfRenders() // if this breaks, GREAT NEWS but update the test please :) - expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`606`) + expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`612`) expect(renderResult.getRenderInfo()).toMatchSnapshot() }) @@ -249,7 +249,7 @@ describe('React Render Count Tests -', () => { const renderCountAfter = renderResult.getNumberOfRenders() // if this breaks, GREAT NEWS but update the test please :) - expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`678`) + expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`684`) expect(renderResult.getRenderInfo()).toMatchSnapshot() }) }) diff --git a/editor/src/uuiui/widgets/popup-list/popup-list.tsx b/editor/src/uuiui/widgets/popup-list/popup-list.tsx index bbdacaec3293..083edb256e48 100644 --- a/editor/src/uuiui/widgets/popup-list/popup-list.tsx +++ b/editor/src/uuiui/widgets/popup-list/popup-list.tsx @@ -88,6 +88,8 @@ const Option = (props: OptionProps) => { selectOption(data) }, [data, selectOption]) + const iconShown = props.data.icon != null + return ( ) => { {props.isSelected ? '✓' : ''} - {props.data.icon == null ? null : } - {props.children} + {props.data.icon == null ? null : ( + + )} + {props.children} ) @@ -428,13 +439,40 @@ const DropdownIndicator: React.FunctionComponent< } const SingleValue = (props: SingleValueProps) => { + const iconShown = props.data.icon != null + return ( - - {props.data.icon == null ? null : } - {props.children} + { + return { ...props.getStyles(name, p), margin: iconShown ? -4 : 0 } + }} + > + {props.data.icon == null ? null : ( +
+ +
+ )} + {props.children}
) } +SingleValue.displayName = 'SingleValue' const displayNone: styleFn = () => ({ display: 'none',