-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(theme-generator): add theme-generator component
- Loading branch information
Showing
23 changed files
with
904 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { defineConfig } from 'father'; | ||
import { StandardConfig } from '@casts/standard'; | ||
|
||
export default defineConfig({ | ||
...StandardConfig.father, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/node_modules | ||
/dist | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# @casts/theme-generator | ||
|
||
[![NPM version](https://img.shields.io/npm/v/@casts/theme-generator.svg?style=flat)](https://npmjs.org/package/@casts/theme-generator) | ||
[![NPM downloads](http://img.shields.io/npm/dm/@casts/theme-generator.svg?style=flat)](https://npmjs.org/package/@casts/theme-generator) | ||
|
||
## Install | ||
|
||
```bash | ||
$ pnpm add @casts/theme-generator | ||
``` | ||
|
||
```bash | ||
$ pnpm run dev | ||
$ pnpm run build | ||
``` | ||
|
||
## Options | ||
|
||
TODO | ||
|
||
## License | ||
|
||
MIT © [moecasts <moecasts.caster@gmail.com>](https://github.com/moecasts <moecasts.caster@gmail.com>) |
16 changes: 16 additions & 0 deletions
16
packages/casts-theme-generator/docs/_theme-generator.en-US.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
title: ThemeGenerator | ||
group: | ||
title: General | ||
nav: | ||
title: Components | ||
path: /components | ||
--- | ||
|
||
## Installation | ||
|
||
```bash | ||
$ pnpm add @casts/theme-generator | ||
``` | ||
|
||
TODO |
16 changes: 16 additions & 0 deletions
16
packages/casts-theme-generator/docs/_theme-generator.zh-CN.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
title: ThemeGenerator | ||
group: | ||
title: 通用 | ||
nav: | ||
title: 组件 | ||
path: /components | ||
--- | ||
|
||
## 安装 | ||
|
||
```bash | ||
$ pnpm add @casts/theme-generator | ||
``` | ||
|
||
TODO |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{ | ||
"name": "@casts/theme-generator", | ||
"version": "0.0.1", | ||
"description": "a react theme generator for casts design component", | ||
"authors": [ | ||
"moecasts <moecasts.caster@gmail.com>" | ||
], | ||
"license": "MIT", | ||
"repository": "https://github.com/moecasts/casts-design.git", | ||
"main": "dist/cjs/index.js", | ||
"module": "dist/esm/index.js", | ||
"types": "dist/esm/index.d.ts", | ||
"scripts": { | ||
"dev": "father dev", | ||
"build": "father build", | ||
"build:deps": "father prebundle", | ||
"prepublishOnly": "father doctor && pnpm run build", | ||
"test": "vitest", | ||
"test:coverage": "vitest run --coverage" | ||
}, | ||
"keywords": [], | ||
"files": [ | ||
"dist", | ||
"compiled" | ||
], | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"devDependencies": { | ||
"@casts/standard": "workspace:^0.0.1", | ||
"@swc/core": "^1.3.82", | ||
"@testing-library/jest-dom": "^6.1.2", | ||
"@testing-library/react": "^14.0.0", | ||
"@vitest/coverage-v8": "^1.3.1", | ||
"father": "^4.3.2", | ||
"jsdom": "^22.1.0", | ||
"ts-node": "^10.9.1", | ||
"typescript": "5.5.1-rc", | ||
"vite": "^4.4.9", | ||
"vitest": "^1.3.1" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=17" | ||
}, | ||
"dependencies": { | ||
"@casts/common": "workspace:^0.0.1", | ||
"@casts/config-provider": "workspace:^0.0.1", | ||
"@casts/drawer": "workspace:^0.0.1", | ||
"@casts/switch": "workspace:^0.0.1", | ||
"@casts/theme": "workspace:^0.0.1", | ||
"@ctrl/tinycolor": "^4.0.3", | ||
"clsx": "^2.0.0", | ||
"react-color-palette": "^7.1.0" | ||
}, | ||
"sideEffects": [ | ||
"**/*.{css,scss,sass}" | ||
] | ||
} |
37 changes: 37 additions & 0 deletions
37
packages/casts-theme-generator/src/components/color-picker.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { noop, useControlled } from '@casts/common'; | ||
import { | ||
ColorPicker as BaseColorPicker, | ||
ColorService, | ||
IColor, | ||
} from 'react-color-palette'; | ||
|
||
export type UseColorPickerProps = Omit< | ||
Parameters<typeof BaseColorPicker>[0], | ||
'color' | 'onChange' | ||
> & { | ||
color?: string; | ||
defaultColor?: string; | ||
onChange?: (color: string) => void; | ||
}; | ||
export type ColorPickerProps = UseColorPickerProps; | ||
|
||
export const useColorPicker = (props: UseColorPickerProps) => { | ||
const { onChange = noop, ...rest } = props; | ||
const [color, setColor] = useControlled<string>(props, 'color', onChange); | ||
|
||
const handleChange = (iColor: IColor) => { | ||
setColor(iColor.hex); | ||
}; | ||
|
||
return { | ||
...rest, | ||
color: ColorService.convert('hex', color), | ||
onChange: handleChange, | ||
}; | ||
}; | ||
|
||
export const ColorPicker = (props: ColorPickerProps) => { | ||
const { color, onChange, ...rest } = useColorPicker(props); | ||
|
||
return <BaseColorPicker {...rest} color={color} onChange={onChange} />; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './use-theme-generator'; |
147 changes: 147 additions & 0 deletions
147
packages/casts-theme-generator/src/components/hooks/use-theme-generator.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import { CSSProperties, useEffect, useRef } from 'react'; | ||
import { | ||
noop, | ||
useCircleTransition, | ||
useControlled, | ||
useDebounceFn, | ||
} from '@casts/common'; | ||
import { useConfig } from '@casts/config-provider'; | ||
import { clsx } from 'clsx'; | ||
|
||
import { MainColor, ThemeMode, UseThemeGeneratorProps } from '../types'; | ||
import { | ||
appendThemeVariablesToHead, | ||
generatePalettes, | ||
toCssVariables, | ||
} from '../utils/generate-palette'; | ||
|
||
export const useThemeGenerator = (props: UseThemeGeneratorProps) => { | ||
const { className, style, addThemeCodeOnMounted } = props; | ||
|
||
const [visible, onVisibleChange] = useControlled<boolean>( | ||
props, | ||
'visible', | ||
props.onVisibleChange || noop, | ||
); | ||
|
||
const { getPrefixCls } = useConfig(); | ||
|
||
/* --------------------------------- classes and styles ---------------------------------------- */ | ||
const prefixCls = getPrefixCls('theme-generator'); | ||
|
||
const classes = clsx(prefixCls, className); | ||
const styles: CSSProperties = { ...style }; | ||
|
||
const drawerClasses = `${prefixCls}-drawer`; | ||
|
||
const itemClasses = `${prefixCls}-item`; | ||
|
||
const itemTitleClasses = `${itemClasses}-title`; | ||
|
||
const itemContentClasses = `${itemClasses}-content`; | ||
|
||
const pickerClasses = `${prefixCls}-picker`; | ||
|
||
const pickerPreviewClasses = `${pickerClasses}-preview`; | ||
const pickerTextClasses = `${pickerClasses}-text`; | ||
|
||
/* --------------------------------- states ---------------------------------------- */ | ||
const [mode, setMode] = useControlled<ThemeMode>( | ||
props, | ||
'mode', | ||
props.onModeChange || noop, | ||
'default', | ||
); | ||
|
||
const { circleTransition } = useCircleTransition(); | ||
const generatorRef = useRef<HTMLElement>(null); | ||
|
||
const [mainColors, setMainColors] = useControlled<MainColor[]>( | ||
props, | ||
'mainColors', | ||
props.onMainColorsChange || noop, | ||
[], | ||
); | ||
|
||
/* --------------------------------- events ---------------------------------------- */ | ||
|
||
const debounceGeneratePalettes = useDebounceFn( | ||
(mainColors: MainColor[], mode: ThemeMode = 'default') => { | ||
const update = () => { | ||
const reverse = mode === 'dark' ? true : false; | ||
|
||
const palettes = generatePalettes(mainColors, reverse); | ||
|
||
const cssCodes = toCssVariables(palettes); | ||
document.documentElement.setAttribute('theme-mode', mode); | ||
document.documentElement.setAttribute('theme-palette', 'custom'); | ||
appendThemeVariablesToHead(cssCodes); | ||
}; | ||
|
||
circleTransition({ | ||
ref: generatorRef, | ||
update, | ||
}); | ||
}, | ||
{ | ||
wait: 300, | ||
}, | ||
); | ||
|
||
const handleMainColorsChange = (payload: { name: string; color: string }) => { | ||
const { name, color } = payload; | ||
|
||
const newColors = [...mainColors]; | ||
|
||
const target = newColors.find((item) => item.name === name); | ||
|
||
if (target) { | ||
target.color = color; | ||
} | ||
|
||
setMainColors(newColors); | ||
|
||
debounceGeneratePalettes.run(newColors, mode); | ||
}; | ||
|
||
const handleModeChange = (reverse: boolean) => { | ||
const mode = reverse ? 'dark' : 'default'; | ||
setMode(mode); | ||
|
||
debounceGeneratePalettes.run(mainColors, mode); | ||
}; | ||
|
||
// generate current theme when component mounted | ||
useEffect(() => { | ||
if (!addThemeCodeOnMounted) { | ||
return; | ||
} | ||
debounceGeneratePalettes.run(mainColors, mode); | ||
debounceGeneratePalettes.flush(); | ||
}, []); | ||
|
||
return { | ||
classes, | ||
styles, | ||
|
||
drawerClasses, | ||
|
||
itemClasses, | ||
itemTitleClasses, | ||
itemContentClasses, | ||
|
||
pickerClasses, | ||
pickerPreviewClasses, | ||
pickerTextClasses, | ||
|
||
mainColors, | ||
handleMainColorsChange, | ||
reverse: mode === 'dark', | ||
handleModeChange, | ||
|
||
visible, | ||
onVisibleChange, | ||
|
||
generatorRef, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './hooks'; | ||
export * from './theme-generator'; | ||
export * from './types'; | ||
export * from './utils/generate-palette'; |
47 changes: 47 additions & 0 deletions
47
packages/casts-theme-generator/src/components/styles/theme-generator.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// @import '@casts/theme/styles/scss/core'; | ||
@import '@casts/theme/styles/scss/vars/core'; | ||
|
||
$theme-generator-prefix-cls: #{$prefix-cls}-theme-generator; | ||
|
||
.#{$theme-generator-prefix-cls} { | ||
max-width: 320px; | ||
|
||
&-drawer { | ||
.#{$prefix-cls}-drawer-overlay { | ||
background-color: transparent; | ||
} | ||
} | ||
|
||
&-item { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
|
||
&-title { | ||
padding-right: $space-05-x; | ||
} | ||
|
||
& + & { | ||
margin-top: $space-1-x; | ||
} | ||
} | ||
|
||
&-picker { | ||
display: inline-flex; | ||
gap: $space-05-x; | ||
align-items: center; | ||
width: 128px; | ||
padding: $space-05-x; | ||
cursor: pointer; | ||
border: $border-width-xsmall solid $color-border-component-default; | ||
border-radius: $radius-medium; | ||
|
||
&-preview { | ||
flex-shrink: 0; | ||
width: $size-small; | ||
height: $size-small; | ||
border-radius: $radius-medium; | ||
box-shadow: $shadow-level-1; | ||
} | ||
} | ||
} |
Oops, something went wrong.