sanity-plugin-hotspot-array 0.0.2 → 0.0.3

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/README.md CHANGED
@@ -115,18 +115,35 @@ Here's an example object schema complete with initial values, validation, fields
115
115
 
116
116
  ## Custom tooltip
117
117
 
118
- You can customise the Tooltip to display any Component, it will accept a single prop `spot` which contains the values of the object. Example:
118
+ You can customise the Tooltip to display any Component, it will accept a single prop `spot` which contains the values of the object.
119
119
 
120
- ```js
121
- import HotspotArray from 'sanity-plugin-hotspot-array'
122
- import ProductPreview from '../../components/ProductPreview'
120
+ In this example our `spot` object has a `reference` field to the `product` schema type, and will show a Document Preview.
123
121
 
122
+ ```js
124
123
  // Setup a custom tooltip component
125
- function ProductPreview({spot}) {
126
- return <div>{JSON.stringify(spot)}</div>
124
+ import Preview from 'part:@sanity/base/preview'
125
+ import schema from 'part:@sanity/base/schema'
126
+ import {Box} from '@sanity/ui'
127
+
128
+ export default function ProductPreview({spot}) {
129
+ return (
130
+ <Box padding={2} style={{minWidth: 200}}>
131
+ {spot?.product?._ref ? (
132
+ <Preview value={{_id: spot.product._ref}} type={schema.get(`product`)} />
133
+ ) : (
134
+ `No Reference Selected`
135
+ )}
136
+ </Box>
137
+ )
127
138
  }
139
+ ```
140
+
141
+ Then back in your schema definition
142
+
143
+ ```js
144
+ import HotspotArray from 'sanity-plugin-hotspot-array'
145
+ import ProductPreview from '../../components/ProductPreview'
128
146
 
129
- // ...then add to your schema definition
130
147
  options: {
131
148
  hotspotImagePath: `hotspotImage`,
132
149
  hotspotTooltip: ProductPreview,
package/lib/Spot.js CHANGED
@@ -67,7 +67,7 @@ function Spot(_ref) {
67
67
  y = _React$useState2$.y,
68
68
  setXY = _React$useState2[1];
69
69
 
70
- var _React$useState3 = _react.default.useState({
70
+ var _React$useState3 = _react.default.useState(bounds !== null && bounds !== void 0 && bounds.current ? bounds.current.getBoundingClientRect() : {
71
71
  width: 0,
72
72
  height: 0
73
73
  }),
@@ -91,7 +91,10 @@ function Spot(_ref) {
91
91
  x: round(clientRect.width * (spot.x / 100)),
92
92
  y: round(clientRect.height * (spot.y / 100))
93
93
  });
94
- setRect(clientRect);
94
+
95
+ if (!rect.width || !rect.height) {
96
+ setRect(clientRect);
97
+ }
95
98
  }
96
99
  }, [bounds, bounds.current]);
97
100
 
@@ -111,6 +114,12 @@ function Spot(_ref) {
111
114
  currentX,
112
115
  currentY
113
116
  }, event.srcElement);
117
+ }
118
+
119
+ if (!rect.width || !rect.height) {
120
+ return console.warn("Rect width/height not yet set", {
121
+ rect
122
+ }, bounds === null || bounds === void 0 ? void 0 : bounds.current);
114
123
  } // Which we need to convert back to `%` to patch the document
115
124
 
116
125
 
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","rect","setRect","isDragging","setIsDragging","useEffect","clientRect","current","getBoundingClientRect","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({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 setRect(clientRect)\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 // 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,"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanity-plugin-hotspot-array",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
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": {
package/src/Spot.tsx CHANGED
@@ -21,7 +21,7 @@ const round = (num) => Math.round(num * 100) / 100
21
21
  export default function Spot({spot, bounds = undefined, update, hotspotDescriptionPath = ``, tooltip}) {
22
22
  // x/y are stored as % but need to be displayed as px
23
23
  const [{x, y}, setXY] = React.useState({x: 0, y: 0})
24
- const [rect, setRect] = React.useState({width: 0, height: 0})
24
+ const [rect, setRect] = React.useState(bounds?.current ? bounds.current.getBoundingClientRect() : {width: 0, height:0})
25
25
  const [isDragging, setIsDragging] = React.useState(false)
26
26
 
27
27
  React.useEffect(() => {
@@ -34,7 +34,9 @@ export default function Spot({spot, bounds = undefined, update, hotspotDescripti
34
34
  y: round(clientRect.height * (spot.y / 100)),
35
35
  })
36
36
 
37
- setRect(clientRect)
37
+ if (!rect.width || !rect.height) {
38
+ setRect(clientRect)
39
+ }
38
40
  }
39
41
  }, [bounds, bounds.current])
40
42
 
@@ -57,10 +59,14 @@ export default function Spot({spot, bounds = undefined, update, hotspotDescripti
57
59
  return console.warn(`Missing or non-number X or Y`, {currentX, currentY}, event.srcElement)
58
60
  }
59
61
 
62
+ if (!rect.width || !rect.height) {
63
+ return console.warn(`Rect width/height not yet set`, {rect}, bounds?.current)
64
+ }
65
+
60
66
  // Which we need to convert back to `%` to patch the document
61
67
  const newX = round((currentX * 100) / rect.width)
62
68
  const newY = round((currentY * 100) / rect.height)
63
-
69
+
64
70
  // Don't go below 0 or above 100
65
71
  const safeX = Math.max(0, Math.min(100, newX))
66
72
  const safeY = Math.max(0, Math.min(100, newY))