-
-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
NgocNhi123
committed
Jun 30, 2024
1 parent
2b24b71
commit f2a6f7a
Showing
28 changed files
with
761 additions
and
7 deletions.
There are no files selected for viewing
Binary file not shown.
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
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 { Canvas, Meta, Story } from "@storybook/blocks"; | ||
import { ColorBackground } from "./background"; | ||
|
||
<Meta title="Patterns/Color/Background" /> | ||
|
||
# Background Color | ||
|
||
The `background` utility contains classes that set the | ||
[CSS `background-color`][1] property. This is the recommended way to set | ||
background color since they automatically change based on the current theme. | ||
|
||
```ts | ||
import { background } from "@moai/core"; | ||
|
||
<div className={background.weak}>Text</div>; | ||
``` | ||
|
||
There are only 2 colors in the `background` utility at the moment: | ||
|
||
<ColorBackground rows={[{ key: "weak" }, { key: "strong" }]} /> | ||
|
||
The `weak` value sets a light gray background on light theme and a daker | ||
background on dark theme. It should be used for underlying backgrounds, like | ||
the background of your app. It can also be used to separate an area, such as | ||
the header of a table. | ||
|
||
The `strong` value sets a white background on light theme and a lighter | ||
background on dark theme. It should be used for elevated containers, such as | ||
panes, toolbars or popovers. | ||
|
||
## See also | ||
|
||
- The [Pane][2] component uses `strong` background along with border and shadow | ||
to better elevate contents. | ||
|
||
[1]: https://developer.mozilla.org/en-US/docs/Web/CSS/background-color | ||
[2]: /docs/components-pane-docs |
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,11 @@ | ||
.name { | ||
font-family: "Source Code Pro", monospace; | ||
width: 160px; | ||
min-width: 160px; | ||
} | ||
|
||
.container { | ||
overflow: auto; | ||
white-space: nowrap; | ||
border-width: 2px; | ||
} |
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,48 @@ | ||
import { border, background, Table, text } from "../../../../core/src"; | ||
import { ColorSample } from "../sample/sample"; | ||
import s from "./background.module.css"; | ||
|
||
type BackgroundKey = keyof typeof background; | ||
|
||
interface Row { | ||
key: BackgroundKey; | ||
} | ||
|
||
const MakeColumn = | ||
(theme: "light" | "dark", text: string) => | ||
(row: Row): JSX.Element => ( | ||
<div className={theme}> | ||
<ColorSample | ||
background={background[row.key]} | ||
foreground={{ type: "text", cls: text, usage: "both" }} | ||
/> | ||
</div> | ||
); | ||
|
||
const LightStrong = MakeColumn("light", text.normal); | ||
const LightWeak = MakeColumn("light", text.muted); | ||
const DarkStrong = MakeColumn("dark", text.normal); | ||
const DarkWeak = MakeColumn("dark", text.muted); | ||
|
||
interface Props { | ||
rows: Row[]; | ||
} | ||
|
||
export const ColorBackground = (props: Props): JSX.Element => ( | ||
<div className={[s.container, border.weak].join(" ")}> | ||
<Table<Row> | ||
size={Table.sizes.small} | ||
fixed={{ firstColumn: true }} | ||
fill | ||
rows={props.rows} | ||
rowKey={(row) => row.key} | ||
columns={[ | ||
{ title: "Name", className: s.name, render: "key" }, | ||
{ title: "Light", render: LightStrong }, | ||
{ title: "Light (muted)", render: LightWeak }, | ||
{ title: "Dark", render: DarkStrong }, | ||
{ title: "Dark (muted)", render: DarkWeak }, | ||
]} | ||
/> | ||
</div> | ||
); |
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,28 @@ | ||
import { Meta, Canvas, Story } from "@storybook/blocks"; | ||
import { ColorBorder } from "./border"; | ||
|
||
<Meta title="Patterns/Color/Border" /> | ||
|
||
# Border Color | ||
|
||
The `border` utility contains classes that set the [CSS `border-color`][1] | ||
property. This is the recommended way to set border color since they | ||
automatically change based on the current theme. | ||
|
||
Note that this only set the color. To have a border, you also need to set a | ||
width, e.g. using the "border" class from Tailwind. You don't need to set the | ||
border style since it's already default to "solid" in our [CSS reset][2]. | ||
|
||
```ts | ||
import { border } from "@moai/core"; | ||
|
||
// The "border" class comes from Tailwind to set the border width | ||
<div className={[border.weak, "border"].join(" ")}>Text</div>; | ||
``` | ||
|
||
There are 2 colors in the `border` utility at the moment: | ||
|
||
<ColorBorder rows={[{ key: "weak" }, { key: "strong" }]} /> | ||
|
||
[1]: https://developer.mozilla.org/en-US/docs/Web/CSS/border-color | ||
[2]: https://github.com/moaijs/moai/blob/739a87de82bd061bb41f38c5a51a410b59944a3d/lib/core/src/style/reset.css#L404-L417 |
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,11 @@ | ||
.name { | ||
font-family: "Source Code Pro", monospace; | ||
width: 160px; | ||
min-width: 160px; | ||
} | ||
|
||
.container { | ||
overflow: auto; | ||
white-space: nowrap; | ||
border-width: 2px; | ||
} |
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,48 @@ | ||
import { background, border, Table } from "../../../../core/src"; | ||
import { ColorSample } from "../sample/sample"; | ||
import s from "./border.module.css"; | ||
|
||
type BorderKey = keyof typeof border; | ||
|
||
interface Row { | ||
key: BorderKey; | ||
} | ||
|
||
const MakeColumn = | ||
(theme: "light" | "dark", back: string) => | ||
(row: Row): JSX.Element => ( | ||
<div className={theme}> | ||
<ColorSample | ||
background={back} | ||
foreground={{ type: "border", cls: border[row.key] }} | ||
/> | ||
</div> | ||
); | ||
|
||
const LightStrong = MakeColumn("light", background.strong); | ||
const LightWeak = MakeColumn("light", background.weak); | ||
const DarkStrong = MakeColumn("dark", background.strong); | ||
const DarkWeak = MakeColumn("dark", background.weak); | ||
|
||
interface Props { | ||
rows: Row[]; | ||
} | ||
|
||
export const ColorBorder = (props: Props): JSX.Element => ( | ||
<div className={s.container}> | ||
<Table<Row> | ||
size={Table.sizes.small} | ||
fixed={{ firstColumn: true }} | ||
fill | ||
rows={props.rows} | ||
rowKey={(row) => row.key} | ||
columns={[ | ||
{ title: "Name", className: s.name, render: "key" }, | ||
{ title: "Light", render: LightStrong }, | ||
{ title: "Light (alt bg)", render: LightWeak }, | ||
{ title: "Dark", render: DarkStrong }, | ||
{ title: "Dark (alt bg)", render: DarkWeak }, | ||
]} | ||
/> | ||
</div> | ||
); |
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 @@ | ||
import { Meta, Canvas, Story } from "@storybook/blocks"; | ||
import { ColorCategoryTable } from "./category"; | ||
|
||
<Meta title="Patterns/Color/Category" /> | ||
|
||
# Category Colors | ||
|
||
Category colors have no semantic meaning attached. Instead, they are used to | ||
show relationships between elements (e.g. categorization, labelling in data | ||
visualizations). They still conform to the AA level of [WCAG of contrast | ||
ratios][1]. | ||
|
||
## Usage | ||
|
||
[At the moment][2], Moai does not support using category colors directly. | ||
Instead, category colors are used via several components that support them: | ||
|
||
<ColorCategoryTable /> | ||
|
||
(The list is quite short at the moment. We are adding more to it!) | ||
|
||
[1]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Perceivable/Color_contrast | ||
[2]: https://github.com/moaijs/moai/issues/210 |
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 @@ | ||
.container { | ||
border-width: 2px; | ||
} |
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 React from "react"; | ||
import { border, Table } from "../../../../core/src"; | ||
import { GalleryTag } from "../../../../gallery/src"; | ||
import s from "./category.module.css"; | ||
|
||
interface Row { | ||
name: string; | ||
link: string; | ||
example: React.ReactNode; | ||
} | ||
|
||
const Name = (row: Row): JSX.Element => ( | ||
<a href={row.link} children={row.name} /> | ||
); | ||
|
||
const Example = (row: Row): JSX.Element => <div children={row.example} />; | ||
|
||
export const ColorCategoryTable = (): JSX.Element => ( | ||
<div className={[s.container, border.weak].join(" ")}> | ||
<Table<Row> | ||
rows={[ | ||
{ | ||
name: "Tag", | ||
link: "/docs/components-tag", | ||
example: <GalleryTag />, | ||
}, | ||
]} | ||
rowKey={(row) => row.name} | ||
columns={[ | ||
{ title: "Component", render: Name }, | ||
{ title: "Example", render: Example }, | ||
]} | ||
fill | ||
fixed={{ firstColumn: true }} | ||
/> | ||
</div> | ||
); |
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,20 @@ | ||
import { Canvas, Meta, Story } from "@storybook/blocks"; | ||
|
||
<Meta title="Patterns/Color" /> | ||
|
||
# Colors | ||
|
||
For recommended color usages, see [Text][1], [Background][2], and [Border][3]. | ||
They provide accessible colors that are automatically changed based on the | ||
current theme. | ||
|
||
For colors that are persistent across themes, see [Static Colors][4]. | ||
|
||
For colors that have no semantic meaning and should be used for data | ||
visualizations, see [Category Colors][5] | ||
|
||
[1]: /docs/patterns-color-text--docs | ||
[2]: /docs/patterns-color-background--docs | ||
[3]: /docs/patterns-color-border--docs | ||
[4]: /docs/patterns-color-static--docs | ||
[5]: /docs/patterns-color-category--docs |
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,17 @@ | ||
.container { | ||
padding: 12px; | ||
width: 120px; | ||
font-variant-numeric: "tabular-nums"; | ||
border-radius: 4px; | ||
|
||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
} | ||
|
||
.border { | ||
width: 16px; | ||
height: 16px; | ||
border-radius: 16px; | ||
border-width: 1px; | ||
} |
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,82 @@ | ||
import Color from "color"; | ||
import { useEffect, useRef, useState } from "react"; | ||
import { HiCheckCircle } from "react-icons/hi"; | ||
import { CategoryColor, categoryColors, Icon, Tag } from "../../../../core/src"; | ||
import s from "./sample.module.css"; | ||
|
||
export type ColorSampleUsage = "text" | "icon" | "both"; | ||
|
||
interface Props { | ||
background: string; | ||
foreground: | ||
| { type: "text"; cls: string; usage: ColorSampleUsage } | ||
| { type: "border"; cls: string }; | ||
} | ||
|
||
const getColor = (contrast: number): CategoryColor => { | ||
const rounded = Math.round(contrast * 10) / 10; | ||
if (rounded >= 4.5) return categoryColors.green; | ||
if (rounded >= 3) return categoryColors.yellow; | ||
return categoryColors.red; | ||
}; | ||
|
||
const getContrast = ( | ||
props: Props, | ||
backElement: HTMLDivElement, | ||
foreElement: HTMLElement, | ||
): number => { | ||
const back = window.getComputedStyle(backElement).backgroundColor; | ||
const foreStyle = window.getComputedStyle(foreElement); | ||
const isText = props.foreground.type === "text"; | ||
// Only use long hand name. | ||
// See: https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle#notes | ||
const fore = foreStyle[isText ? "color" : "borderLeftColor"]; | ||
return Color(back).contrast(Color(fore)); | ||
}; | ||
|
||
const ColorIcon = (): JSX.Element => ( | ||
<Icon component={HiCheckCircle} size={16} display="inline" /> | ||
); | ||
|
||
export const ColorSample = (props: Props): JSX.Element => { | ||
const backRef = useRef<HTMLDivElement>(null); | ||
const foreRef = useRef<HTMLElement>(null); | ||
const [contrast, setContrast] = useState(0); | ||
|
||
useEffect(() => { | ||
window.setTimeout(() => { | ||
const [back, fore] = [backRef.current, foreRef.current]; | ||
if (back === null) throw Error("backElm is null"); | ||
if (fore === null) throw Error("foreElm is null"); | ||
setContrast(getContrast(props, back, fore)); | ||
}, 0); // Wait for all styles are applied | ||
}, [setContrast]); | ||
Check warning on line 53 in new-docs/src/color/sample/sample.tsx GitHub Actions / lint
|
||
|
||
return ( | ||
<div | ||
ref={backRef} | ||
className={[props.background, s.container].join(" ")} | ||
> | ||
{/* "background" also set color so the "fore" must be in another | ||
element of the "back" */} | ||
{props.foreground.type === "text" ? ( | ||
<span ref={foreRef} className={props.foreground.cls}> | ||
{props.foreground.usage !== "icon" && <span>Aa</span>} | ||
{props.foreground.usage === "both" && <span> </span>} | ||
{props.foreground.usage !== "text" && <ColorIcon />} | ||
</span> | ||
) : ( | ||
<span | ||
ref={foreRef} | ||
className={[s.border, props.foreground.cls].join(" ")} | ||
/> | ||
)} | ||
<span title="Color contrast" aria-label="Color contrast"> | ||
<Tag | ||
color={getColor(contrast)} | ||
children={contrast.toFixed(1)} | ||
/> | ||
</span> | ||
</div> | ||
); | ||
}; |
Oops, something went wrong.