Skip to content

Commit

Permalink
Data picker - move the picker next to the prop name (#4885)
Browse files Browse the repository at this point in the history
* `useDataPickerButton`

* array & object control

* update snapshots
  • Loading branch information
bkrmendy authored Feb 13, 2024
1 parent 0d843a1 commit f6f3261
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,23 +165,6 @@ export const ParseErrorControl = React.memo((props: ParseErrorProps) => {
)
})

const WarningTooltip = React.memo(({ warning }: { warning: string }) => {
const colorTheme = useColorTheme()
return (
<Tooltip title={warning}>
<div
style={{
width: 5,
height: 5,
background: colorTheme.warningBgSolid.value,
borderRadius: '50%',
marginRight: 4,
}}
/>
</Tooltip>
)
})

interface AbstractRowForControlProps {
propPath: PropertyPath
isScene: boolean
Expand Down Expand Up @@ -209,6 +192,81 @@ function getLabelControlStyle(
}
}

const isBaseIndentationLevel = (props: AbstractRowForControlProps) => props.indentationLevel === 1

function useDataPickerButton(propPath: PropertyPath) {
const [referenceElement, setReferenceElement] = React.useState<HTMLDivElement | null>(null)
const [popperElement, setPopperElement] = React.useState<HTMLDivElement | null>(null)
const popper = usePopper(referenceElement, popperElement, {
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8],
},
},
],
})

const [popupIsOpen, setPopupIsOpen] = React.useState(false)
const togglePopup = React.useCallback(() => setPopupIsOpen((v) => !v), [])
const closePopup = React.useCallback(() => setPopupIsOpen(false), [])

const onClick = React.useCallback(
(e: React.MouseEvent) => {
e.stopPropagation()
e.preventDefault()

togglePopup()
},
[togglePopup],
)

const variablePickerButtonAvailable = useVariablesInScopeForSelectedElement().length > 0
const variablePickerButtonTooltipText = variablePickerButtonAvailable
? 'Pick data source'
: 'No data sources available'

const DataPickerComponent = React.useMemo(
() => (
<DataPickerPopup
{...popper.attributes.popper}
style={popper.styles.popper}
closePopup={closePopup}
ref={setPopperElement}
propPath={propPath}
/>
),
[closePopup, popper.attributes.popper, popper.styles.popper, propPath],
)

const DataPickerOpener = React.useMemo(
() => (
<Button
onClick={onClick}
data-testid={DataPickerPopupButtonTestId}
disabled={!variablePickerButtonAvailable}
>
<Icn
type='pipette'
color='secondary'
tooltipText={variablePickerButtonTooltipText}
width={18}
height={18}
/>
</Button>
),
[onClick, variablePickerButtonAvailable, variablePickerButtonTooltipText],
)

return {
popupIsOpen,
DataPickerOpener,
DataPickerComponent,
setReferenceElement,
}
}

interface RowForBaseControlProps extends AbstractRowForControlProps {
label?: React.ComponentType<React.PropsWithChildren<any>> // TODO Before Merge this probably should not be a component
controlDescription: BaseControlDescription
Expand Down Expand Up @@ -256,35 +314,7 @@ const RowForBaseControl = React.memo((props: RowForBaseControlProps) => {
<props.label />
)

const [referenceElement, setReferenceElement] = React.useState<HTMLDivElement | null>(null)
const [popperElement, setPopperElement] = React.useState<HTMLDivElement | null>(null)
const { styles, attributes } = usePopper(referenceElement, popperElement, {
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8],
},
},
],
})

const [popupIsOpen, setPopupIsOpen] = React.useState(false)
const togglePopup = React.useCallback(() => setPopupIsOpen((v) => !v), [])
const closePopup = React.useCallback(() => setPopupIsOpen(false), [])

const onClick = React.useCallback(
(e: React.MouseEvent) => {
togglePopup()
e.stopPropagation()
},
[togglePopup],
)

const variablePickerButtonAvailable = useVariablesInScopeForSelectedElement().length > 0
const variablePickerButtonTooltipText = variablePickerButtonAvailable
? 'Pick data source'
: 'No data sources available'
const dataPickerButtonData = useDataPickerButton(props.propPath)

if (controlDescription.control === 'none') {
// do not list anything for `none` controls
Expand All @@ -298,22 +328,14 @@ const RowForBaseControl = React.memo((props: RowForBaseControlProps) => {
items={contextMenuItems}
data={null}
>
{popupIsOpen ? (
<DataPickerPopup
{...attributes.popper}
style={styles.popper}
closePopup={closePopup}
ref={setPopperElement}
propPath={propPath}
/>
) : null}
{dataPickerButtonData.popupIsOpen ? dataPickerButtonData.DataPickerComponent : null}
<UIGridRow
padded={false}
style={{ paddingLeft: 0, paddingRight: 8, paddingTop: 3, paddingBottom: 3 }}
variant='<--1fr--><--1fr-->|-18px-|'
>
{propertyLabel}
<div ref={setReferenceElement}>
<div ref={dataPickerButtonData.setReferenceElement}>
<ControlForProp
propPath={propPath}
propName={propName}
Expand All @@ -323,19 +345,7 @@ const RowForBaseControl = React.memo((props: RowForBaseControlProps) => {
focusOnMount={props.focusOnMount}
/>
</div>
<Button
onClick={onClick}
data-testid={DataPickerPopupButtonTestId}
disabled={!variablePickerButtonAvailable}
>
<Icn
type='pipette'
color='secondary'
tooltipText={variablePickerButtonTooltipText}
width={18}
height={18}
/>
</Button>
{when(isBaseIndentationLevel(props), dataPickerButtonData.DataPickerOpener)}
</UIGridRow>
</InspectorContextMenuWrapper>
)
Expand Down Expand Up @@ -530,34 +540,45 @@ const RowForArrayControl = React.memo((props: RowForArrayControlProps) => {
false,
)

const dataPickerButtonData = useDataPickerButton(props.propPath)

return (
<React.Fragment>
{when(dataPickerButtonData.popupIsOpen, dataPickerButtonData.DataPickerComponent)}
<InspectorSectionHeader>
<SimpleFlexRow style={{ flexGrow: 1, gap: 5 }}>
<PropertyLabel target={[propPath]} style={{ textTransform: 'capitalize', paddingTop: 2 }}>
{title}
</PropertyLabel>
{propertyStatus.overwritable ? (
<SquareButton
highlight
onMouseDown={toggleInsertRow}
data-testid={`toggle-insert-${PP.toString(propPath)}`}
<SimpleFlexRow
style={{ gap: 5, justifyContent: 'space-between', flexGrow: 1, paddingRight: 3 }}
>
<FlexRow style={{ gap: 5 }} ref={dataPickerButtonData.setReferenceElement}>
<PropertyLabel
target={[propPath]}
style={{ textTransform: 'capitalize', paddingTop: 2 }}
>
{insertingRow ? (
<Icons.Minus
color={propertyStatus.controlled ? 'dynamic' : 'secondary'}
width={16}
height={16}
/>
) : (
<Icons.Plus
color={propertyStatus.controlled ? 'dynamic' : 'secondary'}
width={16}
height={16}
/>
)}
</SquareButton>
) : null}
{title}
</PropertyLabel>
{propertyStatus.overwritable ? (
<SquareButton
highlight
onMouseDown={toggleInsertRow}
data-testid={`toggle-insert-${PP.toString(propPath)}`}
>
{insertingRow ? (
<Icons.Minus
color={propertyStatus.controlled ? 'dynamic' : 'secondary'}
width={16}
height={16}
/>
) : (
<Icons.Plus
color={propertyStatus.controlled ? 'dynamic' : 'secondary'}
width={16}
height={16}
/>
)}
</SquareButton>
) : null}
</FlexRow>
{when(isBaseIndentationLevel(props), dataPickerButtonData.DataPickerOpener)}
</SimpleFlexRow>
</InspectorSectionHeader>
<div
Expand Down Expand Up @@ -633,7 +654,7 @@ const ArrayControlItem = React.memo((props: ArrayControlItemProps) => {
isScene={isScene}
propPath={PP.appendPropertyPathElems(propPath, [index])}
setGlobalCursor={props.setGlobalCursor}
indentationLevel={1}
indentationLevel={2}
focusOnMount={props.focusOnMount && index === 0}
disableToggling={true}
/>
Expand Down Expand Up @@ -689,6 +710,7 @@ const RowForTupleControl = React.memo((props: RowForTupleControlProps) => {
<React.Fragment>
<InspectorSectionHeader>
<SimpleFlexRow style={{ flexGrow: 1 }}>
{when(isBaseIndentationLevel(props), <div>I0</div>)}
<PropertyLabel target={[propPath]} style={{ textTransform: 'capitalize' }}>
{title}
</PropertyLabel>
Expand Down Expand Up @@ -796,6 +818,8 @@ const RowForObjectControl = React.memo((props: RowForObjectControlProps) => {
addOnUnsetValues([PP.lastPart(propPath)], propMetadata.onUnsetValues),
])

const dataPickerButtonData = useDataPickerButton(props.propPath)

return (
<div
css={{
Expand All @@ -809,30 +833,37 @@ const RowForObjectControl = React.memo((props: RowForObjectControlProps) => {
},
}}
>
<div onClick={handleOnClick}>
<div>
<InspectorContextMenuWrapper
id={`context-menu-for-${PP.toString(propPath)}`}
items={contextMenuItems}
data={null}
>
<SimpleFlexRow style={{ flexGrow: 1, paddingRight: 8 }}>
<PropertyLabel
target={[propPath]}
style={{
textTransform: 'capitalize',
paddingLeft: indentation,
display: 'flex',
alignItems: 'center',
height: 34,
fontWeight: 500,
gap: 4,
cursor: props.disableToggling ? 'default' : 'pointer',
}}
>
{title}
{unless(props.disableToggling, <ObjectIndicator open={open} />)}
</PropertyLabel>
</SimpleFlexRow>
{when(dataPickerButtonData.popupIsOpen, dataPickerButtonData.DataPickerComponent)}
<FlexRow
style={{ flexGrow: 1, justifyContent: 'space-between', paddingRight: 10 }}
ref={dataPickerButtonData.setReferenceElement}
>
<SimpleFlexRow style={{ flexGrow: 1, paddingRight: 8 }} onClick={handleOnClick}>
<PropertyLabel
target={[propPath]}
style={{
textTransform: 'capitalize',
paddingLeft: indentation,
display: 'flex',
alignItems: 'center',
height: 34,
fontWeight: 500,
gap: 4,
cursor: props.disableToggling ? 'default' : 'pointer',
}}
>
{title}
{unless(props.disableToggling, <ObjectIndicator open={open} />)}
</PropertyLabel>
</SimpleFlexRow>
{when(isBaseIndentationLevel(props), dataPickerButtonData.DataPickerOpener)}
</FlexRow>
</InspectorContextMenuWrapper>
</div>
{when(
Expand Down Expand Up @@ -923,6 +954,7 @@ const RowForUnionControl = React.memo((props: RowForUnionControlProps) => {
} else {
return (
<React.Fragment>
{when(isBaseIndentationLevel(props), <div>I0</div>)}
{label}
<RowForControl {...props} controlDescription={controlToUse} focusOnMount={false} />
</React.Fragment>
Expand Down
Loading

0 comments on commit f6f3261

Please sign in to comment.