@gnl-org/base-design-system 0.1.0
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 +48 -0
- package/components/Button.tsx +77 -0
- package/components/Card.tsx +38 -0
- package/components/Checkbox.tsx +30 -0
- package/components/Radio.tsx +30 -0
- package/components/Typography.tsx +50 -0
- package/components/index.ts +5 -0
- package/dist/components/Button.d.ts +8 -0
- package/dist/components/Button.js +50 -0
- package/dist/components/Card.d.ts +6 -0
- package/dist/components/Card.js +19 -0
- package/dist/components/Checkbox.d.ts +6 -0
- package/dist/components/Checkbox.js +14 -0
- package/dist/components/Radio.d.ts +6 -0
- package/dist/components/Radio.js +14 -0
- package/dist/components/Typography.d.ts +8 -0
- package/dist/components/Typography.js +29 -0
- package/dist/components/index.d.ts +5 -0
- package/dist/components/index.js +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/theme/colors.d.ts +15 -0
- package/dist/theme/colors.js +16 -0
- package/dist/theme/cornerRadius.d.ts +9 -0
- package/dist/theme/cornerRadius.js +10 -0
- package/dist/theme/fonts.d.ts +20 -0
- package/dist/theme/fonts.js +21 -0
- package/dist/theme/index.d.ts +5 -0
- package/dist/theme/index.js +5 -0
- package/dist/theme/sizes.d.ts +9 -0
- package/dist/theme/sizes.js +10 -0
- package/dist/theme/spacers.d.ts +9 -0
- package/dist/theme/spacers.js +10 -0
- package/dist/utils/classNames.d.ts +1 -0
- package/dist/utils/classNames.js +4 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/styleHelpers.d.ts +2 -0
- package/dist/utils/styleHelpers.js +7 -0
- package/dist/utils/theme.d.ts +64 -0
- package/dist/utils/theme.js +13 -0
- package/package.json +25 -0
- package/theme/colors.ts +16 -0
- package/theme/cornerRadius.ts +10 -0
- package/theme/fonts.ts +21 -0
- package/theme/index.ts +5 -0
- package/theme/sizes.ts +10 -0
- package/theme/spacers.ts +10 -0
- package/utils/classNames.ts +4 -0
- package/utils/index.ts +3 -0
- package/utils/styleHelpers.ts +8 -0
- package/utils/theme.ts +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# @base/design-system
|
|
2
|
+
|
|
3
|
+
A reusable React design system with theme, colors, spacers, sizes, corner radius, fonts, and components (Button, Card, Typography, Checkbox, Radio, etc).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @base/design-system
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { Button, Card, Typography, Checkbox, Radio, theme } from '@base/design-system';
|
|
15
|
+
|
|
16
|
+
export default function Example() {
|
|
17
|
+
return (
|
|
18
|
+
<Card>
|
|
19
|
+
<Typography variant="h1">Hello Design System</Typography>
|
|
20
|
+
<Button variant="primary">Click me</Button>
|
|
21
|
+
<Checkbox label="Accept terms" />
|
|
22
|
+
<Radio label="Option 1" name="group" />
|
|
23
|
+
</Card>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Theming
|
|
29
|
+
|
|
30
|
+
All theme values (colors, spacers, sizes, fonts, etc) are exported from the `theme` object. You can use or override them as needed.
|
|
31
|
+
|
|
32
|
+
## Components
|
|
33
|
+
- **Button**: Variants: primary, secondary, outline, ghost. Sizes: sm, md, lg.
|
|
34
|
+
- **Card**: Variants: elevated, outlined, flat.
|
|
35
|
+
- **Typography**: Variants: display, h1, h2, h3, h4, body, caption.
|
|
36
|
+
- **Checkbox**: Custom styled checkbox.
|
|
37
|
+
- **Radio**: Custom styled radio.
|
|
38
|
+
|
|
39
|
+
## Development
|
|
40
|
+
|
|
41
|
+
- `npm run build` — Build the library to `dist/`
|
|
42
|
+
- `npm publish` — Publish to npm (after build)
|
|
43
|
+
|
|
44
|
+
## Example App
|
|
45
|
+
See the `example/` folder for a sample React app using this design system.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
MIT License
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { theme } from '../utils/theme';
|
|
3
|
+
import { classNames } from '../utils/classNames';
|
|
4
|
+
|
|
5
|
+
export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
6
|
+
variant?: 'primary' | 'secondary' | 'outline' | 'ghost';
|
|
7
|
+
size?: 'sm' | 'md' | 'lg';
|
|
8
|
+
fullWidth?: boolean;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const sizeStyles = {
|
|
12
|
+
sm: {
|
|
13
|
+
padding: `${theme.spacers.sm}px ${theme.spacers.md}px`,
|
|
14
|
+
fontSize: theme.fonts.size.sm,
|
|
15
|
+
},
|
|
16
|
+
md: {
|
|
17
|
+
padding: `${theme.spacers.md}px ${theme.spacers.lg}px`,
|
|
18
|
+
fontSize: theme.fonts.size.md,
|
|
19
|
+
},
|
|
20
|
+
lg: {
|
|
21
|
+
padding: `${theme.spacers.lg}px ${theme.spacers.xl}px`,
|
|
22
|
+
fontSize: theme.fonts.size.lg,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const Button: React.FC<ButtonProps> = ({
|
|
27
|
+
children,
|
|
28
|
+
variant = 'primary',
|
|
29
|
+
size = 'md',
|
|
30
|
+
fullWidth = false,
|
|
31
|
+
className,
|
|
32
|
+
style,
|
|
33
|
+
...props
|
|
34
|
+
}) => {
|
|
35
|
+
const baseStyle: React.CSSProperties = {
|
|
36
|
+
borderRadius: theme.cornerRadius.md,
|
|
37
|
+
fontFamily: theme.fonts.family.sans,
|
|
38
|
+
fontWeight: theme.fonts.weight.medium,
|
|
39
|
+
border: 'none',
|
|
40
|
+
cursor: 'pointer',
|
|
41
|
+
transition: 'background 0.2s, color 0.2s',
|
|
42
|
+
width: fullWidth ? '100%' : undefined,
|
|
43
|
+
...sizeStyles[size],
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const variants: Record<string, React.CSSProperties> = {
|
|
47
|
+
primary: {
|
|
48
|
+
background: theme.colors.primary,
|
|
49
|
+
color: '#fff',
|
|
50
|
+
},
|
|
51
|
+
secondary: {
|
|
52
|
+
background: theme.colors.secondary,
|
|
53
|
+
color: '#fff',
|
|
54
|
+
},
|
|
55
|
+
outline: {
|
|
56
|
+
background: 'transparent',
|
|
57
|
+
color: theme.colors.primary,
|
|
58
|
+
border: `1px solid ${theme.colors.primary}`,
|
|
59
|
+
},
|
|
60
|
+
ghost: {
|
|
61
|
+
background: 'transparent',
|
|
62
|
+
color: theme.colors.primary,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<button
|
|
68
|
+
className={classNames('ds-btn', className)}
|
|
69
|
+
style={{ ...baseStyle, ...variants[variant], ...style }}
|
|
70
|
+
{...props}
|
|
71
|
+
>
|
|
72
|
+
{children}
|
|
73
|
+
</button>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export default Button;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { theme } from '../utils/theme';
|
|
3
|
+
import { classNames } from '../utils/classNames';
|
|
4
|
+
|
|
5
|
+
export type CardProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
6
|
+
variant?: 'elevated' | 'outlined' | 'flat';
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Card: React.FC<CardProps> = ({
|
|
10
|
+
children,
|
|
11
|
+
variant = 'elevated',
|
|
12
|
+
className,
|
|
13
|
+
style,
|
|
14
|
+
...props
|
|
15
|
+
}) => {
|
|
16
|
+
const baseStyle: React.CSSProperties = {
|
|
17
|
+
background: theme.colors.surface,
|
|
18
|
+
borderRadius: theme.cornerRadius.lg,
|
|
19
|
+
padding: theme.spacers.lg,
|
|
20
|
+
boxSizing: 'border-box',
|
|
21
|
+
boxShadow:
|
|
22
|
+
variant === 'elevated'
|
|
23
|
+
? '0 2px 8px rgba(0,0,0,0.08)'
|
|
24
|
+
: undefined,
|
|
25
|
+
border:
|
|
26
|
+
variant === 'outlined'
|
|
27
|
+
? `1px solid ${theme.colors.border}`
|
|
28
|
+
: undefined,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div className={classNames('ds-card', className)} style={{ ...baseStyle, ...style }} {...props}>
|
|
33
|
+
{children}
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default Card;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { theme } from '../utils/theme';
|
|
3
|
+
import { classNames } from '../utils/classNames';
|
|
4
|
+
|
|
5
|
+
export type CheckboxProps = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
6
|
+
label?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Checkbox: React.FC<CheckboxProps> = ({ label, className, style, ...props }) => {
|
|
10
|
+
return (
|
|
11
|
+
<label className={classNames('ds-checkbox-label', className)} style={{ display: 'inline-flex', alignItems: 'center', cursor: 'pointer', ...style }}>
|
|
12
|
+
<input
|
|
13
|
+
type="checkbox"
|
|
14
|
+
className="ds-checkbox"
|
|
15
|
+
style={{
|
|
16
|
+
width: theme.sizes.sm,
|
|
17
|
+
height: theme.sizes.sm,
|
|
18
|
+
borderRadius: theme.cornerRadius.sm,
|
|
19
|
+
border: `1.5px solid ${theme.colors.border}`,
|
|
20
|
+
accentColor: theme.colors.primary,
|
|
21
|
+
marginRight: theme.spacers.sm,
|
|
22
|
+
}}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
{label && <span style={{ fontFamily: theme.fonts.family.sans, fontSize: theme.fonts.size.md, color: theme.colors.text }}>{label}</span>}
|
|
26
|
+
</label>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default Checkbox;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { theme } from '../utils/theme';
|
|
3
|
+
import { classNames } from '../utils/classNames';
|
|
4
|
+
|
|
5
|
+
export type RadioProps = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
6
|
+
label?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Radio: React.FC<RadioProps> = ({ label, className, style, ...props }) => {
|
|
10
|
+
return (
|
|
11
|
+
<label className={classNames('ds-radio-label', className)} style={{ display: 'inline-flex', alignItems: 'center', cursor: 'pointer', ...style }}>
|
|
12
|
+
<input
|
|
13
|
+
type="radio"
|
|
14
|
+
className="ds-radio"
|
|
15
|
+
style={{
|
|
16
|
+
width: theme.sizes.sm,
|
|
17
|
+
height: theme.sizes.sm,
|
|
18
|
+
borderRadius: '50%',
|
|
19
|
+
border: `1.5px solid ${theme.colors.border}`,
|
|
20
|
+
accentColor: theme.colors.primary,
|
|
21
|
+
marginRight: theme.spacers.sm,
|
|
22
|
+
}}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
{label && <span style={{ fontFamily: theme.fonts.family.sans, fontSize: theme.fonts.size.md, color: theme.colors.text }}>{label}</span>}
|
|
26
|
+
</label>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default Radio;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { theme } from '../utils/theme';
|
|
3
|
+
import { classNames } from '../utils/classNames';
|
|
4
|
+
|
|
5
|
+
export type TypographyProps = React.HTMLAttributes<HTMLElement> & {
|
|
6
|
+
variant?: 'display' | 'h1' | 'h2' | 'h3' | 'h4' | 'body' | 'caption';
|
|
7
|
+
as?: keyof JSX.IntrinsicElements;
|
|
8
|
+
weight?: 'regular' | 'medium' | 'bold';
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const variantMap = {
|
|
12
|
+
display: { as: 'h1', fontSize: theme.fonts.size.display, fontWeight: theme.fonts.weight.bold },
|
|
13
|
+
h1: { as: 'h1', fontSize: theme.fonts.size.xxl, fontWeight: theme.fonts.weight.bold },
|
|
14
|
+
h2: { as: 'h2', fontSize: theme.fonts.size.xl, fontWeight: theme.fonts.weight.bold },
|
|
15
|
+
h3: { as: 'h3', fontSize: theme.fonts.size.lg, fontWeight: theme.fonts.weight.medium },
|
|
16
|
+
h4: { as: 'h4', fontSize: theme.fonts.size.md, fontWeight: theme.fonts.weight.medium },
|
|
17
|
+
body: { as: 'p', fontSize: theme.fonts.size.md, fontWeight: theme.fonts.weight.regular },
|
|
18
|
+
caption: { as: 'span', fontSize: theme.fonts.size.sm, fontWeight: theme.fonts.weight.regular },
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const Typography: React.FC<TypographyProps> = ({
|
|
22
|
+
children,
|
|
23
|
+
variant = 'body',
|
|
24
|
+
as,
|
|
25
|
+
weight,
|
|
26
|
+
className,
|
|
27
|
+
style,
|
|
28
|
+
...props
|
|
29
|
+
}) => {
|
|
30
|
+
const v = variantMap[variant];
|
|
31
|
+
const Tag = as || v.as;
|
|
32
|
+
return React.createElement(
|
|
33
|
+
Tag,
|
|
34
|
+
{
|
|
35
|
+
className: classNames('ds-typography', className),
|
|
36
|
+
style: {
|
|
37
|
+
fontFamily: theme.fonts.family.sans,
|
|
38
|
+
fontSize: v.fontSize,
|
|
39
|
+
fontWeight: weight ? theme.fonts.weight[weight] : v.fontWeight,
|
|
40
|
+
color: theme.colors.text,
|
|
41
|
+
margin: 0,
|
|
42
|
+
...style,
|
|
43
|
+
},
|
|
44
|
+
...props,
|
|
45
|
+
},
|
|
46
|
+
children
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default Typography;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
3
|
+
variant?: 'primary' | 'secondary' | 'outline' | 'ghost';
|
|
4
|
+
size?: 'sm' | 'md' | 'lg';
|
|
5
|
+
fullWidth?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare const Button: React.FC<ButtonProps>;
|
|
8
|
+
export default Button;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { theme } from '../utils/theme';
|
|
3
|
+
import { classNames } from '../utils/classNames';
|
|
4
|
+
const sizeStyles = {
|
|
5
|
+
sm: {
|
|
6
|
+
padding: `${theme.spacers.sm}px ${theme.spacers.md}px`,
|
|
7
|
+
fontSize: theme.fonts.size.sm,
|
|
8
|
+
},
|
|
9
|
+
md: {
|
|
10
|
+
padding: `${theme.spacers.md}px ${theme.spacers.lg}px`,
|
|
11
|
+
fontSize: theme.fonts.size.md,
|
|
12
|
+
},
|
|
13
|
+
lg: {
|
|
14
|
+
padding: `${theme.spacers.lg}px ${theme.spacers.xl}px`,
|
|
15
|
+
fontSize: theme.fonts.size.lg,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
export const Button = ({ children, variant = 'primary', size = 'md', fullWidth = false, className, style, ...props }) => {
|
|
19
|
+
const baseStyle = {
|
|
20
|
+
borderRadius: theme.cornerRadius.md,
|
|
21
|
+
fontFamily: theme.fonts.family.sans,
|
|
22
|
+
fontWeight: theme.fonts.weight.medium,
|
|
23
|
+
border: 'none',
|
|
24
|
+
cursor: 'pointer',
|
|
25
|
+
transition: 'background 0.2s, color 0.2s',
|
|
26
|
+
width: fullWidth ? '100%' : undefined,
|
|
27
|
+
...sizeStyles[size],
|
|
28
|
+
};
|
|
29
|
+
const variants = {
|
|
30
|
+
primary: {
|
|
31
|
+
background: theme.colors.primary,
|
|
32
|
+
color: '#fff',
|
|
33
|
+
},
|
|
34
|
+
secondary: {
|
|
35
|
+
background: theme.colors.secondary,
|
|
36
|
+
color: '#fff',
|
|
37
|
+
},
|
|
38
|
+
outline: {
|
|
39
|
+
background: 'transparent',
|
|
40
|
+
color: theme.colors.primary,
|
|
41
|
+
border: `1px solid ${theme.colors.primary}`,
|
|
42
|
+
},
|
|
43
|
+
ghost: {
|
|
44
|
+
background: 'transparent',
|
|
45
|
+
color: theme.colors.primary,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
return (_jsx("button", { className: classNames('ds-btn', className), style: { ...baseStyle, ...variants[variant], ...style }, ...props, children: children }));
|
|
49
|
+
};
|
|
50
|
+
export default Button;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { theme } from '../utils/theme';
|
|
3
|
+
import { classNames } from '../utils/classNames';
|
|
4
|
+
export const Card = ({ children, variant = 'elevated', className, style, ...props }) => {
|
|
5
|
+
const baseStyle = {
|
|
6
|
+
background: theme.colors.surface,
|
|
7
|
+
borderRadius: theme.cornerRadius.lg,
|
|
8
|
+
padding: theme.spacers.lg,
|
|
9
|
+
boxSizing: 'border-box',
|
|
10
|
+
boxShadow: variant === 'elevated'
|
|
11
|
+
? '0 2px 8px rgba(0,0,0,0.08)'
|
|
12
|
+
: undefined,
|
|
13
|
+
border: variant === 'outlined'
|
|
14
|
+
? `1px solid ${theme.colors.border}`
|
|
15
|
+
: undefined,
|
|
16
|
+
};
|
|
17
|
+
return (_jsx("div", { className: classNames('ds-card', className), style: { ...baseStyle, ...style }, ...props, children: children }));
|
|
18
|
+
};
|
|
19
|
+
export default Card;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { theme } from '../utils/theme';
|
|
3
|
+
import { classNames } from '../utils/classNames';
|
|
4
|
+
export const Checkbox = ({ label, className, style, ...props }) => {
|
|
5
|
+
return (_jsxs("label", { className: classNames('ds-checkbox-label', className), style: { display: 'inline-flex', alignItems: 'center', cursor: 'pointer', ...style }, children: [_jsx("input", { type: "checkbox", className: "ds-checkbox", style: {
|
|
6
|
+
width: theme.sizes.sm,
|
|
7
|
+
height: theme.sizes.sm,
|
|
8
|
+
borderRadius: theme.cornerRadius.sm,
|
|
9
|
+
border: `1.5px solid ${theme.colors.border}`,
|
|
10
|
+
accentColor: theme.colors.primary,
|
|
11
|
+
marginRight: theme.spacers.sm,
|
|
12
|
+
}, ...props }), label && _jsx("span", { style: { fontFamily: theme.fonts.family.sans, fontSize: theme.fonts.size.md, color: theme.colors.text }, children: label })] }));
|
|
13
|
+
};
|
|
14
|
+
export default Checkbox;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { theme } from '../utils/theme';
|
|
3
|
+
import { classNames } from '../utils/classNames';
|
|
4
|
+
export const Radio = ({ label, className, style, ...props }) => {
|
|
5
|
+
return (_jsxs("label", { className: classNames('ds-radio-label', className), style: { display: 'inline-flex', alignItems: 'center', cursor: 'pointer', ...style }, children: [_jsx("input", { type: "radio", className: "ds-radio", style: {
|
|
6
|
+
width: theme.sizes.sm,
|
|
7
|
+
height: theme.sizes.sm,
|
|
8
|
+
borderRadius: '50%',
|
|
9
|
+
border: `1.5px solid ${theme.colors.border}`,
|
|
10
|
+
accentColor: theme.colors.primary,
|
|
11
|
+
marginRight: theme.spacers.sm,
|
|
12
|
+
}, ...props }), label && _jsx("span", { style: { fontFamily: theme.fonts.family.sans, fontSize: theme.fonts.size.md, color: theme.colors.text }, children: label })] }));
|
|
13
|
+
};
|
|
14
|
+
export default Radio;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type TypographyProps = React.HTMLAttributes<HTMLElement> & {
|
|
3
|
+
variant?: 'display' | 'h1' | 'h2' | 'h3' | 'h4' | 'body' | 'caption';
|
|
4
|
+
as?: keyof JSX.IntrinsicElements;
|
|
5
|
+
weight?: 'regular' | 'medium' | 'bold';
|
|
6
|
+
};
|
|
7
|
+
export declare const Typography: React.FC<TypographyProps>;
|
|
8
|
+
export default Typography;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { theme } from '../utils/theme';
|
|
3
|
+
import { classNames } from '../utils/classNames';
|
|
4
|
+
const variantMap = {
|
|
5
|
+
display: { as: 'h1', fontSize: theme.fonts.size.display, fontWeight: theme.fonts.weight.bold },
|
|
6
|
+
h1: { as: 'h1', fontSize: theme.fonts.size.xxl, fontWeight: theme.fonts.weight.bold },
|
|
7
|
+
h2: { as: 'h2', fontSize: theme.fonts.size.xl, fontWeight: theme.fonts.weight.bold },
|
|
8
|
+
h3: { as: 'h3', fontSize: theme.fonts.size.lg, fontWeight: theme.fonts.weight.medium },
|
|
9
|
+
h4: { as: 'h4', fontSize: theme.fonts.size.md, fontWeight: theme.fonts.weight.medium },
|
|
10
|
+
body: { as: 'p', fontSize: theme.fonts.size.md, fontWeight: theme.fonts.weight.regular },
|
|
11
|
+
caption: { as: 'span', fontSize: theme.fonts.size.sm, fontWeight: theme.fonts.weight.regular },
|
|
12
|
+
};
|
|
13
|
+
export const Typography = ({ children, variant = 'body', as, weight, className, style, ...props }) => {
|
|
14
|
+
const v = variantMap[variant];
|
|
15
|
+
const Tag = as || v.as;
|
|
16
|
+
return React.createElement(Tag, {
|
|
17
|
+
className: classNames('ds-typography', className),
|
|
18
|
+
style: {
|
|
19
|
+
fontFamily: theme.fonts.family.sans,
|
|
20
|
+
fontSize: v.fontSize,
|
|
21
|
+
fontWeight: weight ? theme.fonts.weight[weight] : v.fontWeight,
|
|
22
|
+
color: theme.colors.text,
|
|
23
|
+
margin: 0,
|
|
24
|
+
...style,
|
|
25
|
+
},
|
|
26
|
+
...props,
|
|
27
|
+
}, children);
|
|
28
|
+
};
|
|
29
|
+
export default Typography;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const colors: {
|
|
2
|
+
primary: string;
|
|
3
|
+
primaryDark: string;
|
|
4
|
+
secondary: string;
|
|
5
|
+
secondaryDark: string;
|
|
6
|
+
success: string;
|
|
7
|
+
error: string;
|
|
8
|
+
warning: string;
|
|
9
|
+
info: string;
|
|
10
|
+
background: string;
|
|
11
|
+
surface: string;
|
|
12
|
+
border: string;
|
|
13
|
+
text: string;
|
|
14
|
+
muted: string;
|
|
15
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Color palette for the design system
|
|
2
|
+
export const colors = {
|
|
3
|
+
primary: '#2563eb',
|
|
4
|
+
primaryDark: '#1e40af',
|
|
5
|
+
secondary: '#f59e42',
|
|
6
|
+
secondaryDark: '#b45309',
|
|
7
|
+
success: '#22c55e',
|
|
8
|
+
error: '#ef4444',
|
|
9
|
+
warning: '#facc15',
|
|
10
|
+
info: '#0ea5e9',
|
|
11
|
+
background: '#ffffff',
|
|
12
|
+
surface: '#f3f4f6',
|
|
13
|
+
border: '#e5e7eb',
|
|
14
|
+
text: '#111827',
|
|
15
|
+
muted: '#6b7280',
|
|
16
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const fonts: {
|
|
2
|
+
family: {
|
|
3
|
+
sans: string;
|
|
4
|
+
mono: string;
|
|
5
|
+
};
|
|
6
|
+
size: {
|
|
7
|
+
xs: number;
|
|
8
|
+
sm: number;
|
|
9
|
+
md: number;
|
|
10
|
+
lg: number;
|
|
11
|
+
xl: number;
|
|
12
|
+
xxl: number;
|
|
13
|
+
display: number;
|
|
14
|
+
};
|
|
15
|
+
weight: {
|
|
16
|
+
regular: number;
|
|
17
|
+
medium: number;
|
|
18
|
+
bold: number;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Font families and sizes
|
|
2
|
+
export const fonts = {
|
|
3
|
+
family: {
|
|
4
|
+
sans: 'Inter, system-ui, Avenir, Helvetica, Arial, sans-serif',
|
|
5
|
+
mono: 'Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
|
6
|
+
},
|
|
7
|
+
size: {
|
|
8
|
+
xs: 12,
|
|
9
|
+
sm: 14,
|
|
10
|
+
md: 16,
|
|
11
|
+
lg: 20,
|
|
12
|
+
xl: 24,
|
|
13
|
+
xxl: 32,
|
|
14
|
+
display: 48,
|
|
15
|
+
},
|
|
16
|
+
weight: {
|
|
17
|
+
regular: 400,
|
|
18
|
+
medium: 500,
|
|
19
|
+
bold: 700,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function classNames(...args: (string | undefined | false | null)[]): string;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export declare const theme: {
|
|
2
|
+
colors: {
|
|
3
|
+
primary: string;
|
|
4
|
+
primaryDark: string;
|
|
5
|
+
secondary: string;
|
|
6
|
+
secondaryDark: string;
|
|
7
|
+
success: string;
|
|
8
|
+
error: string;
|
|
9
|
+
warning: string;
|
|
10
|
+
info: string;
|
|
11
|
+
background: string;
|
|
12
|
+
surface: string;
|
|
13
|
+
border: string;
|
|
14
|
+
text: string;
|
|
15
|
+
muted: string;
|
|
16
|
+
};
|
|
17
|
+
spacers: {
|
|
18
|
+
none: number;
|
|
19
|
+
xs: number;
|
|
20
|
+
sm: number;
|
|
21
|
+
md: number;
|
|
22
|
+
lg: number;
|
|
23
|
+
xl: number;
|
|
24
|
+
xxl: number;
|
|
25
|
+
};
|
|
26
|
+
sizes: {
|
|
27
|
+
xs: number;
|
|
28
|
+
sm: number;
|
|
29
|
+
md: number;
|
|
30
|
+
lg: number;
|
|
31
|
+
xl: number;
|
|
32
|
+
xxl: number;
|
|
33
|
+
full: string;
|
|
34
|
+
};
|
|
35
|
+
cornerRadius: {
|
|
36
|
+
none: number;
|
|
37
|
+
sm: number;
|
|
38
|
+
md: number;
|
|
39
|
+
lg: number;
|
|
40
|
+
xl: number;
|
|
41
|
+
pill: number;
|
|
42
|
+
circle: string;
|
|
43
|
+
};
|
|
44
|
+
fonts: {
|
|
45
|
+
family: {
|
|
46
|
+
sans: string;
|
|
47
|
+
mono: string;
|
|
48
|
+
};
|
|
49
|
+
size: {
|
|
50
|
+
xs: number;
|
|
51
|
+
sm: number;
|
|
52
|
+
md: number;
|
|
53
|
+
lg: number;
|
|
54
|
+
xl: number;
|
|
55
|
+
xxl: number;
|
|
56
|
+
display: number;
|
|
57
|
+
};
|
|
58
|
+
weight: {
|
|
59
|
+
regular: number;
|
|
60
|
+
medium: number;
|
|
61
|
+
bold: number;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Utility to get theme values
|
|
2
|
+
import { colors } from '../theme/colors';
|
|
3
|
+
import { spacers } from '../theme/spacers';
|
|
4
|
+
import { sizes } from '../theme/sizes';
|
|
5
|
+
import { cornerRadius } from '../theme/cornerRadius';
|
|
6
|
+
import { fonts } from '../theme/fonts';
|
|
7
|
+
export const theme = {
|
|
8
|
+
colors,
|
|
9
|
+
spacers,
|
|
10
|
+
sizes,
|
|
11
|
+
cornerRadius,
|
|
12
|
+
fonts,
|
|
13
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gnl-org/base-design-system",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A reusable React design system with theme, colors, spacers, sizes, corner radius, fonts, and components.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": ["dist", "theme", "components", "utils"],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc --project tsconfig.json",
|
|
11
|
+
"prepublishOnly": "npm run build"
|
|
12
|
+
},
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"react": ">=17.0.0",
|
|
15
|
+
"react-dom": ">=17.0.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"typescript": "^5.0.0",
|
|
19
|
+
"@types/react": "^18.0.0",
|
|
20
|
+
"@types/react-dom": "^18.0.0"
|
|
21
|
+
},
|
|
22
|
+
"keywords": ["react", "design-system", "ui", "components", "theme"],
|
|
23
|
+
"author": "Your Name",
|
|
24
|
+
"license": "MIT"
|
|
25
|
+
}
|
package/theme/colors.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Color palette for the design system
|
|
2
|
+
export const colors = {
|
|
3
|
+
primary: '#2563eb',
|
|
4
|
+
primaryDark: '#1e40af',
|
|
5
|
+
secondary: '#f59e42',
|
|
6
|
+
secondaryDark: '#b45309',
|
|
7
|
+
success: '#22c55e',
|
|
8
|
+
error: '#ef4444',
|
|
9
|
+
warning: '#facc15',
|
|
10
|
+
info: '#0ea5e9',
|
|
11
|
+
background: '#ffffff',
|
|
12
|
+
surface: '#f3f4f6',
|
|
13
|
+
border: '#e5e7eb',
|
|
14
|
+
text: '#111827',
|
|
15
|
+
muted: '#6b7280',
|
|
16
|
+
};
|
package/theme/fonts.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Font families and sizes
|
|
2
|
+
export const fonts = {
|
|
3
|
+
family: {
|
|
4
|
+
sans: 'Inter, system-ui, Avenir, Helvetica, Arial, sans-serif',
|
|
5
|
+
mono: 'Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
|
6
|
+
},
|
|
7
|
+
size: {
|
|
8
|
+
xs: 12,
|
|
9
|
+
sm: 14,
|
|
10
|
+
md: 16,
|
|
11
|
+
lg: 20,
|
|
12
|
+
xl: 24,
|
|
13
|
+
xxl: 32,
|
|
14
|
+
display: 48,
|
|
15
|
+
},
|
|
16
|
+
weight: {
|
|
17
|
+
regular: 400,
|
|
18
|
+
medium: 500,
|
|
19
|
+
bold: 700,
|
|
20
|
+
},
|
|
21
|
+
};
|
package/theme/index.ts
ADDED
package/theme/sizes.ts
ADDED
package/theme/spacers.ts
ADDED
package/utils/index.ts
ADDED
package/utils/theme.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Utility to get theme values
|
|
2
|
+
import { colors } from '../theme/colors';
|
|
3
|
+
import { spacers } from '../theme/spacers';
|
|
4
|
+
import { sizes } from '../theme/sizes';
|
|
5
|
+
import { cornerRadius } from '../theme/cornerRadius';
|
|
6
|
+
import { fonts } from '../theme/fonts';
|
|
7
|
+
|
|
8
|
+
export const theme = {
|
|
9
|
+
colors,
|
|
10
|
+
spacers,
|
|
11
|
+
sizes,
|
|
12
|
+
cornerRadius,
|
|
13
|
+
fonts,
|
|
14
|
+
};
|