sanity-plugin-hotspot-array 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +16 -4
- package/lib/Feedback.js +0 -4
- package/lib/Feedback.js.map +1 -1
- package/lib/HotspotArray.js +21 -60
- package/lib/HotspotArray.js.map +1 -1
- package/lib/NestedFormBuilder.js +53 -0
- package/lib/NestedFormBuilder.js.map +1 -0
- package/lib/Spot.js +19 -43
- package/lib/Spot.js.map +1 -1
- package/lib/useUnsetInputComponent.js +0 -8
- package/lib/useUnsetInputComponent.js.map +1 -1
- package/package.json +13 -12
- package/src/HotspotArray.tsx +5 -4
- package/src/NestedFormBuilder.tsx +44 -0
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -30,7 +30,8 @@ export default {
|
|
|
30
30
|
// see `Spot object` setup below
|
|
31
31
|
],
|
|
32
32
|
options: {
|
|
33
|
-
// see `Image and description
|
|
33
|
+
// see `Image and description paths` setup below
|
|
34
|
+
imageHotspotPathRoot: `document`,
|
|
34
35
|
hotspotImagePath: `featureImage`,
|
|
35
36
|
hotspotDescriptionPath: `details`,
|
|
36
37
|
// see `Custom tooltip` setup below
|
|
@@ -51,9 +52,9 @@ The plugin makes a number of assumptions to add and update data in the array. In
|
|
|
51
52
|
|
|
52
53
|
### Image and description paths
|
|
53
54
|
|
|
54
|
-
The custom input has the current values of all fields in the document, and so can "pick" the image out of the document by its path.
|
|
55
|
+
The custom input has the current values of all fields in the document by default, and so can "pick" the image out of the document by its path.
|
|
55
56
|
|
|
56
|
-
For example, if you want to add hotspots to an image, and that image is uploaded to the field `featuredImage`, your fields `options` would look like:
|
|
57
|
+
For example, if you want to add hotspots to an image, and that image is uploaded to the document field of `featuredImage`, your fields `options` would look like:
|
|
57
58
|
|
|
58
59
|
```js
|
|
59
60
|
options: {
|
|
@@ -61,6 +62,17 @@ options: {
|
|
|
61
62
|
}
|
|
62
63
|
```
|
|
63
64
|
|
|
65
|
+
Alternatively, you may supply 'parent' to the `imageHotspotPathRoot` option to pick from the parent object instead. Using 'parent' as `imageHotspotPathRoot` in favor of the default 'document' may be required, e.g. if your schema of hotspots array is defined as a child of another array, and therefore you can not reference dynamically the correct field in a 'document' specified by `hotspotImagePath`.
|
|
66
|
+
|
|
67
|
+
In this case, if the image is uploaded to the parent object field of `featuredImage`, your fields `options` would look like:
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
options: {
|
|
71
|
+
imageHotspotPathRoot: `parent`,
|
|
72
|
+
hotspotImagePath: `featureImage`
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
64
76
|
The custom input can also pre-fill a string or text field with a description of the position of the spot to make them easier to identify. Add a path **relative to the spot object** for this field.
|
|
65
77
|
|
|
66
78
|
```js
|
|
@@ -152,5 +164,5 @@ options: {
|
|
|
152
164
|
|
|
153
165
|
## License
|
|
154
166
|
|
|
155
|
-
MIT ©
|
|
167
|
+
MIT ©
|
|
156
168
|
See LICENSE
|
package/lib/Feedback.js
CHANGED
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = Feedback;
|
|
7
|
-
|
|
8
7
|
var _react = _interopRequireDefault(require("react"));
|
|
9
|
-
|
|
10
8
|
var _ui = require("@sanity/ui");
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
function Feedback(_ref) {
|
|
15
11
|
var children = _ref.children;
|
|
16
12
|
return /*#__PURE__*/_react.default.createElement(_ui.Card, {
|
package/lib/Feedback.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Feedback.js","names":["Feedback","children"],"sources":["../src/Feedback.tsx"],"sourcesContent":["import React from 'react'\nimport {Card, Text} from '@sanity/ui'\n\nexport default function Feedback({children}) {\n return (\n <Card padding={4} radius={2} shadow={1} tone=\"caution\">\n <Text>{children}</Text>\n </Card>\n )\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Feedback.js","names":["Feedback","children"],"sources":["../src/Feedback.tsx"],"sourcesContent":["import React from 'react'\nimport {Card, Text} from '@sanity/ui'\n\nexport default function Feedback({children}) {\n return (\n <Card padding={4} radius={2} shadow={1} tone=\"caution\">\n <Text>{children}</Text>\n </Card>\n )\n}\n"],"mappings":";;;;;;AAAA;AACA;AAAqC;AAEtB,SAASA,QAAQ,OAAa;EAAA,IAAXC,QAAQ,QAARA,QAAQ;EACxC,oBACE,6BAAC,QAAI;IAAC,OAAO,EAAE,CAAE;IAAC,MAAM,EAAE,CAAE;IAAC,MAAM,EAAE,CAAE;IAAC,IAAI,EAAC;EAAS,gBACpD,6BAAC,QAAI,QAAEA,QAAQ,CAAQ,CAClB;AAEX"}
|
package/lib/HotspotArray.js
CHANGED
|
@@ -4,76 +4,50 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _client = _interopRequireDefault(require("part:@sanity/base/client"));
|
|
9
|
-
|
|
10
8
|
var _formBuilder = require("part:@sanity/form-builder");
|
|
11
|
-
|
|
12
9
|
var _assetUtils = require("@sanity/asset-utils");
|
|
13
|
-
|
|
14
|
-
var _FormBuilderInput = require("@sanity/form-builder/lib/FormBuilderInput");
|
|
15
|
-
|
|
16
10
|
var _PatchEvent = require("@sanity/form-builder/PatchEvent");
|
|
17
|
-
|
|
18
11
|
var _imageUrl = _interopRequireDefault(require("@sanity/image-url"));
|
|
19
|
-
|
|
20
12
|
var _ui = require("@sanity/ui");
|
|
21
|
-
|
|
22
13
|
var _content = require("@sanity/util/content");
|
|
23
|
-
|
|
24
14
|
var _get = _interopRequireDefault(require("lodash/get"));
|
|
25
|
-
|
|
26
15
|
var _react = _interopRequireWildcard(require("react"));
|
|
27
|
-
|
|
28
16
|
var _web = require("@react-hookz/web");
|
|
29
|
-
|
|
30
17
|
var _Feedback = _interopRequireDefault(require("./Feedback"));
|
|
31
|
-
|
|
32
18
|
var _Spot = _interopRequireDefault(require("./Spot"));
|
|
33
|
-
|
|
34
19
|
var _useUnsetInputComponent = require("./useUnsetInputComponent");
|
|
35
|
-
|
|
20
|
+
var _NestedFormBuilder = require("./NestedFormBuilder");
|
|
36
21
|
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); }
|
|
37
|
-
|
|
38
22
|
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; }
|
|
39
|
-
|
|
40
23
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
41
|
-
|
|
42
24
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
43
|
-
|
|
44
25
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
45
|
-
|
|
46
26
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
47
|
-
|
|
48
27
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
49
|
-
|
|
50
28
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
51
|
-
|
|
52
29
|
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
53
|
-
|
|
54
30
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
55
|
-
|
|
56
31
|
var imageStyle = {
|
|
57
32
|
width: "100%",
|
|
58
33
|
height: "auto"
|
|
59
34
|
};
|
|
60
35
|
var VALID_ROOT_PATHS = ['document', 'parent'];
|
|
61
|
-
|
|
62
36
|
var HotspotArray = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
63
37
|
var _type$options, _type$options2, _type$options3;
|
|
64
|
-
|
|
38
|
+
console.log(props);
|
|
65
39
|
var type = props.type,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
40
|
+
value = props.value,
|
|
41
|
+
onChange = props.onChange,
|
|
42
|
+
document = props.document;
|
|
70
43
|
var _ref = type !== null && type !== void 0 ? type : {},
|
|
71
|
-
|
|
72
|
-
// Re-renders can still occur if this Component is used again in a nested field
|
|
73
|
-
|
|
44
|
+
options = _ref.options;
|
|
74
45
|
|
|
46
|
+
// Attempt prevention of infinite loop in <FormBuilderInput />
|
|
47
|
+
// Re-renders can still occur if this Component is used again in a nested field
|
|
75
48
|
var typeWithoutInputComponent = (0, _useUnsetInputComponent.useUnsetInputComponent)(type, type === null || type === void 0 ? void 0 : type.inputComponent);
|
|
76
49
|
var imageHotspotPathRoot = VALID_ROOT_PATHS.includes(options === null || options === void 0 ? void 0 : options.imageHotspotPathRoot) ? props[options.imageHotspotPathRoot] : document;
|
|
50
|
+
|
|
77
51
|
/**
|
|
78
52
|
* Finding the image from the imageHotspotPathRoot (defaults to document),
|
|
79
53
|
* using the path from the hotspot's `options` field
|
|
@@ -81,22 +55,16 @@ var HotspotArray = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
|
81
55
|
* when changes in imageHotspotPathRoot (e.g. document) occur,
|
|
82
56
|
* check if there are any changes to the hotspotImage and update the reference
|
|
83
57
|
*/
|
|
84
|
-
|
|
85
58
|
var hotspotImage = _react.default.useMemo(() => {
|
|
86
59
|
return (0, _get.default)(imageHotspotPathRoot, options === null || options === void 0 ? void 0 : options.hotspotImagePath);
|
|
87
60
|
}, [imageHotspotPathRoot]);
|
|
88
|
-
|
|
89
61
|
var displayImage = _react.default.useMemo(() => {
|
|
90
62
|
var _hotspotImage$asset;
|
|
91
|
-
|
|
92
63
|
var builder = (0, _imageUrl.default)(_client.default).dataset(_client.default.config().dataset);
|
|
93
|
-
|
|
94
64
|
var urlFor = source => builder.image(source);
|
|
95
|
-
|
|
96
65
|
if (hotspotImage !== null && hotspotImage !== void 0 && (_hotspotImage$asset = hotspotImage.asset) !== null && _hotspotImage$asset !== void 0 && _hotspotImage$asset._ref) {
|
|
97
66
|
var _getImageDimensions = (0, _assetUtils.getImageDimensions)(hotspotImage.asset._ref),
|
|
98
|
-
|
|
99
|
-
|
|
67
|
+
aspectRatio = _getImageDimensions.aspectRatio;
|
|
100
68
|
var width = 1200;
|
|
101
69
|
var height = Math.round(width / aspectRatio);
|
|
102
70
|
var url = urlFor(hotspotImage).width(width).url();
|
|
@@ -106,13 +74,12 @@ var HotspotArray = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
|
106
74
|
url
|
|
107
75
|
};
|
|
108
76
|
}
|
|
109
|
-
|
|
110
77
|
return null;
|
|
111
78
|
}, [hotspotImage]);
|
|
112
|
-
|
|
113
79
|
var handleHotspotImageClick = _react.default.useCallback(event => {
|
|
114
|
-
var nativeEvent = event.nativeEvent;
|
|
80
|
+
var nativeEvent = event.nativeEvent;
|
|
115
81
|
|
|
82
|
+
// Calculate the x/y percentage of the click position
|
|
116
83
|
var x = Number((nativeEvent.offsetX * 100 / nativeEvent.srcElement.width).toFixed(2));
|
|
117
84
|
var y = Number((nativeEvent.offsetY * 100 / nativeEvent.srcElement.height).toFixed(2));
|
|
118
85
|
var description = "New Hotspot at ".concat(x, "% x ").concat(y, "%");
|
|
@@ -122,31 +89,27 @@ var HotspotArray = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
|
122
89
|
x,
|
|
123
90
|
y
|
|
124
91
|
};
|
|
125
|
-
|
|
126
92
|
if (options !== null && options !== void 0 && options.hotspotDescriptionPath) {
|
|
127
93
|
newRow[options.hotspotDescriptionPath] = description;
|
|
128
94
|
}
|
|
129
|
-
|
|
130
95
|
onChange(_PatchEvent.PatchEvent.from((0, _PatchEvent.setIfMissing)([]), (0, _PatchEvent.insert)([newRow], 'after', [-1])));
|
|
131
96
|
}, []);
|
|
132
|
-
|
|
133
97
|
var handleHotspotMove = _react.default.useCallback((key, x, y) => {
|
|
134
|
-
onChange(_PatchEvent.PatchEvent.from(
|
|
98
|
+
onChange(_PatchEvent.PatchEvent.from(
|
|
99
|
+
// Set the `x` value of this array key item
|
|
135
100
|
(0, _PatchEvent.set)(x, [{
|
|
136
101
|
_key: key
|
|
137
|
-
}, 'x']),
|
|
102
|
+
}, 'x']),
|
|
103
|
+
// Set the `y` value of this array key item
|
|
138
104
|
(0, _PatchEvent.set)(y, [{
|
|
139
105
|
_key: key
|
|
140
106
|
}, 'y'])));
|
|
141
107
|
}, [value]);
|
|
142
|
-
|
|
143
108
|
var hotspotImageRef = _react.default.useRef(null);
|
|
144
|
-
|
|
145
109
|
var _useState = (0, _react.useState)(),
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
110
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
111
|
+
imageRect = _useState2[0],
|
|
112
|
+
setImageRect = _useState2[1];
|
|
150
113
|
var updateImageRectCallback = (0, _web.useDebouncedCallback)(e => setImageRect(e.contentRect), [setImageRect], 200);
|
|
151
114
|
(0, _web.useResizeObserver)(hotspotImageRef, updateImageRectCallback);
|
|
152
115
|
return /*#__PURE__*/_react.default.createElement(_ui.Stack, {
|
|
@@ -177,13 +140,11 @@ var HotspotArray = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
|
177
140
|
alt: "",
|
|
178
141
|
style: imageStyle,
|
|
179
142
|
onClick: handleHotspotImageClick
|
|
180
|
-
})))) : /*#__PURE__*/_react.default.createElement(_Feedback.default, null, type !== null && type !== void 0 && (_type$options = type.options) !== null && _type$options !== void 0 && _type$options.hotspotImagePath ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "No Hotspot image found at path ", /*#__PURE__*/_react.default.createElement("code", null, type === null || type === void 0 ? void 0 : (_type$options2 = type.options) === null || _type$options2 === void 0 ? void 0 : _type$options2.hotspotImagePath)) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "Define a path in this field using to the image field in this document at", ' ', /*#__PURE__*/_react.default.createElement("code", null, "options.hotspotImagePath"))), (type === null || type === void 0 ? void 0 : (_type$options3 = type.options) === null || _type$options3 === void 0 ? void 0 : _type$options3.imageHotspotPathRoot) && !VALID_ROOT_PATHS.includes(type.options.imageHotspotPathRoot) && /*#__PURE__*/_react.default.createElement(_Feedback.default, null, "The supplied imageHotspotPathRoot \"", type.options.imageHotspotPathRoot, "\" is not valid, falling back to \"document\". Available values are \"", VALID_ROOT_PATHS.join(', '), "\"."), /*#__PURE__*/_react.default.createElement(
|
|
143
|
+
})))) : /*#__PURE__*/_react.default.createElement(_Feedback.default, null, type !== null && type !== void 0 && (_type$options = type.options) !== null && _type$options !== void 0 && _type$options.hotspotImagePath ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "No Hotspot image found at path ", /*#__PURE__*/_react.default.createElement("code", null, type === null || type === void 0 ? void 0 : (_type$options2 = type.options) === null || _type$options2 === void 0 ? void 0 : _type$options2.hotspotImagePath)) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "Define a path in this field using to the image field in this document at", ' ', /*#__PURE__*/_react.default.createElement("code", null, "options.hotspotImagePath"))), (type === null || type === void 0 ? void 0 : (_type$options3 = type.options) === null || _type$options3 === void 0 ? void 0 : _type$options3.imageHotspotPathRoot) && !VALID_ROOT_PATHS.includes(type.options.imageHotspotPathRoot) && /*#__PURE__*/_react.default.createElement(_Feedback.default, null, "The supplied imageHotspotPathRoot \"", type.options.imageHotspotPathRoot, "\" is not valid, falling back to \"document\". Available values are \"", VALID_ROOT_PATHS.join(', '), "\"."), /*#__PURE__*/_react.default.createElement(_NestedFormBuilder.NestedFormBuilder, _extends({}, props, {
|
|
181
144
|
type: typeWithoutInputComponent,
|
|
182
145
|
ref: ref
|
|
183
146
|
})));
|
|
184
147
|
});
|
|
185
|
-
|
|
186
|
-
var _default = (0, _formBuilder.withDocument)(HotspotArray);
|
|
187
|
-
|
|
148
|
+
var _default = (0, _formBuilder.withParent)((0, _formBuilder.withDocument)(HotspotArray));
|
|
188
149
|
exports.default = _default;
|
|
189
150
|
//# sourceMappingURL=HotspotArray.js.map
|
package/lib/HotspotArray.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HotspotArray.js","names":["imageStyle","width","height","VALID_ROOT_PATHS","HotspotArray","React","forwardRef","props","ref","type","value","onChange","document","options","typeWithoutInputComponent","useUnsetInputComponent","inputComponent","imageHotspotPathRoot","includes","hotspotImage","useMemo","get","hotspotImagePath","displayImage","builder","imageUrlBuilder","sanityClient","dataset","config","urlFor","source","image","asset","_ref","getImageDimensions","aspectRatio","Math","round","url","handleHotspotImageClick","useCallback","event","nativeEvent","x","Number","offsetX","srcElement","toFixed","y","offsetY","description","newRow","_key","randomKey","_type","hotspotDescriptionPath","PatchEvent","from","setIfMissing","insert","handleHotspotMove","key","set","hotspotImageRef","useRef","useState","imageRect","setImageRect","updateImageRectCallback","useDebouncedCallback","e","contentRect","useResizeObserver","position","length","map","spot","index","hotspotTooltip","join","withDocument"],"sources":["../src/HotspotArray.tsx"],"sourcesContent":["/* eslint-disable react/display-name */\n\n// @ts-ignore\nimport sanityClient from 'part:@sanity/base/client'\n// @ts-ignore\nimport {withDocument} from 'part:@sanity/form-builder'\n\nimport {getImageDimensions} from '@sanity/asset-utils'\nimport {FormBuilderInput} from '@sanity/form-builder/lib/FormBuilderInput'\nimport {insert, PatchEvent, set, setIfMissing} from '@sanity/form-builder/PatchEvent'\nimport imageUrlBuilder from '@sanity/image-url'\nimport {Card, Flex, Stack} from '@sanity/ui'\nimport {randomKey} from '@sanity/util/content'\nimport get from 'lodash/get'\nimport React, {useState} from 'react'\n\nimport {IUseResizeObserverCallback, useDebouncedCallback, useResizeObserver} from '@react-hookz/web'\nimport Feedback from './Feedback'\nimport Spot from './Spot'\nimport {useUnsetInputComponent} from './useUnsetInputComponent'\n\nconst imageStyle = {width: `100%`, height: `auto`}\n\nconst VALID_ROOT_PATHS = ['document', 'parent']\n\nexport type FnHotspotMove = (key: string, x: number, y: number) => void\n\nexport type TSpot = {\n _key: string\n _type: `spot`\n x: number\n y: number\n} & {[key: string]: unknown}\n\nconst HotspotArray = React.forwardRef((props: any, ref) => {\n const {type, value, onChange, document} = props\n const {options} = type ?? {}\n\n // Attempt prevention of infinite loop in <FormBuilderInput />\n // Re-renders can still occur if this Component is used again in a nested field\n const typeWithoutInputComponent = useUnsetInputComponent(type, type?.inputComponent)\n const imageHotspotPathRoot = VALID_ROOT_PATHS.includes(options?.imageHotspotPathRoot)\n ? props[options.imageHotspotPathRoot]\n : document\n\n /**\n * Finding the image from the imageHotspotPathRoot (defaults to document),\n * using the path from the hotspot's `options` field\n *\n * when changes in imageHotspotPathRoot (e.g. document) occur,\n * check if there are any changes to the hotspotImage and update the reference\n */\n const hotspotImage = React.useMemo(() => {\n return get(imageHotspotPathRoot, options?.hotspotImagePath)\n }, [imageHotspotPathRoot])\n\n const displayImage = React.useMemo(() => {\n const builder = imageUrlBuilder(sanityClient).dataset(sanityClient.config().dataset)\n const urlFor = (source) => builder.image(source)\n\n if (hotspotImage?.asset?._ref) {\n const {aspectRatio} = getImageDimensions(hotspotImage.asset._ref)\n const width = 1200\n const height = Math.round(width / aspectRatio)\n const url = urlFor(hotspotImage).width(width).url()\n\n return {width, height, url}\n }\n\n return null\n }, [hotspotImage])\n\n const handleHotspotImageClick = React.useCallback((event) => {\n const {nativeEvent} = event\n\n // Calculate the x/y percentage of the click position\n const x = Number(((nativeEvent.offsetX * 100) / nativeEvent.srcElement.width).toFixed(2))\n const y = Number(((nativeEvent.offsetY * 100) / nativeEvent.srcElement.height).toFixed(2))\n const description = `New Hotspot at ${x}% x ${y}%`\n\n const newRow: TSpot = {\n _key: randomKey(12),\n _type: `spot`,\n x,\n y,\n }\n\n if (options?.hotspotDescriptionPath) {\n newRow[options.hotspotDescriptionPath] = description\n }\n\n onChange(PatchEvent.from(setIfMissing([]), insert([newRow], 'after', [-1])))\n }, [])\n\n const handleHotspotMove: FnHotspotMove = React.useCallback(\n (key, x, y) => {\n onChange(\n PatchEvent.from(\n // Set the `x` value of this array key item\n set(x, [{_key: key}, 'x']),\n // Set the `y` value of this array key item\n set(y, [{_key: key}, 'y'])\n )\n )\n },\n [value]\n )\n\n const hotspotImageRef = React.useRef<HTMLImageElement | null>(null)\n\n const [imageRect, setImageRect] = useState<DOMRectReadOnly>()\n const updateImageRectCallback = useDebouncedCallback(\n ((e) => setImageRect(e.contentRect)) as IUseResizeObserverCallback,\n [setImageRect],\n 200\n )\n useResizeObserver(hotspotImageRef, updateImageRectCallback)\n\n return (\n <Stack space={[2, 2, 3]}>\n {displayImage?.url ? (\n <div style={{position: `relative`}}>\n {imageRect &&\n value?.length > 0 &&\n value.map((spot, index) => (\n <Spot\n index={index}\n key={spot._key}\n spot={spot}\n bounds={imageRect}\n update={handleHotspotMove}\n hotspotDescriptionPath={options?.hotspotDescriptionPath}\n tooltip={options?.hotspotTooltip}\n />\n ))}\n\n <Card __unstable_checkered shadow={1}>\n <Flex align=\"center\" justify=\"center\">\n <img\n ref={hotspotImageRef}\n src={displayImage.url}\n width={displayImage.width}\n height={displayImage.height}\n alt=\"\"\n style={imageStyle}\n onClick={handleHotspotImageClick}\n />\n </Flex>\n </Card>\n </div>\n ) : (\n <Feedback>\n {type?.options?.hotspotImagePath ? (\n <>\n No Hotspot image found at path <code>{type?.options?.hotspotImagePath}</code>\n </>\n ) : (\n <>\n Define a path in this field using to the image field in this document at{' '}\n <code>options.hotspotImagePath</code>\n </>\n )}\n </Feedback>\n )}\n {type?.options?.imageHotspotPathRoot &&\n !VALID_ROOT_PATHS.includes(type.options.imageHotspotPathRoot) && (\n <Feedback>\n The supplied imageHotspotPathRoot \"{type.options.imageHotspotPathRoot}\" is not valid,\n falling back to \"document\". Available values are \"{VALID_ROOT_PATHS.join(', ')}\".\n </Feedback>\n )}\n <FormBuilderInput {...props} type={typeWithoutInputComponent} ref={ref} />\n </Stack>\n )\n})\n\nexport default withDocument(HotspotArray)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HotspotArray.js","names":["imageStyle","width","height","VALID_ROOT_PATHS","HotspotArray","React","forwardRef","props","ref","console","log","type","value","onChange","document","options","typeWithoutInputComponent","useUnsetInputComponent","inputComponent","imageHotspotPathRoot","includes","hotspotImage","useMemo","get","hotspotImagePath","displayImage","builder","imageUrlBuilder","sanityClient","dataset","config","urlFor","source","image","asset","_ref","getImageDimensions","aspectRatio","Math","round","url","handleHotspotImageClick","useCallback","event","nativeEvent","x","Number","offsetX","srcElement","toFixed","y","offsetY","description","newRow","_key","randomKey","_type","hotspotDescriptionPath","PatchEvent","from","setIfMissing","insert","handleHotspotMove","key","set","hotspotImageRef","useRef","useState","imageRect","setImageRect","updateImageRectCallback","useDebouncedCallback","e","contentRect","useResizeObserver","position","length","map","spot","index","hotspotTooltip","join","withParent","withDocument"],"sources":["../src/HotspotArray.tsx"],"sourcesContent":["/* eslint-disable react/display-name */\n\n// @ts-ignore\nimport sanityClient from 'part:@sanity/base/client'\n// @ts-ignore\nimport {withDocument, withParent} from 'part:@sanity/form-builder'\n\nimport {getImageDimensions} from '@sanity/asset-utils'\nimport {insert, PatchEvent, set, setIfMissing} from '@sanity/form-builder/PatchEvent'\nimport imageUrlBuilder from '@sanity/image-url'\nimport {Card, Flex, Stack} from '@sanity/ui'\nimport {randomKey} from '@sanity/util/content'\nimport get from 'lodash/get'\nimport React, {useState} from 'react'\n\nimport {IUseResizeObserverCallback, useDebouncedCallback, useResizeObserver} from '@react-hookz/web'\nimport Feedback from './Feedback'\nimport Spot from './Spot'\nimport {useUnsetInputComponent} from './useUnsetInputComponent'\nimport { NestedFormBuilder } from './NestedFormBuilder'\n\nconst imageStyle = {width: `100%`, height: `auto`}\n\nconst VALID_ROOT_PATHS = ['document', 'parent']\n\nexport type FnHotspotMove = (key: string, x: number, y: number) => void\n\nexport type TSpot = {\n _key: string\n _type: `spot`\n x: number\n y: number\n} & {[key: string]: unknown}\n\nconst HotspotArray = React.forwardRef((props: any, ref) => {\n console.log(props);\n const {type, value, onChange, document} = props\n const {options} = type ?? {}\n\n // Attempt prevention of infinite loop in <FormBuilderInput />\n // Re-renders can still occur if this Component is used again in a nested field\n const typeWithoutInputComponent = useUnsetInputComponent(type, type?.inputComponent)\n const imageHotspotPathRoot = VALID_ROOT_PATHS.includes(options?.imageHotspotPathRoot)\n ? props[options.imageHotspotPathRoot]\n : document\n\n /**\n * Finding the image from the imageHotspotPathRoot (defaults to document),\n * using the path from the hotspot's `options` field\n *\n * when changes in imageHotspotPathRoot (e.g. document) occur,\n * check if there are any changes to the hotspotImage and update the reference\n */\n const hotspotImage = React.useMemo(() => {\n return get(imageHotspotPathRoot, options?.hotspotImagePath)\n }, [imageHotspotPathRoot])\n\n const displayImage = React.useMemo(() => {\n const builder = imageUrlBuilder(sanityClient).dataset(sanityClient.config().dataset)\n const urlFor = (source) => builder.image(source)\n\n if (hotspotImage?.asset?._ref) {\n const {aspectRatio} = getImageDimensions(hotspotImage.asset._ref)\n const width = 1200\n const height = Math.round(width / aspectRatio)\n const url = urlFor(hotspotImage).width(width).url()\n\n return {width, height, url}\n }\n\n return null\n }, [hotspotImage])\n\n const handleHotspotImageClick = React.useCallback((event) => {\n const {nativeEvent} = event\n\n // Calculate the x/y percentage of the click position\n const x = Number(((nativeEvent.offsetX * 100) / nativeEvent.srcElement.width).toFixed(2))\n const y = Number(((nativeEvent.offsetY * 100) / nativeEvent.srcElement.height).toFixed(2))\n const description = `New Hotspot at ${x}% x ${y}%`\n\n const newRow: TSpot = {\n _key: randomKey(12),\n _type: `spot`,\n x,\n y,\n }\n\n if (options?.hotspotDescriptionPath) {\n newRow[options.hotspotDescriptionPath] = description\n }\n\n onChange(PatchEvent.from(setIfMissing([]), insert([newRow], 'after', [-1])))\n }, [])\n\n const handleHotspotMove: FnHotspotMove = React.useCallback(\n (key, x, y) => {\n onChange(\n PatchEvent.from(\n // Set the `x` value of this array key item\n set(x, [{_key: key}, 'x']),\n // Set the `y` value of this array key item\n set(y, [{_key: key}, 'y'])\n )\n )\n },\n [value]\n )\n\n const hotspotImageRef = React.useRef<HTMLImageElement | null>(null)\n\n const [imageRect, setImageRect] = useState<DOMRectReadOnly>()\n const updateImageRectCallback = useDebouncedCallback(\n ((e) => setImageRect(e.contentRect)) as IUseResizeObserverCallback,\n [setImageRect],\n 200\n )\n useResizeObserver(hotspotImageRef, updateImageRectCallback)\n\n return (\n <Stack space={[2, 2, 3]}>\n {displayImage?.url ? (\n <div style={{position: `relative`}}>\n {imageRect &&\n value?.length > 0 &&\n value.map((spot, index) => (\n <Spot\n index={index}\n key={spot._key}\n spot={spot}\n bounds={imageRect}\n update={handleHotspotMove}\n hotspotDescriptionPath={options?.hotspotDescriptionPath}\n tooltip={options?.hotspotTooltip}\n />\n ))}\n\n <Card __unstable_checkered shadow={1}>\n <Flex align=\"center\" justify=\"center\">\n <img\n ref={hotspotImageRef}\n src={displayImage.url}\n width={displayImage.width}\n height={displayImage.height}\n alt=\"\"\n style={imageStyle}\n onClick={handleHotspotImageClick}\n />\n </Flex>\n </Card>\n </div>\n ) : (\n <Feedback>\n {type?.options?.hotspotImagePath ? (\n <>\n No Hotspot image found at path <code>{type?.options?.hotspotImagePath}</code>\n </>\n ) : (\n <>\n Define a path in this field using to the image field in this document at{' '}\n <code>options.hotspotImagePath</code>\n </>\n )}\n </Feedback>\n )}\n {type?.options?.imageHotspotPathRoot &&\n !VALID_ROOT_PATHS.includes(type.options.imageHotspotPathRoot) && (\n <Feedback>\n The supplied imageHotspotPathRoot \"{type.options.imageHotspotPathRoot}\" is not valid,\n falling back to \"document\". Available values are \"{VALID_ROOT_PATHS.join(', ')}\".\n </Feedback>\n )}\n <NestedFormBuilder {...props} type={typeWithoutInputComponent} ref={ref} />\n </Stack>\n )\n})\n\nexport default withParent(withDocument(HotspotArray))\n"],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.NestedFormBuilder = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _FormBuilderInput = require("@sanity/form-builder/lib/FormBuilderInput");
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
11
|
+
/**
|
|
12
|
+
* Nesting FormBuilderInput components results in inconsistent focus & tab-index behaviour.
|
|
13
|
+
*
|
|
14
|
+
* FormBuilderInputs requests focus if props.focusPath matches the input.focusPath
|
|
15
|
+
* when mounted and when props change. If multiple components "handle" the same focus path,
|
|
16
|
+
* there is a race-condition on which component will receive the focus, often resulting
|
|
17
|
+
* in seemingly random scrollbehaviour.
|
|
18
|
+
*
|
|
19
|
+
* This is a workaround, reusing as much of FormBuilderInput as possible.
|
|
20
|
+
*
|
|
21
|
+
* Use FormBuilderInput when you need to render a field obtained from a SchemaType (type.fields or type.fieldset[].field).
|
|
22
|
+
*
|
|
23
|
+
* Use NestedFormBuilder for decorator components that are used as inputComponent or in input-resolver.ts.
|
|
24
|
+
*
|
|
25
|
+
* Decorator components are components that just want to modify a type, add some markup or so on,
|
|
26
|
+
* then delegate back to Sanity to obtain an actual input implementation.
|
|
27
|
+
*
|
|
28
|
+
* FormBuilderInput should only be used as the outermost component when resolving
|
|
29
|
+
* inputs recursively.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
class NestedFormBuilder extends _FormBuilderInput.FormBuilderInput {
|
|
33
|
+
componentDidMount() {
|
|
34
|
+
// do nothing - prevent focus-bug when nesting FormBuilderInput
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// eslint-disable-next-line camelcase
|
|
38
|
+
UNSAFE_componentWillReceiveProps() {
|
|
39
|
+
// do nothing - prevent focus-bug when nesting FormBuilderInput
|
|
40
|
+
}
|
|
41
|
+
componentDidUpdate() {
|
|
42
|
+
// do nothing - prevent focus-bug when nesting FormBuilderInput
|
|
43
|
+
}
|
|
44
|
+
render() {
|
|
45
|
+
var type = this.props.type;
|
|
46
|
+
var InputComponent = this.resolveInputComponent(type);
|
|
47
|
+
return /*#__PURE__*/_react.default.createElement(InputComponent, _extends({}, this.props, {
|
|
48
|
+
ref: this.setInput
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.NestedFormBuilder = NestedFormBuilder;
|
|
53
|
+
//# sourceMappingURL=NestedFormBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NestedFormBuilder.js","names":["NestedFormBuilder","FormBuilderInput","componentDidMount","UNSAFE_componentWillReceiveProps","componentDidUpdate","render","type","props","InputComponent","resolveInputComponent","setInput"],"sources":["../src/NestedFormBuilder.tsx"],"sourcesContent":["import React from 'react';\nimport { FormBuilderInput } from '@sanity/form-builder/lib/FormBuilderInput';\n\n/**\n * Nesting FormBuilderInput components results in inconsistent focus & tab-index behaviour.\n *\n * FormBuilderInputs requests focus if props.focusPath matches the input.focusPath\n * when mounted and when props change. If multiple components \"handle\" the same focus path,\n * there is a race-condition on which component will receive the focus, often resulting\n * in seemingly random scrollbehaviour.\n *\n * This is a workaround, reusing as much of FormBuilderInput as possible.\n *\n * Use FormBuilderInput when you need to render a field obtained from a SchemaType (type.fields or type.fieldset[].field).\n *\n * Use NestedFormBuilder for decorator components that are used as inputComponent or in input-resolver.ts.\n *\n * Decorator components are components that just want to modify a type, add some markup or so on,\n * then delegate back to Sanity to obtain an actual input implementation.\n *\n * FormBuilderInput should only be used as the outermost component when resolving\n * inputs recursively.\n */\n\nexport class NestedFormBuilder extends FormBuilderInput {\n componentDidMount() {\n // do nothing - prevent focus-bug when nesting FormBuilderInput\n }\n \n // eslint-disable-next-line camelcase\n UNSAFE_componentWillReceiveProps() {\n // do nothing - prevent focus-bug when nesting FormBuilderInput\n }\n \n componentDidUpdate() {\n // do nothing - prevent focus-bug when nesting FormBuilderInput\n }\n \n render(): JSX.Element {\n const { type } = this.props;\n const InputComponent = this.resolveInputComponent(type);\n return <InputComponent {...this.props} ref={this.setInput} />;\n }\n }"],"mappings":";;;;;;AAAA;AACA;AAA6E;AAAA;AAE7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO,MAAMA,iBAAiB,SAASC,kCAAgB,CAAC;EACpDC,iBAAiB,GAAG;IAClB;EACF;;EAEA;EACAC,gCAAgC,GAAG;IACjC;EACF;EAEAC,kBAAkB,GAAG;IACnB;EACF;EAEAC,MAAM,GAAgB;IACpB,IAAQC,IAAI,GAAK,IAAI,CAACC,KAAK,CAAnBD,IAAI;IACZ,IAAME,cAAc,GAAG,IAAI,CAACC,qBAAqB,CAACH,IAAI,CAAC;IACvD,oBAAO,6BAAC,cAAc,eAAK,IAAI,CAACC,KAAK;MAAE,GAAG,EAAE,IAAI,CAACG;IAAS,GAAG;EAC/D;AACF;AAAC"}
|
package/lib/Spot.js
CHANGED
|
@@ -4,39 +4,22 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = Spot;
|
|
7
|
-
|
|
8
7
|
var _ui = require("@sanity/ui");
|
|
9
|
-
|
|
10
8
|
var _framerMotion = require("framer-motion");
|
|
11
|
-
|
|
12
9
|
var _get = _interopRequireDefault(require("lodash/get"));
|
|
13
|
-
|
|
14
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
15
|
-
|
|
16
11
|
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); }
|
|
17
|
-
|
|
18
12
|
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; }
|
|
19
|
-
|
|
20
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
-
|
|
22
14
|
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; }
|
|
23
|
-
|
|
24
15
|
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; }
|
|
25
|
-
|
|
26
16
|
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; }
|
|
27
|
-
|
|
28
17
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
29
|
-
|
|
30
18
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
31
|
-
|
|
32
19
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
33
|
-
|
|
34
20
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
35
|
-
|
|
36
21
|
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
37
|
-
|
|
38
22
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
39
|
-
|
|
40
23
|
var dragStyle = {
|
|
41
24
|
width: '1.4rem',
|
|
42
25
|
height: '1.4rem',
|
|
@@ -87,63 +70,56 @@ var labelStyle = {
|
|
|
87
70
|
var labelStyleWhileActive = {
|
|
88
71
|
visibility: 'hidden'
|
|
89
72
|
};
|
|
90
|
-
|
|
91
73
|
var round = num => Math.round(num * 100) / 100;
|
|
92
|
-
|
|
93
74
|
function Spot(_ref) {
|
|
94
75
|
var spot = _ref.spot,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
76
|
+
bounds = _ref.bounds,
|
|
77
|
+
update = _ref.update,
|
|
78
|
+
hotspotDescriptionPath = _ref.hotspotDescriptionPath,
|
|
79
|
+
tooltip = _ref.tooltip,
|
|
80
|
+
index = _ref.index;
|
|
101
81
|
var _React$useState = _react.default.useState(false),
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
82
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
83
|
+
isDragging = _React$useState2[0],
|
|
84
|
+
setIsDragging = _React$useState2[1];
|
|
106
85
|
var _React$useState3 = _react.default.useState(false),
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
86
|
+
_React$useState4 = _slicedToArray(_React$useState3, 2),
|
|
87
|
+
isHovering = _React$useState4[0],
|
|
88
|
+
setIsHovering = _React$useState4[1];
|
|
111
89
|
|
|
90
|
+
// x/y are stored as % but need to be converted to px
|
|
112
91
|
var x = (0, _framerMotion.useMotionValue)(round(bounds.width * (spot.x / 100)));
|
|
113
92
|
var y = (0, _framerMotion.useMotionValue)(round(bounds.height * (spot.y / 100)));
|
|
93
|
+
|
|
114
94
|
/**
|
|
115
95
|
* update x/y if the bounds change when resizing the window
|
|
116
96
|
*/
|
|
117
|
-
|
|
118
97
|
(0, _react.useEffect)(() => {
|
|
119
98
|
x.set(round(bounds.width * (spot.x / 100)));
|
|
120
99
|
y.set(round(bounds.height * (spot.y / 100)));
|
|
121
100
|
}, [bounds]);
|
|
122
|
-
|
|
123
101
|
var handleDragEnd = _react.default.useCallback(() => {
|
|
124
|
-
setIsDragging(false);
|
|
102
|
+
setIsDragging(false);
|
|
125
103
|
|
|
104
|
+
// get current values for x/y in px
|
|
126
105
|
var currentX = x.get();
|
|
127
|
-
var currentY = y.get();
|
|
106
|
+
var currentY = y.get();
|
|
128
107
|
|
|
108
|
+
// Which we need to convert back to `%` to patch the document
|
|
129
109
|
var newX = round(currentX * 100 / bounds.width);
|
|
130
|
-
var newY = round(currentY * 100 / bounds.height);
|
|
110
|
+
var newY = round(currentY * 100 / bounds.height);
|
|
131
111
|
|
|
112
|
+
// Don't go below 0 or above 100
|
|
132
113
|
var safeX = Math.max(0, Math.min(100, newX));
|
|
133
114
|
var safeY = Math.max(0, Math.min(100, newY));
|
|
134
115
|
update(spot._key, safeX, safeY);
|
|
135
116
|
}, [spot]);
|
|
136
|
-
|
|
137
117
|
var handleDragStart = _react.default.useCallback(() => setIsDragging(true), []);
|
|
138
|
-
|
|
139
118
|
var handleHoverStart = _react.default.useCallback(() => setIsHovering(true), []);
|
|
140
|
-
|
|
141
119
|
var handleHoverEnd = _react.default.useCallback(() => setIsHovering(false), []);
|
|
142
|
-
|
|
143
120
|
if (!x || !y) {
|
|
144
121
|
return null;
|
|
145
122
|
}
|
|
146
|
-
|
|
147
123
|
return /*#__PURE__*/_react.default.createElement(_ui.Tooltip, {
|
|
148
124
|
key: spot._key,
|
|
149
125
|
disabled: isDragging,
|
package/lib/Spot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Spot.js","names":["dragStyle","width","height","position","boxSizing","top","left","margin","cursor","display","justifyContent","alignItems","borderRadius","background","color","dragStyleWhileDrag","border","dragStyleWhileHover","dotStyle","visibility","pointerEvents","dotStyleWhileActive","labelStyle","fontSize","fontWeight","lineHeight","labelStyleWhileActive","round","num","Math","Spot","spot","bounds","update","hotspotDescriptionPath","tooltip","index","React","useState","isDragging","setIsDragging","isHovering","setIsHovering","x","useMotionValue","y","useEffect","set","handleDragEnd","useCallback","currentX","get","currentY","newX","newY","safeX","max","min","safeY","_key","handleDragStart","handleHoverStart","handleHoverEnd","createElement","maxWidth"],"sources":["../src/Spot.tsx"],"sourcesContent":["import {Box, Text, Tooltip} from '@sanity/ui'\nimport {motion, useMotionValue} from 'framer-motion'\nimport get from 'lodash/get'\nimport React, {CSSProperties, ReactElement, useEffect} from 'react'\nimport {FnHotspotMove, TSpot} from './HotspotArray'\n\nconst dragStyle: CSSProperties = {\n width: '1.4rem',\n height: '1.4rem',\n position: 'absolute',\n boxSizing: 'border-box',\n top: 0,\n left: 0,\n margin: '-0.7rem 0 0 -0.7rem',\n cursor: 'pointer',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n borderRadius: '50%',\n background: '#000',\n color: 'white',\n}\n\nconst dragStyleWhileDrag: CSSProperties = {\n background: 'rgba(0, 0, 0, 0.1)',\n border: '1px solid #fff',\n cursor: 'none',\n}\n\nconst dragStyleWhileHover: CSSProperties = {\n background: 'rgba(0, 0, 0, 0.1)',\n border: '1px solid #fff',\n}\n\nconst dotStyle: CSSProperties = {\n position: 'absolute',\n left: '50%',\n top: '50%',\n height: '0.2rem',\n width: '0.2rem',\n margin: '-0.1rem 0 0 -0.1rem',\n background: '#fff',\n visibility: 'hidden',\n borderRadius: '50%',\n // make sure pointer events only run on the parent\n pointerEvents: 'none',\n}\n\nconst dotStyleWhileActive: CSSProperties = {\n visibility: 'visible',\n}\n\nconst labelStyle: CSSProperties = {\n color: 'white',\n fontSize: '0.7rem',\n fontWeight: 600,\n lineHeight: '1',\n}\n\nconst labelStyleWhileActive: CSSProperties = {\n visibility: 'hidden',\n}\n\nconst round = (num) => Math.round(num * 100) / 100\n\ninterface IHotspot {\n spot: TSpot\n bounds: DOMRectReadOnly\n update: FnHotspotMove\n hotspotDescriptionPath?: string\n tooltip?: ReactElement\n index: number\n}\n\nexport default function Spot({\n spot,\n bounds,\n update,\n hotspotDescriptionPath,\n tooltip,\n index,\n}: IHotspot) {\n const [isDragging, setIsDragging] = React.useState(false)\n const [isHovering, setIsHovering] = React.useState(false)\n\n // x/y are stored as % but need to be converted to px\n const x = useMotionValue(round(bounds.width * (spot.x / 100)))\n const y = useMotionValue(round(bounds.height * (spot.y / 100)))\n\n /**\n * update x/y if the bounds change when resizing the window\n */\n useEffect(() => {\n x.set(round(bounds.width * (spot.x / 100)))\n y.set(round(bounds.height * (spot.y / 100)))\n }, [bounds])\n\n const handleDragEnd = React.useCallback(() => {\n setIsDragging(false)\n\n // get current values for x/y in px\n const currentX = x.get()\n const currentY = y.get()\n\n // Which we need to convert back to `%` to patch the document\n const newX = round((currentX * 100) / bounds.width)\n const newY = round((currentY * 100) / bounds.height)\n\n // Don't go below 0 or above 100\n const safeX = Math.max(0, Math.min(100, newX))\n const safeY = Math.max(0, Math.min(100, newY))\n\n update(spot._key, safeX, safeY)\n }, [spot])\n const handleDragStart = React.useCallback(() => setIsDragging(true), [])\n\n const handleHoverStart = React.useCallback(() => setIsHovering(true), [])\n const handleHoverEnd = React.useCallback(() => setIsHovering(false), [])\n\n if (!x || !y) {\n return null\n }\n\n return (\n <Tooltip\n key={spot._key}\n disabled={isDragging}\n portal\n content={\n tooltip && typeof tooltip === 'function' ? (\n React.createElement(tooltip, {spot})\n ) : (\n <Box padding={2} style={{maxWidth: 200, pointerEvents: `none`}}>\n <Text textOverflow=\"ellipsis\">\n {hotspotDescriptionPath\n ? (get(spot, hotspotDescriptionPath) as string)\n : `${spot.x}% x ${spot.y}%`}\n </Text>\n </Box>\n )\n }\n >\n <motion.div\n drag\n dragConstraints={bounds}\n dragElastic={0}\n dragMomentum={false}\n onDragEnd={handleDragEnd}\n onDragStart={handleDragStart}\n onHoverStart={handleHoverStart}\n onHoverEnd={handleHoverEnd}\n style={{\n ...dragStyle,\n x,\n y,\n ...(isDragging && {...dragStyleWhileDrag}),\n ...(isHovering && {...dragStyleWhileHover}),\n }}\n >\n {/* Dot */}\n <Box\n style={{\n ...dotStyle,\n ...((isDragging || isHovering) && {...dotStyleWhileActive}),\n }}\n />\n {/* Label */}\n <div\n style={{\n ...labelStyle,\n ...((isDragging || isHovering) && {...labelStyleWhileActive}),\n }}\n >\n {index + 1}\n </div>\n </motion.div>\n </Tooltip>\n )\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Spot.js","names":["dragStyle","width","height","position","boxSizing","top","left","margin","cursor","display","justifyContent","alignItems","borderRadius","background","color","dragStyleWhileDrag","border","dragStyleWhileHover","dotStyle","visibility","pointerEvents","dotStyleWhileActive","labelStyle","fontSize","fontWeight","lineHeight","labelStyleWhileActive","round","num","Math","Spot","spot","bounds","update","hotspotDescriptionPath","tooltip","index","React","useState","isDragging","setIsDragging","isHovering","setIsHovering","x","useMotionValue","y","useEffect","set","handleDragEnd","useCallback","currentX","get","currentY","newX","newY","safeX","max","min","safeY","_key","handleDragStart","handleHoverStart","handleHoverEnd","createElement","maxWidth"],"sources":["../src/Spot.tsx"],"sourcesContent":["import {Box, Text, Tooltip} from '@sanity/ui'\nimport {motion, useMotionValue} from 'framer-motion'\nimport get from 'lodash/get'\nimport React, {CSSProperties, ReactElement, useEffect} from 'react'\nimport {FnHotspotMove, TSpot} from './HotspotArray'\n\nconst dragStyle: CSSProperties = {\n width: '1.4rem',\n height: '1.4rem',\n position: 'absolute',\n boxSizing: 'border-box',\n top: 0,\n left: 0,\n margin: '-0.7rem 0 0 -0.7rem',\n cursor: 'pointer',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n borderRadius: '50%',\n background: '#000',\n color: 'white',\n}\n\nconst dragStyleWhileDrag: CSSProperties = {\n background: 'rgba(0, 0, 0, 0.1)',\n border: '1px solid #fff',\n cursor: 'none',\n}\n\nconst dragStyleWhileHover: CSSProperties = {\n background: 'rgba(0, 0, 0, 0.1)',\n border: '1px solid #fff',\n}\n\nconst dotStyle: CSSProperties = {\n position: 'absolute',\n left: '50%',\n top: '50%',\n height: '0.2rem',\n width: '0.2rem',\n margin: '-0.1rem 0 0 -0.1rem',\n background: '#fff',\n visibility: 'hidden',\n borderRadius: '50%',\n // make sure pointer events only run on the parent\n pointerEvents: 'none',\n}\n\nconst dotStyleWhileActive: CSSProperties = {\n visibility: 'visible',\n}\n\nconst labelStyle: CSSProperties = {\n color: 'white',\n fontSize: '0.7rem',\n fontWeight: 600,\n lineHeight: '1',\n}\n\nconst labelStyleWhileActive: CSSProperties = {\n visibility: 'hidden',\n}\n\nconst round = (num) => Math.round(num * 100) / 100\n\ninterface IHotspot {\n spot: TSpot\n bounds: DOMRectReadOnly\n update: FnHotspotMove\n hotspotDescriptionPath?: string\n tooltip?: ReactElement\n index: number\n}\n\nexport default function Spot({\n spot,\n bounds,\n update,\n hotspotDescriptionPath,\n tooltip,\n index,\n}: IHotspot) {\n const [isDragging, setIsDragging] = React.useState(false)\n const [isHovering, setIsHovering] = React.useState(false)\n\n // x/y are stored as % but need to be converted to px\n const x = useMotionValue(round(bounds.width * (spot.x / 100)))\n const y = useMotionValue(round(bounds.height * (spot.y / 100)))\n\n /**\n * update x/y if the bounds change when resizing the window\n */\n useEffect(() => {\n x.set(round(bounds.width * (spot.x / 100)))\n y.set(round(bounds.height * (spot.y / 100)))\n }, [bounds])\n\n const handleDragEnd = React.useCallback(() => {\n setIsDragging(false)\n\n // get current values for x/y in px\n const currentX = x.get()\n const currentY = y.get()\n\n // Which we need to convert back to `%` to patch the document\n const newX = round((currentX * 100) / bounds.width)\n const newY = round((currentY * 100) / bounds.height)\n\n // Don't go below 0 or above 100\n const safeX = Math.max(0, Math.min(100, newX))\n const safeY = Math.max(0, Math.min(100, newY))\n\n update(spot._key, safeX, safeY)\n }, [spot])\n const handleDragStart = React.useCallback(() => setIsDragging(true), [])\n\n const handleHoverStart = React.useCallback(() => setIsHovering(true), [])\n const handleHoverEnd = React.useCallback(() => setIsHovering(false), [])\n\n if (!x || !y) {\n return null\n }\n\n return (\n <Tooltip\n key={spot._key}\n disabled={isDragging}\n portal\n content={\n tooltip && typeof tooltip === 'function' ? (\n React.createElement(tooltip, {spot})\n ) : (\n <Box padding={2} style={{maxWidth: 200, pointerEvents: `none`}}>\n <Text textOverflow=\"ellipsis\">\n {hotspotDescriptionPath\n ? (get(spot, hotspotDescriptionPath) as string)\n : `${spot.x}% x ${spot.y}%`}\n </Text>\n </Box>\n )\n }\n >\n <motion.div\n drag\n dragConstraints={bounds}\n dragElastic={0}\n dragMomentum={false}\n onDragEnd={handleDragEnd}\n onDragStart={handleDragStart}\n onHoverStart={handleHoverStart}\n onHoverEnd={handleHoverEnd}\n style={{\n ...dragStyle,\n x,\n y,\n ...(isDragging && {...dragStyleWhileDrag}),\n ...(isHovering && {...dragStyleWhileHover}),\n }}\n >\n {/* Dot */}\n <Box\n style={{\n ...dotStyle,\n ...((isDragging || isHovering) && {...dotStyleWhileActive}),\n }}\n />\n {/* Label */}\n <div\n style={{\n ...labelStyle,\n ...((isDragging || isHovering) && {...labelStyleWhileActive}),\n }}\n >\n {index + 1}\n </div>\n </motion.div>\n </Tooltip>\n )\n}\n"],"mappings":"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"}
|
|
@@ -4,26 +4,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.useUnsetInputComponent = useUnsetInputComponent;
|
|
7
|
-
|
|
8
7
|
var _react = _interopRequireDefault(require("react"));
|
|
9
|
-
|
|
10
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
9
|
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; }
|
|
13
|
-
|
|
14
10
|
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; }
|
|
15
|
-
|
|
16
11
|
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; }
|
|
17
|
-
|
|
18
12
|
function useUnsetInputComponent(type, component) {
|
|
19
13
|
return _react.default.useMemo(() => unsetInputComponent(type, component), [type, component]);
|
|
20
14
|
}
|
|
21
|
-
|
|
22
15
|
function unsetInputComponent(type, component) {
|
|
23
16
|
var t = _objectSpread(_objectSpread({}, type), {}, {
|
|
24
17
|
inputComponent: type.inputComponent === component ? undefined : type.inputComponent
|
|
25
18
|
});
|
|
26
|
-
|
|
27
19
|
var typeOfType = t.type ? unsetInputComponent(t.type, component) : undefined;
|
|
28
20
|
return _objectSpread(_objectSpread({}, t), {}, {
|
|
29
21
|
type: typeOfType
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUnsetInputComponent.js","names":["useUnsetInputComponent","type","component","React","useMemo","unsetInputComponent","t","inputComponent","undefined","typeOfType"],"sources":["../src/useUnsetInputComponent.ts"],"sourcesContent":["import React from 'react'\n\nexport function useUnsetInputComponent(type, component) {\n return React.useMemo(() => unsetInputComponent(type, component), [type, component])\n}\n\nfunction unsetInputComponent(type, component) {\n const t = {\n ...type,\n inputComponent: type.inputComponent === component ? undefined : type.inputComponent,\n }\n const typeOfType = t.type ? unsetInputComponent(t.type, component) : undefined\n return {\n ...t,\n type: typeOfType,\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useUnsetInputComponent.js","names":["useUnsetInputComponent","type","component","React","useMemo","unsetInputComponent","t","inputComponent","undefined","typeOfType"],"sources":["../src/useUnsetInputComponent.ts"],"sourcesContent":["import React from 'react'\n\nexport function useUnsetInputComponent(type, component) {\n return React.useMemo(() => unsetInputComponent(type, component), [type, component])\n}\n\nfunction unsetInputComponent(type, component) {\n const t = {\n ...type,\n inputComponent: type.inputComponent === component ? undefined : type.inputComponent,\n }\n const typeOfType = t.type ? unsetInputComponent(t.type, component) : undefined\n return {\n ...t,\n type: typeOfType,\n }\n}\n"],"mappings":";;;;;;AAAA;AAAyB;AAAA;AAAA;AAAA;AAElB,SAASA,sBAAsB,CAACC,IAAI,EAAEC,SAAS,EAAE;EACtD,OAAOC,cAAK,CAACC,OAAO,CAAC,MAAMC,mBAAmB,CAACJ,IAAI,EAAEC,SAAS,CAAC,EAAE,CAACD,IAAI,EAAEC,SAAS,CAAC,CAAC;AACrF;AAEA,SAASG,mBAAmB,CAACJ,IAAI,EAAEC,SAAS,EAAE;EAC5C,IAAMI,CAAC,mCACFL,IAAI;IACPM,cAAc,EAAEN,IAAI,CAACM,cAAc,KAAKL,SAAS,GAAGM,SAAS,GAAGP,IAAI,CAACM;EAAc,EACpF;EACD,IAAME,UAAU,GAAGH,CAAC,CAACL,IAAI,GAAGI,mBAAmB,CAACC,CAAC,CAACL,IAAI,EAAEC,SAAS,CAAC,GAAGM,SAAS;EAC9E,uCACKF,CAAC;IACJL,IAAI,EAAEQ;EAAU;AAEpB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sanity-plugin-hotspot-array",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "A configurable Custom Input for Arrays that will add and update items by clicking on an Image",
|
|
5
5
|
"main": "lib/HotspotArray.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,20 +19,20 @@
|
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
22
|
-
"url": "git+ssh://git@github.com/
|
|
22
|
+
"url": "git+ssh://git@github.com/sanity-io/sanity-plugin-hotspot-array.git"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|
|
25
25
|
"sanity",
|
|
26
26
|
"sanity-plugin"
|
|
27
27
|
],
|
|
28
|
-
"author": "
|
|
28
|
+
"author": "Sanity.io <hello@sanity.io>",
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@react-hookz/web": "^14.2.2",
|
|
32
|
-
"@sanity/asset-utils": "^1.
|
|
33
|
-
"@sanity/base": "^2.
|
|
34
|
-
"@sanity/form-builder": "^2.
|
|
35
|
-
"@sanity/ui": "^0.37.
|
|
32
|
+
"@sanity/asset-utils": "^1.3.0",
|
|
33
|
+
"@sanity/base": "^2.35.0",
|
|
34
|
+
"@sanity/form-builder": "^2.35.0",
|
|
35
|
+
"@sanity/ui": "^0.37.22",
|
|
36
36
|
"framer-motion": "^6.3.11",
|
|
37
37
|
"husky": "^8.0.1"
|
|
38
38
|
},
|
|
@@ -46,15 +46,16 @@
|
|
|
46
46
|
"sanipack": "^2.1.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@sanity/image-url": "1.0.1",
|
|
50
|
-
"@sanity/util": "2.
|
|
49
|
+
"@sanity/image-url": "^1.0.1",
|
|
50
|
+
"@sanity/util": "^2.35.0",
|
|
51
51
|
"lodash": "4.17.21",
|
|
52
|
-
"react": "^17
|
|
52
|
+
"react": "^17",
|
|
53
|
+
"react-dom": "^17"
|
|
53
54
|
},
|
|
54
55
|
"bugs": {
|
|
55
|
-
"url": "https://github.com/
|
|
56
|
+
"url": "https://github.com/sanity-io/sanity-plugin-hotspot-array/issues"
|
|
56
57
|
},
|
|
57
|
-
"homepage": "https://github.com/
|
|
58
|
+
"homepage": "https://github.com/sanity-io/sanity-plugin-hotspot-array#readme",
|
|
58
59
|
"prettier": {
|
|
59
60
|
"semi": false,
|
|
60
61
|
"printWidth": 100,
|
package/src/HotspotArray.tsx
CHANGED
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
// @ts-ignore
|
|
4
4
|
import sanityClient from 'part:@sanity/base/client'
|
|
5
5
|
// @ts-ignore
|
|
6
|
-
import {withDocument} from 'part:@sanity/form-builder'
|
|
6
|
+
import {withDocument, withParent} from 'part:@sanity/form-builder'
|
|
7
7
|
|
|
8
8
|
import {getImageDimensions} from '@sanity/asset-utils'
|
|
9
|
-
import {FormBuilderInput} from '@sanity/form-builder/lib/FormBuilderInput'
|
|
10
9
|
import {insert, PatchEvent, set, setIfMissing} from '@sanity/form-builder/PatchEvent'
|
|
11
10
|
import imageUrlBuilder from '@sanity/image-url'
|
|
12
11
|
import {Card, Flex, Stack} from '@sanity/ui'
|
|
@@ -18,6 +17,7 @@ import {IUseResizeObserverCallback, useDebouncedCallback, useResizeObserver} fro
|
|
|
18
17
|
import Feedback from './Feedback'
|
|
19
18
|
import Spot from './Spot'
|
|
20
19
|
import {useUnsetInputComponent} from './useUnsetInputComponent'
|
|
20
|
+
import { NestedFormBuilder } from './NestedFormBuilder'
|
|
21
21
|
|
|
22
22
|
const imageStyle = {width: `100%`, height: `auto`}
|
|
23
23
|
|
|
@@ -33,6 +33,7 @@ export type TSpot = {
|
|
|
33
33
|
} & {[key: string]: unknown}
|
|
34
34
|
|
|
35
35
|
const HotspotArray = React.forwardRef((props: any, ref) => {
|
|
36
|
+
console.log(props);
|
|
36
37
|
const {type, value, onChange, document} = props
|
|
37
38
|
const {options} = type ?? {}
|
|
38
39
|
|
|
@@ -169,9 +170,9 @@ const HotspotArray = React.forwardRef((props: any, ref) => {
|
|
|
169
170
|
falling back to "document". Available values are "{VALID_ROOT_PATHS.join(', ')}".
|
|
170
171
|
</Feedback>
|
|
171
172
|
)}
|
|
172
|
-
<
|
|
173
|
+
<NestedFormBuilder {...props} type={typeWithoutInputComponent} ref={ref} />
|
|
173
174
|
</Stack>
|
|
174
175
|
)
|
|
175
176
|
})
|
|
176
177
|
|
|
177
|
-
export default withDocument(HotspotArray)
|
|
178
|
+
export default withParent(withDocument(HotspotArray))
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FormBuilderInput } from '@sanity/form-builder/lib/FormBuilderInput';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Nesting FormBuilderInput components results in inconsistent focus & tab-index behaviour.
|
|
6
|
+
*
|
|
7
|
+
* FormBuilderInputs requests focus if props.focusPath matches the input.focusPath
|
|
8
|
+
* when mounted and when props change. If multiple components "handle" the same focus path,
|
|
9
|
+
* there is a race-condition on which component will receive the focus, often resulting
|
|
10
|
+
* in seemingly random scrollbehaviour.
|
|
11
|
+
*
|
|
12
|
+
* This is a workaround, reusing as much of FormBuilderInput as possible.
|
|
13
|
+
*
|
|
14
|
+
* Use FormBuilderInput when you need to render a field obtained from a SchemaType (type.fields or type.fieldset[].field).
|
|
15
|
+
*
|
|
16
|
+
* Use NestedFormBuilder for decorator components that are used as inputComponent or in input-resolver.ts.
|
|
17
|
+
*
|
|
18
|
+
* Decorator components are components that just want to modify a type, add some markup or so on,
|
|
19
|
+
* then delegate back to Sanity to obtain an actual input implementation.
|
|
20
|
+
*
|
|
21
|
+
* FormBuilderInput should only be used as the outermost component when resolving
|
|
22
|
+
* inputs recursively.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export class NestedFormBuilder extends FormBuilderInput {
|
|
26
|
+
componentDidMount() {
|
|
27
|
+
// do nothing - prevent focus-bug when nesting FormBuilderInput
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// eslint-disable-next-line camelcase
|
|
31
|
+
UNSAFE_componentWillReceiveProps() {
|
|
32
|
+
// do nothing - prevent focus-bug when nesting FormBuilderInput
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
componentDidUpdate() {
|
|
36
|
+
// do nothing - prevent focus-bug when nesting FormBuilderInput
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
render(): JSX.Element {
|
|
40
|
+
const { type } = this.props;
|
|
41
|
+
const InputComponent = this.resolveInputComponent(type);
|
|
42
|
+
return <InputComponent {...this.props} ref={this.setInput} />;
|
|
43
|
+
}
|
|
44
|
+
}
|