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 +24 -7
- package/lib/Spot.js +11 -2
- package/lib/Spot.js.map +1 -1
- package/package.json +1 -1
- package/src/Spot.tsx +9 -3
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.
|
|
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
|
-
|
|
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
|
-
|
|
126
|
-
|
|
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
|
-
|
|
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","
|
|
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
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:
|
|
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
|
-
|
|
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))
|