テーマの調整
変える手段は3つあります。上から順に試してください。下にいくほど強く、壊れやすくなります。
1. CSS 変数を上書きする
ブランド色を変えるならこれだけで済みます。 --novi-color-primary を使う全コンポーネントに一度に効きます。
/* app/globals.css */
@import '@novi-ui/core/base.css';
@import '@novi-ui/raster/raster.css';
:root {
--novi-color-primary: oklch(58% 0.18 265);
--novi-color-primary-fg: oklch(99% 0 0);
}
[data-novi-scheme='dark'] {
--novi-color-primary: oklch(72% 0.15 265);
}色は oklch() で書いてください。明度を数値で扱えるため、 ライトとダークで同じコントラスト比を保ったまま色相だけ差し替えられます。
2. slot にクラスを足す
1箇所だけ形を変えたいときは classNames を使います。 variant が付けたクラスを打ち消したいときも、拡張ではなくこちらが正解です。
import { Button, Card, CardBody, CardHeader } from '@novi-ui/raster'
// slot ごとにクラスを足す。variant のクラスを上書きしたいときもこれを使う。
export function WideSaveButton() {
return (
<Button
color="primary"
classNames={{
root: 'w-full justify-between',
label: 'tracking-wide',
}}
>
保存
</Button>
)
}
// どの slot があるかは各コンポーネントのページの slot 表にある。
export function TightCard() {
return (
<Card classNames={{ header: 'pb-1', body: 'pt-1' }}>
<CardHeader>売上</CardHeader>
<CardBody>¥1,240,000</CardBody>
</Card>
)
}3. styles を拡張する
同じ見た目を何度も使うなら、派生した styles を1つ作ります。tailwind-variants が必要です。
pnpm add tailwind-variantsimport { Button, buttonStyles } from '@novi-ui/raster'
import { tv } from 'tailwind-variants'
// slot ベースの定義では `base` は効かない。**必ず `slots` を使う。**
export const wideButtonStyles = tv({
extend: buttonStyles,
slots: {
root: 'w-full justify-between',
},
})
// 拡張した styles は自分で呼び、結果を classNames に渡す。
export function WideButton() {
const s = wideButtonStyles({ size: 'lg' })
return (
<Button size="lg" classNames={{ root: s.root() }}>
続ける
</Button>
)
}slot ベースの定義では base が効きません。 tv({ extend, base }) と書いても無視されるため、slots を使ってください。 また extend で足したクラスは base に加算されるだけなので、 variant のクラスには勝てません。勝たせたいときは 2 の classNames を使います。
上書きできる変数
Raster(@novi-ui/raster)が定義する値です。 この表は CSS を出力しているのと同じ定義から作られているため、実装とズレません。
角丸
Raster では full 以外すべて 2px 以下。角を立てるのが思想(ADR-R1)
| CSS 変数 | 値 |
|---|---|
| --novi-radius-none | 0px |
| --novi-radius-sm | 2px |
| --novi-radius-md | 2px |
| --novi-radius-lg | 2px |
| --novi-radius-full | 9999px |
影
Raster ではすべて none。階層は境界線と背景色の差で表す
| CSS 変数 | 値 |
|---|---|
| --novi-shadow-none | none |
| --novi-shadow-sm | none |
| --novi-shadow-md | none |
| --novi-shadow-lg | none |
文字サイズ
比率 1.2(minor third)。単一比率で階層を作る
| CSS 変数 | 値 |
|---|---|
| --novi-text-xs | 12px |
| --novi-text-sm | 14px |
| --novi-text-base | 16px |
| --novi-text-lg | 20px |
| --novi-text-xl | 24px |
| --novi-text-2xl | 30px |
| --novi-text-3xl | 36px |
モーション
Raster では速度を1つに固定している。動きで飾らない
| CSS 変数 | 値 |
|---|---|
| --novi-duration-fast | 120ms |
| --novi-duration-base | 120ms |
| --novi-duration-slow | 120ms |
| --novi-ease-standard | cubic-bezier(0.2, 0, 0, 1) |
| --novi-ease-emphasized | cubic-bezier(0.2, 0, 0, 1) |
色
ブランド色を変えるならここ。中立色の chroma は 0 に固定している
bgsubtlefgmutedborderborder-strongoverlaydefaultdefault-fgprimaryprimary-fgsecondarysecondary-fgsuccesssuccess-fgwarningwarning-fgdangerdanger-fg
| CSS 変数 | ライト | ダーク |
|---|---|---|
| --novi-color-bg | oklch(99% 0 0) | oklch(16% 0 0) |
| --novi-color-subtle | oklch(96% 0 0) | oklch(21% 0 0) |
| --novi-color-fg | oklch(20% 0 0) | oklch(95% 0 0) |
| --novi-color-muted | oklch(48% 0 0) | oklch(72% 0 0) |
| --novi-color-border | oklch(88% 0 0) | oklch(28% 0 0) |
| --novi-color-border-strong | oklch(58% 0 0) | oklch(55% 0 0) |
| --novi-color-overlay | oklch(20% 0 0 / 0.45) | oklch(10% 0 0 / 0.6) |
| --novi-color-default | oklch(96% 0 0) | oklch(25% 0 0) |
| --novi-color-default-fg | oklch(20% 0 0) | oklch(95% 0 0) |
| --novi-color-primary | oklch(48% 0.18 250) | oklch(74% 0.14 250) |
| --novi-color-primary-fg | oklch(99% 0 0) | oklch(16% 0 0) |
| --novi-color-secondary | oklch(46% 0.16 300) | oklch(74% 0.13 300) |
| --novi-color-secondary-fg | oklch(99% 0 0) | oklch(16% 0 0) |
| --novi-color-success | oklch(45% 0.13 150) | oklch(76% 0.13 150) |
| --novi-color-success-fg | oklch(99% 0 0) | oklch(16% 0 0) |
| --novi-color-warning | oklch(45% 0.12 70) | oklch(82% 0.12 70) |
| --novi-color-warning-fg | oklch(99% 0 0) | oklch(16% 0 0) |
| --novi-color-danger | oklch(48% 0.19 25) | oklch(72% 0.16 25) |
| --novi-color-danger-fg | oklch(99% 0 0) | oklch(16% 0 0) |
変えても効かないもの
テーマは語彙を解釈する自由を持っています。Raster は角を立てる思想のため、radius="lg" を渡しても見た目が変わりません。 これは仕様であって不具合ではありません。詳しくは Raster のデザイン言語を読んでください。