Skip to content

Commit 7af2ba7

Browse files
fix(datagrid-web): enhance RTL support with dynamic floating styles and resize observer
1 parent 9426929 commit 7af2ba7

File tree

1 file changed

+69
-6
lines changed

1 file changed

+69
-6
lines changed

packages/pluggableWidgets/datagrid-web/src/components/ColumnSelector.tsx

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,78 @@ export function ColumnSelector(props: ColumnSelectorProps): ReactElement {
3737
}
3838
})
3939
],
40-
transform: false
40+
transform: false,
41+
whileElementsMounted: (reference, _, updateFn) => {
42+
if (reference instanceof Element) {
43+
const observer = new ResizeObserver(() => updateFn());
44+
observer.observe(reference);
45+
return () => observer.disconnect();
46+
}
47+
48+
updateFn();
49+
return () => {};
50+
}
4151
});
4252

53+
const isRTL = useMemo(() => {
54+
const refEl = refs.reference.current;
55+
56+
if (refEl instanceof Element) {
57+
try {
58+
const dir = getComputedStyle(refEl).direction;
59+
return dir === "rtl";
60+
} catch {
61+
return document?.dir === "rtl";
62+
}
63+
}
64+
65+
if (typeof document !== "undefined") {
66+
return document.dir === "rtl";
67+
}
68+
69+
return false;
70+
// eslint-disable-next-line react-hooks/exhaustive-deps
71+
}, [refs.reference.current]);
72+
73+
const correctedFloatingStyles = useMemo(() => {
74+
const styles = floatingStyles;
75+
76+
if (!isRTL || !styles || styles.left == null) {
77+
return styles;
78+
}
79+
80+
const leftVal =
81+
typeof styles.left === "number" ? styles.left : parseFloat(String(styles.left).replace("px", ""));
82+
83+
const floatingEl = refs.floating.current;
84+
const floatingWidth = floatingEl instanceof HTMLElement ? floatingEl.offsetWidth : 0;
85+
86+
const viewportWidth = typeof window !== "undefined" ? window.innerWidth : 0;
87+
const rightVal = Math.max(0, viewportWidth - leftVal - floatingWidth);
88+
89+
return {
90+
...styles,
91+
left: "auto",
92+
right: rightVal
93+
};
94+
// eslint-disable-next-line react-hooks/exhaustive-deps
95+
}, [isRTL, floatingStyles, refs.floating.current]);
96+
97+
useEffect(() => {
98+
update();
99+
}, [isRTL, update]);
100+
43101
useEffect(() => {
44-
if (!show || !refs.reference.current || !refs.floating.current) {
45-
return;
102+
if (!show) return;
103+
104+
const ref = refs.reference.current;
105+
const flt = refs.floating.current;
106+
if (ref && flt) {
107+
const cleanup = autoUpdate(ref, flt, update);
108+
return () => cleanup();
46109
}
47-
return autoUpdate(refs.reference.current, refs.floating.current, update);
48-
}, [show, refs.reference, refs.floating, update]);
110+
// eslint-disable-next-line react-hooks/exhaustive-deps
111+
}, [show, refs.reference.current, refs.floating.current, update]);
49112

50113
const dismiss = useDismiss(context);
51114
const click = useClick(context);
@@ -63,7 +126,7 @@ export function ColumnSelector(props: ColumnSelectorProps): ReactElement {
63126
className={`column-selectors`}
64127
data-focusindex={0}
65128
role="menu"
66-
style={{ ...floatingStyles, maxHeight }}
129+
style={{ ...correctedFloatingStyles, maxHeight }}
67130
{...getFloatingProps()}
68131
>
69132
{props.columns.map((column, index) => {

0 commit comments

Comments
 (0)