diff --git a/packages/devextreme-scss/scss/widgets/generic/checkBox/_sizes.scss b/packages/devextreme-scss/scss/widgets/generic/checkBox/_sizes.scss index 55d24ea98e3c..2fe26ef0c144 100644 --- a/packages/devextreme-scss/scss/widgets/generic/checkBox/_sizes.scss +++ b/packages/devextreme-scss/scss/widgets/generic/checkBox/_sizes.scss @@ -7,7 +7,7 @@ $generic-checkbox-icon-font-size: null !default; $generic-checkbox-border-width: 1px !default; -$generic-checkbox-border-radius: $base-border-radius-exsmall !default; +$generic-checkbox-border-radius: null !default; $generic-checkbox-arrow-icon-size: 1em !default; $generic-checkbox-arrow-font-size: null !default; @@ -18,10 +18,12 @@ $generic-checkbox-indeterminate-icon-border-radius: 2px !default; $generic-checkbox-icon-font-size: 22px !default; $generic-checkbox-arrow-font-size: 0.727273em !default; $generic-checkbox-indeterminate-icon-size: 0.545455em !default; + $generic-checkbox-border-radius: if($base-border-radius-exsmall, min($base-border-radius-exsmall, 2px), null) !default; } @else if $size == "compact" { $generic-checkbox-icon-font-size: 16px !default; $generic-checkbox-arrow-font-size: 0.625em !default; $generic-checkbox-indeterminate-icon-size: 0.5em !default; + $generic-checkbox-border-radius: if($base-border-radius-exsmall, min($base-border-radius-exsmall, 2px), null) !default; } diff --git a/packages/devextreme-scss/scss/widgets/material/checkBox/_sizes.scss b/packages/devextreme-scss/scss/widgets/material/checkBox/_sizes.scss index f7d9f0989a16..1acba7c28ef3 100644 --- a/packages/devextreme-scss/scss/widgets/material/checkBox/_sizes.scss +++ b/packages/devextreme-scss/scss/widgets/material/checkBox/_sizes.scss @@ -20,7 +20,7 @@ $material-checkbox-indeterminate-icon-width: null !default; $material-checkbox-icon-font-size: 18px !default; $material-checkbox-ripple-size: 2.222223em !default; - $material-checkbox-border-radius: $base-border-radius - 2px !default; + $material-checkbox-border-radius: min($base-border-radius - 2px, 2px) !default; $material-checkbox-arrow-font-size: 0.888889em !default; $material-checkbox-indeterminate-icon-height: 0.111112em !default; @@ -31,7 +31,7 @@ $material-checkbox-indeterminate-icon-width: null !default; $material-checkbox-icon-font-size: 16px !default; $material-checkbox-ripple-size: 2em !default; - $material-checkbox-border-radius: $base-border-radius !default; + $material-checkbox-border-radius: min($base-border-radius, 2px) !default; $material-checkbox-arrow-font-size: 0.875em !default; $material-checkbox-indeterminate-icon-height: 0.125em !default; diff --git a/packages/devextreme-scss/tests/checkbox-border-radius.test.ts b/packages/devextreme-scss/tests/checkbox-border-radius.test.ts new file mode 100644 index 000000000000..588d5f118af6 --- /dev/null +++ b/packages/devextreme-scss/tests/checkbox-border-radius.test.ts @@ -0,0 +1,102 @@ +import * as path from 'path'; +import { compileStringAsync } from 'sass-embedded'; + +const scssRoot = path.resolve(__dirname, '..', 'scss'); + +const probeSelector = '.probe'; + +const extractBorderRadius = (css: string): string | null => { + const match = css.match(/\.probe\s*\{\s*border-radius:\s*([^;}]+)/); + return match ? match[1].trim() : null; +}; + +const hasBorderRadiusDeclaration = (css: string): boolean => ( + /\.probe\s*\{\s*border-radius:/.test(css) +); + +const compile = async (source: string): Promise => { + const result = await compileStringAsync(source, { loadPaths: [scssRoot] }); + return result.css; +}; + +const genericSource = (baseBorderRadius: string): string => ` + @use "widgets/generic/colors" with ( + $color: "light", + $base-border-radius: ${baseBorderRadius} + ); + @use "widgets/generic/sizes" with ($size: "default"); + @use "widgets/generic/checkBox/sizes" as cb; + + ${probeSelector} { border-radius: cb.$generic-checkbox-border-radius; } +`; + +const genericContrastSource = (): string => ` + @use "widgets/generic/colors" with ($color: "contrast"); + @use "widgets/generic/sizes" with ($size: "default"); + @use "widgets/generic/checkBox/sizes" as cb; + + ${probeSelector} { border-radius: cb.$generic-checkbox-border-radius; } +`; + +const materialSource = ( + baseBorderRadius: string, + size: 'default' | 'compact' = 'default', +): string => ` + @use "widgets/material/colors" with ($color: "blue", $mode: "light"); + @use "widgets/material/sizes" with ( + $size: "${size}", + $base-border-radius: ${baseBorderRadius} + ); + @use "widgets/material/checkBox/sizes" as cb; + + ${probeSelector} { border-radius: cb.$material-checkbox-border-radius; } +`; + +describe('CheckBox border-radius capping (T1330300)', () => { + describe('generic theme', () => { + test('default radius keeps the original (small) value', async () => { + const css = await compile(genericSource('2px')); + expect(extractBorderRadius(css)).toBe('0px'); + }); + + test('large base-border-radius is capped at 2px', async () => { + const css = await compile(genericSource('12px')); + expect(extractBorderRadius(css)).toBe('2px'); + }) + + test('intermediate base-border-radius is not over-clamped', async () => { + const css = await compile(genericSource('3px')); + expect(extractBorderRadius(css)).toBe('1px'); + }); + + test('contrast color scheme (no exsmall) does not break compilation', async () => { + const css = await compile(genericContrastSource()); + // $base-border-radius-exsmall is null in contrast → border-radius must + // stay null (no declaration emitted), not throw on min(null, 2px). + expect(hasBorderRadiusDeclaration(css)).toBe(false); + }); + }); + + describe('material theme', () => { + test('default size: large base-border-radius is capped at 2px', async () => { + const css = await compile(materialSource('12px', 'default')); + expect(extractBorderRadius(css)).toBe('2px'); + }); + + test('default size: small base-border-radius is not over-clamped', async () => { + const css = await compile(materialSource('3px', 'default')); + expect(extractBorderRadius(css)).toBe('1px'); + }); + + test('compact size: large base-border-radius is capped at 2px', async () => { + const css = await compile(materialSource('12px', 'compact')); + expect(extractBorderRadius(css)).toBe('2px'); + }); + + test('compact size: small base-border-radius is not over-clamped', async () => { + const css = await compile(materialSource('1px', 'compact')); + expect(extractBorderRadius(css)).toBe('1px'); + }); + }); +}); +