react-datocms 7.2.7 → 7.2.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/dist/cjs/ContentLink/index.js +2 -1
- package/dist/cjs/ContentLink/index.js.map +1 -1
- package/dist/cjs/VideoPlayer/index.js +4 -1
- package/dist/cjs/VideoPlayer/index.js.map +1 -1
- package/dist/cjs/useContentLink/index.js +10 -1
- package/dist/cjs/useContentLink/index.js.map +1 -1
- package/dist/esm/ContentLink/index.js +2 -1
- package/dist/esm/ContentLink/index.js.map +1 -1
- package/dist/esm/VideoPlayer/index.js +4 -1
- package/dist/esm/VideoPlayer/index.js.map +1 -1
- package/dist/esm/useContentLink/index.js +10 -1
- package/dist/esm/useContentLink/index.js.map +1 -1
- package/dist/types/ContentLink/index.d.ts +17 -5
- package/dist/types/useContentLink/index.d.ts +24 -3
- package/package.json +1 -1
- package/src/ContentLink/index.tsx +21 -3
- package/src/VideoPlayer/index.tsx +5 -1
- package/src/useContentLink/index.ts +44 -8
|
@@ -90,7 +90,8 @@ function ContentLink(props) {
|
|
|
90
90
|
}, [currentPath, setCurrentPath]);
|
|
91
91
|
// Enable click-to-edit on mount if requested
|
|
92
92
|
(0, react_1.useEffect)(() => {
|
|
93
|
-
if (enableClickToEditOptions !== undefined
|
|
93
|
+
if (enableClickToEditOptions !== undefined &&
|
|
94
|
+
enableClickToEditOptions !== false) {
|
|
94
95
|
enableClickToEdit(enableClickToEditOptions === true
|
|
95
96
|
? undefined
|
|
96
97
|
: enableClickToEditOptions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ContentLink/index.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ContentLink/index.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;AAgGb,kCAmCC;AAjID,iCAAkC;AAClC,yDAIoC;AAyBpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AACH,SAAgB,WAAW,CAAC,KAAuB;IACjD,MAAM,EACJ,WAAW,EACX,iBAAiB,EAAE,wBAAwB,EAC3C,UAAU,KAER,KAAK,EADJ,qBAAqB,UACtB,KAAK,EALH,kDAKL,CAAQ,CAAC;IAEV,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,GAAG,IAAA,yBAAc,kCACvD,qBAAqB,KACxB,OAAO,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,IACzD,CAAC;IAEH,oCAAoC;IACpC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,cAAc,CAAC,WAAW,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;IAElC,6CAA6C;IAC7C,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IACE,wBAAwB,KAAK,SAAS;YACtC,wBAAwB,KAAK,KAAK,EAClC,CAAC;YACD,iBAAiB,CACf,wBAAwB,KAAK,IAAI;gBAC/B,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,wBAAwB,CAC7B,CAAC;QACJ,CAAC;IACH,CAAC,EAAE,CAAC,wBAAwB,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAElD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -65,6 +65,7 @@ const lazy_1 = __importDefault(require("@mux/mux-player-react/lazy"));
|
|
|
65
65
|
// The core of this component is the `useVideoPlayer` hook: it takes
|
|
66
66
|
// data from DatoCMS GraphQL API and returns props as expected by the
|
|
67
67
|
// `<MuxPlayer />` component.
|
|
68
|
+
const content_link_1 = require("@datocms/content-link");
|
|
68
69
|
const index_js_1 = require("../useVideoPlayer/index.js");
|
|
69
70
|
exports.VideoPlayer = (0, react_1.forwardRef)((props, ref) => {
|
|
70
71
|
const { data = {}, disableCookies = true, disableTracking = true, preload = 'metadata', style: styleFromProps } = props, rest = __rest(props, ["data", "disableCookies", "disableTracking", "preload", "style"]);
|
|
@@ -75,6 +76,8 @@ exports.VideoPlayer = (0, react_1.forwardRef)((props, ref) => {
|
|
|
75
76
|
// Extract alt for DatoCMS Content Link integration
|
|
76
77
|
// See: https://github.com/datocms/content-link
|
|
77
78
|
const { alt } = data;
|
|
79
|
+
// Only include data-datocms-content-link-source if alt contains stega encoding
|
|
80
|
+
const contentLinkSource = alt && (0, content_link_1.decodeStega)(alt) ? alt : undefined;
|
|
78
81
|
// Note: Custom data-* attributes can be passed to the underlying <mux-player> web component
|
|
79
82
|
// in two ways:
|
|
80
83
|
//
|
|
@@ -90,6 +93,6 @@ exports.VideoPlayer = (0, react_1.forwardRef)((props, ref) => {
|
|
|
90
93
|
// web component attribute conventions. Any props not explicitly handled by VideoPlayer
|
|
91
94
|
// are spread via {...rest} and forwarded to MuxPlayer, which then applies them to
|
|
92
95
|
// the underlying <mux-player> element.
|
|
93
|
-
return (react_1.default.createElement(lazy_1.default, Object.assign({ ref: ref, streamType: "on-demand", preload: preload, title: title, disableCookies: disableCookies, disableTracking: disableTracking, playbackId: playbackId, style: style, placeholder: placeholder, "data-datocms-content-link-source":
|
|
96
|
+
return (react_1.default.createElement(lazy_1.default, Object.assign({ ref: ref, streamType: "on-demand", preload: preload, title: title, disableCookies: disableCookies, disableTracking: disableTracking, playbackId: playbackId, style: style, placeholder: placeholder, "data-datocms-content-link-source": contentLinkSource }, rest)));
|
|
94
97
|
});
|
|
95
98
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/VideoPlayer/index.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEb,gFAAgF;AAChF,8EAA8E;AAC9E,2EAA2E;AAC3E,EAAE;AACF,qEAAqE;AACrE,EAAE;AACF,kCAAkC;AAElC,+CAA0C;AAO1C,gFAAgF;AAChF,+EAA+E;AAC/E,mEAAmE;AACnE,kBAAkB;AAElB,sEAAmD;AAEnD,oEAAoE;AACpE,qEAAqE;AACrE,6BAA6B;AAE7B,yDAA4D;AAuC/C,QAAA,WAAW,GAEY,IAAA,kBAAU,EAG5C,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACf,MAAM,EACJ,IAAI,GAAG,EAAE,EACT,cAAc,GAAG,IAAI,EACrB,eAAe,GAAG,IAAI,EACtB,OAAO,GAAG,UAAU,EACpB,KAAK,EAAE,cAAc,KAEnB,KAAK,EADJ,IAAI,UACL,KAAK,EAPH,iEAOL,CAAQ,CAAC;IAEV,MAAM,EACJ,KAAK,EACL,UAAU,EACV,KAAK,EAAE,aAAa,EACpB,WAAW,GACZ,GAAG,IAAA,yBAAc,EAAC;QACjB,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,KAAK,mCACN,aAAa,GACb,cAAc,CAClB,CAAC;IAEF,mDAAmD;IACnD,+CAA+C;IAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAErB,4FAA4F;IAC5F,eAAe;IACf,EAAE;IACF,wCAAwC;IACxC,gDAAgD;IAChD,EAAE;IACF,8CAA8C;IAC9C,8CAA8C;IAC9C,EAAE;IACF,0DAA0D;IAC1D,EAAE;IACF,kFAAkF;IAClF,uFAAuF;IACvF,kFAAkF;IAClF,uCAAuC;IAEvC,OAAO,CACL,8BAAC,cAAS,kBACR,GAAG,EAAE,GAAG,EACR,UAAU,EAAC,WAAW,EACtB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,cAAc,EAC9B,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,sCACU,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/VideoPlayer/index.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEb,gFAAgF;AAChF,8EAA8E;AAC9E,2EAA2E;AAC3E,EAAE;AACF,qEAAqE;AACrE,EAAE;AACF,kCAAkC;AAElC,+CAA0C;AAO1C,gFAAgF;AAChF,+EAA+E;AAC/E,mEAAmE;AACnE,kBAAkB;AAElB,sEAAmD;AAEnD,oEAAoE;AACpE,qEAAqE;AACrE,6BAA6B;AAE7B,wDAAoD;AACpD,yDAA4D;AAuC/C,QAAA,WAAW,GAEY,IAAA,kBAAU,EAG5C,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACf,MAAM,EACJ,IAAI,GAAG,EAAE,EACT,cAAc,GAAG,IAAI,EACrB,eAAe,GAAG,IAAI,EACtB,OAAO,GAAG,UAAU,EACpB,KAAK,EAAE,cAAc,KAEnB,KAAK,EADJ,IAAI,UACL,KAAK,EAPH,iEAOL,CAAQ,CAAC;IAEV,MAAM,EACJ,KAAK,EACL,UAAU,EACV,KAAK,EAAE,aAAa,EACpB,WAAW,GACZ,GAAG,IAAA,yBAAc,EAAC;QACjB,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,KAAK,mCACN,aAAa,GACb,cAAc,CAClB,CAAC;IAEF,mDAAmD;IACnD,+CAA+C;IAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAErB,+EAA+E;IAC/E,MAAM,iBAAiB,GAAG,GAAG,IAAI,IAAA,0BAAW,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpE,4FAA4F;IAC5F,eAAe;IACf,EAAE;IACF,wCAAwC;IACxC,gDAAgD;IAChD,EAAE;IACF,8CAA8C;IAC9C,8CAA8C;IAC9C,EAAE;IACF,0DAA0D;IAC1D,EAAE;IACF,kFAAkF;IAClF,uFAAuF;IACvF,kFAAkF;IAClF,uCAAuC;IAEvC,OAAO,CACL,8BAAC,cAAS,kBACR,GAAG,EAAE,GAAG,EACR,UAAU,EAAC,WAAW,EACtB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,cAAc,EAC9B,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,sCACU,iBAAiB,IAC/C,IAAI,EACR,CACH,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -72,7 +72,16 @@ function useContentLink(options = {}) {
|
|
|
72
72
|
// Stable method references that call through to the controller
|
|
73
73
|
const enableClickToEdit = (0, react_1.useCallback)((opts) => {
|
|
74
74
|
var _a;
|
|
75
|
-
|
|
75
|
+
// If hoverOnly is true, check if the device supports hover
|
|
76
|
+
if (opts === null || opts === void 0 ? void 0 : opts.hoverOnly) {
|
|
77
|
+
const supportsHover = typeof window !== 'undefined' &&
|
|
78
|
+
window.matchMedia('(hover: hover)').matches;
|
|
79
|
+
if (!supportsHover) {
|
|
80
|
+
// Don't enable click-to-edit on touch-only devices
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
(_a = controllerRef.current) === null || _a === void 0 ? void 0 : _a.enableClickToEdit((opts === null || opts === void 0 ? void 0 : opts.scrollToNearestTarget) ? { scrollToNearestTarget: true } : undefined);
|
|
76
85
|
}, []);
|
|
77
86
|
const disableClickToEdit = (0, react_1.useCallback)(() => {
|
|
78
87
|
var _a;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/useContentLink/index.ts"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/useContentLink/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -87,7 +87,8 @@ export function ContentLink(props) {
|
|
|
87
87
|
}, [currentPath, setCurrentPath]);
|
|
88
88
|
// Enable click-to-edit on mount if requested
|
|
89
89
|
useEffect(() => {
|
|
90
|
-
if (enableClickToEditOptions !== undefined
|
|
90
|
+
if (enableClickToEditOptions !== undefined &&
|
|
91
|
+
enableClickToEditOptions !== false) {
|
|
91
92
|
enableClickToEdit(enableClickToEditOptions === true
|
|
92
93
|
? undefined
|
|
93
94
|
: enableClickToEditOptions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ContentLink/index.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ContentLink/index.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAGL,cAAc,GACf,MAAM,4BAA4B,CAAC;AAyBpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,EACJ,WAAW,EACX,iBAAiB,EAAE,wBAAwB,EAC3C,UAAU,KAER,KAAK,EADJ,qBAAqB,UACtB,KAAK,EALH,kDAKL,CAAQ,CAAC;IAEV,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,GAAG,cAAc,iCACvD,qBAAqB,KACxB,OAAO,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,IACzD,CAAC;IAEH,oCAAoC;IACpC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,cAAc,CAAC,WAAW,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;IAElC,6CAA6C;IAC7C,SAAS,CAAC,GAAG,EAAE;QACb,IACE,wBAAwB,KAAK,SAAS;YACtC,wBAAwB,KAAK,KAAK,EAClC,CAAC;YACD,iBAAiB,CACf,wBAAwB,KAAK,IAAI;gBAC/B,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,wBAAwB,CAC7B,CAAC;QACJ,CAAC;IACH,CAAC,EAAE,CAAC,wBAAwB,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAElD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -26,6 +26,7 @@ import MuxPlayer from '@mux/mux-player-react/lazy';
|
|
|
26
26
|
// The core of this component is the `useVideoPlayer` hook: it takes
|
|
27
27
|
// data from DatoCMS GraphQL API and returns props as expected by the
|
|
28
28
|
// `<MuxPlayer />` component.
|
|
29
|
+
import { decodeStega } from '@datocms/content-link';
|
|
29
30
|
import { useVideoPlayer } from '../useVideoPlayer/index.js';
|
|
30
31
|
export const VideoPlayer = forwardRef((props, ref) => {
|
|
31
32
|
const { data = {}, disableCookies = true, disableTracking = true, preload = 'metadata', style: styleFromProps } = props, rest = __rest(props, ["data", "disableCookies", "disableTracking", "preload", "style"]);
|
|
@@ -36,6 +37,8 @@ export const VideoPlayer = forwardRef((props, ref) => {
|
|
|
36
37
|
// Extract alt for DatoCMS Content Link integration
|
|
37
38
|
// See: https://github.com/datocms/content-link
|
|
38
39
|
const { alt } = data;
|
|
40
|
+
// Only include data-datocms-content-link-source if alt contains stega encoding
|
|
41
|
+
const contentLinkSource = alt && decodeStega(alt) ? alt : undefined;
|
|
39
42
|
// Note: Custom data-* attributes can be passed to the underlying <mux-player> web component
|
|
40
43
|
// in two ways:
|
|
41
44
|
//
|
|
@@ -51,6 +54,6 @@ export const VideoPlayer = forwardRef((props, ref) => {
|
|
|
51
54
|
// web component attribute conventions. Any props not explicitly handled by VideoPlayer
|
|
52
55
|
// are spread via {...rest} and forwarded to MuxPlayer, which then applies them to
|
|
53
56
|
// the underlying <mux-player> element.
|
|
54
|
-
return (React.createElement(MuxPlayer, Object.assign({ ref: ref, streamType: "on-demand", preload: preload, title: title, disableCookies: disableCookies, disableTracking: disableTracking, playbackId: playbackId, style: style, placeholder: placeholder, "data-datocms-content-link-source":
|
|
57
|
+
return (React.createElement(MuxPlayer, Object.assign({ ref: ref, streamType: "on-demand", preload: preload, title: title, disableCookies: disableCookies, disableTracking: disableTracking, playbackId: playbackId, style: style, placeholder: placeholder, "data-datocms-content-link-source": contentLinkSource }, rest)));
|
|
55
58
|
});
|
|
56
59
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/VideoPlayer/index.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;AAEb,gFAAgF;AAChF,8EAA8E;AAC9E,2EAA2E;AAC3E,EAAE;AACF,qEAAqE;AACrE,EAAE;AACF,kCAAkC;AAElC,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAO1C,gFAAgF;AAChF,+EAA+E;AAC/E,mEAAmE;AACnE,kBAAkB;AAElB,OAAO,SAAS,MAAM,4BAA4B,CAAC;AAEnD,oEAAoE;AACpE,qEAAqE;AACrE,6BAA6B;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAuC5D,MAAM,CAAC,MAAM,WAAW,GAEY,UAAU,CAG5C,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACf,MAAM,EACJ,IAAI,GAAG,EAAE,EACT,cAAc,GAAG,IAAI,EACrB,eAAe,GAAG,IAAI,EACtB,OAAO,GAAG,UAAU,EACpB,KAAK,EAAE,cAAc,KAEnB,KAAK,EADJ,IAAI,UACL,KAAK,EAPH,iEAOL,CAAQ,CAAC;IAEV,MAAM,EACJ,KAAK,EACL,UAAU,EACV,KAAK,EAAE,aAAa,EACpB,WAAW,GACZ,GAAG,cAAc,CAAC;QACjB,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,KAAK,mCACN,aAAa,GACb,cAAc,CAClB,CAAC;IAEF,mDAAmD;IACnD,+CAA+C;IAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAErB,4FAA4F;IAC5F,eAAe;IACf,EAAE;IACF,wCAAwC;IACxC,gDAAgD;IAChD,EAAE;IACF,8CAA8C;IAC9C,8CAA8C;IAC9C,EAAE;IACF,0DAA0D;IAC1D,EAAE;IACF,kFAAkF;IAClF,uFAAuF;IACvF,kFAAkF;IAClF,uCAAuC;IAEvC,OAAO,CACL,oBAAC,SAAS,kBACR,GAAG,EAAE,GAAG,EACR,UAAU,EAAC,WAAW,EACtB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,cAAc,EAC9B,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,sCACU,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/VideoPlayer/index.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;AAEb,gFAAgF;AAChF,8EAA8E;AAC9E,2EAA2E;AAC3E,EAAE;AACF,qEAAqE;AACrE,EAAE;AACF,kCAAkC;AAElC,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAO1C,gFAAgF;AAChF,+EAA+E;AAC/E,mEAAmE;AACnE,kBAAkB;AAElB,OAAO,SAAS,MAAM,4BAA4B,CAAC;AAEnD,oEAAoE;AACpE,qEAAqE;AACrE,6BAA6B;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAuC5D,MAAM,CAAC,MAAM,WAAW,GAEY,UAAU,CAG5C,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACf,MAAM,EACJ,IAAI,GAAG,EAAE,EACT,cAAc,GAAG,IAAI,EACrB,eAAe,GAAG,IAAI,EACtB,OAAO,GAAG,UAAU,EACpB,KAAK,EAAE,cAAc,KAEnB,KAAK,EADJ,IAAI,UACL,KAAK,EAPH,iEAOL,CAAQ,CAAC;IAEV,MAAM,EACJ,KAAK,EACL,UAAU,EACV,KAAK,EAAE,aAAa,EACpB,WAAW,GACZ,GAAG,cAAc,CAAC;QACjB,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,KAAK,mCACN,aAAa,GACb,cAAc,CAClB,CAAC;IAEF,mDAAmD;IACnD,+CAA+C;IAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAErB,+EAA+E;IAC/E,MAAM,iBAAiB,GAAG,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpE,4FAA4F;IAC5F,eAAe;IACf,EAAE;IACF,wCAAwC;IACxC,gDAAgD;IAChD,EAAE;IACF,8CAA8C;IAC9C,8CAA8C;IAC9C,EAAE;IACF,0DAA0D;IAC1D,EAAE;IACF,kFAAkF;IAClF,uFAAuF;IACvF,kFAAkF;IAClF,uCAAuC;IAEvC,OAAO,CACL,oBAAC,SAAS,kBACR,GAAG,EAAE,GAAG,EACR,UAAU,EAAC,WAAW,EACtB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,cAAc,EAC9B,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,sCACU,iBAAiB,IAC/C,IAAI,EACR,CACH,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -66,7 +66,16 @@ export function useContentLink(options = {}) {
|
|
|
66
66
|
// Stable method references that call through to the controller
|
|
67
67
|
const enableClickToEdit = useCallback((opts) => {
|
|
68
68
|
var _a;
|
|
69
|
-
|
|
69
|
+
// If hoverOnly is true, check if the device supports hover
|
|
70
|
+
if (opts === null || opts === void 0 ? void 0 : opts.hoverOnly) {
|
|
71
|
+
const supportsHover = typeof window !== 'undefined' &&
|
|
72
|
+
window.matchMedia('(hover: hover)').matches;
|
|
73
|
+
if (!supportsHover) {
|
|
74
|
+
// Don't enable click-to-edit on touch-only devices
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
(_a = controllerRef.current) === null || _a === void 0 ? void 0 : _a.enableClickToEdit((opts === null || opts === void 0 ? void 0 : opts.scrollToNearestTarget) ? { scrollToNearestTarget: true } : undefined);
|
|
70
79
|
}, []);
|
|
71
80
|
const disableClickToEdit = useCallback(() => {
|
|
72
81
|
var _a;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/useContentLink/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAmB,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAIvD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/useContentLink/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,23 @@
|
|
|
1
|
-
import { type UseContentLinkOptions } from '../useContentLink/index.js';
|
|
1
|
+
import { type ClickToEditOptions, type UseContentLinkOptions } from '../useContentLink/index.js';
|
|
2
2
|
export type ContentLinkProps = Omit<UseContentLinkOptions, 'enabled'> & {
|
|
3
3
|
/** Current pathname to sync with Web Previews plugin */
|
|
4
4
|
currentPath?: string;
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Whether to enable click-to-edit overlays on mount, or options to configure them.
|
|
7
|
+
*
|
|
8
|
+
* - `true`: Enable click-to-edit mode immediately
|
|
9
|
+
* - `{ scrollToNearestTarget: true }`: Enable and scroll to nearest editable if none visible
|
|
10
|
+
* - `{ hoverOnly: true }`: Only enable on devices with hover capability (non-touch)
|
|
11
|
+
* - `false`/`undefined`: Don't enable automatically (use Alt/Option key to toggle)
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <ContentLink enableClickToEdit={true} />
|
|
16
|
+
* <ContentLink enableClickToEdit={{ scrollToNearestTarget: true }} />
|
|
17
|
+
* <ContentLink enableClickToEdit={{ hoverOnly: true, scrollToNearestTarget: true }} />
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
enableClickToEdit?: boolean | ClickToEditOptions;
|
|
9
21
|
/** Whether to strip stega encoding from text nodes after stamping. */
|
|
10
22
|
stripStega?: boolean;
|
|
11
23
|
};
|
|
@@ -24,13 +24,34 @@ export type UseContentLinkOptions = {
|
|
|
24
24
|
/** Ref to limit scanning to this root instead of document */
|
|
25
25
|
root?: React.RefObject<HTMLElement>;
|
|
26
26
|
};
|
|
27
|
+
export interface ClickToEditOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Whether to automatically scroll to the nearest editable element if none
|
|
30
|
+
* is currently visible in the viewport when click-to-edit mode is enabled.
|
|
31
|
+
*
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
scrollToNearestTarget?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Only enable click-to-edit on devices that support hover (i.e., non-touch devices).
|
|
37
|
+
* Uses `window.matchMedia('(hover: hover)')` to detect hover capability.
|
|
38
|
+
*
|
|
39
|
+
* This is useful to avoid showing overlays on touch devices where they may
|
|
40
|
+
* interfere with normal scrolling and tapping behavior.
|
|
41
|
+
*
|
|
42
|
+
* When set to `true` on a touch-only device, click-to-edit will not be
|
|
43
|
+
* automatically enabled, but users can still toggle it manually using
|
|
44
|
+
* the Alt/Option key.
|
|
45
|
+
*
|
|
46
|
+
* @default false
|
|
47
|
+
*/
|
|
48
|
+
hoverOnly?: boolean;
|
|
49
|
+
}
|
|
27
50
|
export type UseContentLinkResult = {
|
|
28
51
|
/** The controller instance, or null if disabled */
|
|
29
52
|
controller: Controller | null;
|
|
30
53
|
/** Enable click-to-edit overlays */
|
|
31
|
-
enableClickToEdit: (options?:
|
|
32
|
-
scrollToNearestTarget: boolean;
|
|
33
|
-
}) => void;
|
|
54
|
+
enableClickToEdit: (options?: ClickToEditOptions) => void;
|
|
34
55
|
/** Disable click-to-edit overlays */
|
|
35
56
|
disableClickToEdit: () => void;
|
|
36
57
|
/** Check if click-to-edit is enabled */
|
package/package.json
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect } from 'react';
|
|
4
4
|
import {
|
|
5
|
+
type ClickToEditOptions,
|
|
5
6
|
type UseContentLinkOptions,
|
|
6
7
|
useContentLink,
|
|
7
8
|
} from '../useContentLink/index.js';
|
|
@@ -9,8 +10,22 @@ import {
|
|
|
9
10
|
export type ContentLinkProps = Omit<UseContentLinkOptions, 'enabled'> & {
|
|
10
11
|
/** Current pathname to sync with Web Previews plugin */
|
|
11
12
|
currentPath?: string;
|
|
12
|
-
/**
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Whether to enable click-to-edit overlays on mount, or options to configure them.
|
|
15
|
+
*
|
|
16
|
+
* - `true`: Enable click-to-edit mode immediately
|
|
17
|
+
* - `{ scrollToNearestTarget: true }`: Enable and scroll to nearest editable if none visible
|
|
18
|
+
* - `{ hoverOnly: true }`: Only enable on devices with hover capability (non-touch)
|
|
19
|
+
* - `false`/`undefined`: Don't enable automatically (use Alt/Option key to toggle)
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* <ContentLink enableClickToEdit={true} />
|
|
24
|
+
* <ContentLink enableClickToEdit={{ scrollToNearestTarget: true }} />
|
|
25
|
+
* <ContentLink enableClickToEdit={{ hoverOnly: true, scrollToNearestTarget: true }} />
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
enableClickToEdit?: boolean | ClickToEditOptions;
|
|
14
29
|
/** Whether to strip stega encoding from text nodes after stamping. */
|
|
15
30
|
stripStega?: boolean;
|
|
16
31
|
};
|
|
@@ -101,7 +116,10 @@ export function ContentLink(props: ContentLinkProps): null {
|
|
|
101
116
|
|
|
102
117
|
// Enable click-to-edit on mount if requested
|
|
103
118
|
useEffect(() => {
|
|
104
|
-
if (
|
|
119
|
+
if (
|
|
120
|
+
enableClickToEditOptions !== undefined &&
|
|
121
|
+
enableClickToEditOptions !== false
|
|
122
|
+
) {
|
|
105
123
|
enableClickToEdit(
|
|
106
124
|
enableClickToEditOptions === true
|
|
107
125
|
? undefined
|
|
@@ -26,6 +26,7 @@ import MuxPlayer from '@mux/mux-player-react/lazy';
|
|
|
26
26
|
// data from DatoCMS GraphQL API and returns props as expected by the
|
|
27
27
|
// `<MuxPlayer />` component.
|
|
28
28
|
|
|
29
|
+
import { decodeStega } from '@datocms/content-link';
|
|
29
30
|
import { useVideoPlayer } from '../useVideoPlayer/index.js';
|
|
30
31
|
|
|
31
32
|
type Maybe<T> = T | null;
|
|
@@ -98,6 +99,9 @@ export const VideoPlayer: (
|
|
|
98
99
|
// See: https://github.com/datocms/content-link
|
|
99
100
|
const { alt } = data;
|
|
100
101
|
|
|
102
|
+
// Only include data-datocms-content-link-source if alt contains stega encoding
|
|
103
|
+
const contentLinkSource = alt && decodeStega(alt) ? alt : undefined;
|
|
104
|
+
|
|
101
105
|
// Note: Custom data-* attributes can be passed to the underlying <mux-player> web component
|
|
102
106
|
// in two ways:
|
|
103
107
|
//
|
|
@@ -125,7 +129,7 @@ export const VideoPlayer: (
|
|
|
125
129
|
playbackId={playbackId}
|
|
126
130
|
style={style}
|
|
127
131
|
placeholder={placeholder}
|
|
128
|
-
data-datocms-content-link-source={
|
|
132
|
+
data-datocms-content-link-source={contentLinkSource}
|
|
129
133
|
{...rest}
|
|
130
134
|
/>
|
|
131
135
|
);
|
|
@@ -29,11 +29,36 @@ export type UseContentLinkOptions = {
|
|
|
29
29
|
root?: React.RefObject<HTMLElement>;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
export interface ClickToEditOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Whether to automatically scroll to the nearest editable element if none
|
|
35
|
+
* is currently visible in the viewport when click-to-edit mode is enabled.
|
|
36
|
+
*
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
scrollToNearestTarget?: boolean;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Only enable click-to-edit on devices that support hover (i.e., non-touch devices).
|
|
43
|
+
* Uses `window.matchMedia('(hover: hover)')` to detect hover capability.
|
|
44
|
+
*
|
|
45
|
+
* This is useful to avoid showing overlays on touch devices where they may
|
|
46
|
+
* interfere with normal scrolling and tapping behavior.
|
|
47
|
+
*
|
|
48
|
+
* When set to `true` on a touch-only device, click-to-edit will not be
|
|
49
|
+
* automatically enabled, but users can still toggle it manually using
|
|
50
|
+
* the Alt/Option key.
|
|
51
|
+
*
|
|
52
|
+
* @default false
|
|
53
|
+
*/
|
|
54
|
+
hoverOnly?: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
32
57
|
export type UseContentLinkResult = {
|
|
33
58
|
/** The controller instance, or null if disabled */
|
|
34
59
|
controller: Controller | null;
|
|
35
60
|
/** Enable click-to-edit overlays */
|
|
36
|
-
enableClickToEdit: (options?:
|
|
61
|
+
enableClickToEdit: (options?: ClickToEditOptions) => void;
|
|
37
62
|
/** Disable click-to-edit overlays */
|
|
38
63
|
disableClickToEdit: () => void;
|
|
39
64
|
/** Check if click-to-edit is enabled */
|
|
@@ -89,7 +114,8 @@ export function useContentLink(
|
|
|
89
114
|
// The onNavigateTo callback is accessed via ref, so changes don't trigger recreation
|
|
90
115
|
useEffect(() => {
|
|
91
116
|
// Check if controller is disabled
|
|
92
|
-
const isEnabled =
|
|
117
|
+
const isEnabled =
|
|
118
|
+
enabled === true || (typeof enabled === 'object' && enabled !== null);
|
|
93
119
|
|
|
94
120
|
if (!isEnabled) {
|
|
95
121
|
if (controllerRef.current) {
|
|
@@ -117,12 +143,22 @@ export function useContentLink(
|
|
|
117
143
|
}, [enabled, root]);
|
|
118
144
|
|
|
119
145
|
// Stable method references that call through to the controller
|
|
120
|
-
const enableClickToEdit = useCallback(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
146
|
+
const enableClickToEdit = useCallback((opts?: ClickToEditOptions) => {
|
|
147
|
+
// If hoverOnly is true, check if the device supports hover
|
|
148
|
+
if (opts?.hoverOnly) {
|
|
149
|
+
const supportsHover =
|
|
150
|
+
typeof window !== 'undefined' &&
|
|
151
|
+
window.matchMedia('(hover: hover)').matches;
|
|
152
|
+
if (!supportsHover) {
|
|
153
|
+
// Don't enable click-to-edit on touch-only devices
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
controllerRef.current?.enableClickToEdit(
|
|
159
|
+
opts?.scrollToNearestTarget ? { scrollToNearestTarget: true } : undefined,
|
|
160
|
+
);
|
|
161
|
+
}, []);
|
|
126
162
|
|
|
127
163
|
const disableClickToEdit = useCallback(() => {
|
|
128
164
|
controllerRef.current?.disableClickToEdit();
|