@goncharovv/layout 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -0
- package/dist/esm/components/Stacks/HStack.d.ts +7 -0
- package/dist/esm/components/Stacks/HStack.js +14 -0
- package/dist/esm/components/Stacks/Stack.d.ts +11 -0
- package/dist/esm/components/Stacks/Stack.js +18 -0
- package/dist/esm/components/Stacks/VStack.d.ts +7 -0
- package/dist/esm/components/Stacks/VStack.js +14 -0
- package/dist/esm/components/Stacks/factory.d.ts +46 -0
- package/dist/esm/components/Stacks/factory.js +25 -0
- package/dist/esm/components/Stacks/index.d.ts +3 -0
- package/dist/esm/components/Stacks/index.js +3 -0
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/index.js +1 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/shared/spacings/config.d.ts +42 -0
- package/dist/esm/shared/spacings/config.js +30 -0
- package/dist/esm/shared/spacings/index.d.ts +1 -0
- package/dist/esm/shared/spacings/index.js +1 -0
- package/dist/esm/shared/types/index.d.ts +3 -0
- package/dist/esm/shared/types/index.js +1 -0
- package/dist/esm/ui-kit/Stacks/Stack.module.css +22 -0
- package/dist/styles/index.css +1 -0
- package/dist/styles/spacings.css +20 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# React + TypeScript + Vite
|
|
2
|
+
|
|
3
|
+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
|
4
|
+
|
|
5
|
+
Currently, two official plugins are available:
|
|
6
|
+
|
|
7
|
+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
|
|
8
|
+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
|
9
|
+
|
|
10
|
+
## Expanding the ESLint configuration
|
|
11
|
+
|
|
12
|
+
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
export default defineConfig([
|
|
16
|
+
globalIgnores(['dist']),
|
|
17
|
+
{
|
|
18
|
+
files: ['**/*.{ts,tsx}'],
|
|
19
|
+
extends: [
|
|
20
|
+
// Other configs...
|
|
21
|
+
|
|
22
|
+
// Remove tseslint.configs.recommended and replace with this
|
|
23
|
+
tseslint.configs.recommendedTypeChecked,
|
|
24
|
+
// Alternatively, use this for stricter rules
|
|
25
|
+
tseslint.configs.strictTypeChecked,
|
|
26
|
+
// Optionally, add this for stylistic rules
|
|
27
|
+
tseslint.configs.stylisticTypeChecked,
|
|
28
|
+
|
|
29
|
+
// Other configs...
|
|
30
|
+
],
|
|
31
|
+
languageOptions: {
|
|
32
|
+
parserOptions: {
|
|
33
|
+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
|
34
|
+
tsconfigRootDir: import.meta.dirname,
|
|
35
|
+
},
|
|
36
|
+
// other options...
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
])
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
// eslint.config.js
|
|
46
|
+
import reactX from 'eslint-plugin-react-x'
|
|
47
|
+
import reactDom from 'eslint-plugin-react-dom'
|
|
48
|
+
|
|
49
|
+
export default defineConfig([
|
|
50
|
+
globalIgnores(['dist']),
|
|
51
|
+
{
|
|
52
|
+
files: ['**/*.{ts,tsx}'],
|
|
53
|
+
extends: [
|
|
54
|
+
// Other configs...
|
|
55
|
+
// Enable lint rules for React
|
|
56
|
+
reactX.configs['recommended-typescript'],
|
|
57
|
+
// Enable lint rules for React DOM
|
|
58
|
+
reactDom.configs.recommended,
|
|
59
|
+
],
|
|
60
|
+
languageOptions: {
|
|
61
|
+
parserOptions: {
|
|
62
|
+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
|
63
|
+
tsconfigRootDir: import.meta.dirname,
|
|
64
|
+
},
|
|
65
|
+
// other options...
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
])
|
|
69
|
+
```
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BaseStackProps } from './factory';
|
|
2
|
+
export interface HStackProps extends BaseStackProps {
|
|
3
|
+
reverse?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare const HStack: <TElementType extends import("react").ElementType = "div">(props: {
|
|
6
|
+
as?: TElementType | undefined;
|
|
7
|
+
} & Omit<HStackProps, "as"> & Omit<import("react").PropsWithoutRef<import("react").ComponentProps<TElementType>>, "style" | "alignItems" | "align" | "justifyContent" | "justify" | "wrap" | "gap" | "centered" | "className" | "children" | "spacing" | "reverse">) => import("react").ReactNode;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import cn from 'classnames';
|
|
2
|
+
import { createStack } from './factory';
|
|
3
|
+
import styles from './Stack.module.css';
|
|
4
|
+
export const HStack = createStack('HStack', {
|
|
5
|
+
overrideProps: (props) => {
|
|
6
|
+
const { reverse, className, ...rest } = props;
|
|
7
|
+
return {
|
|
8
|
+
...rest,
|
|
9
|
+
className: cn(styles.horizontal, {
|
|
10
|
+
[styles.reversed]: reverse,
|
|
11
|
+
}, className),
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
import { BaseStackProps } from './factory';
|
|
3
|
+
export type StackDirection = 'vertical' | 'horizontal';
|
|
4
|
+
export interface StackProps extends BaseStackProps {
|
|
5
|
+
vertical?: boolean;
|
|
6
|
+
horizontal?: boolean;
|
|
7
|
+
direction?: CSSProperties['flexDirection'];
|
|
8
|
+
}
|
|
9
|
+
export declare const Stack: <TElementType extends import("react").ElementType = "div">(props: {
|
|
10
|
+
as?: TElementType | undefined;
|
|
11
|
+
} & Omit<StackProps, "as"> & Omit<import("react").PropsWithoutRef<import("react").ComponentProps<TElementType>>, "style" | "alignItems" | "align" | "justifyContent" | "justify" | "wrap" | "gap" | "centered" | "className" | "children" | "spacing" | "horizontal" | "vertical" | "direction">) => import("react").ReactNode;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import cn from 'classnames';
|
|
2
|
+
import { createStack } from './factory';
|
|
3
|
+
import styles from './Stack.module.css';
|
|
4
|
+
export const Stack = createStack('Stack', {
|
|
5
|
+
overrideProps: (props) => {
|
|
6
|
+
const { direction, horizontal, vertical, className, ...rest } = props;
|
|
7
|
+
return {
|
|
8
|
+
...rest,
|
|
9
|
+
className: cn({
|
|
10
|
+
[styles.vertical]: vertical,
|
|
11
|
+
[styles.horizontal]: horizontal,
|
|
12
|
+
}, className),
|
|
13
|
+
styles: {
|
|
14
|
+
flexDirection: direction,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BaseStackProps } from './factory';
|
|
2
|
+
export interface VStackProps extends BaseStackProps {
|
|
3
|
+
reverse?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare const VStack: <TElementType extends import("react").ElementType = "div">(props: {
|
|
6
|
+
as?: TElementType | undefined;
|
|
7
|
+
} & Omit<VStackProps, "as"> & Omit<import("react").PropsWithoutRef<import("react").ComponentProps<TElementType>>, "style" | "alignItems" | "align" | "justifyContent" | "justify" | "wrap" | "gap" | "centered" | "className" | "children" | "spacing" | "reverse">) => import("react").ReactNode;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import cn from 'classnames';
|
|
2
|
+
import { createStack } from './factory';
|
|
3
|
+
import styles from './Stack.module.css';
|
|
4
|
+
export const VStack = createStack('VStack', {
|
|
5
|
+
overrideProps: (props) => {
|
|
6
|
+
const { reverse, className, ...rest } = props;
|
|
7
|
+
return {
|
|
8
|
+
...rest,
|
|
9
|
+
className: cn(styles.vertical, {
|
|
10
|
+
[styles.reversed]: reverse,
|
|
11
|
+
}, className),
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React, { CSSProperties, ElementType, PropsWithChildren, ReactNode } from 'react';
|
|
2
|
+
import { PropsWithSpacing } from '../../shared/spacings';
|
|
3
|
+
import { Prettify } from '../../shared/types';
|
|
4
|
+
export interface BaseStackProps<TElementType extends ElementType = 'div'> extends PropsWithChildren, PropsWithSpacing {
|
|
5
|
+
as?: TElementType;
|
|
6
|
+
alignItems?: CSSProperties['alignItems'];
|
|
7
|
+
/**
|
|
8
|
+
* shortcut for `alignItems`
|
|
9
|
+
*/
|
|
10
|
+
align?: CSSProperties['alignItems'];
|
|
11
|
+
justifyContent?: CSSProperties['justifyContent'];
|
|
12
|
+
/**
|
|
13
|
+
* shortcut for `justifyContent`
|
|
14
|
+
*/
|
|
15
|
+
justify?: CSSProperties['justifyContent'];
|
|
16
|
+
/**
|
|
17
|
+
* `flex-wrap` property
|
|
18
|
+
*
|
|
19
|
+
* If value equals `true`, add css property `flex-wrap: wrap`;
|
|
20
|
+
*/
|
|
21
|
+
wrap?: true | CSSProperties['flexWrap'];
|
|
22
|
+
/**
|
|
23
|
+
* Custom gap. This is uncommon prop. Consider using `spacing` instead.
|
|
24
|
+
*/
|
|
25
|
+
gap?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Alias for:
|
|
28
|
+
* ```css
|
|
29
|
+
* justify-content: center;
|
|
30
|
+
* align-items: center;
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
centered?: boolean;
|
|
34
|
+
style?: CSSProperties;
|
|
35
|
+
className?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* `_TPropsHint` is used only to show in IDE list of own Stack props
|
|
39
|
+
*/
|
|
40
|
+
type StackPropsBuilder<TElementType extends ElementType, TProps, _TPropsHint = Prettify<TProps>> = {
|
|
41
|
+
as?: TElementType;
|
|
42
|
+
} & Omit<TProps, 'as'> & Omit<React.ComponentPropsWithoutRef<TElementType>, keyof Omit<TProps, 'as'>>;
|
|
43
|
+
export declare function createStack<TProps extends BaseStackProps>(name: string, options: {
|
|
44
|
+
overrideProps?: (props: TProps) => BaseStackProps;
|
|
45
|
+
}): <TElementType extends ElementType = "div">(props: StackPropsBuilder<TElementType, TProps>) => ReactNode;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { getSpacingStyles } from '../../shared/spacings';
|
|
4
|
+
import styles from './Stack.module.css';
|
|
5
|
+
export function createStack(name, options) {
|
|
6
|
+
const Component = function GenericStack(_props) {
|
|
7
|
+
const props = options.overrideProps ? options.overrideProps(_props) : _props;
|
|
8
|
+
// WARNING: Avoid proxying *component props* to real DOM
|
|
9
|
+
const { as: Element = 'div', align, alignItems, centered, gap, justify, justifyContent, spacing, style, wrap, className, children, ...rest } = props;
|
|
10
|
+
return (_jsx(Element, { ...rest, className: cn(styles.stack, {
|
|
11
|
+
[styles.centered]: centered,
|
|
12
|
+
}, className), style: {
|
|
13
|
+
gap: spacing ? getSpacingStyles(spacing).gap : gap,
|
|
14
|
+
flexWrap: wrap === true ? 'wrap' : wrap,
|
|
15
|
+
alignItems: centered ? undefined : (alignItems ?? align),
|
|
16
|
+
justifyContent: centered ? undefined : (justifyContent ?? justify),
|
|
17
|
+
...style,
|
|
18
|
+
}, children: children }));
|
|
19
|
+
};
|
|
20
|
+
Component.displayName = name;
|
|
21
|
+
/**
|
|
22
|
+
* Typing for better DX
|
|
23
|
+
*/
|
|
24
|
+
return Component;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Stacks';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Stacks';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
export declare const spacings: {
|
|
3
|
+
none: number;
|
|
4
|
+
'small-xs': number;
|
|
5
|
+
'small-s': number;
|
|
6
|
+
'small-m': number;
|
|
7
|
+
'small-l': number;
|
|
8
|
+
'medium-xs': number;
|
|
9
|
+
'medium-s': number;
|
|
10
|
+
'medium-m': number;
|
|
11
|
+
'medium-l': number;
|
|
12
|
+
'large-xxs': number;
|
|
13
|
+
'large-xs': number;
|
|
14
|
+
'large-s': number;
|
|
15
|
+
'large-m': number;
|
|
16
|
+
'large-l': number;
|
|
17
|
+
};
|
|
18
|
+
export type Spacing = keyof typeof spacings;
|
|
19
|
+
export interface PropsWithSpacing {
|
|
20
|
+
/**
|
|
21
|
+
* - none: 0px
|
|
22
|
+
* - small:
|
|
23
|
+
* - 'small-xs': 2px
|
|
24
|
+
* - 'small-s': 4px
|
|
25
|
+
* - 'small-m': 6px
|
|
26
|
+
* - 'small-l': 8px
|
|
27
|
+
* - medium:
|
|
28
|
+
* - 'medium-xs': 12px
|
|
29
|
+
* - 'medium-s': 16px
|
|
30
|
+
* - 'medium-m': 20px
|
|
31
|
+
* - 'medium-l': 24px
|
|
32
|
+
* - large:
|
|
33
|
+
* - 'large-xxs': 32px
|
|
34
|
+
* - 'large-xs': 40px
|
|
35
|
+
* - 'large-s': 48px
|
|
36
|
+
* - 'large-m': 64px
|
|
37
|
+
* - 'large-l': 80px
|
|
38
|
+
*/
|
|
39
|
+
spacing?: Spacing;
|
|
40
|
+
}
|
|
41
|
+
export declare function getSpacing(spacing: Spacing | undefined): number | undefined;
|
|
42
|
+
export declare function getSpacingStyles(spacing: Spacing | undefined): CSSProperties;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//
|
|
2
|
+
// MUST keep in sync with the `spacings.css`
|
|
3
|
+
//
|
|
4
|
+
export const spacings = {
|
|
5
|
+
'none': 0,
|
|
6
|
+
'small-xs': 2,
|
|
7
|
+
'small-s': 4,
|
|
8
|
+
'small-m': 6,
|
|
9
|
+
'small-l': 8,
|
|
10
|
+
'medium-xs': 12,
|
|
11
|
+
'medium-s': 16,
|
|
12
|
+
'medium-m': 20,
|
|
13
|
+
'medium-l': 24,
|
|
14
|
+
'large-xxs': 32,
|
|
15
|
+
'large-xs': 40,
|
|
16
|
+
'large-s': 48,
|
|
17
|
+
'large-m': 64,
|
|
18
|
+
'large-l': 80,
|
|
19
|
+
};
|
|
20
|
+
export function getSpacing(spacing) {
|
|
21
|
+
if (!spacing) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
return spacings[spacing];
|
|
25
|
+
}
|
|
26
|
+
export function getSpacingStyles(spacing) {
|
|
27
|
+
return {
|
|
28
|
+
gap: `var(--spacing-${spacing})`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './config';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './config';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.stack {
|
|
2
|
+
display: flex;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.vertical {
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
}
|
|
8
|
+
.vertical.reversed {
|
|
9
|
+
flex-direction: column-reverse;;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.horizontal {
|
|
13
|
+
flex-direction: row;
|
|
14
|
+
}
|
|
15
|
+
.horizontal.reversed {
|
|
16
|
+
flex-direction: row-reverse;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.centered {
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './spacings.css';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MUST keep in sync with the `shared/spacings/config.ts`
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
:root {
|
|
6
|
+
--spacing-small-xxs: 0px;
|
|
7
|
+
--spacing-small-xs: 2px;
|
|
8
|
+
--spacing-small-s: 4px;
|
|
9
|
+
--spacing-small-m: 6px;
|
|
10
|
+
--spacing-small-l: 8px;
|
|
11
|
+
--spacing-medium-xs: 12px;
|
|
12
|
+
--spacing-medium-s: 16px;
|
|
13
|
+
--spacing-medium-m: 20px;
|
|
14
|
+
--spacing-medium-l: 24px;
|
|
15
|
+
--spacing-large-xxs: 32px;
|
|
16
|
+
--spacing-large-xs: 40px;
|
|
17
|
+
--spacing-large-s: 48px;
|
|
18
|
+
--spacing-large-m: 64px;
|
|
19
|
+
--spacing-large-l: 80px;
|
|
20
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@goncharovv/layout",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/esm/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "vite",
|
|
13
|
+
"build": "gulp",
|
|
14
|
+
"lint": "eslint .",
|
|
15
|
+
"preview": "vite preview"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"classnames": "2.5.1"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"react": "^19",
|
|
22
|
+
"react-dom": "^19"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@goncharovv/eslint-config": "1.0.6",
|
|
26
|
+
"@gravity-ui/gulp-utils": "1.0.3",
|
|
27
|
+
"@types/react": "^19.1.13",
|
|
28
|
+
"@types/react-dom": "^19.1.9",
|
|
29
|
+
"@vitejs/plugin-react": "^5.0.2",
|
|
30
|
+
"eslint": "^9.35.0",
|
|
31
|
+
"globals": "16.4.0",
|
|
32
|
+
"gulp": "5.0.1",
|
|
33
|
+
"rimraf": "6.0.1",
|
|
34
|
+
"typescript": "~5.8.3",
|
|
35
|
+
"vite": "^7.1.6"
|
|
36
|
+
}
|
|
37
|
+
}
|