Skip to content

Commit

Permalink
Merge pull request #400 from curvefi/task/new-design-system
Browse files Browse the repository at this point in the history
Implement `curve-ui-kit` package to represent Figma design
  • Loading branch information
ignromanov authored Oct 22, 2024
2 parents 42f52ea + 5b7dd47 commit bfd98b2
Show file tree
Hide file tree
Showing 62 changed files with 15,665 additions and 237 deletions.
21 changes: 11 additions & 10 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,34 @@ module.exports = {
extends: ['custom'],
settings: {
next: {
rootDir: ['apps/*/', 'packages/ui/*/', 'packages/onboard-helpers/*/']
}
rootDir: ['apps/*/', 'packages/ui/*/', 'packages/onboard-helpers/*/', 'packages/curve-ui-kit/*/'],
},
},
overrides: [
// enforce Feature Sliced rules for loan app (except 'pages' folder) and curve-lib
{
files: [
'apps/loan/src/{app,widgets,features,entities,shared}/**/*.{ts,tsx}',
'packages/curve-lib/src/shared/**/*.ts'
'packages/curve-lib/src/shared/**/*.ts',
'packages/curve-ui-kit/src/**/*.{ts,tsx}',
],
rules: {
'import/order': 'error', // feature-sliced/import-order
'import/no-internal-modules': 'error', // feature-sliced/public-api
'boundaries/element-types': 'error' // feature-sliced/layers-slices
}
'boundaries/element-types': 'error', // feature-sliced/layers-slices
},
},
// warn about Feature Sliced rules for main and lend apps, plus loan 'pages' folder
{
files: [
'apps/{main,lend}/src/{app,pages,widgets,features,entities,shared}/**/*.{ts,tsx}',
'apps/loan/src/pages/**/*.{ts,tsx}'
'apps/loan/src/pages/**/*.{ts,tsx}',
],
rules: {
'import/order': 'warn', // feature-sliced/import-order
'import/no-internal-modules': 'warn', // feature-sliced/public-api
'boundaries/element-types': 'warn' // feature-sliced/layers-slices
}
}
]
'boundaries/element-types': 'warn', // feature-sliced/layers-slices
},
},
],
}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@ report.*.json

# hardhat
tests/cache

# storybook
storybook-static
*storybook.log
2 changes: 1 addition & 1 deletion .vercel/storybook-branch-filtering.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

echo "VERCEL_GIT_COMMIT_REF: $VERCEL_GIT_COMMIT_REF"

if [[ "$VERCEL_GIT_COMMIT_REF" == "develop" ]] ; then
if [[ "$VERCEL_GIT_COMMIT_REF" == "develop" || "$VERCEL_GIT_COMMIT_REF" == "task/new-design-system" ]] ; then
# Proceed with the build
echo "✅ - Build can proceed"
exit 1;
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"lint": "turbo lint",
"lint:fix": "turbo lint -- --fix",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"prepare": "is-ci || husky"
"prepare": "is-ci || husky",
"storybook": "turbo run storybook --filter=curve-ui-kit",
"storybook:build": "turbo run storybook:build --filter=curve-ui-kit"
},
"devDependencies": {
"@commitlint/cli": "^19.5.0",
Expand Down
Empty file removed packages/curve-ui-kit/.gitkeep
Empty file.
103 changes: 103 additions & 0 deletions packages/curve-ui-kit/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { join, dirname } from 'path'
import type { StorybookConfig } from '@storybook/nextjs'
import path from 'path'

/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
function getAbsolutePath(packageName: string) {
return dirname(require.resolve(join(packageName, 'package.json')))
}

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|mts|ts|tsx)'],
staticDirs: ['../public'],
addons: [
getAbsolutePath('@storybook/addon-essentials'),
getAbsolutePath('@chromatic-com/storybook'),
getAbsolutePath('@storybook/addon-interactions'),
getAbsolutePath('@storybook/addon-themes'),
getAbsolutePath('@storybook/addon-a11y'),
],

framework: {
name: getAbsolutePath('@storybook/nextjs'),
options: {},
},

core: {
disableTelemetry: true,
},

docs: {},
typescript: {},

/**
* TODO: Temporary workaround for Storybook issue #12129
*
* There's currently a bug in Storybook that affects the TypeScript configuration
* and causes issues with react-docgen-typescript. The configuration below is commented out
* due to these issues.
*
* Instead, we're currently using a solution proposed in a comment on the GitHub issue:
* https://github.com/storybookjs/storybook/issues/12129#issuecomment-1486722918
*
* This solution involves manually defining `argTypes` in each story file. While this
* requires more work, it allows us to have proper typing and avoid build errors.
*
* Example usage in a story file:
* ```
* export default {
* component: MyComponent,
* argTypes: {
* prop1: { control: 'text' },
* prop2: { control: 'boolean' },
* },
* } as Meta<typeof MyComponent>;
* ```
*
* Once the Storybook issue is resolved, we can revisit this configuration and potentially
* switch back to using react-docgen-typescript for automatic prop type inference.
*/
// typescript: {
// reactDocgen: react-docgen-typescript,
// reactDocgenTypescriptOptions: {
// include: ['**/**.tsx', 'src/entities/theme/types/button.d.ts', '../src/**/*.ts', '../src/**/*.d.ts'],
// tsconfigPath: '../tsconfig.json',
// // Speeds up Storybook build time
// compilerOptions: {
// allowSyntheticDefaultImports: false,
// esModuleInterop: false,
// // include: ['../src/**/*.tsx', '../src/**/*.ts', '../src/**/*.d.ts'],
// },
// // Makes union prop types like variant and size appear as select controls
// shouldExtractLiteralValuesFromEnum: true,
// // Makes string and boolean types that can be undefined appear as inputs and switches
// shouldRemoveUndefinedFromOptional: true,
// // Filter out third-party props from node_modules except @mui packages
// propFilter: (prop) =>
// prop.parent ? /@mui/.test(prop.parent.fileName) || !/node_modules/.test(prop.parent.fileName) : true,
// },
// },

webpackFinal: async (config) => {
if (config.resolve) {
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, '../src'),
}
}
return config
},

previewHead: (head) => `
${head}
<style>
#storybook-root {
padding: 1rem;
}
</style>
`,
}
export default config
17 changes: 17 additions & 0 deletions packages/curve-ui-kit/.storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<link rel="preload" href="/fonts/Mona-Sans.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" href="/fonts/Hubot-Sans.woff2" as="font" type="font/woff2" crossorigin="anonymous" />

<style>
@font-face {
font-family: 'Mona-Sans', sans-serif;
src:
url('fonts/Mona-Sans.woff2'),
url('fonts/Mona-Sans.woff2') format('woff2');
}
@font-face {
font-family: 'Hubot-Sans', sans-serif;
src:
url('fonts/Hubot-Sans.woff2'),
url('fonts/Hubot-Sans.woff2') format('woff2');
}
</style>
64 changes: 64 additions & 0 deletions packages/curve-ui-kit/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { CssBaseline, ThemeProvider } from '@mui/material'
import { withThemeFromJSXProvider } from '@storybook/addon-themes'
import type { Decorator, Preview, ReactRenderer } from '@storybook/react'

import { chadTheme, darkTheme, lightTheme } from '../src/entities/themes'

export const decorators: Decorator[] = [
withThemeFromJSXProvider<ReactRenderer>({
themes: {
light: lightTheme,
dark: darkTheme,
chad: chadTheme,
},
defaultTheme: 'light',
Provider: ThemeProvider,
GlobalStyles: CssBaseline,
}),
]

const preview: Preview = {
decorators: decorators,
parameters: {
themes: {
light: lightTheme,
dark: darkTheme,
chad: chadTheme,
},
controls: {
expanded: true, // Adds the description and default columns
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
docs: {
// TODO: Fix docs container theme application
// The current issue is that the theme is only applied to individual components
// within the docs, but not to the root level of the documentation container.
// This results in inconsistent styling, where component examples may have the
// correct theme, but the surrounding documentation does not.
//
// Potential solution:
// Implement a custom docs container that applies the theme at the root level.
// This may involve creating a wrapper component that uses the current theme
// from the Storybook context and applies it to the entire docs container.
//
// container: ({ children, context }) => {
// const theme = context.store.userGlobals.globals.theme
// return (
// <DocsContainer context={context}>
// <ThemeProvider theme={chadTheme}>
// <CssBaseline />
// {children}
// </ThemeProvider>
// </DocsContainer>
// )
// },
},
layout: 'centered',
},
tags: ['autodocs'],
}

export default preview
45 changes: 45 additions & 0 deletions packages/curve-ui-kit/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "curve-ui-kit",
"version": "0.1.0",
"type": "module",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "MIT",
"private": true,
"scripts": {
"lint": "eslint \"**/*.ts*\"",
"validate:figma-tokens": "node src/shared/api/figma-tokens/validation/validate-figma-tokens.js",
"storybook": "yarn validate:figma-tokens && storybook dev -p 6006 --no-open",
"build:storybook": "yarn validate:figma-tokens && storybook build"
},
"dependencies": {
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@mui/material": "^6.1.4",
"@mui/utils": "^6.1.4"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
},
"devDependencies": {
"@chromatic-com/storybook": "^2.0.2",
"@storybook/addon-a11y": "^8.3.5",
"@storybook/addon-docs": "^8.3.5",
"@storybook/addon-essentials": "^8.3.5",
"@storybook/addon-interactions": "^8.3.5",
"@storybook/addon-themes": "^8.3.5",
"@storybook/blocks": "^8.3.5",
"@storybook/nextjs": "^8.3.5",
"@storybook/react": "^8.3.5",
"@storybook/test": "^8.3.5",
"@types/react": "*",
"@types/react-dom": "*",
"ajv": "^8.17.1",
"prop-types": "^15.8.1",
"react-docgen-typescript": "^2.2.2",
"storybook": "^8.3.5",
"tsconfig": "*",
"type-fest": "^4.26.1"
}
}
Binary file added packages/curve-ui-kit/public/assets/sample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions packages/curve-ui-kit/src/entities/themes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib'
16 changes: 16 additions & 0 deletions packages/curve-ui-kit/src/entities/themes/lib/generate-themes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createTheme as createMuiTheme, type Theme } from '@mui/material/styles'
import { basicMuiTheme, type ThemeKey } from '@/shared/lib/basic-theme'
import { createComponents, createPalette, createSpacing, createTypography } from '../model'

const generateTheme = (mode: ThemeKey): Theme =>
createMuiTheme({
...basicMuiTheme,
palette: createPalette(mode),
typography: createTypography(mode),
components: createComponents(mode),
...createSpacing(mode),
})

export const lightTheme = generateTheme('light')
export const darkTheme = generateTheme('dark')
export const chadTheme = generateTheme('chad')
1 change: 1 addition & 0 deletions packages/curve-ui-kit/src/entities/themes/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './generate-themes'
12 changes: 12 additions & 0 deletions packages/curve-ui-kit/src/entities/themes/model/components.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { type ThemeOptions } from '@mui/material/styles'
import { figmaTokens } from '@/shared/api/figma-tokens'
import type { ThemeKey } from '@/shared/lib/basic-theme'
import { defineMuiButton } from '@/shared/ui/Button'
import { defineMuiCssBaseline } from '@/shared/ui/CssBaseline'
import { defineMuiTypography } from '@/shared/ui/Typography'

export const createComponents = (mode: ThemeKey): ThemeOptions['components'] => ({
MuiTypography: defineMuiTypography(),
MuiCssBaseline: defineMuiCssBaseline(),
MuiButton: defineMuiButton(figmaTokens, mode),
})
4 changes: 4 additions & 0 deletions packages/curve-ui-kit/src/entities/themes/model/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './components'
export * from './pallette'
export * from './spacing'
export * from './typography'
Loading

0 comments on commit bfd98b2

Please sign in to comment.