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/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: () => ( - - - + + + ), }; 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 ( 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..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,8 +4,14 @@ * 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"; export interface LayoutProps { @@ -21,20 +27,12 @@ export const Layout = ({ headerProps, content, }: LayoutProps) => { + const theme = useTheme(); const defaultLayoutWidth = 240; const collapsedLayoutWidth = 56; - const [isCollapsed, setIsCollapsed] = useState(window.innerWidth < 768); - - const handleResize = () => { - setIsCollapsed(window.innerWidth < 768); - }; - - useEffect(() => { - window.addEventListener("resize", handleResize); - return () => { - window.removeEventListener("resize", handleResize); - }; - }, []); + const isCollapsed = useMediaQuery(theme.breakpoints.down("sm"), { + noSsr: true, + }); return ( diff --git a/packages/open-ui-kit/src/theme/common.tsx b/packages/open-ui-kit/src/theme/common.tsx index fe4fd13..88336dd 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,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: breakpointValues, +}; + export const commonMixins = { toolbar: { minHeight: TOOLBAR_MINIMUM_HEIGHT, - "@media (min-width:0px) and (orientation: landscape)": { - minHeight: TOOLBAR_MINIMUM_HEIGHT, - }, - "@media (min-width:600px)": { + [`@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/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..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: "480px", + maxWidth: breakpointValues.sm, }, "&.MuiDialog-paperWidthLg": { - maxWidth: "720px", + maxWidth: breakpointValues.md, }, "&.MuiDialog-paperWidthXl": { - maxWidth: "1200px", + maxWidth: breakpointValues.lg, }, }, }, 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;