From 816e0190a332ca19f22a625ee42325f59d21ef92 Mon Sep 17 00:00:00 2001 From: Andrey Yamanov Date: Mon, 24 Nov 2025 11:11:08 +0100 Subject: [PATCH] feat: fixed mod for dimensions --- .changeset/afraid-keys-approve.md | 5 +++++ chromatic.config.json | 9 +++++++++ package.json | 3 ++- src/stories/Tasty.docs.mdx | 3 ++- src/tasty/styles/dimension.test.ts | 28 ++++++++++++++++++++++++++++ src/tasty/styles/dimension.ts | 9 +++++++++ 6 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 .changeset/afraid-keys-approve.md create mode 100644 chromatic.config.json diff --git a/.changeset/afraid-keys-approve.md b/.changeset/afraid-keys-approve.md new file mode 100644 index 000000000..14942147b --- /dev/null +++ b/.changeset/afraid-keys-approve.md @@ -0,0 +1,5 @@ +--- +"@cube-dev/ui-kit": patch +--- + +Add `fixed` modifier to `height` and `width` styles. Use `fixed 10x` to set min, base, and max dimensions to the same value, creating a truly fixed size that cannot flex. diff --git a/chromatic.config.json b/chromatic.config.json new file mode 100644 index 000000000..7745ad808 --- /dev/null +++ b/chromatic.config.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://www.chromatic.com/config-file.schema.json", + "projectId": "Project:cube-ui-kit", + "onlyChanged": true, + "buildScriptName": "build-storybook", + "exitZeroOnChanges": true, + "exitOnceUploaded": true +} + diff --git a/package.json b/package.json index 0b1c94343..b15a02f48 100644 --- a/package.json +++ b/package.json @@ -39,8 +39,9 @@ "lint": "npm-run-all -p eslint prettier", "fix": "npm-run-all -p eslint:fix prettier:fix", "storybook": "STORYBOOK_MODE=stories storybook dev -p 6060", - "build-storybook": "STORYBOOK_MODE=stories storybook build", + "build-storybook": "STORYBOOK_MODE=stories storybook build --stats-json", "build-docs": "STORYBOOK_MODE=docs storybook build --docs -o storybook-docs", + "chromatic": "chromatic --only-changed", "build-static-docs": "npm run build-docs && node scripts/snapshot-docs.js", "size": "size-limit", "prepare": "husky install", diff --git a/src/stories/Tasty.docs.mdx b/src/stories/Tasty.docs.mdx index 86a2f9d5f..0b68a545a 100644 --- a/src/stories/Tasty.docs.mdx +++ b/src/stories/Tasty.docs.mdx @@ -372,6 +372,7 @@ width: '1x 10x', // min-width, max-width width: '1x 5x 10x', // min, value, max width: 'min 2x', // min-width only ('var(--gap)' default) width: 'max 100%', // max-width only ('100%' default) +width: 'fixed 10x', // Fixed size (all three equal: min, value, max) width: 'stretch', // Fill available space (browser-specific) // Default values: @@ -379,7 +380,7 @@ width: 'stretch', // Fill available space (browser-specific) // - Min default: 'var(--gap)' // - Max default: '100%' // Intrinsic sizing: max-content, min-content, fit-content, stretch -// Modifiers: min, max +// Modifiers: min, max, fixed // ✅ Prefer unified syntax over separate maxWidth/minWidth properties ``` diff --git a/src/tasty/styles/dimension.test.ts b/src/tasty/styles/dimension.test.ts index 888f70882..d69ac3ce1 100644 --- a/src/tasty/styles/dimension.test.ts +++ b/src/tasty/styles/dimension.test.ts @@ -110,4 +110,32 @@ describe('dimensionStyle – width & height helpers', () => { expect(parsed.output).toBe('calc-size(fit-content)'); expect(parsed.groups[0].values).toEqual(['calc-size(fit-content)']); }); + + test('fixed modifier with pixels', () => { + const res = widthStyle({ width: 'fixed 10px' }) as any; + expect(res.width).toBe('10px'); + expect(res['min-width']).toBe('10px'); + expect(res['max-width']).toBe('10px'); + }); + + test('fixed modifier with gap units', () => { + const res = heightStyle({ height: 'fixed 5x' }) as any; + expect(res.height).toBe('calc(5 * var(--gap))'); + expect(res['min-height']).toBe('calc(5 * var(--gap))'); + expect(res['max-height']).toBe('calc(5 * var(--gap))'); + }); + + test('fixed modifier with rem units', () => { + const res = widthStyle({ width: 'fixed 2rem' }) as any; + expect(res.width).toBe('2rem'); + expect(res['min-width']).toBe('2rem'); + expect(res['max-width']).toBe('2rem'); + }); + + test('fixed modifier with percentage', () => { + const res = heightStyle({ height: 'fixed 100%' }) as any; + expect(res.height).toBe('100%'); + expect(res['min-height']).toBe('100%'); + expect(res['max-height']).toBe('100%'); + }); }); diff --git a/src/tasty/styles/dimension.ts b/src/tasty/styles/dimension.ts index 2a3bc71b1..2efe0c25a 100644 --- a/src/tasty/styles/dimension.ts +++ b/src/tasty/styles/dimension.ts @@ -46,6 +46,15 @@ export function dimensionStyle(name) { styles[maxStyle] = values[0] || DEFAULT_MAX_SIZE; flag = true; break; + case 'fixed': { + // Fixed modifier: set all three dimensions to the same value + const fixedValue = values[0] || 'max-content'; + styles[minStyle] = fixedValue; + styles[name] = fixedValue; + styles[maxStyle] = fixedValue; + flag = true; + break; + } default: break; }