Skip to content

Commit

Permalink
add ColorSchemes docs
Browse files Browse the repository at this point in the history
  • Loading branch information
YieldRay committed May 11, 2024
1 parent 163c6c4 commit 7564e7a
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 84 deletions.
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "soda-material",
"version": "0.0.26",
"version": "0.0.27",
"type": "module",
"types": "dist",
"main": "dist/index.js",
Expand All @@ -25,30 +25,30 @@
"@material/material-color-utilities": "^0.2.7",
"@mdi/js": "^7.4.47",
"@mdi/react": "^1.6.1",
"@storybook/addon-essentials": "^8.0.9",
"@storybook/addon-interactions": "^8.0.9",
"@storybook/addon-links": "^8.0.9",
"@storybook/blocks": "^8.0.9",
"@storybook/react": "^8.0.9",
"@storybook/react-vite": "^8.0.9",
"@storybook/addon-essentials": "^8.0.10",
"@storybook/addon-interactions": "^8.0.10",
"@storybook/addon-links": "^8.0.10",
"@storybook/blocks": "^8.0.10",
"@storybook/react": "^8.0.10",
"@storybook/react-vite": "^8.0.10",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"@vitejs/plugin-react": "^4.2.1",
"chromatic": "^11.3.0",
"chromatic": "^11.3.2",
"clsx": "^2.1.1",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.6",
"eslint-plugin-react-refresh": "^0.4.7",
"eslint-plugin-storybook": "^0.8.0",
"glob": "^10.3.12",
"glob": "^10.3.14",
"prettier": "^3.2.5",
"sass": "^1.76.0",
"storybook": "^8.0.9",
"styled-jsx": "^5.1.2",
"sass": "^1.77.1",
"storybook": "^8.0.10",
"styled-jsx": "^5.1.3",
"typescript": "^5.4.5",
"vite": "^5.2.10"
"vite": "^5.2.11"
},
"publishConfig": {
"registry": "https://registry.npmjs.org"
Expand Down
12 changes: 10 additions & 2 deletions src/components/tabs/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import './tabs.scss'
import clsx from 'clsx'
import { forwardRef, useEffect, useRef, useState } from 'react'
import { forwardRef, useCallback, useEffect, useRef, useState } from 'react'
import { useAutoState } from '@/hooks/use-auto-state'
import { useMergeRefs } from '@/hooks/use-merge'
import { Ripple } from '@/ripple/Ripple'
Expand Down Expand Up @@ -59,7 +59,7 @@ export const Tabs = forwardRef<
const [left, setLeft] = useState('0')
const [width, setWidth] = useState('36px')

useEffect(() => {
const correctlyPlaceIndicator = useCallback(() => {
const tabs = ref.current
if (!tabs) return
const item = tabs.querySelectorAll('.sd-tabs-item')[
Expand Down Expand Up @@ -96,6 +96,14 @@ export const Tabs = forwardRef<
}
}, [index, variant])

useEffect(correctlyPlaceIndicator, [correctlyPlaceIndicator])

useEffect(() => {
window.addEventListener('resize', correctlyPlaceIndicator)
return () =>
window.removeEventListener('resize', correctlyPlaceIndicator)
}, [correctlyPlaceIndicator])

return (
<div
{...props}
Expand Down
26 changes: 26 additions & 0 deletions src/documentation/ColorSchemes.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Canvas, Meta, Story } from '@storybook/blocks'
import { ColorStatic } from './ColorSchemes'

<Meta title="ColorSchemes" />

# Dynamic Color

```ts
// provide some helper function
import { type Theme, themeFromHexString, themeFromImageOrFile } from "soda-material/dist/utils/theme.js"
const theme: Theme = themeFromHexString('#6750a4')
const theme: Theme = await themeFromImageOrFile(/* accept HTMLImageElement or File object */)

// apply theme
import { applyThemeForSoda } from 'soda-material/dist/utils/theme.js'
applyThemeForSoda('#6750a4')
applyThemeForSoda(theme)
```

It's actually a module that provides some helper function and re-export the [@material/material-color-utilities](https://npm.im/@material/material-color-utilities) package.

# Color Schemes

Refer to [https://m3.material.io/styles/color/static/baseline](https://m3.material.io/styles/color/static/baseline)

<ColorStatic />
72 changes: 72 additions & 0 deletions src/documentation/ColorSchemes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const COLOR_TOKEN_MAP = {
'surface-tint': ['', 'color'],
'on-error': ['', 'container'],
error: ['', 'container'],
'on-tertiary': ['', 'container'],
tertiary: ['', 'container'],
shadow: [''],
outline: ['', 'variant'],
'on-background': [''],
background: [''],
'inverse-on-surface': [''],
'inverse-surface': [''],
'on-surface': ['', 'variant'],
surface: [
'',
'variant',
'container',
'container-lowest',
'container-low',
'container-high',
'container-highest',
],
'on-secondary': ['', 'container'],
secondary: ['', 'container'],
'inverse-primary': [''],
'on-primary': ['', 'container'],
primary: ['', 'container'],
}

export function ColorStatic() {
return Object.entries(COLOR_TOKEN_MAP).map(([prefix, decorates]) => (
<section key={prefix}>
<ul
style={{
padding: '0',
listStyle: 'none',
display: 'grid',
gridTemplateColumns:
'repeat(auto-fill, minmax(360px, 1fr))',
gap: '.3rem',
}}
>
{decorates.map((decorate) => {
const name = decorate ? `${prefix}-${decorate}` : prefix
const color = `var(--md-sys-color-${name})`
return (
<li
style={{
background: color,
margin: '0',
padding: '.5rem 1rem',
boxSizing: 'border-box',
borderRadius: '.25rem',
border: 'solid 1px var(--md-sys-color-outline)',
}}
>
<span
style={{
color,
filter: 'grayscale(1) contrast(999) invert(1)',
userSelect: 'all',
}}
>
{color}
</span>
</li>
)
})}
</ul>
</section>
))
}
87 changes: 19 additions & 68 deletions src/documentation/ThemingExample.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from 'react'
import { Fragment, useEffect, useRef, useState } from 'react'
import {
mdiCheckboxOutline,
mdiDeleteOutline,
Expand All @@ -19,7 +19,6 @@ import {
} from '@mdi/js'
import Icon from '@mdi/react'
import {
Badge,
BottomAppBar,
BottomSheet,
BottomSheetHandle,
Expand Down Expand Up @@ -53,7 +52,6 @@ import { useFullscreen } from '@/hooks/use-fullscreen'
import { usePrefersDark, useWindowSizeType } from '@/hooks/use-media-query'
import {
applyThemeForSoda,
argbFromHex,
themeFromHexString,
themeFromImageOrFile,
} from '@/utils/theme'
Expand All @@ -66,13 +64,8 @@ export function ThemingExample() {
const [sourceColor, setSourceColor] = useState(
localStorage.getItem('sourceColor') || '#6750a4',
)
const [customColors, setCustomColors] = useState<string[]>([])

const [file, setFile] = useState<File | null>(null)
const customColorArray = customColors.map((color, index) => ({
name: `custom-${index}`,
value: argbFromHex(color),
blend: true,
}))

useEffect(() => {
localStorage.setItem('sourceColor', sourceColor)
Expand All @@ -82,25 +75,26 @@ export function ThemingExample() {
// eslint-disable-next-line no-extra-semi
;(async () => {
const theme = file
? await themeFromImageOrFile(file, customColorArray)
: themeFromHexString(sourceColor, customColorArray)
? await themeFromImageOrFile(file)
: themeFromHexString(sourceColor)

applyThemeForSoda(theme, prefersDark)
})()
}, [customColorArray, prefersDark, sourceColor, file])
}, [prefersDark, sourceColor, file])

return (
<Card
style={{
padding: '1rem',
margin: '2.5rem 0 5rem',
maxWidth: '350px',
maxWidth: '400px',
}}
disabled
>
<section>
<h3>SourceColor</h3>

<h1>Change Theme</h1>
<p>
<strong>Manually select a color:</strong>
<br />
<input
type="color"
value={sourceColor}
Expand All @@ -109,7 +103,11 @@ export function ThemingExample() {
setSourceColor(e.target.value)
}}
/>
</p>

<p>
<strong>Dynamic color from image:</strong>
<br />
<input
type="file"
accept="image/*"
Expand All @@ -119,57 +117,7 @@ export function ThemingExample() {
setFile(file)
}}
/>
</section>

<section>
<h3>CustomColors</h3>

{customColors.map((customColor, index) => (
<div
key={index}
style={{
display: 'flex',
alignItems: 'center',
gap: '1rem',
margin: '.5rem 0',
}}
>
<input
key={index}
type="color"
value={customColor}
onChange={(e) => {
setCustomColors(
customColors.toSpliced(
index,
1,
e.target.value,
),
)
}}
/>
<Badge label={index}>
<Button
onClick={() => {
setCustomColors(
customColors.toSpliced(index, 1),
)
}}
>
Delete This
</Button>
</Badge>
</div>
))}

<Button
onClick={() =>
setCustomColors([...customColors, '#ffffff'])
}
>
Add One
</Button>
</section>
</p>
</Card>
)
}
Expand Down Expand Up @@ -544,7 +492,10 @@ function WithTabs({
variant="secondary"
/>
{tabs.map(
({ children, ...item }) => item.value === value && children,
({ children, ...item }) =>
item.value === value && (
<Fragment key={item.value}>{children}</Fragment>
),
)}
</>
)
Expand Down

0 comments on commit 7564e7a

Please sign in to comment.