sanity-plugin-hotspot-array 0.0.5 → 0.0.6

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Feedback.tsx"],"names":["Feedback","children"],"mappings":";;;;;;;AAAA;;AACA;;;;AAEe,SAASA,QAAT,OAA8B;AAAA,MAAXC,QAAW,QAAXA,QAAW;AAC3C,sBACE,6BAAC,QAAD;AAAM,IAAA,OAAO,EAAE,CAAf;AAAkB,IAAA,MAAM,EAAE,CAA1B;AAA6B,IAAA,MAAM,EAAE,CAArC;AAAwC,IAAA,IAAI,EAAC;AAA7C,kBACE,6BAAC,QAAD,QAAOA,QAAP,CADF,CADF;AAKD","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"],"file":"Feedback.js"}
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;;;;AAEe,SAASA,QAAT,OAA8B;EAAA,IAAXC,QAAW,QAAXA,QAAW;EAC3C,oBACE,6BAAC,QAAD;IAAM,OAAO,EAAE,CAAf;IAAkB,MAAM,EAAE,CAA1B;IAA6B,MAAM,EAAE,CAArC;IAAwC,IAAI,EAAC;EAA7C,gBACE,6BAAC,QAAD,QAAOA,QAAP,CADF,CADF;AAKD"}
@@ -33,27 +33,29 @@ var _Feedback = _interopRequireDefault(require("./Feedback"));
33
33
 
34
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35
35
 
36
- function _extends() { _extends = Object.assign || 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); }
36
+ 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); }
37
37
 
38
38
  var imageStyle = {
39
39
  width: "100%",
40
40
  height: "auto"
41
41
  };
42
+ var VALID_ROOT_PATHS = ['document', 'parent'];
42
43
 
43
44
  var HotspotArray = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
44
- var _type$options, _type$options2;
45
+ var _type$options, _type$options2, _type$options3;
45
46
 
46
47
  var type = props.type,
47
48
  value = props.value,
48
49
  onChange = props.onChange,
49
- sanityDocument = props.document;
50
+ document = props.document,
51
+ parent = props.parent;
50
52
 
51
53
  var _ref = type !== null && type !== void 0 ? type : {},
52
54
  options = _ref.options; // Attempt prevention of infinite loop in <FormBuilderInput />
53
55
  // Re-renders can still occur if this Component is used again in a nested field
54
56
 
55
57
 
56
- var typeWithoutInputComponent = (0, _useUnsetInputComponent.useUnsetInputComponent)(type, type === null || type === void 0 ? void 0 : type.inputComponent); // Finding the image from the document,
58
+ var typeWithoutInputComponent = (0, _useUnsetInputComponent.useUnsetInputComponent)(type, type === null || type === void 0 ? void 0 : type.inputComponent); // Finding the image from the imageHotspotPathRoot (defaults to document),
57
59
  // using the path from the hotspot's `options` field
58
60
 
59
61
  var displayImage = _react.default.useMemo(() => {
@@ -63,7 +65,8 @@ var HotspotArray = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
63
65
 
64
66
  var urlFor = source => builder.image(source);
65
67
 
66
- var hotspotImage = (0, _get.default)(sanityDocument, options === null || options === void 0 ? void 0 : options.hotspotImagePath);
68
+ var imageHotspotPathRoot = VALID_ROOT_PATHS.includes(options === null || options === void 0 ? void 0 : options.imageHotspotPathRoot) ? props[options.imageHotspotPathRoot] : document;
69
+ var hotspotImage = (0, _get.default)(imageHotspotPathRoot, options === null || options === void 0 ? void 0 : options.hotspotImagePath);
67
70
 
68
71
  if (hotspotImage !== null && hotspotImage !== void 0 && (_hotspotImage$asset = hotspotImage.asset) !== null && _hotspotImage$asset !== void 0 && _hotspotImage$asset._ref) {
69
72
  var _getImageDimensions = (0, _assetUtils.getImageDimensions)(hotspotImage.asset._ref),
@@ -80,7 +83,7 @@ var HotspotArray = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
80
83
  }
81
84
 
82
85
  return null;
83
- }, [sanityDocument, type]);
86
+ }, [type, document]);
84
87
 
85
88
  var handleHotspotImageClick = _react.default.useCallback(event => {
86
89
  var nativeEvent = event.nativeEvent; // Calculate the x/y percentage of the click position
@@ -149,7 +152,7 @@ var HotspotArray = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
149
152
  alt: "",
150
153
  style: imageStyle,
151
154
  onClick: handleHotspotImageClick
152
- })))) : /*#__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"))), /*#__PURE__*/_react.default.createElement(_FormBuilderInput.FormBuilderInput, _extends({}, props, {
155
+ })))) : /*#__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(_FormBuilderInput.FormBuilderInput, _extends({}, props, {
153
156
  type: typeWithoutInputComponent,
154
157
  ref: ref
155
158
  })));
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/HotspotArray.tsx"],"names":["imageStyle","width","height","HotspotArray","React","forwardRef","props","ref","type","value","onChange","sanityDocument","document","options","typeWithoutInputComponent","inputComponent","displayImage","useMemo","builder","sanityClient","dataset","config","urlFor","source","image","hotspotImage","hotspotImagePath","asset","_ref","aspectRatio","Math","round","url","handleHotspotImageClick","useCallback","event","nativeEvent","x","Number","offsetX","srcElement","toFixed","y","offsetY","description","newRow","_key","_type","hotspotDescriptionPath","PatchEvent","from","handleHotspotMove","key","console","warn","hotspotImageRef","useRef","position","length","map","spot","hotspotTooltip"],"mappings":";;;;;;;AAGA;;AAEA;;AAEA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AAEA;;AACA;;AACA;;;;;;AAEA,IAAMA,UAAU,GAAG;AAACC,EAAAA,KAAK,QAAN;AAAgBC,EAAAA,MAAM;AAAtB,CAAnB;;AAEA,IAAMC,YAAY,gBAAGC,eAAMC,UAAN,CAAiB,CAACC,KAAD,EAAQC,GAAR,KAAgB;AAAA;;AACpD,MAAOC,IAAP,GAA0DF,KAA1D,CAAOE,IAAP;AAAA,MAAaC,KAAb,GAA0DH,KAA1D,CAAaG,KAAb;AAAA,MAAoBC,QAApB,GAA0DJ,KAA1D,CAAoBI,QAApB;AAAA,MAAwCC,cAAxC,GAA0DL,KAA1D,CAA8BM,QAA9B;;AACA,aAAkBJ,IAAlB,aAAkBA,IAAlB,cAAkBA,IAAlB,GAA0B,EAA1B;AAAA,MAAOK,OAAP,QAAOA,OAAP,CAFoD,CAIpD;AACA;;;AACA,MAAMC,yBAAyB,GAAG,oDAAuBN,IAAvB,EAA6BA,IAA7B,aAA6BA,IAA7B,uBAA6BA,IAAI,CAAEO,cAAnC,CAAlC,CANoD,CAQpD;AACA;;AACA,MAAMC,YAAY,GAAGZ,eAAMa,OAAN,CAAc,MAAM;AAAA;;AACvC,QAAMC,OAAO,GAAG,uBAAgBC,eAAhB,EAA8BC,OAA9B,CAAsCD,gBAAaE,MAAb,GAAsBD,OAA5D,CAAhB;;AACA,QAAME,MAAM,GAAIC,MAAD,IAAYL,OAAO,CAACM,KAAR,CAAcD,MAAd,CAA3B;;AACA,QAAME,YAAY,GAAG,kBAAId,cAAJ,EAAoBE,OAApB,aAAoBA,OAApB,uBAAoBA,OAAO,CAAEa,gBAA7B,CAArB;;AAEA,QAAID,YAAJ,aAAIA,YAAJ,sCAAIA,YAAY,CAAEE,KAAlB,gDAAI,oBAAqBC,IAAzB,EAA+B;AAC7B,gCAAsB,oCAAmBH,YAAY,CAACE,KAAb,CAAmBC,IAAtC,CAAtB;AAAA,UAAOC,WAAP,uBAAOA,WAAP;;AACA,UAAM5B,KAAK,GAAG,GAAd;AACA,UAAMC,MAAM,GAAG4B,IAAI,CAACC,KAAL,CAAW9B,KAAK,GAAG4B,WAAnB,CAAf;AACA,UAAMG,GAAG,GAAGV,MAAM,CAACG,YAAD,CAAN,CAAqBxB,KAArB,CAA2BA,KAA3B,EAAkC+B,GAAlC,EAAZ;AAEA,aAAO;AAAC/B,QAAAA,KAAD;AAAQC,QAAAA,MAAR;AAAgB8B,QAAAA;AAAhB,OAAP;AACD;;AAED,WAAO,IAAP;AACD,GAfoB,EAelB,CAACrB,cAAD,EAAiBH,IAAjB,CAfkB,CAArB;;AAiBA,MAAMyB,uBAAuB,GAAG7B,eAAM8B,WAAN,CAAmBC,KAAD,IAAW;AAC3D,QAAOC,WAAP,GAAsBD,KAAtB,CAAOC,WAAP,CAD2D,CAG3D;;AACA,QAAMC,CAAC,GAAGC,MAAM,CAAC,CAAEF,WAAW,CAACG,OAAZ,GAAsB,GAAvB,GAA8BH,WAAW,CAACI,UAAZ,CAAuBvC,KAAtD,EAA6DwC,OAA7D,CAAqE,CAArE,CAAD,CAAhB;AACA,QAAMC,CAAC,GAAGJ,MAAM,CAAC,CAAEF,WAAW,CAACO,OAAZ,GAAsB,GAAvB,GAA8BP,WAAW,CAACI,UAAZ,CAAuBtC,MAAtD,EAA8DuC,OAA9D,CAAsE,CAAtE,CAAD,CAAhB;AACA,QAAMG,WAAW,4BAAqBP,CAArB,iBAA6BK,CAA7B,MAAjB;AAEA,QAAMG,MAAM,GAAG;AACbC,MAAAA,IAAI,EAAE,wBAAU,EAAV,CADO;AAEbC,MAAAA,KAAK,QAFQ;AAGbV,MAAAA,CAHa;AAIbK,MAAAA;AAJa,KAAf;;AAOA,QAAI7B,OAAJ,aAAIA,OAAJ,eAAIA,OAAO,CAAEmC,sBAAb,EAAqC;AACnCH,MAAAA,MAAM,CAAChC,OAAO,CAACmC,sBAAT,CAAN,GAAyCJ,WAAzC;AACD;;AAEDlC,IAAAA,QAAQ,CAACuC,uBAAWC,IAAX,CAAgB,8BAAa,EAAb,CAAhB,EAAkC,wBAAO,CAACL,MAAD,CAAP,EAAiB,OAAjB,EAA0B,CAAC,CAAC,CAAF,CAA1B,CAAlC,CAAD,CAAR;AACD,GApB+B,EAoB7B,EApB6B,CAAhC;;AAsBA,MAAMM,iBAAiB,GAAG/C,eAAM8B,WAAN,CACxB,CAACkB,GAAD,EAAMf,CAAN,EAASK,CAAT,KAAe;AACb,QAAI,CAACJ,MAAM,CAACD,CAAD,CAAP,IAAc,CAACC,MAAM,CAACI,CAAD,CAAzB,EAA8B;AAC5BW,MAAAA,OAAO,CAACC,IAAR,iCAA6C;AAACjB,QAAAA,CAAD;AAAIK,QAAAA;AAAJ,OAA7C;AACA;AACD;;AAEDhC,IAAAA,QAAQ,CACNuC,uBAAWC,IAAX,EACE;AACA,yBAAIb,CAAJ,EAAO,CAAC;AAACS,MAAAA,IAAI,EAAEM;AAAP,KAAD,EAAc,GAAd,CAAP,CAFF,EAGE;AACA,yBAAIV,CAAJ,EAAO,CAAC;AAACI,MAAAA,IAAI,EAAEM;AAAP,KAAD,EAAc,GAAd,CAAP,CAJF,CADM,CAAR;AAQD,GAfuB,EAgBxB,CAAC3C,KAAD,CAhBwB,CAA1B;;AAmBA,MAAM8C,eAAe,GAAGnD,eAAMoD,MAAN,CAAa,IAAb,CAAxB;;AAEA,sBACE,6BAAC,SAAD;AAAO,IAAA,KAAK,EAAE,CAAC,CAAD,EAAG,CAAH,EAAK,CAAL;AAAd,KACGxC,YAAY,SAAZ,IAAAA,YAAY,WAAZ,IAAAA,YAAY,CAAEgB,GAAd,gBACC;AAAK,IAAA,KAAK,EAAE;AAACyB,MAAAA,QAAQ;AAAT;AAAZ,KACG,CAAAhD,KAAK,SAAL,IAAAA,KAAK,WAAL,YAAAA,KAAK,CAAEiD,MAAP,IAAgB,CAAhB,IACCjD,KAAK,CAACkD,GAAN,CAAWC,IAAD,iBACR,6BAAC,aAAD;AACE,IAAA,GAAG,EAAEA,IAAI,CAACd,IADZ;AAEE,IAAA,IAAI,EAAEc,IAFR;AAGE,IAAA,MAAM,EAAEL,eAHV;AAIE,IAAA,MAAM,EAAEJ,iBAJV;AAKE,IAAA,sBAAsB,EAAEtC,OAAF,aAAEA,OAAF,uBAAEA,OAAO,CAAEmC,sBALnC;AAME,IAAA,OAAO,EAAEnC,OAAF,aAAEA,OAAF,uBAAEA,OAAO,CAAEgD;AANpB,IADF,CAFJ,eAaE,6BAAC,QAAD;AAAM,IAAA,oBAAoB,MAA1B;AAA2B,IAAA,MAAM,EAAE;AAAnC,kBACE,6BAAC,QAAD;AAAM,IAAA,KAAK,EAAC,QAAZ;AAAqB,IAAA,OAAO,EAAC;AAA7B,kBACE;AACE,IAAA,GAAG,EAAEN,eADP;AAEE,IAAA,GAAG,EAAEvC,YAAY,CAACgB,GAFpB;AAGE,IAAA,KAAK,EAAEhB,YAAY,CAACf,KAHtB;AAIE,IAAA,MAAM,EAAEe,YAAY,CAACd,MAJvB;AAKE,IAAA,GAAG,EAAC,EALN;AAME,IAAA,KAAK,EAAEF,UANT;AAOE,IAAA,OAAO,EAAEiC;AAPX,IADF,CADF,CAbF,CADD,gBA6BC,6BAAC,iBAAD,QACKzB,IAAI,SAAJ,IAAAA,IAAI,WAAJ,qBAAAA,IAAI,CAAEK,OAAN,wDAAea,gBAAf,gBACG,4GAAiC,2CAAOlB,IAAP,aAAOA,IAAP,yCAAOA,IAAI,CAAEK,OAAb,mDAAO,eAAea,gBAAtB,CAAjC,CADH,gBAEG,sJAA2E,sEAA3E,CAHR,CA9BJ,eAqCE,6BAAC,kCAAD,eAAsBpB,KAAtB;AAA6B,IAAA,IAAI,EAAEQ,yBAAnC;AAA8D,IAAA,GAAG,EAAEP;AAAnE,KArCF,CADF;AAyCD,CA/GoB,CAArB;;eAiHe,+BAAaJ,YAAb,C","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 React from 'react'\nimport {Card, Flex, Stack, Text} from '@sanity/ui'\nimport {FormBuilderInput} from '@sanity/form-builder/lib/FormBuilderInput'\nimport {randomKey} from '@sanity/util/content'\nimport {PatchEvent, setIfMissing, set, insert} from '@sanity/form-builder/PatchEvent'\nimport imageUrlBuilder from '@sanity/image-url'\nimport {getImageDimensions} from '@sanity/asset-utils'\nimport get from 'lodash/get'\n\nimport Spot from './Spot'\nimport { useUnsetInputComponent } from './useUnsetInputComponent'\nimport Feedback from './Feedback'\n\nconst imageStyle = {width: `100%`, height: `auto`}\n\nconst HotspotArray = React.forwardRef((props, ref) => {\n const {type, value, onChange, document: sanityDocument} = 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\n // Finding the image from the document,\n // using the path from the hotspot's `options` field\n const displayImage = React.useMemo(() => {\n const builder = imageUrlBuilder(sanityClient).dataset(sanityClient.config().dataset)\n const urlFor = (source) => builder.image(source)\n const hotspotImage = get(sanityDocument, options?.hotspotImagePath)\n\n if (hotspotImage?.asset?._ref) {\n const {aspectRatio} = getImageDimensions(hotspotImage.asset._ref)\n const width = 600\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 }, [sanityDocument, type])\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 = {\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 = React.useCallback(\n (key, x, y) => {\n if (!Number(x) || !Number(y)) {\n console.warn(`Missing or non-number X or Y`, {x, y})\n return\n }\n\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(null)\n\n return (\n <Stack space={[2,2,3]}>\n {displayImage?.url ? (\n <div style={{position: `relative`}}>\n {value?.length > 0 &&\n value.map((spot) => (\n <Spot\n key={spot._key}\n spot={spot}\n bounds={hotspotImageRef}\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 ? <>No Hotspot image found at path <code>{type?.options?.hotspotImagePath}</code></> \n : <>Define a path in this field using to the image field in this document at <code>options.hotspotImagePath</code></>\n }\n </Feedback>\n )}\n <FormBuilderInput {...props} type={typeWithoutInputComponent} ref={ref} />\n </Stack>\n )\n})\n\nexport default withDocument(HotspotArray)\n"],"file":"HotspotArray.js"}
1
+ {"version":3,"file":"HotspotArray.js","names":["imageStyle","width","height","VALID_ROOT_PATHS","HotspotArray","React","forwardRef","props","ref","type","value","onChange","document","parent","options","typeWithoutInputComponent","useUnsetInputComponent","inputComponent","displayImage","useMemo","builder","imageUrlBuilder","sanityClient","dataset","config","urlFor","source","image","imageHotspotPathRoot","includes","hotspotImage","get","hotspotImagePath","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","console","warn","set","hotspotImageRef","useRef","position","length","map","spot","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 React from 'react'\nimport {Card, Flex, Stack, Text} from '@sanity/ui'\nimport {FormBuilderInput} from '@sanity/form-builder/lib/FormBuilderInput'\nimport {randomKey} from '@sanity/util/content'\nimport {PatchEvent, setIfMissing, set, insert} from '@sanity/form-builder/PatchEvent'\nimport imageUrlBuilder from '@sanity/image-url'\nimport {getImageDimensions} from '@sanity/asset-utils'\nimport get from 'lodash/get'\n\nimport Spot from './Spot'\nimport { useUnsetInputComponent } from './useUnsetInputComponent'\nimport Feedback from './Feedback'\n\nconst imageStyle = {width: `100%`, height: `auto`}\n\nconst VALID_ROOT_PATHS = ['document', 'parent']\n\nconst HotspotArray = React.forwardRef((props, ref) => {\n const {type, value, onChange, document, parent} = 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\n // Finding the image from the imageHotspotPathRoot (defaults to document),\n // using the path from the hotspot's `options` field\n const displayImage = React.useMemo(() => {\n const builder = imageUrlBuilder(sanityClient).dataset(sanityClient.config().dataset)\n const urlFor = (source) => builder.image(source)\n\n const imageHotspotPathRoot = VALID_ROOT_PATHS.includes(options?.imageHotspotPathRoot) ? props[options.imageHotspotPathRoot] : document\n const hotspotImage = get(imageHotspotPathRoot, options?.hotspotImagePath)\n\n if (hotspotImage?.asset?._ref) {\n const {aspectRatio} = getImageDimensions(hotspotImage.asset._ref)\n const width = 600\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 }, [type, document])\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 = {\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 = React.useCallback(\n (key, x, y) => {\n if (!Number(x) || !Number(y)) {\n console.warn(`Missing or non-number X or Y`, {x, y})\n return\n }\n\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(null)\n\n return (\n <Stack space={[2,2,3]}>\n {displayImage?.url ? (\n <div style={{position: `relative`}}>\n {value?.length > 0 &&\n value.map((spot) => (\n <Spot\n key={spot._key}\n spot={spot}\n bounds={hotspotImageRef}\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 ? <>No Hotspot image found at path <code>{type?.options?.hotspotImagePath}</code></>\n : <>Define a path in this field using to the image field in this document at <code>options.hotspotImagePath</code></>\n }\n </Feedback>\n )}\n {type?.options?.imageHotspotPathRoot && !VALID_ROOT_PATHS.includes(type.options.imageHotspotPathRoot) &&\n <Feedback>\n The supplied imageHotspotPathRoot \"{type.options.imageHotspotPathRoot}\" is not valid, falling back to \"document\". Available values are \"{VALID_ROOT_PATHS.join(', ')}\".\n </Feedback>}\n <FormBuilderInput {...props} type={typeWithoutInputComponent} ref={ref} />\n </Stack>\n )\n})\n\nexport default withDocument(HotspotArray)\n"],"mappings":"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"}
package/lib/Spot.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Spot.tsx"],"names":["dragStyle","width","height","position","dotStyle","borderRadius","pointerEvents","round","num","Math","Spot","spot","bounds","undefined","update","hotspotDescriptionPath","tooltip","React","useState","x","y","setXY","current","getBoundingClientRect","rect","setRect","isDragging","setIsDragging","useEffect","clientRect","handleDragEnd","useCallback","event","srcElement","style","transform","split","map","v","match","pop","replace","currentX","currentY","Number","console","warn","newX","newY","safeX","max","min","safeY","_key","createElement","maxWidth"],"mappings":"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","sourcesContent":["import React from 'react'\nimport {Box, Card, Text, Tooltip} from '@sanity/ui'\nimport {motion} from 'framer-motion'\nimport get from 'lodash/get'\n\nconst dragStyle = {\n width: `1rem`,\n height: `1rem`,\n position: `absolute`,\n}\n\nconst dotStyle = {\n ...dragStyle,\n borderRadius: `50%`,\n // make sure pointer events only run on the parent\n pointerEvents: `none`,\n}\n\nconst round = (num) => Math.round(num * 100) / 100\n\nexport default function Spot({spot, bounds = undefined, update, hotspotDescriptionPath = ``, tooltip}) {\n // x/y are stored as % but need to be displayed as px\n const [{x, y}, setXY] = React.useState({x: 0, y: 0})\n const [rect, setRect] = React.useState(bounds?.current ? bounds.current.getBoundingClientRect() : {width: 0, height:0})\n const [isDragging, setIsDragging] = React.useState(false)\n\n React.useEffect(() => {\n const clientRect = bounds?.current?.getBoundingClientRect()\n\n if (clientRect) {\n // So convert % to px once we know the height/width of the image\n setXY({\n x: round(clientRect.width * (spot.x / 100)),\n y: round(clientRect.height * (spot.y / 100)),\n })\n\n if (!rect.width || !rect.height) {\n setRect(clientRect)\n }\n }\n }, [bounds, bounds.current])\n\n const handleDragEnd = React.useCallback(\n (event) => {\n setIsDragging(false)\n\n // I don't know why, but framer-motion doesn't give you the actual transform values\n // So we have to regex the `px` values off the inline styles\n const [currentX, currentY] = event.srcElement.style.transform.split(` `).map((v) => {\n return v\n ? v\n .match(/\\(([^)]+)\\)/)\n .pop()\n .replace(`px`, ``)\n : null\n })\n\n if (!Number(currentX) || !Number(currentY)) {\n return console.warn(`Missing or non-number X or Y`, {currentX, currentY}, event.srcElement)\n }\n\n if (!rect.width || !rect.height) {\n return console.warn(`Rect width/height not yet set`, {rect}, bounds?.current)\n }\n\n // Which we need to convert back to `%` to patch the document\n const newX = round((currentX * 100) / rect.width)\n const newY = round((currentY * 100) / rect.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 },\n\n [spot]\n )\n\n if (!x || !y) {\n return null\n }\n\n return (\n <Tooltip\n key={spot._key}\n disabled={isDragging}\n boundaryElement={bounds.current}\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\">{hotspotDescriptionPath ? get(spot, hotspotDescriptionPath) : `${spot.x}% x ${spot.y}%`}</Text>\n </Box>\n )\n }\n >\n <motion.div\n drag\n dragConstraints={bounds}\n dragMomentum={false}\n initial={{x, y}}\n onDragEnd={handleDragEnd}\n onDragStart={() => setIsDragging(true)}\n style={dragStyle}\n >\n <Card tone=\"primary\" shadow={3} style={dotStyle} />\n </motion.div>\n </Tooltip>\n )\n}"],"file":"Spot.js"}
1
+ {"version":3,"file":"Spot.js","names":["dragStyle","width","height","position","dotStyle","borderRadius","pointerEvents","round","num","Math","Spot","spot","bounds","undefined","update","hotspotDescriptionPath","tooltip","React","useState","x","y","setXY","current","getBoundingClientRect","rect","setRect","isDragging","setIsDragging","useEffect","clientRect","handleDragEnd","useCallback","event","srcElement","style","transform","split","map","v","match","pop","replace","currentX","currentY","Number","console","warn","newX","newY","safeX","max","min","safeY","_key","createElement","maxWidth","get"],"sources":["../src/Spot.tsx"],"sourcesContent":["import React from 'react'\nimport {Box, Card, Text, Tooltip} from '@sanity/ui'\nimport {motion} from 'framer-motion'\nimport get from 'lodash/get'\n\nconst dragStyle = {\n width: `1rem`,\n height: `1rem`,\n position: `absolute`,\n}\n\nconst dotStyle = {\n ...dragStyle,\n borderRadius: `50%`,\n // make sure pointer events only run on the parent\n pointerEvents: `none`,\n}\n\nconst round = (num) => Math.round(num * 100) / 100\n\nexport default function Spot({spot, bounds = undefined, update, hotspotDescriptionPath = ``, tooltip}) {\n // x/y are stored as % but need to be displayed as px\n const [{x, y}, setXY] = React.useState({x: 0, y: 0})\n const [rect, setRect] = React.useState(bounds?.current ? bounds.current.getBoundingClientRect() : {width: 0, height:0})\n const [isDragging, setIsDragging] = React.useState(false)\n\n React.useEffect(() => {\n const clientRect = bounds?.current?.getBoundingClientRect()\n\n if (clientRect) {\n // So convert % to px once we know the height/width of the image\n setXY({\n x: round(clientRect.width * (spot.x / 100)),\n y: round(clientRect.height * (spot.y / 100)),\n })\n\n if (!rect.width || !rect.height) {\n setRect(clientRect)\n }\n }\n }, [bounds, bounds.current])\n\n const handleDragEnd = React.useCallback(\n (event) => {\n setIsDragging(false)\n\n // I don't know why, but framer-motion doesn't give you the actual transform values\n // So we have to regex the `px` values off the inline styles\n const [currentX, currentY] = event.srcElement.style.transform.split(` `).map((v) => {\n return v\n ? v\n .match(/\\(([^)]+)\\)/)\n .pop()\n .replace(`px`, ``)\n : null\n })\n\n if (!Number(currentX) || !Number(currentY)) {\n return console.warn(`Missing or non-number X or Y`, {currentX, currentY}, event.srcElement)\n }\n\n if (!rect.width || !rect.height) {\n return console.warn(`Rect width/height not yet set`, {rect}, bounds?.current)\n }\n\n // Which we need to convert back to `%` to patch the document\n const newX = round((currentX * 100) / rect.width)\n const newY = round((currentY * 100) / rect.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 },\n\n [spot]\n )\n\n if (!x || !y) {\n return null\n }\n\n return (\n <Tooltip\n key={spot._key}\n disabled={isDragging}\n boundaryElement={bounds.current}\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\">{hotspotDescriptionPath ? get(spot, hotspotDescriptionPath) : `${spot.x}% x ${spot.y}%`}</Text>\n </Box>\n )\n }\n >\n <motion.div\n drag\n dragConstraints={bounds}\n dragMomentum={false}\n initial={{x, y}}\n onDragEnd={handleDragEnd}\n onDragStart={() => setIsDragging(true)}\n style={dragStyle}\n >\n <Card tone=\"primary\" shadow={3} style={dotStyle} />\n </motion.div>\n </Tooltip>\n )\n}"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/useUnsetInputComponent.ts"],"names":["useUnsetInputComponent","type","component","React","useMemo","unsetInputComponent","t","inputComponent","undefined","typeOfType"],"mappings":";;;;;;;AAAA;;;;;;;;;;AAEO,SAASA,sBAAT,CAAgCC,IAAhC,EAAsCC,SAAtC,EAAiD;AACpD,SAAOC,eAAMC,OAAN,CAAc,MAAMC,mBAAmB,CAACJ,IAAD,EAAOC,SAAP,CAAvC,EAA0D,CAACD,IAAD,EAAOC,SAAP,CAA1D,CAAP;AACD;;AAED,SAASG,mBAAT,CAA6BJ,IAA7B,EAAmCC,SAAnC,EAA8C;AAC5C,MAAMI,CAAC,mCACFL,IADE;AAELM,IAAAA,cAAc,EAAEN,IAAI,CAACM,cAAL,KAAwBL,SAAxB,GAAoCM,SAApC,GAAgDP,IAAI,CAACM;AAFhE,IAAP;;AAIA,MAAME,UAAU,GAAGH,CAAC,CAACL,IAAF,GAASI,mBAAmB,CAACC,CAAC,CAACL,IAAH,EAASC,SAAT,CAA5B,GAAkDM,SAArE;AACA,yCACKF,CADL;AAEEL,IAAAA,IAAI,EAAEQ;AAFR;AAID","sourcesContent":["import React from 'react'\n\nexport function useUnsetInputComponent(type, component) {\n return React.useMemo(() => unsetInputComponent(type, component), [type, component])\n }\n \n function 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 }"],"file":"useUnsetInputComponent.js"}
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 \n function 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 }"],"mappings":";;;;;;;AAAA;;;;;;;;;;AAEO,SAASA,sBAAT,CAAgCC,IAAhC,EAAsCC,SAAtC,EAAiD;EACpD,OAAOC,cAAA,CAAMC,OAAN,CAAc,MAAMC,mBAAmB,CAACJ,IAAD,EAAOC,SAAP,CAAvC,EAA0D,CAACD,IAAD,EAAOC,SAAP,CAA1D,CAAP;AACD;;AAED,SAASG,mBAAT,CAA6BJ,IAA7B,EAAmCC,SAAnC,EAA8C;EAC5C,IAAMI,CAAC,mCACFL,IADE;IAELM,cAAc,EAAEN,IAAI,CAACM,cAAL,KAAwBL,SAAxB,GAAoCM,SAApC,GAAgDP,IAAI,CAACM;EAFhE,EAAP;;EAIA,IAAME,UAAU,GAAGH,CAAC,CAACL,IAAF,GAASI,mBAAmB,CAACC,CAAC,CAACL,IAAH,EAASC,SAAT,CAA5B,GAAkDM,SAArE;EACA,uCACKF,CADL;IAEEL,IAAI,EAAEQ;EAFR;AAID"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanity-plugin-hotspot-array",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
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": {
@@ -20,20 +20,24 @@ import Feedback from './Feedback'
20
20
 
21
21
  const imageStyle = {width: `100%`, height: `auto`}
22
22
 
23
+ const VALID_ROOT_PATHS = ['document', 'parent']
24
+
23
25
  const HotspotArray = React.forwardRef((props, ref) => {
24
- const {type, value, onChange, document: sanityDocument} = props
26
+ const {type, value, onChange, document, parent} = props
25
27
  const {options} = type ?? {}
26
28
 
27
29
  // Attempt prevention of infinite loop in <FormBuilderInput />
28
30
  // Re-renders can still occur if this Component is used again in a nested field
29
31
  const typeWithoutInputComponent = useUnsetInputComponent(type, type?.inputComponent)
30
32
 
31
- // Finding the image from the document,
33
+ // Finding the image from the imageHotspotPathRoot (defaults to document),
32
34
  // using the path from the hotspot's `options` field
33
35
  const displayImage = React.useMemo(() => {
34
36
  const builder = imageUrlBuilder(sanityClient).dataset(sanityClient.config().dataset)
35
37
  const urlFor = (source) => builder.image(source)
36
- const hotspotImage = get(sanityDocument, options?.hotspotImagePath)
38
+
39
+ const imageHotspotPathRoot = VALID_ROOT_PATHS.includes(options?.imageHotspotPathRoot) ? props[options.imageHotspotPathRoot] : document
40
+ const hotspotImage = get(imageHotspotPathRoot, options?.hotspotImagePath)
37
41
 
38
42
  if (hotspotImage?.asset?._ref) {
39
43
  const {aspectRatio} = getImageDimensions(hotspotImage.asset._ref)
@@ -45,7 +49,7 @@ const HotspotArray = React.forwardRef((props, ref) => {
45
49
  }
46
50
 
47
51
  return null
48
- }, [sanityDocument, type])
52
+ }, [type, document])
49
53
 
50
54
  const handleHotspotImageClick = React.useCallback((event) => {
51
55
  const {nativeEvent} = event
@@ -122,12 +126,16 @@ const HotspotArray = React.forwardRef((props, ref) => {
122
126
  </div>
123
127
  ) : (
124
128
  <Feedback>
125
- {type?.options?.hotspotImagePath
126
- ? <>No Hotspot image found at path <code>{type?.options?.hotspotImagePath}</code></>
129
+ {type?.options?.hotspotImagePath
130
+ ? <>No Hotspot image found at path <code>{type?.options?.hotspotImagePath}</code></>
127
131
  : <>Define a path in this field using to the image field in this document at <code>options.hotspotImagePath</code></>
128
132
  }
129
133
  </Feedback>
130
134
  )}
135
+ {type?.options?.imageHotspotPathRoot && !VALID_ROOT_PATHS.includes(type.options.imageHotspotPathRoot) &&
136
+ <Feedback>
137
+ The supplied imageHotspotPathRoot "{type.options.imageHotspotPathRoot}" is not valid, falling back to "document". Available values are "{VALID_ROOT_PATHS.join(', ')}".
138
+ </Feedback>}
131
139
  <FormBuilderInput {...props} type={typeWithoutInputComponent} ref={ref} />
132
140
  </Stack>
133
141
  )