🥺
TypeScriptでCSSの単位を型安全に相互変換する_1
サイズを渡す時に単位まで指定できない問題
下記のようなパディングの値を渡せるようなコンポーネントがあるとする
数値を渡せるようにしたが、これだと使用者側には単位が分からない
そもそもチーム内で使用する単位は統一しろっていう話だけど、、、
example.tsx
type Props = Readonly<{
padding: number;
}>;
const Wrapper: React:FC<Props> = ({
children,
padding,
}) => {
return (
<div css={{ padding: `${padding}rem` }}>
{children}
</div>
);
};
pixel-unitsを使って解決する
numberを使用したい単位の型に書き換えるだけ
example.tsx
import { Rem } from '@karibash/pixel-units';
type Props = Readonly<{
padding: Rem;
}>;
const Wrapper: React:FC<Props> = ({
children,
padding,
}) => {
return (
<div css={{ padding: `${padding}` }}>
{children}
</div>
);
};
export default Wrapper;
使う側はこんな感じ
Rem単位しか使えないようにコンポーネント側で強制できる
example.tsx
import { Rem } from '@karibash/pixel-units';
import Wrapper from 'components/wrapper';
const Page: React:FC = () => {
const padding = new Rem(2);
return (
<Wrapper padding={padding}>
{children}
</Wrapper>
);
};
export default Page;
単位の相互変換も出来る
remに変換する場合はルート要素のフォントサイズの指定が必要になる
そのため、ルート要素のフォントサイズを取得するヘルパー関数も用意している
example.ts
import { Pixel, tryFindRootFontSize } from '@karibash/pixel-units';
const pixel = new Pixel(32);
console.log(`${pixel}`);
// -> 32px
const rem = pixel.toRem(tryFindRootFontSize());
console.log(`${rem}`);
// -> 2rem
まとめ
暇だったから思いつきで作ったけどあんまり需要なさそう
Discussion
ちょうど同じあたりで悩むことが最近あって結局単位縛りしていたのですが、このアプローチはとても良さそうです。有益な情報ありがとうございます。
需要があるのか分からずにコーディングしていたのでお役に立てて嬉しいです😭