Skip to content

Commit 0afe804

Browse files
leoc4eVlad Shilov
authored andcommitted
use div to determine window
1 parent 07335db commit 0afe804

File tree

4 files changed

+26
-14
lines changed

4 files changed

+26
-14
lines changed

src/components/common/AlphaColorPicker.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { useRef } from "react";
22

33
import { Hue } from "./Hue";
44
import { Saturation } from "./Saturation";
@@ -20,14 +20,15 @@ export const AlphaColorPicker = <T extends AnyColor>({
2020
onChange,
2121
...rest
2222
}: Props<T>): JSX.Element => {
23-
useStyleSheet();
23+
const containerRef = useRef<HTMLDivElement>(null);
24+
useStyleSheet(containerRef);
2425

2526
const [hsva, updateHsva] = useColorManipulation<T>(colorModel, color, onChange);
2627

2728
const nodeClassName = formatClassName(["react-colorful", className]);
2829

2930
return (
30-
<div {...rest} className={nodeClassName}>
31+
<div {...rest} ref={containerRef} className={nodeClassName}>
3132
<Saturation hsva={hsva} onChange={updateHsva} />
3233
<Hue hue={hsva.h} onChange={updateHsva} />
3334
<Alpha hsva={hsva} onChange={updateHsva} className="react-colorful__last-control" />

src/components/common/ColorPicker.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { useRef } from "react";
22

33
import { Hue } from "./Hue";
44
import { Saturation } from "./Saturation";
@@ -19,14 +19,15 @@ export const ColorPicker = <T extends AnyColor>({
1919
onChange,
2020
...rest
2121
}: Props<T>): JSX.Element => {
22-
useStyleSheet();
22+
const containerRef = useRef<HTMLDivElement>(null);
23+
useStyleSheet(containerRef);
2324

2425
const [hsva, updateHsva] = useColorManipulation<T>(colorModel, color, onChange);
2526

2627
const nodeClassName = formatClassName(["react-colorful", className]);
2728

2829
return (
29-
<div {...rest} className={nodeClassName}>
30+
<div {...rest} ref={containerRef} className={nodeClassName}>
3031
<Saturation hsva={hsva} onChange={updateHsva} />
3132
<Hue hue={hsva.h} onChange={updateHsva} className="react-colorful__last-control" />
3233
</div>

src/components/common/Interactive.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ const getRelativePosition = (
2828

2929
// Get user's pointer position from `touches` array if it's a `TouchEvent`
3030
const pointer = isTouch(event) ? getTouchPoint(event.touches, touchId) : (event as MouseEvent);
31+
const nodeWindow = node.ownerDocument.defaultView || window;
3132

3233
return {
33-
left: clamp((pointer.pageX - (rect.left + window.pageXOffset)) / rect.width),
34-
top: clamp((pointer.pageY - (rect.top + window.pageYOffset)) / rect.height),
34+
left: clamp((pointer.pageX - (rect.left + nodeWindow.pageXOffset)) / rect.width),
35+
top: clamp((pointer.pageY - (rect.top + nodeWindow.pageYOffset)) / rect.height),
3536
};
3637
};
3738

@@ -120,8 +121,13 @@ const InteractiveBase = ({ onMove, onKey, ...rest }: Props) => {
120121

121122
function toggleDocumentEvents(state?: boolean) {
122123
const touch = hasTouch.current;
124+
const el = container.current;
125+
const containerWindow = (el && el.ownerDocument.defaultView) || self;
126+
123127
// add or remove additional pointer event listeners
124-
const toggleEvent = state ? self.addEventListener : self.removeEventListener;
128+
const toggleEvent = state
129+
? containerWindow.addEventListener
130+
: containerWindow.removeEventListener;
125131
toggleEvent(touch ? "touchmove" : "mousemove", handleMove);
126132
toggleEvent(touch ? "touchend" : "mouseup", handleMoveEnd);
127133
}

src/hooks/useStyleSheet.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,27 @@ import { getNonce } from "../utils/nonce";
33

44
// Bundler is configured to load this as a processed minified CSS-string
55
import styles from "../css/styles.css";
6+
import { RefObject } from "react";
67

7-
let styleElement: HTMLStyleElement | undefined;
8+
const styleElementMap: Map<Document, HTMLStyleElement> = new Map();
89

910
/**
1011
* Injects CSS code into the document's <head>
1112
*/
12-
export const useStyleSheet = (): void => {
13+
export const useStyleSheet = (containerRef?: RefObject<HTMLDivElement>): void => {
1314
useIsomorphicLayoutEffect(() => {
14-
if (typeof document !== "undefined" && !styleElement) {
15-
styleElement = document.createElement("style");
15+
const containerDocument =
16+
containerRef && containerRef.current ? containerRef.current.ownerDocument : document;
17+
if (typeof containerDocument !== "undefined" && !styleElementMap.has(containerDocument)) {
18+
const styleElement = containerDocument.createElement("style");
1619
styleElement.innerHTML = styles;
20+
styleElementMap.set(containerDocument, styleElement);
1721

1822
// Conform to CSP rules by setting `nonce` attribute to the inline styles
1923
const nonce = getNonce();
2024
if (nonce) styleElement.setAttribute("nonce", nonce);
2125

22-
document.head.appendChild(styleElement);
26+
containerDocument.head.appendChild(styleElement);
2327
}
2428
}, []);
2529
};

0 commit comments

Comments
 (0)