diff --git a/packages/vkui/src/components/Box/Box.stories.tsx b/packages/vkui/src/components/Box/Box.stories.tsx index 2c3ed9f416a..1c234abb83e 100644 --- a/packages/vkui/src/components/Box/Box.stories.tsx +++ b/packages/vkui/src/components/Box/Box.stories.tsx @@ -19,7 +19,7 @@ type Story = StoryObj; export const Playground: Story = { args: {}, render: (args) => ( - + {Array.from({ length: 5 }, (_, index) => { return ; })} diff --git a/packages/vkui/src/lib/layouts/layoutProps.ts b/packages/vkui/src/lib/layouts/layoutProps.ts index acd02a022a5..9893d5d0302 100644 --- a/packages/vkui/src/lib/layouts/layoutProps.ts +++ b/packages/vkui/src/lib/layouts/layoutProps.ts @@ -26,7 +26,7 @@ const CSS_INTRINSIC_KEYWORDS: CSSIntrinsicSizingKeywords[] = [ const CSS_GLOBAL_KEYWORDS: CSSGlobalValue[] = ['inherit', 'initial', 'unset']; const CSS_KEYWORDS = [...CSS_INTRINSIC_KEYWORDS, ...CSS_GLOBAL_KEYWORDS]; -const PADDING_VALUES = [...DESIGN_SYSTEM_SIZES, ...CSS_GLOBAL_KEYWORDS]; +const PADDING_VALUES = [...DESIGN_SYSTEM_SIZES, ...CSS_GLOBAL_KEYWORDS, 'system']; const SIZE_VALUES = CSS_KEYWORDS; const MINMAX_SIZE_VALUES = [...CSS_KEYWORDS.filter((opt) => opt !== 'auto')]; const FLEX_VALUES = CSS_GLOBAL_KEYWORDS; @@ -42,6 +42,9 @@ const OVERFLOW_VALUES: OverflowValue[] = [ ...CSS_GLOBAL_KEYWORDS, ]; +export const SYSTEM_PADDING_VERTICAL = 'var(--vkui--size_base_padding_vertical--regular)'; +export const SYSTEM_PADDING_HORIZONTAL = 'var(--vkui--size_base_padding_horizontal--regular)'; + export const LAYOUT_PROPS = { padding: PADDING_VALUES, paddingInline: PADDING_VALUES, diff --git a/packages/vkui/src/lib/layouts/resolveLayoutProps.test.ts b/packages/vkui/src/lib/layouts/resolveLayoutProps.test.ts index 8c0e8d3d596..796889a96a1 100644 --- a/packages/vkui/src/lib/layouts/resolveLayoutProps.test.ts +++ b/packages/vkui/src/lib/layouts/resolveLayoutProps.test.ts @@ -43,7 +43,7 @@ describe('resolveLayoutProps', () => { }); it('should handle string values from predefined list (position)', () => { - const props = { position: 'absolute' }; + const props = { position: 'absolute' as const }; const result = resolveLayoutProps(props); expect(result).toEqual({ diff --git a/packages/vkui/src/lib/layouts/resolveLayoutProps.ts b/packages/vkui/src/lib/layouts/resolveLayoutProps.ts index 00d066377d0..5b3dcbe8cb6 100644 --- a/packages/vkui/src/lib/layouts/resolveLayoutProps.ts +++ b/packages/vkui/src/lib/layouts/resolveLayoutProps.ts @@ -2,10 +2,12 @@ import { classNames } from '@vkontakte/vkjs'; import { mergeStyle } from '../../helpers/mergeStyle'; import { generateConstantClassName, generateVariable, generateVariableClassName } from './helpers'; import { LAYOUT_PROPS, type LayoutPropKeys } from './layoutProps'; +import type { LayoutProps } from './types'; -export type ComponentProps = { +export type ComponentProps = Partial & { className?: string; style?: React.CSSProperties; +} & { [key: string]: unknown; }; diff --git a/packages/vkui/src/lib/layouts/types.ts b/packages/vkui/src/lib/layouts/types.ts index 89a02802ab9..bafdf17cbff 100644 --- a/packages/vkui/src/lib/layouts/types.ts +++ b/packages/vkui/src/lib/layouts/types.ts @@ -14,7 +14,10 @@ export type PositionValue = 'static' | 'relative' | 'absolute' | 'fixed' | 'stic export type OverflowValue = 'visible' | 'hidden' | 'clip' | 'scroll' | 'auto' | CSSGlobalValue; // Тип для отступов -export type PaddingProp = LiteralUnion; +export type PaddingProp = LiteralUnion< + DesignSystemSize | CSSGlobalValue | 'system', + number | string +>; // Типы для параметров позиционирования export type InsetProp = LiteralUnion; diff --git a/tools/postcss-layout-classes/index.js b/tools/postcss-layout-classes/index.js index 3ea4c51cb08..7837c42aa05 100644 --- a/tools/postcss-layout-classes/index.js +++ b/tools/postcss-layout-classes/index.js @@ -60,6 +60,8 @@ module.exports = () => { const { LAYOUT_PROPS, DESIGN_SYSTEM_SIZES, + SYSTEM_PADDING_VERTICAL, + SYSTEM_PADDING_HORIZONTAL, generateConstantClassName, generateVariableClassName, generateVariable, @@ -82,6 +84,20 @@ module.exports = () => { values.forEach((value) => { const className = `.${generateConstantClassName(cssProperty, value)}`; + const getValue = () => { + if (cssProperty.startsWith('padding') && value === 'system') { + if (cssProperty.startsWith('padding-block')) { + return SYSTEM_PADDING_VERTICAL; + } else if (cssProperty.startsWith('padding-inline')) { + return SYSTEM_PADDING_HORIZONTAL; + } + return `${SYSTEM_PADDING_VERTICAL} ${SYSTEM_PADDING_HORIZONTAL}`; + } + return DESIGN_SYSTEM_SIZES.includes(value) + ? `var(--vkui--spacing_size_${value})` + : value; + }; + root.append({ selector: className, raws: { semicolon: true }, @@ -89,9 +105,7 @@ module.exports = () => { nodes: [ { prop: cssProperty, - value: DESIGN_SYSTEM_SIZES.includes(value) - ? `var(--vkui--spacing_size_${value})` - : value, + value: getValue(), source: root.source, }, ], diff --git a/tools/postcss-layout-classes/postcss-layout-classes.test.js.snapshot b/tools/postcss-layout-classes/postcss-layout-classes.test.js.snapshot index 5f94a71023a..fcbe36c2424 100644 --- a/tools/postcss-layout-classes/postcss-layout-classes.test.js.snapshot +++ b/tools/postcss-layout-classes/postcss-layout-classes.test.js.snapshot @@ -35,6 +35,9 @@ exports[`generate layout classes 1`] = ` .vkui-padding-unset { padding: unset; } +.vkui-padding-system { + padding: var(--vkui--size_base_padding_vertical--regular) var(--vkui--size_base_padding_horizontal--regular); +} .vkui-padding { padding: var(--vkui_internal--padding); } @@ -74,6 +77,9 @@ exports[`generate layout classes 1`] = ` .vkui-padding-inline-unset { padding-inline: unset; } +.vkui-padding-inline-system { + padding-inline: var(--vkui--size_base_padding_horizontal--regular); +} .vkui-padding-inline { padding-inline: var(--vkui_internal--padding-inline); } @@ -113,6 +119,9 @@ exports[`generate layout classes 1`] = ` .vkui-padding-block-unset { padding-block: unset; } +.vkui-padding-block-system { + padding-block: var(--vkui--size_base_padding_vertical--regular); +} .vkui-padding-block { padding-block: var(--vkui_internal--padding-block); } @@ -152,6 +161,9 @@ exports[`generate layout classes 1`] = ` .vkui-padding-inline-start-unset { padding-inline-start: unset; } +.vkui-padding-inline-start-system { + padding-inline-start: var(--vkui--size_base_padding_horizontal--regular); +} .vkui-padding-inline-start { padding-inline-start: var(--vkui_internal--padding-inline-start); } @@ -191,6 +203,9 @@ exports[`generate layout classes 1`] = ` .vkui-padding-inline-end-unset { padding-inline-end: unset; } +.vkui-padding-inline-end-system { + padding-inline-end: var(--vkui--size_base_padding_horizontal--regular); +} .vkui-padding-inline-end { padding-inline-end: var(--vkui_internal--padding-inline-end); } @@ -230,6 +245,9 @@ exports[`generate layout classes 1`] = ` .vkui-padding-block-start-unset { padding-block-start: unset; } +.vkui-padding-block-start-system { + padding-block-start: var(--vkui--size_base_padding_vertical--regular); +} .vkui-padding-block-start { padding-block-start: var(--vkui_internal--padding-block-start); } @@ -269,6 +287,9 @@ exports[`generate layout classes 1`] = ` .vkui-padding-block-end-unset { padding-block-end: unset; } +.vkui-padding-block-end-system { + padding-block-end: var(--vkui--size_base_padding_vertical--regular); +} .vkui-padding-block-end { padding-block-end: var(--vkui_internal--padding-block-end); } diff --git a/website/content/components/box.mdx b/website/content/components/box.mdx index ce365449843..35151915932 100644 --- a/website/content/components/box.mdx +++ b/website/content/components/box.mdx @@ -44,6 +44,7 @@ description: Универсальный компонент для создани - токены дизайн-системы VKUI (`'2xs', 'xs', 's', 'm', 'l', 'xl', '2xl', '3xl', '4xl'`); - стандартные CSS-значения (`'inherit'`, `'initial'`, `'unset'`); +- специальное значение `'system'` — автоматически устанавливает системные отступы VKUI (эквивалентно использованию `--vkui--size_base_padding_vertical--regular` и `--vkui--size_base_padding_horizontal--regular`); - числовые значения (будут преобразованы в пиксели); - любое валидное строковое значение (`"2rem", "10%"`, CSS-переменные).