Skip to content

Commit

Permalink
[form-builder] Slight refactor of ArrayInput
Browse files Browse the repository at this point in the history
* Split `ArrayInputItem` into 2 components – `ArrayInputGridItem` and `ArrayInputListItem`. These components have separate layouts, and solving that with CSS only was causing issues.
* Improve readability of component code by adding newlines between methods, consts, and return bodies.
* Add a `className` property to `ArrayFunctions` to avoid importing the same CSS module in multiple components (which is a bad pattern).
  • Loading branch information
mariuslundgard authored and rexxars committed Oct 6, 2020
1 parent c392246 commit de5ae2e
Show file tree
Hide file tree
Showing 13 changed files with 579 additions and 135 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.root {
composes: functions from 'part:@sanity/components/fieldsets/default-style';
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React from 'react'
import {ArraySchemaType, SchemaType, isReferenceSchemaType} from '@sanity/types'
import classNames from 'classnames'
import DropDownButton from 'part:@sanity/components/buttons/dropdown'
import Button from 'part:@sanity/components/buttons/default'
import ButtonGrid from 'part:@sanity/components/buttons/button-grid'
import PlusIcon from 'part:@sanity/base/plus-icon'
import React from 'react'
import PatchEvent from '../../PatchEvent'
import styles from './styles/ArrayInput.css'
import {ItemValue} from './typedefs'

type Props = {
import styles from './ArrayFunctions.css'

interface ArrayFunctionsProps {
className?: string
type: ArraySchemaType
children: Node | null
value: ItemValue[]
Expand All @@ -20,18 +23,22 @@ type Props = {
onChange: (event: PatchEvent) => void
}

export default class ArrayFunctions extends React.Component<Props> {
export default class ArrayFunctions extends React.Component<ArrayFunctionsProps> {
handleDropDownAction = (menuItem: {type: SchemaType}) => {
this.handleInsertItem(menuItem.type)
}

handleAddBtnClick = () => {
this.handleInsertItem(this.props.type.of[0])
}

handleInsertItem = type => {
const {onCreateValue, onAppendItem} = this.props
const item = onCreateValue(type)

onAppendItem(item)
}

renderSelectType() {
const items = this.props.type.of.map(memberDef => {
// Use reference icon if reference is to one type only
Expand All @@ -47,19 +54,23 @@ export default class ArrayFunctions extends React.Component<Props> {
icon
}
})

return (
<DropDownButton inverted items={items} onAction={this.handleDropDownAction}>
Add
</DropDownButton>
)
}

render() {
const {type, readOnly, children} = this.props
const {className, type, readOnly, children} = this.props

if (readOnly) {
return null
}

return (
<div className={styles.functions}>
<div className={classNames(styles.root, className)}>
<ButtonGrid align="start">
{type.of.length === 1 ? (
<Button inverted onClick={this.handleAddBtnClick}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,12 @@
}

.functions {
composes: functions from 'part:@sanity/components/fieldsets/default-style';
}

.list + .functions {
margin-top: var(--small-padding);
@nest .list + & {
margin-top: var(--small-padding);

@media (--screen-medium) {
margin-top: var(--medium-padding);
@media (--screen-medium) {
margin-top: var(--medium-padding);
}
}
}

Expand Down
21 changes: 11 additions & 10 deletions packages/@sanity/form-builder/src/inputs/ArrayInput/ArrayInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import Details from '../common/Details'
import Warning from '../Warning'
import resolveListComponents from './resolveListComponents'
import {ItemValue} from './typedefs'
import ArrayInputListItem from './item/ArrayInputListItem'
import {ArrayInputItem} from './item'
import randomKey from './randomKey'

import styles from './ArrayInput.css'
Expand Down Expand Up @@ -197,20 +197,20 @@ export default class ArrayInput extends React.Component<Props, ArrayInputState>
className={isGrid ? styles.gridItem : listItemClassName}
{...itemProps}
>
<ArrayInputListItem
type={type}
value={item}
level={level}
<ArrayInputItem
compareValue={compareValue}
filterField={filterField}
focusPath={focusPath}
level={level}
markers={childMarkers.length === 0 ? NO_MARKERS : childMarkers}
onRemove={this.handleRemoveItem}
onBlur={onBlur}
onChange={this.handleItemChange}
focusPath={focusPath}
filterField={filterField}
onFocus={onFocus}
onBlur={onBlur}
readOnly={readOnly || hasMissingKeys}
onRemove={this.handleRemoveItem}
presence={childPresence}
readOnly={readOnly || hasMissingKeys}
type={type}
value={item}
/>
</Item>
)
Expand Down Expand Up @@ -403,6 +403,7 @@ export default class ArrayInput extends React.Component<Props, ArrayInputState>
{value && value.length > 0 && this.renderList()}
{this.renderUnknownValueTypes()}
<ArrayFunctions
className={styles.functions}
type={type}
value={value}
readOnly={readOnly}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
@import 'part:@sanity/base/theme/variables-style';

.root {
position: relative;
}

.inner {
display: flex;
justify-content: space-between;
align-items: center;
}

.innerWithError {
composes: inner;
}

.popupAnchor {
/*
This is where the popover sticks to
*/
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: var(--selectable-item-color-highlighted);
}

.editRootFold {
position: relative;
width: calc(100% + var(--medium-padding) * 2);
margin-left: calc(var(--medium-padding) * -1);
}

.missingKeyMessage {
color: var(--state-warning-color);
position: absolute;
top: 0;
right: 0;
z-index: 200;
padding: var(--extra-small-padding) var(--small-padding);
background-color: var(--input-bg);
}

.dragHandle {
display: block;
flex-grow: 0;
margin-right: var(--extra-small-padding);

@nest & > button {
cursor: ns-resize;
}
}

.linkToReference {
}

.previewWrapper {
composes: listItemStates from 'part:@sanity/base/theme/layout/backgrounds-style';
border-radius: var(--border-radius-base);
flex-grow: 1;
outline: none;
user-select: none;
min-width: 0;

@nest &:focus {
box-shadow: var(--input-box-shadow--focus);
}
}

.previewWrapperHelper {
outline: none;
}

.previewWrapperHelper:focus {
@nest .innerWithError & {
box-shadow: var(--input-box-shadow--invalid-focus);
}
}

.functions {
position: absolute;
z-index: 1;
display: flex;
align-items: center;
flex-grow: 0;
top: var(--extra-small-padding);
right: var(--extra-small-padding);
color: var(--text-color);

@nest & > * {
margin: 0;
}

@media (hover: hover) {
display: none;

@nest .root:hover & {
display: block;
}
}
}

.validationIconError {
composes: validationIconError from 'part:@sanity/base/theme/forms/validation-style';
}

0 comments on commit de5ae2e

Please sign in to comment.