UNPKG

@sanity/form-builder

Version:
164 lines (163 loc) • 10.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ArrayItem = void 0; var _changeIndicators = require("@sanity/base/change-indicators"); var _types = require("@sanity/types"); var _react = _interopRequireWildcard(require("react")); var _paths = require("@sanity/util/paths"); var _ui = require("@sanity/ui"); var _internal = require("@sanity/base/_internal"); var _empty = require("../../../../utils/empty"); var _focusUtils = require("../../../../utils/focusUtils"); var _useScrollIntoViewOnFocusWithin = require("../../../../hooks/useScrollIntoViewOnFocusWithin"); var _EditPortal = require("../../../../EditPortal"); var _useDidUpdate = require("../../../../hooks/useDidUpdate"); var _helpers = require("./helpers"); var _ItemForm = require("./ItemForm"); var _RowItem = require("./RowItem"); var _CellItem = require("./CellItem"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /* eslint-disable import/no-unresolved,no-nested-ternary */ var ArrayItem = /*#__PURE__*/(0, _react.memo)(function ArrayItem(props) { var _useConditionalReadOn, _type$options, _type$options4; var value = props.value, markers = props.markers, type = props.type, index = props.index, itemKey = props.itemKey, readOnly = props.readOnly, presence = props.presence, focusPath = props.focusPath, onFocus = props.onFocus, onChange = props.onChange, onRemove = props.onRemove, onInsert = props.onInsert, onBlur = props.onBlur, filterField = props.filterField, compareValue = props.compareValue, ReferenceItemComponent = props.ReferenceItemComponent; var innerElementRef = (0, _react.useRef)(null); var conditionalReadOnly = (_useConditionalReadOn = (0, _internal.useConditionalReadOnly)()) !== null && _useConditionalReadOn !== void 0 ? _useConditionalReadOn : readOnly; var hasFocusWithin = (0, _focusUtils.hasFocusWithinPath)(props.focusPath, props.value); (0, _useScrollIntoViewOnFocusWithin.useScrollIntoViewOnFocusWithin)(innerElementRef, hasFocusWithin); (0, _useDidUpdate.useDidUpdate)((0, _focusUtils.hasFocusAtPath)(props.focusPath, props.value), (hadFocus, hasFocus) => { if (!hadFocus && hasFocus && innerElementRef.current) { // Note: if editing an inline item, focus is handled by the item input itself and no ref is being set innerElementRef.current.focus(); } }); var itemPath = (0, _react.useMemo)(() => (0, _paths.pathFor)([itemKey ? { _key: itemKey } : index]), [index, itemKey]); var emitFocus = (0, _react.useCallback)(path => { if (itemKey) { onFocus([{ _key: itemKey }, ...path]); } }, [onFocus, itemKey]); var handleItemElementFocus = (0, _react.useCallback)(event => { if (event.target === event.currentTarget) { emitFocus([]); } }, [emitFocus]); var handleEditOpen = (0, _react.useCallback)(() => emitFocus([_paths.FOCUS_TERMINATOR]), [emitFocus]); var handleEditClose = (0, _react.useCallback)(() => { if ((0, _helpers.isEmpty)(value)) { onRemove(value); } else { emitFocus([]); } }, [value, onRemove, emitFocus]); var handleChange = (0, _react.useCallback)((event, valueOverride) => onChange(event, typeof valueOverride === 'undefined' ? value : valueOverride), [onChange, value]); var handleRemove = (0, _react.useCallback)(() => onRemove(value), [onRemove, value]); var handleKeyPress = (0, _react.useCallback)(event => { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); handleEditOpen(); } }, [handleEditOpen]); var options = type.options || {}; var isSortable = !conditionalReadOnly && options.sortable !== false; var isEditing = (0, _focusUtils.hasFocusWithinPath)(focusPath, value); var itemType = (0, _helpers.getItemType)(type, value); var isGrid = ((_type$options = type.options) === null || _type$options === void 0 ? void 0 : _type$options.layout) === 'grid'; var ItemComponent = isGrid ? _CellItem.CellItem : _RowItem.RowItem; var itemMarkers = _react.default.useMemo(() => markers.filter(marker => (0, _paths.startsWith)(itemPath, marker.path)), [itemPath, markers]); var scopedValidation = (0, _react.useMemo)(() => itemMarkers.length === 0 ? _empty.EMPTY_ARRAY : itemMarkers.filter(_types.isValidationMarker).map(marker => { if (marker.path.length <= 1) { return marker; } var level = marker.level === 'error' ? 'errors' : 'warnings'; return _objectSpread(_objectSpread({}, marker), {}, { item: marker.item.cloneWithMessage("Contains ".concat(level)) }); }), [itemMarkers]); var itemPresence = (0, _react.useMemo)(() => presence.filter(presenceItem => (0, _paths.startsWith)(itemPath, presenceItem.path)), [itemPath, presence]); var isReference = itemType && (0, _types.isReferenceSchemaType)(itemType); var editForm = (0, _react.useMemo)(() => { var _type$options2, _type$options3; if (!isEditing && !isReference) { return null; } var form = /*#__PURE__*/_react.default.createElement(_ItemForm.ItemForm, { onChange: handleChange, markers: itemMarkers, filterField: filterField, focusPath: focusPath, onFocus: onFocus, onBlur: onBlur, onInsert: onInsert, insertableTypes: type.of, type: itemType, value: value, isSortable: isSortable, ReferenceItemComponent: ReferenceItemComponent, readOnly: conditionalReadOnly, presence: itemPresence, compareValue: compareValue }); return isReference && !isGrid ? form : /*#__PURE__*/_react.default.createElement(_EditPortal.EditPortal, { header: conditionalReadOnly ? "View ".concat((itemType === null || itemType === void 0 ? void 0 : itemType.title) || '') : "Edit ".concat((itemType === null || itemType === void 0 ? void 0 : itemType.title) || ''), type: (type === null || type === void 0 || (_type$options2 = type.options) === null || _type$options2 === void 0 ? void 0 : _type$options2.editModal) === 'fold' ? 'dialog' : (type === null || type === void 0 || (_type$options3 = type.options) === null || _type$options3 === void 0 ? void 0 : _type$options3.editModal) || 'dialog', id: value._key, onClose: handleEditClose, legacy_referenceElement: innerElementRef.current }, form); }, [ReferenceItemComponent, compareValue, filterField, focusPath, handleChange, handleEditClose, isEditing, isGrid, isReference, isSortable, itemMarkers, itemPresence, itemType, onBlur, onFocus, onInsert, conditionalReadOnly, type === null || type === void 0 || (_type$options4 = type.options) === null || _type$options4 === void 0 ? void 0 : _type$options4.editModal, value]); var item = /*#__PURE__*/_react.default.createElement(ItemComponent, { "aria-selected": isEditing, index: index, value: value, readOnly: readOnly, type: itemType, insertableTypes: type.of, presence: isEditing ? _empty.EMPTY_ARRAY : itemPresence, validation: scopedValidation, isSortable: isSortable, onInsert: onInsert, onFocus: handleItemElementFocus, onClick: itemType ? handleEditOpen : undefined, onRemove: handleRemove, onKeyPress: handleKeyPress, ref: innerElementRef }); return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_changeIndicators.ChangeIndicatorScope, { path: itemPath }, /*#__PURE__*/_react.default.createElement(_changeIndicators.ContextProvidedChangeIndicator, { compareDeep: true, disabled: isEditing && !isReference }, isGrid ? // grid should be rendered without a margin item : /*#__PURE__*/_react.default.createElement(_ui.Box, { marginX: 1 }, isReference ? editForm : item))), isEditing && (!isReference || isGrid) ? editForm : null); }); exports.ArrayItem = ArrayItem;