Skip to content

Commit

Permalink
fix(core): add readOnly prop to dragHandle (#6190)
Browse files Browse the repository at this point in the history
* fix(core): add readOnly prop to dragHandle

* fix(core): disable tooltip on dragHandle when readOnly

Signed-off-by: Fred Carlsen <fred@sjelfull.no>

* fix(core): persist dragHandle in grid layout

---------

Signed-off-by: Fred Carlsen <fred@sjelfull.no>
Co-authored-by: Fred Carlsen <fred@sjelfull.no>
  • Loading branch information
pedrobonamin and sjelfull committed Apr 8, 2024
1 parent e978813 commit 234d009
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function ReferenceItem<Item extends ReferenceItemValue = ReferenceItemVal
inputProps: {onChange, focusPath, onPathFocus, renderPreview, elementProps},
} = props

const sortable = !readOnly && parentSchemaType.options?.sortable !== false
const sortable = parentSchemaType.options?.sortable !== false
const insertableTypes = parentSchemaType.of

const elementRef = useRef<HTMLDivElement | null>(null)
Expand Down Expand Up @@ -296,6 +296,7 @@ export function ReferenceItem<Item extends ReferenceItemValue = ReferenceItemVal
<ReferenceItemRefProvider menuRef={menuRef} containerRef={containerRef}>
<RowLayout
dragHandle={sortable}
readOnly={!!readOnly}
presence={
!isEditing && presence.length > 0 && <FieldPresence presence={presence} maxAvatars={1} />
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {IncompatibleItemType} from './IncompatibleItemType'

const MENU_POPOVER_PROPS = {portal: true, tone: 'default'} as const

export function ErrorItem(props: {member: ArrayItemError; sortable?: boolean}) {
const {member, sortable} = props
export function ErrorItem(props: {member: ArrayItemError; sortable?: boolean; readOnly?: boolean}) {
const {member, sortable, readOnly} = props
const id = useId()
const {onChange} = useFormCallbacks()
const {t} = useTranslation()
Expand All @@ -26,6 +26,7 @@ export function ErrorItem(props: {member: ArrayItemError; sortable?: boolean}) {
return (
<CellLayout
dragHandle={sortable}
readOnly={readOnly}
tone="caution"
style={{height: '100%'}}
menu={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ export function GridArrayInput<Item extends ObjectItem>(props: ArrayOfObjectsInp
renderPreview={renderPreview}
/>
)}
{member.kind === 'error' && <ErrorItem sortable={sortable} member={member} />}
{member.kind === 'error' && (
<ErrorItem sortable={sortable} member={member} readOnly={readOnly} />
)}
</Item>
))}
</List>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export function GridItem<Item extends ObjectItem = ObjectItem>(props: GridItemPr
} = props
const {t} = useTranslation()

const sortable = !readOnly && parentSchemaType.options?.sortable !== false
const sortable = parentSchemaType.options?.sortable !== false
const insertableTypes = parentSchemaType.of

const previewCardRef = useRef<FIXME | null>(null)
Expand Down Expand Up @@ -175,6 +175,7 @@ export function GridItem<Item extends ObjectItem = ObjectItem>(props: GridItemPr
border
dragHandle={sortable}
selected={open}
readOnly={readOnly}
>
<PreviewCard
tone="inherit"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ export function ErrorItem(props: {
member: ArrayItemError
sortable?: boolean
onRemove: () => void
readOnly?: boolean
}) {
const {member, sortable, onRemove} = props
const {member, sortable, onRemove, readOnly} = props
const id = useId()

const {t} = useTranslation()
Expand All @@ -25,6 +26,7 @@ export function ErrorItem(props: {
<Box paddingX={1}>
<RowLayout
dragHandle={sortable}
readOnly={!!readOnly}
tone="caution"
menu={
<MenuButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ export function ListArrayInput<Item extends ObjectItem>(props: ArrayOfObjectsInp
)}
{member.kind === 'error' && (
<ErrorItem
readOnly={readOnly}
sortable={sortable}
member={member}
onRemove={() => props.onItemRemove(member.key)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export function PreviewItem<Item extends ObjectItem = ObjectItem>(props: Preview
} = props
const {t} = useTranslation()

const sortable = !readOnly && parentSchemaType.options?.sortable !== false
const sortable = parentSchemaType.options?.sortable !== false
const insertableTypes = parentSchemaType.of

const previewCardRef = useRef<HTMLDivElement | null>(null)
Expand Down Expand Up @@ -156,6 +156,7 @@ export function PreviewItem<Item extends ObjectItem = ObjectItem>(props: Preview
focused={focused}
dragHandle={sortable}
selected={open}
readOnly={!!readOnly}
>
<Card
as="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ export class ArrayOfPrimitivesInput extends PureComponent<ArrayOfPrimitivesInput
)}
{member.kind === 'error' && (
<ErrorItem
readOnly={readOnly}
sortable={isSortable}
member={member}
onRemove={() => onItemRemove(index)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@ export const ItemRow = forwardRef(function ItemRow(
return (
<RowLayout
tone={tone}
readOnly={!!readOnly}
menu={!readOnly && menu}
dragHandle={!readOnly && sortable}
dragHandle={sortable}
presence={presence.length === 0 ? null : <FieldPresence presence={presence} maxAvatars={1} />}
validation={
validation.length > 0 ? (
Expand Down
21 changes: 14 additions & 7 deletions packages/sanity/src/core/form/inputs/arrays/common/DragHandle.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import {useSortable} from '@dnd-kit/sortable'
import {DragHandleIcon} from '@sanity/icons'
import {createContext, useContext} from 'react'
import {styled} from 'styled-components'
import {css, styled} from 'styled-components'

import {Button, type ButtonProps} from '../../../../../ui-components'
import {useTranslation} from '../../../../i18n'

const DragHandleButton = styled(Button)<{$grid?: boolean}>`
cursor: ${(props) => (props.$grid ? 'move' : 'ns-resize')};
`
const DragHandleButton = styled(Button)<{$grid?: boolean; disabled?: boolean}>((props) => {
const {$grid, disabled} = props
if (disabled) return css``
return css`
cursor: ${$grid ? 'move' : 'ns-resize'};
`
})

export const SortableItemIdContext = createContext<string | null>(null)

Expand All @@ -17,26 +21,29 @@ interface DragHandleProps {
size?: ButtonProps['size']
mode?: ButtonProps['mode']
paddingY?: ButtonProps['paddingY']
readOnly: boolean
}

export const DragHandle = function DragHandle(props: DragHandleProps) {
const id = useContext(SortableItemIdContext)!
const {listeners, attributes} = useSortable({id})
const {mode = 'bleed', readOnly, ...rest} = props
const {listeners, attributes} = useSortable({id, disabled: readOnly})
const {t} = useTranslation()
const {mode = 'bleed', ...rest} = props

return (
<DragHandleButton
icon={DragHandleIcon}
tooltipProps={{
content: t('inputs.array.action.drag.tooltip'),
delay: {open: 1000},
disabled: !!readOnly,
}}
mode={mode}
data-ui="DragHandleButton"
{...attributes}
{...rest}
{...attributes}
{...listeners}
disabled={readOnly}
/>
)
}
15 changes: 13 additions & 2 deletions packages/sanity/src/core/form/inputs/arrays/layouts/CellLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,18 @@ const Root = styled(Card)`
* Use this to get the layout for grid items
*/
export function CellLayout(props: RowLayoutProps & ComponentProps<typeof Root>) {
const {validation, selected, tone, presence, children, dragHandle, menu, footer, ...rest} = props
const {
validation,
selected,
tone,
presence,
children,
dragHandle,
menu,
footer,
readOnly,
...rest
} = props

return (
<Root
Expand All @@ -89,7 +100,7 @@ export function CellLayout(props: RowLayoutProps & ComponentProps<typeof Root>)
tone="inherit"
data-ui="DragHandleCard"
>
<DragHandle $grid mode="ghost" />
<DragHandle $grid mode="ghost" readOnly={!!readOnly} />
</DragHandleCard>
)}

Expand Down
16 changes: 14 additions & 2 deletions packages/sanity/src/core/form/inputs/arrays/layouts/RowLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface RowLayoutProps {
footer?: ReactNode
selected?: boolean
children?: ReactNode
readOnly: boolean
}

const Root = styled(Card)`
Expand All @@ -42,7 +43,18 @@ const Root = styled(Card)`
`

export function RowLayout(props: RowLayoutProps) {
const {validation, selected, tone, presence, focused, children, dragHandle, menu, footer} = props
const {
validation,
selected,
tone,
presence,
focused,
children,
dragHandle,
menu,
footer,
readOnly,
} = props

const elementRef = useRef<HTMLDivElement | null>(null)

Expand All @@ -63,7 +75,7 @@ export function RowLayout(props: RowLayoutProps) {
>
<Stack space={1}>
<Flex align="center" gap={1}>
{dragHandle && <DragHandle paddingY={3} />}
{dragHandle && <DragHandle paddingY={3} readOnly={readOnly} />}

<Box flex={1}>{children}</Box>

Expand Down

0 comments on commit 234d009

Please sign in to comment.