UNPKG

sanity-plugin-grid

Version:

A custom input component for displaying an array of grid objects.

341 lines (277 loc) 12.6 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.basic = void 0; var _react = _interopRequireWildcard(require("react")); var _defaultStyle = _interopRequireDefault(require("part:@sanity/components/fieldsets/default-style")); var _component = _interopRequireDefault(require("./component.css")); var _propTypes = _interopRequireDefault(require("prop-types")); var _functions = _interopRequireDefault(require("part:@sanity/form-builder/input/array/functions")); var _formBuilder = require("part:@sanity/form-builder"); var _itemValue = _interopRequireDefault(require("./components/itemValue")); var _paths = require("@sanity/util/paths"); var _patchEvent = _interopRequireWildcard(require("part:@sanity/form-builder/patch-event")); var _utils = require("./utils"); var _gsap = _interopRequireDefault(require("gsap")); var _Draggable = _interopRequireDefault(require("gsap/Draggable")); var _useEventListener = _interopRequireDefault(require("./utils/hooks/useEventListener")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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); if (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 = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } _gsap["default"].registerPlugin(_Draggable["default"]); var SanityGrid = (0, _react.forwardRef)(function (props, ref) { var level = props.level, value = props.value, type = props.type, document = props.document; var NO_MARKERS = []; var gridRef = (0, _react.useRef)(null); var draggableRef = (0, _react.useRef)(null); var colFallback = 6, rowFallback = 4; var _ref = document.sanitygrid || {}, _ref$rows = _ref.rows, rows = _ref$rows === void 0 ? rowFallback : _ref$rows, _ref$columns = _ref.columns, columns = _ref$columns === void 0 ? colFallback : _ref$columns; console.debug("[ Grid ] - props: ", props); var gridDetails = { rowHeight: 0, columnWidth: 0, gap: 5 }; var handleDragEnd = function handleDragEnd(e) { var _e$target; var closestElement = (_e$target = e.target) === null || _e$target === void 0 ? void 0 : _e$target.closest(".".concat(_component["default"].grid_item)); if (!closestElement) { console.error("Sanity Grid Input could not find the dragged element."); console.debug("[Sanity Grid] Handle Drag End - e.target: ".concat(e.target), e.target); return; } var rowHeight = gridDetails.rowHeight, columnWidth = gridDetails.columnWidth; var itemKey = closestElement.dataset.key; var item = value.find(function (element) { return element._key === itemKey; }); var gridBounding = gridRef.current.getBoundingClientRect(); var elementBounding = closestElement.getBoundingClientRect(); var diffs = { x: Math.round(elementBounding.left - gridBounding.left), y: Math.round(elementBounding.top - gridBounding.top) }; var pos = { col: Math.round(diffs.x / columnWidth) + 1, row: Math.round(diffs.y / rowHeight) + 1 }; var newItem = _objectSpread({}, item) || {}; !newItem.settings ? newItem.settings = {} : null; newItem.settings.posX = pos.col; newItem.settings.posY = pos.row; var patch = _patchEvent["default"].from((0, _patchEvent.set)(newItem)); closestElement.style.transform = null; item && item && handleItemChange(patch, item); _gsap["default"].set(closestElement, { transform: null, gridColumnStart: pos.col, gridRowStart: pos.row }); }; var createDraggable = function createDraggable() { var snap = function snap(value, snapTo) { return Math.round(value / snapTo) * snapTo; }; draggableRef.current = _Draggable["default"].create(".".concat(_component["default"].grid_item), { bounds: gridRef.current, throwProps: true, type: "x,y", liveSnap: { x: function x(value) { return snap(value, gridDetails.columnWidth); }, y: function y(value) { return snap(value, gridDetails.rowHeight); } }, onDragEnd: handleDragEnd }); }; var updateGridDetails = function updateGridDetails() { var grid = gridRef.current; if (!grid) { return; } // dimensions with the grid gap included gridDetails.rowHeight = grid.offsetHeight / rows; gridDetails.columnWidth = grid.offsetWidth / columns; }; var handleResize = function handleResize() { updateGridDetails(); }; (0, _useEventListener["default"])("resize", handleResize); (0, _react.useEffect)(function () { updateGridDetails(); createDraggable(); }); var handleItemChange = function handleItemChange(event, item) { var onChange = props.onChange, value = props.value, type = props.type; var memberType = (0, _utils.getMemberType)(item, type); if (!memberType) { return; } if (memberType.readOnly) { return; } var key = item._key || (0, _utils.randomKey)(12); onChange(event.prefixAll({ _key: key }).prepend(item._key ? [] : (0, _patchEvent.set)(key, [value.indexOf(item), "_key"]))); }; var append = function append(itemValue, position, atIndex) { var onChange = props.onChange; var e = _patchEvent["default"].from((0, _patchEvent.setIfMissing)([]), (0, _patchEvent.insert)([itemValue], position, [atIndex])); onChange(e); }; var handleAppend = function handleAppend(value) { append(value, "after", -1); }; var renderGrid = function renderGrid() { var type = props.type, markers = props.markers, value = props.value, _props$focusPath = props.focusPath, focusPath = _props$focusPath === void 0 ? [] : _props$focusPath, onBlur = props.onBlur, onFocus = props.onFocus, level = props.level, filterField = props.filterField; if (value === "undefined") return _react["default"].createElement("p", null, "No grid items created yet"); var removeItem = function removeItem(item) { var onChange = props.onChange, value = props.value; onChange(_patchEvent["default"].from((0, _patchEvent.unset)(item._key ? [{ _key: item._key }] : [value.indexOf(item)]))); }; var handleRemoveItem = function handleRemoveItem(item) { removeItem(item); }; var gridStyles = {}; gridStyles.gridTemplateColumns = "repeat(".concat(columns, ", 1fr)"); gridStyles.gridTemplateRows = "repeat(".concat(rows, ", 1fr)"); var renderShadowGrid = function renderShadowGrid(columns, rows) { var items = []; for (var i = 0; i < columns * (rows || 1); i++) { items.push(_react["default"].createElement("span", { key: i })); } return items; }; return _react["default"].createElement(_react["default"].Fragment, null, _react["default"].createElement("ul", { ref: gridRef, className: _component["default"].grid_field, style: gridStyles }, value ? value.map(function (item, i) { var isChildMarker = function isChildMarker(marker) { return (0, _paths.startsWith)([index], marker.path) || (0, _paths.startsWith)([{ _key: item && item._key }], marker.path); }; var childMarkers = markers === null || markers === void 0 ? void 0 : markers.filter(isChildMarker); var _ref2 = item.settings || {}, width = _ref2.width, height = _ref2.height, posX = _ref2.posX, posY = _ref2.posY; return _react["default"].createElement("li", { className: _component["default"].grid_item, key: item._key || i, style: { gridColumnStart: posX || "auto", gridColumnEnd: width ? "span ".concat(width) : "auto", gridRowStart: posY || "auto", gridRowEnd: height ? "span ".concat(height) : "auto" } }, _react["default"].createElement(_itemValue["default"], { type: type, value: item, level: level, markers: (childMarkers === null || childMarkers === void 0 ? void 0 : childMarkers.length) === 0 ? NO_MARKERS : childMarkers, onRemove: handleRemoveItem, onChange: handleItemChange, focusPath: focusPath, filterField: filterField, onFocus: onFocus, onBlur: onBlur, readOnly: props.readOnly })); }) : null, _react["default"].createElement("div", { className: "".concat(_component["default"].grid_field_shadow), style: gridStyles }, renderShadowGrid(columns || 6, rows || 1)))); }; return _react["default"].createElement("div", { ref: ref, key: "SANITY_GRID_INPUT" }, value && _react["default"].createElement("div", { className: "".concat(_component["default"].grid_field, " ").concat(_defaultStyle["default"].content) }, renderGrid()), _react["default"].createElement(_functions["default"], { type: type, value: value, readOnly: props.readOnly, onAppendItem: handleAppend, onCreateValue: _utils.createProtoValue // onChange={onChange} })); }); // SanityGrid.PropTypes = { // type: PropTypes.shape({ // fields: PropTypes.array.isRequired // }).isRequired, // value: PropTypes.object, // onFocus: PropTypes.func, // onBlur: PropTypes.func, // onChange: PropTypes.func.isRequired // }; var basic = { settings: [{ title: "Columns", name: "columns", fieldset: "settings", type: "number" }, { title: "Rows", name: "rows", fieldset: "settings", type: "number" }], item: [{ title: "Width", description: "Width in number of columns.", name: "width", type: "number" }, { title: "Height", description: "Height in number of rows.", name: "height", type: "number" }, { title: "Column", description: "What column to position the item at.", name: "posX", type: "number" }, { title: "Row", description: "What row to position the item at.", name: "posY", type: "number" }] }; exports.basic = basic; var _default = (0, _formBuilder.withDocument)(SanityGrid); exports["default"] = _default;