diff --git a/packages/@sanity/base/src/styles/forms/text-input.css b/packages/@sanity/base/src/styles/forms/text-input.css index 641754f258b..ebb064812e7 100644 --- a/packages/@sanity/base/src/styles/forms/text-input.css +++ b/packages/@sanity/base/src/styles/forms/text-input.css @@ -17,6 +17,10 @@ @nest &:disabled { opacity: 0.5; } + + @nest &:read-only { + opacity: 0.5; + } } .textInput { @@ -26,17 +30,19 @@ box-shadow: var(--input-box-shadow); @nest &:not(:disabled) { - @nest &:hover { - box-shadow: var(--input-box-shadow--hover); - } + @nest &:not(:read-only) { + @nest &:hover { + box-shadow: var(--input-box-shadow--hover); + } - @nest &:focus, &:focus-within { - /* border-color: var(--input-border-color-focus); */ - box-shadow: var(--input-box-shadow--focus); - } + @nest &:focus, &:focus-within { + /* border-color: var(--input-border-color-focus); */ + box-shadow: var(--input-box-shadow--focus); + } - @nest &:active { - /* border-color: var(--input-border-color-active); */ + @nest &:active { + /* border-color: var(--input-border-color-active); */ + } } } } diff --git a/packages/@sanity/base/src/styles/forms/textarea.css b/packages/@sanity/base/src/styles/forms/textarea.css index 9bead500810..baa68b76da3 100644 --- a/packages/@sanity/base/src/styles/forms/textarea.css +++ b/packages/@sanity/base/src/styles/forms/textarea.css @@ -27,4 +27,8 @@ @nest &:disabled { background-color: var(--input-bg-disabled); } + + @nest &:read-only { + opacity: 0.5; + } } diff --git a/packages/@sanity/components/src/radiobutton/styles/RadioButtonDefault.css b/packages/@sanity/components/src/radiobutton/styles/RadioButtonDefault.css index 69debfa8cf4..dd2c9fb82af 100644 --- a/packages/@sanity/components/src/radiobutton/styles/RadioButtonDefault.css +++ b/packages/@sanity/components/src/radiobutton/styles/RadioButtonDefault.css @@ -33,6 +33,11 @@ composes: root; } +.isDisabled { + opacity: 0.5; + pointer-events: none; +} + .input { line-height: var(--radio-label-height); @@ -45,10 +50,6 @@ opacity: 0; appearance: none; border: none; - - @nest &:disabled { - opacity: 0.2; - } } .circleOutline { diff --git a/packages/@sanity/components/src/selects/DefaultSelect.js b/packages/@sanity/components/src/selects/DefaultSelect.js index aa342b55c4d..939434e4cfe 100644 --- a/packages/@sanity/components/src/selects/DefaultSelect.js +++ b/packages/@sanity/components/src/selects/DefaultSelect.js @@ -12,6 +12,7 @@ export default class DefaultSelect extends React.Component { onBlur: PropTypes.func, hasFocus: PropTypes.bool, disabled: PropTypes.bool, + readOnly: PropTypes.bool, items: PropTypes.arrayOf( PropTypes.shape({ title: PropTypes.string, @@ -23,6 +24,7 @@ export default class DefaultSelect extends React.Component { onChange() {}, onBlur() {}, onFocus() {}, + readOnly: false, hasError: false, hasFocus: false, value: {}, @@ -44,26 +46,27 @@ export default class DefaultSelect extends React.Component { } render() { - const {hasError, items, value, disabled, hasFocus, ...rest} = this.props + const {hasError, items, value, disabled, hasFocus, readOnly, ...rest} = this.props return ( -
+
diff --git a/packages/@sanity/components/src/selects/RadioSelect.js b/packages/@sanity/components/src/selects/RadioSelect.js index 0c6b5f90ba6..b20f29ffc64 100644 --- a/packages/@sanity/components/src/selects/RadioSelect.js +++ b/packages/@sanity/components/src/selects/RadioSelect.js @@ -9,6 +9,7 @@ export default class RadioSelect extends React.Component { direction: PropTypes.oneOf(['horizontal', 'vertical']), onChange: PropTypes.func, value: PropTypes.object, + readOnly: PropTypes.bool, items: PropTypes.arrayOf( PropTypes.shape({ title: PropTypes.string, @@ -45,7 +46,7 @@ export default class RadioSelect extends React.Component { } render() { - const {items, value, name, direction} = this.props + const {items, value, name, direction, readOnly} = this.props const {focusedItem} = this.state return ( @@ -60,6 +61,7 @@ export default class RadioSelect extends React.Component { return (
item, items: [], width: 100, @@ -140,6 +143,7 @@ export default class StatelessSearchableSelect extends React.PureComponent { highlightIndex, isInputSelected, inputValue, + readOnly, onChange, onInputChange, onOpen, @@ -149,6 +153,7 @@ export default class StatelessSearchableSelect extends React.PureComponent { disabled, onHighlightIndexChange, openItemElement, + readOnly, ...rest } = this.props @@ -165,7 +170,9 @@ export default class StatelessSearchableSelect extends React.PureComponent { value={inputValue || ''} selected={isInputSelected} disabled={disabled} + readOnly={readOnly} ref={this.setInput} + readOnly={readOnly} />
{ @@ -174,13 +181,13 @@ export default class StatelessSearchableSelect extends React.PureComponent { ) } { - onClear && value && ( + onClear && value && !readOnly && ( ) } - {!isLoading && ( + {!isLoading && !readOnly && (
{} } @@ -91,6 +93,7 @@ export default class TagsTextField extends React.Component { const { onChange, value, + readOnly, ...rest } = this.props @@ -100,24 +103,26 @@ export default class TagsTextField extends React.Component {
    { - value && value.map((tag, i) => { + value.map((tag, i) => { return ( -
  • +
  • {tag} - - × - + {!readOnly && ( + + × + + )}
  • ) - }) - } + })}
diff --git a/packages/@sanity/components/src/toggles/Switch.js b/packages/@sanity/components/src/toggles/Switch.js index 4fa49c0766f..a4f7e8c4f9d 100644 --- a/packages/@sanity/components/src/toggles/Switch.js +++ b/packages/@sanity/components/src/toggles/Switch.js @@ -9,6 +9,7 @@ export default class Switch extends React.Component { disabled: PropTypes.bool, onFocus: PropTypes.func, onBlur: PropTypes.func, + readOnly: PropTypes.bool } state = { @@ -42,7 +43,7 @@ export default class Switch extends React.Component { } render() { - const {disabled, checked, label, ...rest} = this.props + const {disabled, checked, label, readOnly, ...rest} = this.props const {hasFocus} = this.state let thumbClass = checked ? styles.thumbChecked : styles.thumb @@ -54,8 +55,8 @@ export default class Switch extends React.Component { return ( ) } diff --git a/packages/@sanity/components/src/toggles/styles/Checkbox.css b/packages/@sanity/components/src/toggles/styles/Checkbox.css index 3689ba1d66d..713bd8bd615 100644 --- a/packages/@sanity/components/src/toggles/styles/Checkbox.css +++ b/packages/@sanity/components/src/toggles/styles/Checkbox.css @@ -41,7 +41,8 @@ } .isDisabled { - opacity: 0.2; + opacity: 0.5; + pointer-events: none; } .isEnabled { diff --git a/packages/@sanity/components/src/toggles/styles/Switch.css b/packages/@sanity/components/src/toggles/styles/Switch.css index 5c4ca9410e8..c02022aa49b 100644 --- a/packages/@sanity/components/src/toggles/styles/Switch.css +++ b/packages/@sanity/components/src/toggles/styles/Switch.css @@ -68,7 +68,7 @@ background: var(--switch-track-color); } - @nest .disabled & { + @nest .isDisabled & { background: var(--switch-disabled-track-color); cursor: auto; } @@ -78,8 +78,9 @@ composes: root; } -.disabled { +.isDisabled { composes: root; + pointer-events: none; opacity: 0.5; } diff --git a/packages/@sanity/form-builder/src/FormBuilderInput.js b/packages/@sanity/form-builder/src/FormBuilderInput.js index d4ad454eac2..d0b225ef05f 100644 --- a/packages/@sanity/form-builder/src/FormBuilderInput.js +++ b/packages/@sanity/form-builder/src/FormBuilderInput.js @@ -12,6 +12,7 @@ type Props = { onChange: PatchEvent => void, onFocus: Path => void, onBlur: () => void, + readOnly: boolean, focusPath: Path, level: number, isRoot: boolean, @@ -154,6 +155,7 @@ export const FormBuilderInput = class FormBuilderInput extends React.PureCompone onFocus, onBlur, path, + readOnly, value, type, level, @@ -182,6 +184,7 @@ export const FormBuilderInput = class FormBuilderInput extends React.PureCompone {...rootProps} {...leafProps} value={value} + readOnly={readOnly || type.readOnly} type={type} onChange={this.handleChange} onFocus={this.handleFocus} diff --git a/packages/@sanity/form-builder/src/inputs/Array/Array.js b/packages/@sanity/form-builder/src/inputs/Array/Array.js index ebc241f3881..adf2aa53def 100644 --- a/packages/@sanity/form-builder/src/inputs/Array/Array.js +++ b/packages/@sanity/form-builder/src/inputs/Array/Array.js @@ -12,7 +12,7 @@ import {resolveTypeName} from '../../utils/resolveTypeName' import type {Uploader} from '../../sanity/uploads/typedefs' import type {Type} from '../../typedefs' import type {Path} from '../../typedefs/path' -import {FOCUS_TERMINATOR, isExpanded} from '../../utils/pathUtils' +import {FOCUS_TERMINATOR} from '../../utils/pathUtils' import type {Subscription} from '../../typedefs/observable' import UploadTargetFieldset from '../../utils/UploadTargetFieldset' @@ -48,6 +48,7 @@ type Props = { onFocus: Path => void, onBlur: () => void, focusPath: Path, + readOnly: ?boolean, resolveUploader?: (type: Type, file: File) => Uploader } @@ -208,7 +209,7 @@ export default class ArrayInput extends React.Component { } renderList = () => { - const {type, value, focusPath, onBlur, onFocus, level} = this.props + const {type, readOnly, value, focusPath, onBlur, onFocus, level} = this.props const {isMoving} = this.state const options = type.options || {} @@ -230,7 +231,7 @@ export default class ArrayInput extends React.Component { const listItemClassName = isMoving ? styles.listItemMute : styles.listItem return ( {value.map((item, index) => { @@ -252,6 +253,7 @@ export default class ArrayInput extends React.Component { onChange={this.handleItemChange} focusPath={focusPath} onFocus={onFocus} + readOnly={readOnly} onBlur={onBlur} /> @@ -304,7 +306,7 @@ export default class ArrayInput extends React.Component { } render() { - const {type, level, value} = this.props + const {type, level, readOnly, value} = this.props return ( { ref={this.setElement} > {value && value.length > 0 && this.renderList()} - {!type.readOnly && ( + {!readOnly && (
{this.props.type.of.length === 1 && ( - ) : this.renderSelectType()} -
+ {!readOnly && ( +
+ {type.of.length === 1 ? ( + + ) : this.renderSelectType()} +
+ )}
) diff --git a/packages/@sanity/form-builder/src/inputs/ArrayOfPrimitives/Item.js b/packages/@sanity/form-builder/src/inputs/ArrayOfPrimitives/Item.js index 52f8b42f77f..6094fca6e45 100644 --- a/packages/@sanity/form-builder/src/inputs/ArrayOfPrimitives/Item.js +++ b/packages/@sanity/form-builder/src/inputs/ArrayOfPrimitives/Item.js @@ -27,6 +27,7 @@ type Props = { index: number, value: string | number | boolean, isSortable: boolean, + readOnly: ?boolean, level: number } export default class Item extends React.PureComponent { @@ -64,10 +65,10 @@ export default class Item extends React.PureComponent { } render() { - const {value, level, index, focusPath, onFocus, onBlur, type, isSortable} = this.props + const {value, level, index, focusPath, onFocus, onBlur, type, readOnly, isSortable} = this.props return (
- {isSortable && } + {isSortable && !readOnly && }
{ onFocus={onFocus} onBlur={onBlur} type={type} + readOnly={readOnly || type.readOnly} onKeyUp={this.handleKeyUp} onKeyPress={this.handleKeyPress} onChange={this.handleChange} level={level} />
-
) } diff --git a/packages/@sanity/form-builder/src/inputs/Boolean.js b/packages/@sanity/form-builder/src/inputs/Boolean.js index ac0ef96ab31..2bcaebd7214 100644 --- a/packages/@sanity/form-builder/src/inputs/Boolean.js +++ b/packages/@sanity/form-builder/src/inputs/Boolean.js @@ -8,6 +8,7 @@ import type {Type} from '../typedefs' type Props = { type: Type, value: ?boolean, + readOnly: ?boolean, onChange: PatchEvent => void } @@ -30,13 +31,14 @@ export default class BooleanInput extends React.Component { } render() { - const {value, type, level, description, ...rest} = this.props + const {value, type, readOnly, level, description, ...rest} = this.props const isCheckbox = type.options && type.options.layout === 'checkbox' return isCheckbox ? ( { : ( void, level: number } @@ -144,9 +144,9 @@ export default class DateInput extends React.Component { } render() { - const {value, type, level, ...rest} = this.props + const {value, type, readOnly, level, ...rest} = this.props const {inputValue, isActive} = this.state - const {title, description, readOnly} = type + const {title, description} = type const momentValue: ?Moment = value ? moment(value) : null const options = parseOptions(type.options) diff --git a/packages/@sanity/form-builder/src/inputs/Email.js b/packages/@sanity/form-builder/src/inputs/Email.js index f456b0a0a4b..609fd431582 100644 --- a/packages/@sanity/form-builder/src/inputs/Email.js +++ b/packages/@sanity/form-builder/src/inputs/Email.js @@ -9,6 +9,7 @@ type Props = { type: Type, level: number, value: ?string, + readOnly: ?boolean, onChange: PatchEvent => void } @@ -31,7 +32,7 @@ export default class EmailInput extends React.Component { } render() { - const {value, type, level, ...rest} = this.props + const {value, readOnly, type, level, ...rest} = this.props return ( { {...rest} type="email" value={value} - readOnly={type.readOnly} + readOnly={readOnly} placeholder={type.placeholder} onChange={this.handleChange} ref={this.setInput} diff --git a/packages/@sanity/form-builder/src/inputs/File/FileInput.js b/packages/@sanity/form-builder/src/inputs/File/FileInput.js index c2d479ab5af..0d84e75d208 100644 --- a/packages/@sanity/form-builder/src/inputs/File/FileInput.js +++ b/packages/@sanity/form-builder/src/inputs/File/FileInput.js @@ -6,6 +6,7 @@ import Button from 'part:@sanity/components/buttons/default' import FileInputButton from 'part:@sanity/components/fileinput/button' import ProgressBar from 'part:@sanity/components/progress/bar' import EditIcon from 'part:@sanity/base/edit-icon' +import VisibilityIcon from 'part:@sanity/base/visibility-icon' import FileIcon from 'part:@sanity/base/file-icon' import UploadIcon from 'part:@sanity/base/upload-icon' import {get, partition} from 'lodash' @@ -44,6 +45,7 @@ type Props = { materialize: (string) => ObservableI, onBlur: () => void, onFocus: () => void, + readOnly: ?boolean, focusPath: Array<*> } @@ -232,7 +234,7 @@ export default class FileInput extends React.PureComponent { } renderField(field: FieldT) { - const {value, level, onFocus, onBlur, focusPath} = this.props + const {value, level, focusPath, onFocus, readOnly, onBlur} = this.props const fieldValue = value && value[field.name] return ( @@ -244,12 +246,31 @@ export default class FileInput extends React.PureComponent { path={[field.name]} onFocus={onFocus} onBlur={onBlur} + readOnly={readOnly || field.type.readOnly} focusPath={focusPath} level={level} /> ) } + renderAsset() { + const {value, materialize, readOnly} = this.props + + if (value && value.asset) { + return ( + + {this.renderMaterializedAsset} + + ) + } + + return readOnly ? ( + Field is read only + ) : ( + + ) + } + focus() { if (this._focusArea) { this._focusArea.focus() @@ -267,14 +288,13 @@ export default class FileInput extends React.PureComponent { } handleUpload = ({file, uploader}) => { - this.uploadWith(uploader, file) } render() { - const {type, value, level, materialize} = this.props + const {type, value, level, readOnly} = this.props - const {isAdvancedEditOpen, uploadError, hasFocus} = this.state + const {isAdvancedEditOpen, uploadError} = this.state const [highlightedFields, otherFields] = partition( type.fields.filter(field => !HIDDEN_FIELDS.includes(field.name)), @@ -310,11 +330,7 @@ export default class FileInput extends React.PureComponent { {this.renderUploadState(value._upload)} )} - {hasAsset ? ( - - {this.renderMaterializedAsset} - - ) : } + {this.renderAsset()} {highlightedFields.length > 0 && (
@@ -323,24 +339,26 @@ export default class FileInput extends React.PureComponent { )}
- - Upload - + {!readOnly && ( + + Upload + + )} {value && otherFields.length > 0 && ( )} - {hasAsset && ( + {!readOnly && hasAsset && ( )}
diff --git a/packages/@sanity/form-builder/src/inputs/Image/ImageInput.js b/packages/@sanity/form-builder/src/inputs/Image/ImageInput.js index 0721668f9da..a8d0683108f 100644 --- a/packages/@sanity/form-builder/src/inputs/Image/ImageInput.js +++ b/packages/@sanity/form-builder/src/inputs/Image/ImageInput.js @@ -1,13 +1,13 @@ /* eslint-disable complexity */ -import type {Node} from 'react' // @flow +import type {Node} from 'react' import React from 'react' import Button from 'part:@sanity/components/buttons/default' import FileInputButton from 'part:@sanity/components/fileinput/button' -import ProgressBar from 'part:@sanity/components/progress/bar' import ProgressCircle from 'part:@sanity/components/progress/circle' import EditIcon from 'part:@sanity/base/edit-icon' import UploadIcon from 'part:@sanity/base/upload-icon' +import VisibilityIcon from 'part:@sanity/base/visibility-icon' import {get, partition} from 'lodash' import PatchEvent, {set, setIfMissing, unset} from '../../PatchEvent' import styles from './styles/ImageInput.css' @@ -47,6 +47,7 @@ type Props = { materialize: (string) => ObservableI, onBlur: () => void, onFocus: () => void, + readOnly: ?boolean, focusPath: Array<*> } @@ -238,14 +239,24 @@ export default class ImageInput extends React.PureComponent { } renderAdvancedEdit(fields: Array) { - const {value, level, onChange, materialize} = this.props + const {value, level, onChange, readOnly, materialize} = this.props return ( - {this.isImageToolEnabled() && value && value.asset && ( - - {imageAsset => } - + {this.isImageToolEnabled() && + value && + value.asset && ( + + {imageAsset => ( + + )} + )}
{this.renderFields(fields)} @@ -260,7 +271,7 @@ export default class ImageInput extends React.PureComponent { } renderField(field: FieldT) { - const {value, level, focusPath, onFocus, onBlur} = this.props + const {value, level, focusPath, onFocus, readOnly, onBlur} = this.props const fieldValue = value && value[field.name] return ( @@ -275,6 +286,7 @@ export default class ImageInput extends React.PureComponent { path={[field.name]} onFocus={onFocus} onBlur={onBlur} + readOnly={readOnly || field.type.readOnly} focusPath={focusPath} level={level} /> @@ -318,7 +330,7 @@ export default class ImageInput extends React.PureComponent { } render() { - const {type, value, level, materialize} = this.props + const {type, value, level, materialize, readOnly} = this.props const {isAdvancedEditOpen, isSelectAssetOpen, uploadError, hasFocus} = this.state @@ -363,7 +375,7 @@ export default class ImageInput extends React.PureComponent { {this.renderMaterializedAsset} - ) : } + ) : (readOnly ? Field is read only : )}
{highlightedFields.length > 0 && (
@@ -372,27 +384,27 @@ export default class ImageInput extends React.PureComponent { )}
- Upload - - + } {showAdvancedEditButton && ( )} - {hasAsset && ( + {hasAsset && !readOnly && ( )}
diff --git a/packages/@sanity/form-builder/src/inputs/ImageTool/ImageToolInput.js b/packages/@sanity/form-builder/src/inputs/ImageTool/ImageToolInput.js index 2bafa3ca894..3fd14db444d 100644 --- a/packages/@sanity/form-builder/src/inputs/ImageTool/ImageToolInput.js +++ b/packages/@sanity/form-builder/src/inputs/ImageTool/ImageToolInput.js @@ -33,6 +33,7 @@ type Props = { imageUrl: string, value?: Value, onChange: (PatchEvent) => void, + readOnly: ?boolean, level: number } @@ -56,12 +57,15 @@ export default class ImageToolInput extends React.Component { } handleChangeEnd = () => { - const {onChange} = this.props + const {onChange, readOnly} = this.props const {value} = this.state - onChange(PatchEvent.from([ - set(value.crop, ['crop']), - set(value.hotspot, ['hotspot']) - ])) + if (!readOnly) { + onChange(PatchEvent.from([ + set(value.crop, ['crop']), + set(value.hotspot, ['hotspot']) + ])) + } + this.setState({value: this.props.value}) } handleChange = (nextValue: Value) => { @@ -73,7 +77,7 @@ export default class ImageToolInput extends React.Component { } render() { - const {imageUrl, level} = this.props + const {imageUrl, level, readOnly} = this.props const {value} = this.state return ( @@ -84,6 +88,7 @@ export default class ImageToolInput extends React.Component { diff --git a/packages/@sanity/form-builder/src/inputs/Number.js b/packages/@sanity/form-builder/src/inputs/Number.js index 9a035c86076..b8d8c052b66 100644 --- a/packages/@sanity/form-builder/src/inputs/Number.js +++ b/packages/@sanity/form-builder/src/inputs/Number.js @@ -9,6 +9,7 @@ type Props = { type: Type, level: number, value: ?string, + readOnly: ?boolean, onChange: PatchEvent => void } @@ -31,7 +32,7 @@ export default class NumberInput extends React.Component { } render() { - const {value = '', type, level, ...rest} = this.props + const {value = '', readOnly, type, level, ...rest} = this.props return ( { {...rest} type="number" value={value} - readOnly={type.readOnly} + readOnly={readOnly} placeholder={type.placeholder} onChange={this.handleChange} ref={this.setInput} diff --git a/packages/@sanity/form-builder/src/inputs/Object/Field.js b/packages/@sanity/form-builder/src/inputs/Object/Field.js index 7c0febe9350..4288bb437a9 100644 --- a/packages/@sanity/form-builder/src/inputs/Object/Field.js +++ b/packages/@sanity/form-builder/src/inputs/Object/Field.js @@ -18,6 +18,7 @@ export default class Field extends React.Component { onFocus: PropTypes.func.isRequired, onBlur: PropTypes.func.isRequired, focusPath: PropTypes.array, + readOnly: PropTypes.bool, level: PropTypes.number } @@ -42,7 +43,7 @@ export default class Field extends React.Component { } render() { - const {value, field, level, onFocus, onBlur, focusPath} = this.props + const {value, readOnly, field, level, onFocus, onBlur, focusPath} = this.props if (typeof value !== 'undefined') { const expectedType = field.type.name @@ -77,6 +78,7 @@ export default class Field extends React.Component { path={[field.name]} onFocus={onFocus} onBlur={onBlur} + readOnly={readOnly || field.type.readOnly} focusPath={focusPath} level={level} ref={this.setInput} diff --git a/packages/@sanity/form-builder/src/inputs/Object/Object.js b/packages/@sanity/form-builder/src/inputs/Object/Object.js index b7ec70dd70e..fa66cf33b67 100644 --- a/packages/@sanity/form-builder/src/inputs/Object/Object.js +++ b/packages/@sanity/form-builder/src/inputs/Object/Object.js @@ -43,6 +43,7 @@ export default class ObjectInput extends React.PureComponent { focusPath: PropTypes.array, onBlur: PropTypes.func.isRequired, level: PropTypes.number, + readOnly: PropTypes.bool, isRoot: PropTypes.bool } @@ -91,7 +92,7 @@ export default class ObjectInput extends React.PureComponent { return null } - const {value, focusPath, onFocus, onBlur} = this.props + const {value, readOnly, type, focusPath, onFocus, onBlur} = this.props const fieldValue = value && value[field.name] return ( ) diff --git a/packages/@sanity/form-builder/src/inputs/OptionsArray/Item.js b/packages/@sanity/form-builder/src/inputs/OptionsArray/Item.js index e10b1a5c6ce..1d0031ce39c 100644 --- a/packages/@sanity/form-builder/src/inputs/OptionsArray/Item.js +++ b/packages/@sanity/form-builder/src/inputs/OptionsArray/Item.js @@ -9,7 +9,8 @@ type Props = { type: Type, value: any, checked: boolean, - onChange: (boolean, any) => void + onChange: (boolean, any) => void, + readOnly: ?boolean } export default class Item extends React.PureComponent { handleChange = (event: SyntheticEvent) => { @@ -18,11 +19,12 @@ export default class Item extends React.PureComponent { } render() { - const {value, checked, type} = this.props + const {value, checked, type, readOnly} = this.props return ( {isLegacyOptionsItem(value) ? value.title diff --git a/packages/@sanity/form-builder/src/inputs/OptionsArray/OptionsArray.js b/packages/@sanity/form-builder/src/inputs/OptionsArray/OptionsArray.js index 9959c77ba89..2bbec6dccff 100644 --- a/packages/@sanity/form-builder/src/inputs/OptionsArray/OptionsArray.js +++ b/packages/@sanity/form-builder/src/inputs/OptionsArray/OptionsArray.js @@ -55,6 +55,7 @@ export default class OptionsArrayInput extends React.PureComponent { }), value: PropTypes.array, level: PropTypes.number, + readOnly: PropTypes.bool, onChange: PropTypes.func } @@ -65,7 +66,7 @@ export default class OptionsArrayInput extends React.PureComponent { if (!isChecked && optionValue._key) { // This is an optimization that only works if list items are _keyed - this.props.onChange(PatchEvent.from(unset({_key: optionValue._key}))) + this.props.onChange(PatchEvent.from(unset([{_key: optionValue._key}]))) } const nextValue = list @@ -85,7 +86,7 @@ export default class OptionsArrayInput extends React.PureComponent { } render() { - const {type, value, level} = this.props + const {type, value, level, readOnly} = this.props const options = get(type.options, 'list') const direction = get(type.options, 'direction') // vertical and horizontal @@ -114,6 +115,7 @@ export default class OptionsArrayInput extends React.PureComponent { { type, value, level, + readOnly, onSearch, getPreviewSnapshot, ...rest @@ -240,6 +241,7 @@ export default class ReferenceInput extends React.Component { isLoading={isFetching} items={hits} ref={this.setInput} + readOnly={readOnly} /> diff --git a/packages/@sanity/form-builder/src/inputs/String.js b/packages/@sanity/form-builder/src/inputs/String.js index 16b6ec6020a..5c1f91bd8f4 100644 --- a/packages/@sanity/form-builder/src/inputs/String.js +++ b/packages/@sanity/form-builder/src/inputs/String.js @@ -9,6 +9,7 @@ type Props = { type: Type, level: number, value: ?string, + readOnly: ?boolean, onChange: PatchEvent => void } @@ -31,7 +32,7 @@ export default class StringInput extends React.Component { } render() { - const {value, type, level, ...rest} = this.props + const {value, readOnly, type, level, ...rest} = this.props return ( { {...rest} type="text" value={value} - readOnly={type.readOnly} + readOnly={readOnly} placeholder={type.placeholder} onChange={this.handleChange} ref={this.setInput} diff --git a/packages/@sanity/form-builder/src/inputs/StringSelect.js b/packages/@sanity/form-builder/src/inputs/StringSelect.js index 2dc1c55642c..642fece9d37 100644 --- a/packages/@sanity/form-builder/src/inputs/StringSelect.js +++ b/packages/@sanity/form-builder/src/inputs/StringSelect.js @@ -18,6 +18,7 @@ type Props = { type: Type, level: number, value: ?string, + readOnly: ?boolean, onChange: PatchEvent => void } @@ -44,7 +45,7 @@ export default class StringSelect extends React.Component { } render() { - const {value, type, level, ...rest} = this.props + const {value, readOnly, type, level, ...rest} = this.props const items = toSelectItems(type.options.list || []) @@ -68,6 +69,7 @@ export default class StringSelect extends React.Component { value={currentItem} direction={type.options.direction || 'vertical'} ref={this.setInput} + readOnly={readOnly} /> :