From b816d827a5000db910fac27bd2280311816fb143 Mon Sep 17 00:00:00 2001 From: Jakub007d Date: Tue, 24 Feb 2026 08:57:55 +0100 Subject: [PATCH 1/2] feat: adding custom breakpoint interface --- packages/module/src/WidgetLayout/GridLayout.tsx | 17 ++++++++++++----- packages/module/src/WidgetLayout/utils.ts | 9 +++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/module/src/WidgetLayout/GridLayout.tsx b/packages/module/src/WidgetLayout/GridLayout.tsx index 9e31b63..4c8a938 100644 --- a/packages/module/src/WidgetLayout/GridLayout.tsx +++ b/packages/module/src/WidgetLayout/GridLayout.tsx @@ -62,6 +62,10 @@ export interface GridLayoutProps { droppingWidgetType?: string; /** Resize configuration options */ resizeWidgetConfig?: Partial; + /** Custom breakpoints for responsive layout (container width thresholds in px) */ + customBreakpoints?: Record; + /** Custom column counts per breakpoint variant */ + customColumns?: Record; } const LayoutEmptyState = ({ @@ -107,7 +111,10 @@ const GridLayout = ({ onActiveWidgetsChange, droppingWidgetType, resizeWidgetConfig, + customBreakpoints, + customColumns, }: GridLayoutProps) => { + const activeColumns = customColumns ?? columns; const [isDragging, setIsDragging] = useState(false); const [isInitialRender, setIsInitialRender] = useState(true); const [layoutVariant, setLayoutVariant] = useState('xl'); @@ -172,8 +179,8 @@ const GridLayout = ({ ...layoutItem, ...widget.defaults, // make sure the configuration is valid for all layout sizes - w: size === layoutVariant ? layoutItem.w : Math.min(widget.defaults.w, columns[size as Variants]), - x: size === layoutVariant ? layoutItem.x : Math.min(layoutItem.x, columns[size as Variants]), + w: size === layoutVariant ? layoutItem.w : Math.min(widget.defaults.w, activeColumns[size as Variants]), + x: size === layoutVariant ? layoutItem.x : Math.min(layoutItem.x, activeColumns[size as Variants]), widgetType: data, i: getWidgetIdentifier(data), title: 'New title', @@ -226,7 +233,7 @@ const GridLayout = ({ // Update layout variant when container width changes useEffect(() => { if (mounted && layoutWidth > 0) { - const variant: Variants = getGridDimensions(layoutWidth); + const variant: Variants = getGridDimensions(layoutWidth, customBreakpoints); setLayoutVariant(variant); } }, [layoutWidth, mounted]); @@ -247,7 +254,7 @@ const GridLayout = ({ width={effectiveWidth} droppingItem={droppingItemTemplate} gridConfig={{ - cols: columns[layoutVariant], + cols: activeColumns[layoutVariant], rowHeight: 56, }} dragConfig={{ @@ -283,7 +290,7 @@ const GridLayout = ({ widgetType={widgetType} widgetConfig={{ ...layoutItem, - colWidth: effectiveWidth / columns[layoutVariant], + colWidth: effectiveWidth / activeColumns[layoutVariant], config, maxH: layoutItem.maxH ?? widget.defaults.maxH, minH: layoutItem.minH ?? widget.defaults.minH, diff --git a/packages/module/src/WidgetLayout/utils.ts b/packages/module/src/WidgetLayout/utils.ts index 4448e99..663ec3e 100644 --- a/packages/module/src/WidgetLayout/utils.ts +++ b/packages/module/src/WidgetLayout/utils.ts @@ -52,14 +52,15 @@ export const extendLayout = (extendedTemplateConfig: ExtendedTemplateConfig): Ex /** * Get grid dimensions based on container width */ -export function getGridDimensions(currentWidth: number): Variants { - if (currentWidth >= breakpoints.xl) { +export function getGridDimensions(currentWidth: number, customBreakpoints?: Record): Variants { + const bp = customBreakpoints ?? breakpoints; + if (currentWidth >= bp.xl) { return 'xl'; } - if (currentWidth >= breakpoints.lg) { + if (currentWidth >= bp.lg) { return 'lg'; } - if (currentWidth >= breakpoints.md) { + if (currentWidth >= bp.md) { return 'md'; } return 'sm'; From d01cf1e21b57530bdbf25d9ceb00c7531d26ae7f Mon Sep 17 00:00:00 2001 From: Jakub007d Date: Tue, 24 Feb 2026 16:53:44 +0100 Subject: [PATCH 2/2] feat: updating custom breakpoint props --- .../module/src/WidgetLayout/GridLayout.tsx | 26 +++++++++---------- packages/module/src/WidgetLayout/index.ts | 4 +-- packages/module/src/WidgetLayout/types.ts | 7 +++++ packages/module/src/WidgetLayout/utils.ts | 15 +++++------ 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/packages/module/src/WidgetLayout/GridLayout.tsx b/packages/module/src/WidgetLayout/GridLayout.tsx index 4c8a938..5b7d6f6 100644 --- a/packages/module/src/WidgetLayout/GridLayout.tsx +++ b/packages/module/src/WidgetLayout/GridLayout.tsx @@ -12,14 +12,13 @@ import { ExtendedTemplateConfig, AnalyticsTracker, WidgetConfiguration, + Breakpoints, } from './types'; import { Button, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateVariant, PageSection } from '@patternfly/react-core'; import ExternalLinkAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon'; import GripVerticalIcon from '@patternfly/react-icons/dist/esm/icons/grip-vertical-icon'; import PlusCircleIcon from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon'; -import { columns, breakpoints, droppingElemId, getWidgetIdentifier, extendLayout, getGridDimensions } from './utils'; - -export const defaultBreakpoints = breakpoints; +import { defaultBreakpoints, defaultColumns, droppingElemId, getWidgetIdentifier, extendLayout, getGridDimensions } from './utils'; const createSerializableConfig = (config?: WidgetConfiguration) => { if (!config) { return undefined; } @@ -63,9 +62,9 @@ export interface GridLayoutProps { /** Resize configuration options */ resizeWidgetConfig?: Partial; /** Custom breakpoints for responsive layout (container width thresholds in px) */ - customBreakpoints?: Record; + breakpoints?: Breakpoints; /** Custom column counts per breakpoint variant */ - customColumns?: Record; + columns?: Record; } const LayoutEmptyState = ({ @@ -111,10 +110,9 @@ const GridLayout = ({ onActiveWidgetsChange, droppingWidgetType, resizeWidgetConfig, - customBreakpoints, - customColumns, + breakpoints = defaultBreakpoints, + columns = defaultColumns, }: GridLayoutProps) => { - const activeColumns = customColumns ?? columns; const [isDragging, setIsDragging] = useState(false); const [isInitialRender, setIsInitialRender] = useState(true); const [layoutVariant, setLayoutVariant] = useState('xl'); @@ -179,8 +177,8 @@ const GridLayout = ({ ...layoutItem, ...widget.defaults, // make sure the configuration is valid for all layout sizes - w: size === layoutVariant ? layoutItem.w : Math.min(widget.defaults.w, activeColumns[size as Variants]), - x: size === layoutVariant ? layoutItem.x : Math.min(layoutItem.x, activeColumns[size as Variants]), + w: size === layoutVariant ? layoutItem.w : Math.min(widget.defaults.w, columns[size as Variants]), + x: size === layoutVariant ? layoutItem.x : Math.min(layoutItem.x, columns[size as Variants]), widgetType: data, i: getWidgetIdentifier(data), title: 'New title', @@ -233,10 +231,10 @@ const GridLayout = ({ // Update layout variant when container width changes useEffect(() => { if (mounted && layoutWidth > 0) { - const variant: Variants = getGridDimensions(layoutWidth, customBreakpoints); + const variant: Variants = getGridDimensions(layoutWidth, breakpoints); setLayoutVariant(variant); } - }, [layoutWidth, mounted]); + }, [layoutWidth, mounted, breakpoints]); const activeLayout = internalTemplate[layoutVariant] || []; @@ -254,7 +252,7 @@ const GridLayout = ({ width={effectiveWidth} droppingItem={droppingItemTemplate} gridConfig={{ - cols: activeColumns[layoutVariant], + cols: columns[layoutVariant], rowHeight: 56, }} dragConfig={{ @@ -290,7 +288,7 @@ const GridLayout = ({ widgetType={widgetType} widgetConfig={{ ...layoutItem, - colWidth: effectiveWidth / activeColumns[layoutVariant], + colWidth: effectiveWidth / columns[layoutVariant], config, maxH: layoutItem.maxH ?? widget.defaults.maxH, minH: layoutItem.minH ?? widget.defaults.minH, diff --git a/packages/module/src/WidgetLayout/index.ts b/packages/module/src/WidgetLayout/index.ts index 0f7b92d..9cdcf02 100644 --- a/packages/module/src/WidgetLayout/index.ts +++ b/packages/module/src/WidgetLayout/index.ts @@ -5,8 +5,8 @@ export { default as WidgetDrawer } from './WidgetDrawer'; export * from './types'; export { - columns, - breakpoints, + defaultColumns, + defaultBreakpoints, droppingElemId, getWidgetIdentifier, mapWidgetDefaults, diff --git a/packages/module/src/WidgetLayout/types.ts b/packages/module/src/WidgetLayout/types.ts index 912d6c3..b0bb410 100644 --- a/packages/module/src/WidgetLayout/types.ts +++ b/packages/module/src/WidgetLayout/types.ts @@ -5,6 +5,13 @@ export const widgetIdSeparator = '#'; export type Variants = 'sm' | 'md' | 'lg' | 'xl'; +export interface Breakpoints { + sm: number; + md: number; + lg: number; + xl: number; +} + export type LayoutWithTitle = LayoutItem & { title: string }; export type TemplateConfig = { diff --git a/packages/module/src/WidgetLayout/utils.ts b/packages/module/src/WidgetLayout/utils.ts index 663ec3e..ca4e2ca 100644 --- a/packages/module/src/WidgetLayout/utils.ts +++ b/packages/module/src/WidgetLayout/utils.ts @@ -1,10 +1,10 @@ -import { ExtendedTemplateConfig, TemplateConfig, Variants, widgetIdSeparator } from './types'; +import { ExtendedTemplateConfig, TemplateConfig, Variants, widgetIdSeparator, Breakpoints } from './types'; export const droppingElemId = '__dropping-elem__'; -export const columns: Record = { xl: 4, lg: 3, md: 2, sm: 1 }; +export const defaultColumns: Record = { xl: 4, lg: 3, md: 2, sm: 1 }; -export const breakpoints: Record = { xl: 1550, lg: 1400, md: 1100, sm: 800 }; +export const defaultBreakpoints: Breakpoints = { xl: 1550, lg: 1400, md: 1100, sm: 800 }; /** * Generate a unique widget identifier @@ -52,15 +52,14 @@ export const extendLayout = (extendedTemplateConfig: ExtendedTemplateConfig): Ex /** * Get grid dimensions based on container width */ -export function getGridDimensions(currentWidth: number, customBreakpoints?: Record): Variants { - const bp = customBreakpoints ?? breakpoints; - if (currentWidth >= bp.xl) { +export function getGridDimensions(currentWidth: number, breakpoints: Breakpoints = defaultBreakpoints): Variants { + if (currentWidth >= breakpoints.xl) { return 'xl'; } - if (currentWidth >= bp.lg) { + if (currentWidth >= breakpoints.lg) { return 'lg'; } - if (currentWidth >= bp.md) { + if (currentWidth >= breakpoints.md) { return 'md'; } return 'sm';