From af1b421e98190d72069638231b4667a62e1d5e58 Mon Sep 17 00:00:00 2001 From: Zeeshan Mehboob Date: Thu, 16 Jul 2026 00:34:37 +0530 Subject: [PATCH 1/8] [3914] added flowMetaTheme in buildThemeConfigFromFlowMeta Signed-off-by: Zeeshan Mehboob --- packages/javascript/src/models/flow-meta.ts | 22 +++++++++++++++++++ .../src/utils/buildThemeConfigFromFlowMeta.ts | 1 + 2 files changed, 23 insertions(+) diff --git a/packages/javascript/src/models/flow-meta.ts b/packages/javascript/src/models/flow-meta.ts index f2b5272..510b45b 100644 --- a/packages/javascript/src/models/flow-meta.ts +++ b/packages/javascript/src/models/flow-meta.ts @@ -168,6 +168,17 @@ export interface FlowMetaThemeColorScheme { palette: FlowMetaThemeColors; } +/** + * Size configuration in the v2 theme. + * + * @experimental This API may change in future versions + */ +export interface FlowMetaThemeSize { + small?: string; + medium?: string; + large?: string; +} + /** * Shape / geometry configuration in the v2 theme. * @@ -215,6 +226,17 @@ export interface FlowMetaTheme { /** Typography configuration for the theme */ typography?: FlowMetaThemeTypography; + + /** Border configuration for the theme */ + border?: {width: string; color: string; style: string}; + + /** Shadow configuration for the theme */ + shadows?: FlowMetaThemeSize; + + /** Spacing configuration for the theme */ + spacing?: {unit: number}; + + borderRadius?: FlowMetaThemeSize; } /** diff --git a/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts b/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts index 9ad977c..c36ddb2 100644 --- a/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts +++ b/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts @@ -76,6 +76,7 @@ const buildThemeConfigFromFlowMeta = ( } return { + ...flowMetaTheme, ...(flowMetaTheme.direction ? {direction: flowMetaTheme.direction} : {}), ...(borderRadiusStr ? { From 09d3f0447f6065eef98cc4d1f5fab2af0ae3918f Mon Sep 17 00:00:00 2001 From: Zeeshan Mehboob Date: Thu, 16 Jul 2026 00:48:42 +0530 Subject: [PATCH 2/8] [3914] added flowMetaTheme in vue package as well Signed-off-by: Zeeshan Mehboob --- packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts b/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts index cb4ff47..63b8fac 100644 --- a/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts +++ b/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts @@ -66,6 +66,7 @@ const buildThemeConfigFromFlowMeta = ( } return { + ...flowMetaTheme, ...(flowMetaTheme.direction ? {direction: flowMetaTheme.direction} : {}), ...(borderRadiusStr ? { From 7c01f6170b958bcad661d059859028fc9e1f641d Mon Sep 17 00:00:00 2001 From: Zeeshan Mehboob Date: Thu, 23 Jul 2026 09:39:03 +0530 Subject: [PATCH 3/8] [3914] remove borderRadius from first class, updated the shape property Signed-off-by: Zeeshan Mehboob --- packages/javascript/src/models/flow-meta.ts | 6 ++-- .../src/utils/buildThemeConfigFromFlowMeta.ts | 34 +++++++++++++------ .../src/utils/buildThemeConfigFromFlowMeta.ts | 34 +++++++++++++------ 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/packages/javascript/src/models/flow-meta.ts b/packages/javascript/src/models/flow-meta.ts index 510b45b..b1c6206 100644 --- a/packages/javascript/src/models/flow-meta.ts +++ b/packages/javascript/src/models/flow-meta.ts @@ -185,8 +185,8 @@ export interface FlowMetaThemeSize { * @experimental This API may change in future versions */ export interface FlowMetaThemeShape { - /** Border radius in pixels applied uniformly across components */ - borderRadius?: number; + /** Border radius: a number (px), a numeric string ("8"), a px string ("8px"), or per-size tokens */ + borderRadius?: number | string | FlowMetaThemeSize; } /** @@ -235,8 +235,6 @@ export interface FlowMetaTheme { /** Spacing configuration for the theme */ spacing?: {unit: number}; - - borderRadius?: FlowMetaThemeSize; } /** diff --git a/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts b/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts index c36ddb2..c712bd8 100644 --- a/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts +++ b/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts @@ -36,8 +36,28 @@ const buildThemeConfigFromFlowMeta = ( colorScheme: 'light' | 'dark', ): RecursivePartial => { const scheme: FlowMetaThemeColorScheme | undefined = flowMetaTheme.colorSchemes?.[colorScheme]; - const borderRadius: number | undefined = flowMetaTheme.shape?.borderRadius; - const borderRadiusStr: string | undefined = borderRadius !== undefined ? `${borderRadius}px` : undefined; + const rawBorderRadius = flowMetaTheme.shape?.borderRadius; + + let borderRadiusConfig: {large?: string; medium?: string; small?: string} | undefined; + + // Normalize borderRadius into per-size tokens: if it's already a size object use it directly; + // otherwise coerce a bare number or numeric string to a px string and apply it uniformly. + if (rawBorderRadius !== undefined) { + if (typeof rawBorderRadius === 'object') { + const {small, medium, large} = rawBorderRadius; + if (small !== undefined || medium !== undefined || large !== undefined) { + borderRadiusConfig = { + ...(large !== undefined && {large}), + ...(medium !== undefined && {medium}), + ...(small !== undefined && {small}), + }; + } + } else { + const trimmed = String(rawBorderRadius).trim(); + const radiusStr = /^\d+(\.\d+)?$/.test(trimmed) ? `${trimmed}px` : trimmed; + borderRadiusConfig = {large: radiusStr, medium: radiusStr, small: radiusStr}; + } + } // Build only the colors that the server actually provided. // Each nested object is constructed incrementally so that absent fields are @@ -78,15 +98,7 @@ const buildThemeConfigFromFlowMeta = ( return { ...flowMetaTheme, ...(flowMetaTheme.direction ? {direction: flowMetaTheme.direction} : {}), - ...(borderRadiusStr - ? { - borderRadius: { - large: borderRadiusStr, - medium: borderRadiusStr, - small: borderRadiusStr, - }, - } - : {}), + ...(borderRadiusConfig ? {borderRadius: borderRadiusConfig} : {}), ...(colors && Object.keys(colors).length > 0 ? {colors} : {}), ...(flowMetaTheme.typography?.fontFamily ? {typography: {fontFamily: flowMetaTheme.typography.fontFamily}} : {}), }; diff --git a/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts b/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts index 63b8fac..068bacc 100644 --- a/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts +++ b/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts @@ -31,8 +31,28 @@ const buildThemeConfigFromFlowMeta = ( colorScheme: 'light' | 'dark', ): RecursivePartial => { const scheme: FlowMetaThemeColorScheme | undefined = flowMetaTheme.colorSchemes?.[colorScheme]; - const borderRadius: number | undefined = flowMetaTheme.shape?.borderRadius; - const borderRadiusStr: string | undefined = borderRadius !== undefined ? `${borderRadius}px` : undefined; + const rawBorderRadius = flowMetaTheme.shape?.borderRadius; + + let borderRadiusConfig: {large?: string; medium?: string; small?: string} | undefined; + + // Normalize borderRadius into per-size tokens: if it's already a size object use it directly; + // otherwise coerce a bare number or numeric string to a px string and apply it uniformly. + if (rawBorderRadius !== undefined) { + if (typeof rawBorderRadius === 'object') { + const {small, medium, large} = rawBorderRadius; + if (small !== undefined || medium !== undefined || large !== undefined) { + borderRadiusConfig = { + ...(large !== undefined && {large}), + ...(medium !== undefined && {medium}), + ...(small !== undefined && {small}), + }; + } + } else { + const trimmed = String(rawBorderRadius).trim(); + const radiusStr = /^\d+(\.\d+)?$/.test(trimmed) ? `${trimmed}px` : trimmed; + borderRadiusConfig = {large: radiusStr, medium: radiusStr, small: radiusStr}; + } + } let colors: RecursivePartial | undefined; @@ -68,15 +88,7 @@ const buildThemeConfigFromFlowMeta = ( return { ...flowMetaTheme, ...(flowMetaTheme.direction ? {direction: flowMetaTheme.direction} : {}), - ...(borderRadiusStr - ? { - borderRadius: { - large: borderRadiusStr, - medium: borderRadiusStr, - small: borderRadiusStr, - }, - } - : {}), + ...(borderRadiusConfig ? {borderRadius: borderRadiusConfig} : {}), ...(colors && Object.keys(colors).length > 0 ? {colors} : {}), ...(flowMetaTheme.typography?.fontFamily ? {typography: {fontFamily: flowMetaTheme.typography.fontFamily}} : {}), }; From 1d14a370d0558e225502893a565e1d16a4348f48 Mon Sep 17 00:00:00 2001 From: Zeeshan Mehboob Date: Thu, 23 Jul 2026 10:07:27 +0530 Subject: [PATCH 4/8] [3914] resolve coderabbit comment Signed-off-by: Zeeshan Mehboob --- packages/browser/src/index.ts | 1 + .../src/theme/normalizeBorderRadius.ts | 47 +++++++++++++++++++ .../src/utils/buildThemeConfigFromFlowMeta.ts | 25 +--------- .../src/utils/buildThemeConfigFromFlowMeta.ts | 25 +--------- 4 files changed, 52 insertions(+), 46 deletions(-) create mode 100644 packages/browser/src/theme/normalizeBorderRadius.ts diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index b4e67fe..0468d0a 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -59,6 +59,7 @@ export {default as resolveEmojiUrisInHtml} from './utils/resolveEmojiUrisInHtml' export {detectThemeMode, createClassObserver, createMediaQueryListener} from './theme/themeDetection'; export type {BrowserThemeDetection} from './theme/themeDetection'; export {default as getActiveTheme} from './theme/getActiveTheme'; +export {default as normalizeBorderRadius} from './theme/normalizeBorderRadius'; // Re-export everything from the JavaScript SDK export * from '@thunderid/javascript'; diff --git a/packages/browser/src/theme/normalizeBorderRadius.ts b/packages/browser/src/theme/normalizeBorderRadius.ts new file mode 100644 index 0000000..c8eded3 --- /dev/null +++ b/packages/browser/src/theme/normalizeBorderRadius.ts @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import {FlowMetaThemeShape, FlowMetaThemeSize} from '@thunderid/javascript'; + +/** + * Normalizes a raw `shape.borderRadius` value into per-size tokens suitable + * for `ThemeConfig.borderRadius`. + * + * - Object with `small`/`medium`/`large` → used directly. + * - Bare number or numeric string (e.g. `8` or `"8"`) → appended with `px` and applied uniformly. + * - Pixel string (e.g. `"8px"`) → used as-is and applied uniformly. + */ +const normalizeBorderRadius = (raw: FlowMetaThemeShape['borderRadius']): FlowMetaThemeSize | undefined => { + if (raw === undefined) return undefined; + + if (typeof raw === 'object') { + const {small, medium, large}: FlowMetaThemeSize = raw; + if (small === undefined && medium === undefined && large === undefined) return undefined; + return { + ...(large !== undefined && {large}), + ...(medium !== undefined && {medium}), + ...(small !== undefined && {small}), + }; + } + + const trimmed: string = String(raw).trim(); + const radiusStr: string = /^\d+(\.\d+)?$/.test(trimmed) ? `${trimmed}px` : trimmed; + return {large: radiusStr, medium: radiusStr, small: radiusStr}; +}; + +export default normalizeBorderRadius; diff --git a/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts b/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts index c712bd8..25d286d 100644 --- a/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts +++ b/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts @@ -16,7 +16,7 @@ * under the License. */ -import {FlowMetaTheme, FlowMetaThemeColorScheme, RecursivePartial, ThemeConfig} from '@thunderid/browser'; +import {FlowMetaTheme, FlowMetaThemeColorScheme, RecursivePartial, ThemeConfig, normalizeBorderRadius} from '@thunderid/browser'; /** * Converts a v2 `FlowMetaTheme` into a `RecursivePartial` that @@ -36,28 +36,7 @@ const buildThemeConfigFromFlowMeta = ( colorScheme: 'light' | 'dark', ): RecursivePartial => { const scheme: FlowMetaThemeColorScheme | undefined = flowMetaTheme.colorSchemes?.[colorScheme]; - const rawBorderRadius = flowMetaTheme.shape?.borderRadius; - - let borderRadiusConfig: {large?: string; medium?: string; small?: string} | undefined; - - // Normalize borderRadius into per-size tokens: if it's already a size object use it directly; - // otherwise coerce a bare number or numeric string to a px string and apply it uniformly. - if (rawBorderRadius !== undefined) { - if (typeof rawBorderRadius === 'object') { - const {small, medium, large} = rawBorderRadius; - if (small !== undefined || medium !== undefined || large !== undefined) { - borderRadiusConfig = { - ...(large !== undefined && {large}), - ...(medium !== undefined && {medium}), - ...(small !== undefined && {small}), - }; - } - } else { - const trimmed = String(rawBorderRadius).trim(); - const radiusStr = /^\d+(\.\d+)?$/.test(trimmed) ? `${trimmed}px` : trimmed; - borderRadiusConfig = {large: radiusStr, medium: radiusStr, small: radiusStr}; - } - } + const borderRadiusConfig = normalizeBorderRadius(flowMetaTheme.shape?.borderRadius); // Build only the colors that the server actually provided. // Each nested object is constructed incrementally so that absent fields are diff --git a/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts b/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts index 068bacc..3c3da3a 100644 --- a/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts +++ b/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts @@ -16,7 +16,7 @@ * under the License. */ -import {FlowMetaTheme, FlowMetaThemeColorScheme, RecursivePartial, ThemeConfig} from '@thunderid/browser'; +import {FlowMetaTheme, FlowMetaThemeColorScheme, RecursivePartial, ThemeConfig, normalizeBorderRadius} from '@thunderid/browser'; /** * Converts a v2 `FlowMetaTheme` into a `RecursivePartial` that @@ -31,28 +31,7 @@ const buildThemeConfigFromFlowMeta = ( colorScheme: 'light' | 'dark', ): RecursivePartial => { const scheme: FlowMetaThemeColorScheme | undefined = flowMetaTheme.colorSchemes?.[colorScheme]; - const rawBorderRadius = flowMetaTheme.shape?.borderRadius; - - let borderRadiusConfig: {large?: string; medium?: string; small?: string} | undefined; - - // Normalize borderRadius into per-size tokens: if it's already a size object use it directly; - // otherwise coerce a bare number or numeric string to a px string and apply it uniformly. - if (rawBorderRadius !== undefined) { - if (typeof rawBorderRadius === 'object') { - const {small, medium, large} = rawBorderRadius; - if (small !== undefined || medium !== undefined || large !== undefined) { - borderRadiusConfig = { - ...(large !== undefined && {large}), - ...(medium !== undefined && {medium}), - ...(small !== undefined && {small}), - }; - } - } else { - const trimmed = String(rawBorderRadius).trim(); - const radiusStr = /^\d+(\.\d+)?$/.test(trimmed) ? `${trimmed}px` : trimmed; - borderRadiusConfig = {large: radiusStr, medium: radiusStr, small: radiusStr}; - } - } + const borderRadiusConfig = normalizeBorderRadius(flowMetaTheme.shape?.borderRadius); let colors: RecursivePartial | undefined; From dcc0b01bb6fae65cad97ac61efc90739f368d200 Mon Sep 17 00:00:00 2001 From: Zeeshan Mehboob Date: Thu, 23 Jul 2026 11:26:03 +0530 Subject: [PATCH 5/8] [3914] remove flowmetathemesize import Signed-off-by: Zeeshan Mehboob --- packages/browser/src/theme/normalizeBorderRadius.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/browser/src/theme/normalizeBorderRadius.ts b/packages/browser/src/theme/normalizeBorderRadius.ts index c8eded3..2250f36 100644 --- a/packages/browser/src/theme/normalizeBorderRadius.ts +++ b/packages/browser/src/theme/normalizeBorderRadius.ts @@ -16,8 +16,18 @@ * under the License. */ -import {FlowMetaThemeShape, FlowMetaThemeSize} from '@thunderid/javascript'; +import {FlowMetaThemeShape} from '@thunderid/javascript'; +/** + * Size configuration in the v2 theme. + * + * @experimental This API may change in future versions + */ +interface FlowMetaThemeSize { + small?: string; + medium?: string; + large?: string; +} /** * Normalizes a raw `shape.borderRadius` value into per-size tokens suitable * for `ThemeConfig.borderRadius`. From c13ddeb2064a92fd3f97c65b28ad7240907a3919 Mon Sep 17 00:00:00 2001 From: Zeeshan Mehboob Date: Thu, 23 Jul 2026 19:14:48 +0530 Subject: [PATCH 6/8] [3914] lint issue fixed Signed-off-by: Zeeshan Mehboob --- packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts b/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts index 3c3da3a..9ad61d5 100644 --- a/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts +++ b/packages/vue/src/utils/buildThemeConfigFromFlowMeta.ts @@ -16,7 +16,13 @@ * under the License. */ -import {FlowMetaTheme, FlowMetaThemeColorScheme, RecursivePartial, ThemeConfig, normalizeBorderRadius} from '@thunderid/browser'; +import { + FlowMetaTheme, + FlowMetaThemeColorScheme, + RecursivePartial, + ThemeConfig, + normalizeBorderRadius, +} from '@thunderid/browser'; /** * Converts a v2 `FlowMetaTheme` into a `RecursivePartial` that From 9e832ad325bd27e9b7ea78b92fb8811361725e3c Mon Sep 17 00:00:00 2001 From: Zeeshan Mehboob Date: Thu, 23 Jul 2026 19:34:44 +0530 Subject: [PATCH 7/8] [3914] lint issue fixed Signed-off-by: Zeeshan Mehboob --- packages/react/src/utils/buildThemeConfigFromFlowMeta.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts b/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts index 25d286d..f69a49b 100644 --- a/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts +++ b/packages/react/src/utils/buildThemeConfigFromFlowMeta.ts @@ -16,7 +16,13 @@ * under the License. */ -import {FlowMetaTheme, FlowMetaThemeColorScheme, RecursivePartial, ThemeConfig, normalizeBorderRadius} from '@thunderid/browser'; +import { + FlowMetaTheme, + FlowMetaThemeColorScheme, + RecursivePartial, + ThemeConfig, + normalizeBorderRadius, +} from '@thunderid/browser'; /** * Converts a v2 `FlowMetaTheme` into a `RecursivePartial` that From a7aa79ca86f52c785e4f13f2e716ccaee697b7ce Mon Sep 17 00:00:00 2001 From: Zeeshan Mehboob Date: Thu, 23 Jul 2026 19:41:24 +0530 Subject: [PATCH 8/8] [3914] coderabbit comment resolved Signed-off-by: Zeeshan Mehboob --- packages/browser/src/theme/normalizeBorderRadius.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/browser/src/theme/normalizeBorderRadius.ts b/packages/browser/src/theme/normalizeBorderRadius.ts index 2250f36..2e54f39 100644 --- a/packages/browser/src/theme/normalizeBorderRadius.ts +++ b/packages/browser/src/theme/normalizeBorderRadius.ts @@ -50,7 +50,8 @@ const normalizeBorderRadius = (raw: FlowMetaThemeShape['borderRadius']): FlowMet } const trimmed: string = String(raw).trim(); - const radiusStr: string = /^\d+(\.\d+)?$/.test(trimmed) ? `${trimmed}px` : trimmed; + const radiusStr: string = + typeof raw === 'number' ? `${raw}px` : /^\d+(\.\d+)?$/.test(trimmed) ? `${trimmed}px` : trimmed; return {large: radiusStr, medium: radiusStr, small: radiusStr}; };