From faf16fca8e322e7405b09a44687c13c578713f11 Mon Sep 17 00:00:00 2001 From: misi-bp Date: Thu, 2 Apr 2026 12:39:27 +0200 Subject: [PATCH 1/5] fix: add and apply new breakpoints Signed-off-by: misi-bp --- .../templates/layout/components/layout.tsx | 7 +++++-- packages/open-ui-kit/src/theme/common.tsx | 20 ++++++++++++++++--- .../open-ui-kit/src/theme/dark/dark-theme.tsx | 12 ++--------- .../src/theme/light/light-theme.tsx | 12 ++--------- packages/open-ui-kit/src/theme/mui/dialog.tsx | 6 +++--- packages/open-ui-kit/src/types/theme.ts | 4 ++-- 6 files changed, 31 insertions(+), 30 deletions(-) diff --git a/packages/open-ui-kit/src/templates/layout/components/layout.tsx b/packages/open-ui-kit/src/templates/layout/components/layout.tsx index 28c25e5..5c1b850 100644 --- a/packages/open-ui-kit/src/templates/layout/components/layout.tsx +++ b/packages/open-ui-kit/src/templates/layout/components/layout.tsx @@ -7,6 +7,7 @@ import { useEffect, useState } from "react"; import { Box, Drawer, Toolbar, Typography } from "@mui/material"; import { Header, HeaderProps } from "@/components"; +import { breakpoints } from "@/theme/common"; export interface LayoutProps { content?: React.ReactNode; @@ -23,10 +24,12 @@ export const Layout = ({ }: LayoutProps) => { const defaultLayoutWidth = 240; const collapsedLayoutWidth = 56; - const [isCollapsed, setIsCollapsed] = useState(window.innerWidth < 768); + const [isCollapsed, setIsCollapsed] = useState( + window.innerWidth < (breakpoints.values?.sm ?? 600), + ); const handleResize = () => { - setIsCollapsed(window.innerWidth < 768); + setIsCollapsed(window.innerWidth < (breakpoints.values?.sm ?? 600)); }; useEffect(() => { diff --git a/packages/open-ui-kit/src/theme/common.tsx b/packages/open-ui-kit/src/theme/common.tsx index fe4fd13..c8cc5f0 100644 --- a/packages/open-ui-kit/src/theme/common.tsx +++ b/packages/open-ui-kit/src/theme/common.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Components, Theme } from "@mui/material"; +import { BreakpointsOptions, Components, Theme } from "@mui/material"; import { TypographyVariantsOptions } from "@mui/material/styles/createTypography"; import { KeyboardArrowUp } from "../custom-icons"; import { TOOLBAR_MINIMUM_HEIGHT } from "./constants"; @@ -385,13 +385,27 @@ export const listItemCommonStyles = (theme: Theme) => { }; }; +export const breakpoints: BreakpointsOptions = { + keys: ["xs", "sm", "md", "lg", "xl", "xxl"], + values: { + xs: 0, + sm: 600, + md: 1024, + lg: 1440, + xl: 1920, + xxl: 2560, + }, +}; + export const commonMixins = { toolbar: { minHeight: TOOLBAR_MINIMUM_HEIGHT, - "@media (min-width:0px) and (orientation: landscape)": { + [`@media (min-width:${ + breakpoints.values?.xs ?? 0 + }px) and (orientation: landscape)`]: { minHeight: TOOLBAR_MINIMUM_HEIGHT, }, - "@media (min-width:600px)": { + [`@media (min-width:${breakpoints.values?.sm ?? 600}px)`]: { minHeight: TOOLBAR_MINIMUM_HEIGHT, }, }, diff --git a/packages/open-ui-kit/src/theme/dark/dark-theme.tsx b/packages/open-ui-kit/src/theme/dark/dark-theme.tsx index 5336482..6c33b2b 100644 --- a/packages/open-ui-kit/src/theme/dark/dark-theme.tsx +++ b/packages/open-ui-kit/src/theme/dark/dark-theme.tsx @@ -14,7 +14,7 @@ import { surfaceDark900, surfaceDarkPalette, } from "../color-palette"; -import { typography, commonMixins } from "../common"; +import { typography, breakpoints, commonMixins } from "../common"; import { createTheme, PaletteOptions, @@ -90,15 +90,7 @@ const palette: PaletteOptions = { }; const theme: Theme = createTheme({ - breakpoints: { - keys: ["md", "lg", "xl", "xxl"], - values: { - md: 1024, - lg: 1440, - xl: 1920, - xxl: 2560, - }, - }, + breakpoints, palette, typography, mixins: commonMixins, diff --git a/packages/open-ui-kit/src/theme/light/light-theme.tsx b/packages/open-ui-kit/src/theme/light/light-theme.tsx index 258374c..8459828 100644 --- a/packages/open-ui-kit/src/theme/light/light-theme.tsx +++ b/packages/open-ui-kit/src/theme/light/light-theme.tsx @@ -27,7 +27,7 @@ import { Theme, Shadows, } from "@mui/material"; -import { commonMixins, typography } from "../common"; +import { commonMixins, typography, breakpoints } from "../common"; import { lightVars } from "./light-vars"; import { appBarComponent, @@ -109,15 +109,7 @@ const palette: PaletteOptions = { // }); const theme: Theme = createTheme({ - breakpoints: { - keys: ["md", "lg", "xl", "xxl"], - values: { - md: 1024, - lg: 1440, - xl: 1920, - xxl: 2560, - }, - }, + breakpoints, palette, typography, mixins: commonMixins, diff --git a/packages/open-ui-kit/src/theme/mui/dialog.tsx b/packages/open-ui-kit/src/theme/mui/dialog.tsx index a8581cf..537c007 100644 --- a/packages/open-ui-kit/src/theme/mui/dialog.tsx +++ b/packages/open-ui-kit/src/theme/mui/dialog.tsx @@ -15,13 +15,13 @@ export const dialogComponent = (theme: Theme): Components => { background: theme.palette.vars.controlBackgroundDefault, padding: "24px", "&.MuiDialog-paperWidthMd": { - maxWidth: "480px", + maxWidth: theme.breakpoints.values?.sm ?? 600, }, "&.MuiDialog-paperWidthLg": { - maxWidth: "720px", + maxWidth: theme.breakpoints.values?.md ?? 1024, }, "&.MuiDialog-paperWidthXl": { - maxWidth: "1200px", + maxWidth: theme.breakpoints.values?.lg ?? 1440, }, }, }, diff --git a/packages/open-ui-kit/src/types/theme.ts b/packages/open-ui-kit/src/types/theme.ts index 37ed60b..2f8e8b3 100644 --- a/packages/open-ui-kit/src/types/theme.ts +++ b/packages/open-ui-kit/src/types/theme.ts @@ -33,8 +33,8 @@ declare module "@mui/material/styles" { interface PaletteColor extends ColorPartial {} interface BreakpointOverrides { - xs: false; - sm: false; + xs: true; + sm: true; md: true; lg: true; xl: true; From f6749e219b60ce89a81a72c0f72643d35b336344 Mon Sep 17 00:00:00 2001 From: misi-bp Date: Thu, 2 Apr 2026 14:18:04 +0200 Subject: [PATCH 2/5] refactor(theme): typed breakpointValues and dialog maxWidth mapping docs Made-with: Cursor Signed-off-by: misi-bp --- packages/open-ui-kit/src/theme/common.tsx | 40 ++++++++++++------- packages/open-ui-kit/src/theme/mui/dialog.tsx | 26 ++++++++++-- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/packages/open-ui-kit/src/theme/common.tsx b/packages/open-ui-kit/src/theme/common.tsx index c8cc5f0..88336dd 100644 --- a/packages/open-ui-kit/src/theme/common.tsx +++ b/packages/open-ui-kit/src/theme/common.tsx @@ -385,27 +385,39 @@ export const listItemCommonStyles = (theme: Theme) => { }; }; +/** Pixel widths for each named breakpoint (required keys; aligns with `BreakpointOverrides` in `types/theme.ts`). */ +export type AppBreakpointValues = { + xs: number; + sm: number; + md: number; + lg: number; + xl: number; + xxl: number; +}; + +/** Single source of truth for breakpoint widths (px). Use this instead of `breakpoints.values?.x ?? n`. */ +export const breakpointValues: AppBreakpointValues = { + xs: 0, + sm: 600, + md: 1024, + lg: 1440, + xl: 1920, + xxl: 2560, +}; + export const breakpoints: BreakpointsOptions = { keys: ["xs", "sm", "md", "lg", "xl", "xxl"], - values: { - xs: 0, - sm: 600, - md: 1024, - lg: 1440, - xl: 1920, - xxl: 2560, - }, + values: breakpointValues, }; export const commonMixins = { toolbar: { minHeight: TOOLBAR_MINIMUM_HEIGHT, - [`@media (min-width:${ - breakpoints.values?.xs ?? 0 - }px) and (orientation: landscape)`]: { - minHeight: TOOLBAR_MINIMUM_HEIGHT, - }, - [`@media (min-width:${breakpoints.values?.sm ?? 600}px)`]: { + [`@media (min-width:${breakpointValues.xs}px) and (orientation: landscape)`]: + { + minHeight: TOOLBAR_MINIMUM_HEIGHT, + }, + [`@media (min-width:${breakpointValues.sm}px)`]: { minHeight: TOOLBAR_MINIMUM_HEIGHT, }, }, diff --git a/packages/open-ui-kit/src/theme/mui/dialog.tsx b/packages/open-ui-kit/src/theme/mui/dialog.tsx index 537c007..b5cf55c 100644 --- a/packages/open-ui-kit/src/theme/mui/dialog.tsx +++ b/packages/open-ui-kit/src/theme/mui/dialog.tsx @@ -4,7 +4,27 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * Dialog paper `maxWidth` presets vs layout breakpoints + * ------------------------------------------------------- + * MUI’s `maxWidth` string is a **dialog content-size preset**, not `theme.breakpoints.*`. + * We map three presets to `breakpointValues` pixel widths so modals stay readable; the + * **preset label** (md / lg / xl) does **not** match the **token key** (sm / md / lg). + * + * | MUI `maxWidth` | Paper `maxWidth` (px) | `breakpointValues` key | Same name as layout breakpoint? | + * |----------------|----------------------:|------------------------|--------------------------------| + * | `xs` | *(MUI default)* | — | — | + * | `sm` | *(MUI default)* | — | — | + * | `md` | 600 | `sm` | **No** | + * | `lg` | 1024 | `md` | **No** | + * | `xl` | 1440 | `lg` | **No** | + * + * In Storybook, prefer **S / M / L / XL (content)** in titles, not “layout md/lg”. + * @see docs/new-breakpoints-branch-changes.md + */ + import { Components, Theme } from "@mui/material"; +import { breakpointValues } from "../common"; export const dialogComponent = (theme: Theme): Components => { return { @@ -15,13 +35,13 @@ export const dialogComponent = (theme: Theme): Components => { background: theme.palette.vars.controlBackgroundDefault, padding: "24px", "&.MuiDialog-paperWidthMd": { - maxWidth: theme.breakpoints.values?.sm ?? 600, + maxWidth: breakpointValues.sm, }, "&.MuiDialog-paperWidthLg": { - maxWidth: theme.breakpoints.values?.md ?? 1024, + maxWidth: breakpointValues.md, }, "&.MuiDialog-paperWidthXl": { - maxWidth: theme.breakpoints.values?.lg ?? 1440, + maxWidth: breakpointValues.lg, }, }, }, From 6ac725694fddf8ca4daef59f58f9613498ec578d Mon Sep 17 00:00:00 2001 From: misi-bp Date: Thu, 2 Apr 2026 14:18:10 +0200 Subject: [PATCH 3/5] fix(layout): use useMediaQuery for sidenav collapse instead of window resize Made-with: Cursor Signed-off-by: misi-bp --- .../templates/layout/components/layout.tsx | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/packages/open-ui-kit/src/templates/layout/components/layout.tsx b/packages/open-ui-kit/src/templates/layout/components/layout.tsx index 5c1b850..be76608 100644 --- a/packages/open-ui-kit/src/templates/layout/components/layout.tsx +++ b/packages/open-ui-kit/src/templates/layout/components/layout.tsx @@ -4,10 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { useEffect, useState } from "react"; -import { Box, Drawer, Toolbar, Typography } from "@mui/material"; +import { + Box, + Drawer, + Toolbar, + Typography, + useMediaQuery, + useTheme, +} from "@mui/material"; import { Header, HeaderProps } from "@/components"; -import { breakpoints } from "@/theme/common"; export interface LayoutProps { content?: React.ReactNode; @@ -22,22 +27,12 @@ export const Layout = ({ headerProps, content, }: LayoutProps) => { + const theme = useTheme(); const defaultLayoutWidth = 240; const collapsedLayoutWidth = 56; - const [isCollapsed, setIsCollapsed] = useState( - window.innerWidth < (breakpoints.values?.sm ?? 600), - ); - - const handleResize = () => { - setIsCollapsed(window.innerWidth < (breakpoints.values?.sm ?? 600)); - }; - - useEffect(() => { - window.addEventListener("resize", handleResize); - return () => { - window.removeEventListener("resize", handleResize); - }; - }, []); + const isCollapsed = useMediaQuery(theme.breakpoints.down("sm"), { + noSsr: true, + }); return ( From 0d50c907d033dbb5a9a8f342926d1894a48377f2 Mon Sep 17 00:00:00 2001 From: misi-bp Date: Thu, 2 Apr 2026 14:18:14 +0200 Subject: [PATCH 4/5] refactor: use ResizeObserver instead of window resize in bar-graph and overflow-tooltip Made-with: Cursor Signed-off-by: misi-bp --- .../src/charts/bar-graph/bar-graph.tsx | 20 +++++---- .../components/overflow-tooltip.tsx | 42 +++++++------------ 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/packages/open-ui-kit/src/charts/bar-graph/bar-graph.tsx b/packages/open-ui-kit/src/charts/bar-graph/bar-graph.tsx index 1d5a48f..5e5d16c 100644 --- a/packages/open-ui-kit/src/charts/bar-graph/bar-graph.tsx +++ b/packages/open-ui-kit/src/charts/bar-graph/bar-graph.tsx @@ -68,17 +68,20 @@ export const BarGraph = ({ const [header0, header1] = headers; - const updateYAxisWidth = () => { - if (chartContainerRef.current) { - const chartWidth = - chartContainerRef.current.getBoundingClientRect().width; + useEffect(() => { + const el = chartContainerRef.current; + if (!el) return; + + const updateYAxisWidth = () => { + const chartWidth = el.getBoundingClientRect().width; setYAxisWidth(chartWidth * 0.43); - } - }; + }; - useEffect(() => { updateYAxisWidth(); - window.addEventListener("resize", updateYAxisWidth, false); + + const ro = new ResizeObserver(updateYAxisWidth); + ro.observe(el); + return () => ro.disconnect(); }, []); return ( @@ -177,7 +180,6 @@ export const BarGraph = ({ spacing={2} alignItems="center" overflow="hidden" - position="absolute" bottom={0} sx={{ backgroundColor: theme.palette.vars.interactiveSecondaryWeakDefault, diff --git a/packages/open-ui-kit/src/components/overflow-tooltip/components/overflow-tooltip.tsx b/packages/open-ui-kit/src/components/overflow-tooltip/components/overflow-tooltip.tsx index 0bdd47d..ea74f97 100644 --- a/packages/open-ui-kit/src/components/overflow-tooltip/components/overflow-tooltip.tsx +++ b/packages/open-ui-kit/src/components/overflow-tooltip/components/overflow-tooltip.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { useState, useRef, useEffect } from "react"; +import { useState, useRef, useEffect, useCallback } from "react"; import { rtlWrapperStyle, baseWrapperStyle, spanStyle } from "../styles"; import { Tooltip, TooltipProps } from "@/components"; @@ -24,37 +24,27 @@ export const OverflowTooltip = ({ styleText, ...rest }: OverflowTooltipProps) => { - // Create Ref - const textElementRef = useRef() as React.MutableRefObject; - - /** - * Compares the size of the text element to its container and sets the hover state accordingly - */ - const compareSize = () => { - const compare = - textElementRef.current.scrollWidth > textElementRef.current.clientWidth; - setHover(compare); - }; + const textElementRef = useRef(null); + const [hoverStatus, setHover] = useState(false); - // Add resize listener to compare size on component mount - useEffect(() => { - window.addEventListener("resize", compareSize); + const compareSize = useCallback(() => { + const el = textElementRef.current; + if (!el) return; + setHover(el.scrollWidth > el.clientWidth); }, []); useEffect(() => { - compareSize(); - }, [value]); + const el = textElementRef.current; + if (!el) return; - // Remove resize listener on component unmount - useEffect( - () => () => { - window.removeEventListener("resize", compareSize); - }, - [], - ); + compareSize(); - // Define state and function to update the value - const [hoverStatus, setHover] = useState(false); + const ro = new ResizeObserver(() => { + compareSize(); + }); + ro.observe(el); + return () => ro.disconnect(); + }, [value, someLongText, ellipsisDirection, compareSize]); return ( From 683d53753531e59db781945d56515a1c4678404c Mon Sep 17 00:00:00 2001 From: misi-bp Date: Thu, 2 Apr 2026 14:18:20 +0200 Subject: [PATCH 5/5] docs(storybook): clarify modal content widths vs layout breakpoints Made-with: Cursor Signed-off-by: misi-bp --- .../modal/stories/modal.stories.tsx | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/open-ui-kit/src/components/modal/stories/modal.stories.tsx b/packages/open-ui-kit/src/components/modal/stories/modal.stories.tsx index 1ae6134..6f6b670 100644 --- a/packages/open-ui-kit/src/components/modal/stories/modal.stories.tsx +++ b/packages/open-ui-kit/src/components/modal/stories/modal.stories.tsx @@ -39,6 +39,12 @@ const meta: Meta = { ), }, }, + argTypes: { + maxWidth: { + description: + "Dialog **content width** preset (MUI). This string is **not** the same as layout viewport breakpoints (`theme.breakpoints`). See the **Dialog sizes** story and `docs/new-breakpoints-branch-changes.md`.", + }, + }, }; export default meta; @@ -97,11 +103,32 @@ export const SimpleModal: Story = { }; export const DialogSizes: Story = { + name: "Dialog sizes (content width)", + parameters: { + docs: { + description: { + story: + "Labels use M / L / XL (content) to avoid confusing these with layout breakpoints. Engineers still set MUI maxWidth (md / lg / xl) as shown in each row. Mapping: theme/mui/dialog.tsx docblock and docs/new-breakpoints-branch-changes.md.", + }, + }, + }, render: () => ( - - - + + + ), };