Skip to content

Commit d3c96b5

Browse files
authored
Merge pull request #5 from teambit/automations.design/design-system-foundation
feat: heading component and theme
2 parents 33592ec + 27ba12e commit d3c96b5

23 files changed

+1793
-418
lines changed

.bitmap

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@
99
*/
1010

1111
{
12+
"automations-theme": {
13+
"name": "automations-theme",
14+
"scope": "automations.design",
15+
"version": "7205314d3cc10458a251d9304828496b0d5187c8",
16+
"mainFile": "index.ts",
17+
"rootDir": "bit-components/design/automations-theme",
18+
"onLanesOnly": true,
19+
"isAvailableOnCurrentLane": true
20+
},
1221
"envs/automations-env": {
1322
"name": "envs/automations-env",
1423
"scope": "automations.design",
@@ -30,6 +39,15 @@
3039
"mainFile": "index.ts",
3140
"rootDir": "bit-components/design/patterns/header"
3241
},
42+
"typography/heading": {
43+
"name": "typography/heading",
44+
"scope": "automations.design",
45+
"version": "1d88b85c2d7a37a0daff860ab684dc15adcbae43",
46+
"mainFile": "index.ts",
47+
"rootDir": "bit-components/design/typography/heading",
48+
"onLanesOnly": true,
49+
"isAvailableOnCurrentLane": true
50+
},
3351
"ui/button": {
3452
"name": "ui/button",
3553
"scope": "automations.design",
@@ -58,5 +76,12 @@
5876
"mainFile": "index.ts",
5977
"rootDir": "bit-components/design/ui/input"
6078
},
61-
"$schema-version": "17.0.0"
79+
"$schema-version": "17.0.0",
80+
"_bit_lane": {
81+
"id": {
82+
"name": "design-system-foundation",
83+
"scope": "automations.design"
84+
},
85+
"exported": true
86+
}
6287
}

.github/workflows/pull-request.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
ws-dir: '.'
2222

2323
- name: Bit Pull Request
24-
uses: bit-tasks/pull-request@main
24+
uses: bit-tasks/pull-request@v3
2525
with:
2626
build: true
2727
version-labels: true

.github/workflows/verify.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
name: Bit verify
22

3-
on: push
3+
on:
4+
push:
5+
branches:
6+
- main
47

58
jobs:
69
verify:
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { createTheme } from '@bitdesign/sparks.sparks-theme';
2+
import { AutomationsThemeSchema, automationsTokens } from './automations-tokens.js';
3+
4+
/**
5+
* creating and declaring the automations theme.
6+
* define the theme schema as a type variable for proper type completions.
7+
*/
8+
export const AutomationsThemeProvider = createTheme<AutomationsThemeSchema>({
9+
tokens: automationsTokens,
10+
});
11+
12+
/**
13+
* a react hook for contextual access to design token
14+
* from components.
15+
*/
16+
export const { useTheme } = AutomationsThemeProvider;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { TokenViewer } from '@bitdesign/sparks.sparks-theme';
2+
import { useTheme } from './automations-theme-provider.js';
3+
import { AutomationsTheme } from './automations-theme.js';
4+
5+
function ViewTokens() {
6+
const theme = useTheme();
7+
8+
return <TokenViewer theme={theme} />;
9+
}
10+
11+
export const LightTheme = () => {
12+
return (
13+
<AutomationsTheme>
14+
<ViewTokens />
15+
</AutomationsTheme>
16+
);
17+
};
18+
19+
export const DarkTheme = () => {
20+
return (
21+
<AutomationsTheme initialTheme='dark'>
22+
<ViewTokens />
23+
</AutomationsTheme>
24+
);
25+
};
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
description: A theme for the Automations organization, providing tokens, fonts, and styling for components.
3+
labels: ['theme', 'design tokens', 'theming', 'automations']
4+
---
5+
6+
The `AutomationsTheme` component provides a consistent look and feel across your application by applying design tokens for typography, colors, spacing, and sizes. It supports both light and dark modes.
7+
8+
## Get Started
9+
10+
To use the `AutomationsTheme` in your project:
11+
12+
```bash
13+
bit install @your-org/automations-theme
14+
```
15+
or
16+
```bash
17+
npm install @your-org/automations-theme
18+
```
19+
Wrap your application with the `AutomationsTheme` component:
20+
```tsx
21+
function App() {
22+
return (
23+
<AutomationsTheme>
24+
<YourAppContent />
25+
</AutomationsTheme>
26+
);
27+
}
28+
```
29+
## Usage Examples
30+
### Basic Usage
31+
Apply the `AutomationsTheme` to wrap your application and provide a consistent theme.
32+
```tsx
33+
function AppContent() {
34+
return (
35+
<div>
36+
<h1>Welcome to Automations App</h1>
37+
<p>This is a themed paragraph.</p>
38+
</div>
39+
);
40+
}
41+
export const BasicUsage = () => (
42+
<AutomationsTheme>
43+
<AppContent />
44+
</AutomationsTheme>
45+
);
46+
```
47+
### Dark Mode
48+
Use the `initialTheme` prop to set the theme to dark mode by default.
49+
```tsx
50+
function AppContent() {
51+
return (
52+
<div>
53+
<h1>Welcome to Automations App</h1>
54+
<p>This is a themed paragraph in dark mode.</p>
55+
</div>
56+
);
57+
}
58+
export const DarkModeExample = () => (
59+
<AutomationsTheme initialTheme="dark">
60+
<AppContent />
61+
</AutomationsTheme>
62+
);
63+
```
64+
### Custom Class Name
65+
Add a `className` prop to customize the theme's appearance, and/or override certain styles.
66+
```tsx
67+
function AppContent() {
68+
return (
69+
<div>
70+
<h1>Welcome to Automations App</h1>
71+
<p>This is a themed paragraph with custom styles.</p>
72+
</div>
73+
);
74+
}
75+
export const CustomClassName = () => (
76+
<AutomationsTheme className="my-custom-theme">
77+
<AppContent />
78+
</AutomationsTheme>
79+
);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap');
2+
3+
.automationsTheme {
4+
/* use a font family here to apply a default font on theme childs. */
5+
font-family: var(--typography-font-family);
6+
7+
/* use the theme background color to apply for all components in your tree. */
8+
background-color: var(--colors-surface-background);
9+
}
10+
11+
:global {
12+
html {
13+
box-sizing: border-box;
14+
}
15+
16+
body {
17+
margin: 0;
18+
}
19+
20+
*, *::before, *::after {
21+
box-sizing: inherit;
22+
}
23+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from 'react';
2+
import { render, screen } from '@testing-library/react';
3+
import { MemoryRouter } from 'react-router-dom';
4+
import { AutomationsTheme } from './automations-theme.js';
5+
import styles from './automations-theme.module.scss';
6+
7+
describe('AutomationsTheme', () => {
8+
it('renders with children', () => {
9+
render(
10+
<MemoryRouter>
11+
<AutomationsTheme>
12+
<div>Hello World</div>
13+
</AutomationsTheme>
14+
</MemoryRouter>
15+
);
16+
expect(screen.getByText('Hello World')).toBeInTheDocument();
17+
});
18+
19+
it('applies the automationsTheme class', () => {
20+
const { container } = render(
21+
<MemoryRouter>
22+
<AutomationsTheme>
23+
<div>Hello World</div>
24+
</AutomationsTheme>
25+
</MemoryRouter>
26+
);
27+
expect(container.firstChild).toHaveClass(styles.automationsTheme);
28+
});
29+
30+
it('accepts a className prop', () => {
31+
const { container } = render(
32+
<MemoryRouter>
33+
<AutomationsTheme className="custom-class">
34+
<div>Hello World</div>
35+
</AutomationsTheme>
36+
</MemoryRouter>
37+
);
38+
expect(container.firstChild).toHaveClass('custom-class');
39+
});
40+
});
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { ReactNode, useCallback, useState } from 'react';
2+
import classNames from 'classnames';
3+
import { AutomationsThemeProvider } from './automations-theme-provider.js';
4+
import { AutomationsThemeSchema } from './automations-tokens.js';
5+
import { ThemeContext, ThemeContextValue, ThemeMode } from './theme-controller.js';
6+
import { themeOptions } from './theme-options.js';
7+
import styles from './automations-theme.module.scss';
8+
9+
export type AutomationsThemeProps = {
10+
/**
11+
* a root ReactNode for the component tree
12+
* applied with the theme.
13+
*/
14+
children?: ReactNode;
15+
16+
/**
17+
* inject a class name to override to the theme.
18+
* this allows people to affect your theme. remove to avoid.
19+
*/
20+
className?: string;
21+
22+
/**
23+
* override tokens in the schema
24+
*/
25+
overrides?: Partial<AutomationsThemeSchema>;
26+
27+
/**
28+
* preset of the theme.
29+
*/
30+
initialTheme?: ThemeMode;
31+
32+
/**
33+
* style tags to include.
34+
*/
35+
style?: React.CSSProperties;
36+
};
37+
38+
/**
39+
* a theme for the Automations organization.
40+
* it provides tokens, fonts and general styling for all components.
41+
*/
42+
export function AutomationsTheme({ children, initialTheme = 'light', className, style, ...rest }: AutomationsThemeProps) {
43+
const [themeMode, setThemeModeState] = useState<ThemeMode>(initialTheme);
44+
const themePreset = themeOptions[themeMode];
45+
46+
const setThemeMode = useCallback((mode: ThemeMode) => {
47+
setThemeModeState(mode);
48+
}, []);
49+
50+
const toggleTheme = useCallback(() => {
51+
setThemeModeState(prevMode => (prevMode === 'light' ? 'dark' : 'light'));
52+
}, []);
53+
54+
const themeContextValue: ThemeContextValue = {
55+
themeMode,
56+
toggleTheme,
57+
setThemeMode,
58+
};
59+
60+
return (
61+
<ThemeContext.Provider value={themeContextValue}>
62+
<AutomationsThemeProvider.ThemeProvider
63+
className={classNames(styles.automationsTheme, className)}
64+
style={style}
65+
overrides={themePreset}
66+
{...rest}
67+
>
68+
{children}
69+
</AutomationsThemeProvider.ThemeProvider>
70+
</ThemeContext.Provider>
71+
);
72+
}

0 commit comments

Comments
 (0)