스타일 구성 요소 및 TypeScript와 반응하는 HSLA 색상 시스템

21145 단어 typescriptreact
🚨 Watch on YouTube

React 앱에서 색상을 처리하는 가장 좋은 방법은 무엇입니까? 알아 보자.

네 가지 구성 요소가 있는 HSLA 색상 형식을 사용합니다. 색조는 색상 자체입니다. 0에서 360까지 범위를 갖는 색상환의 각도입니다. 여기서 120은 녹색이고 240은 파란색입니다. 채도는 100%이면 색상이 완전히 포화되고 0%이면 색상이 회색으로 보이는 백분율입니다. 밝기는 백분율 값이기도 합니다. 여기서 100%는 모든 색상을 흰색으로 만들고 0%는 검은색으로 만듭니다. 마지막 구성 요소는 알파입니다. 0이면 색상이 투명하고 1이면 완전히 불투명합니다.

HSLA는 색상을 변경하는 직관적인 방법을 제공합니다. 색상을 조금 더 밝게 만들고 싶습니까? L 성분을 10% 증가시킬 수 있습니다. RGB 또는 HEX로 어떻게 하시겠습니까? 그렇게 쉽거나 우아하지 않을 것입니다.

여기에 HSLA 클래스가 있습니다. 생성자는 4개의 매개변수를 사용하며 여기서 alpha는 기본적으로 1입니다.

export const hslaKeys = ["h", "s", "l", "a"] as const

export type ColorModifiers = Partial<
  Record<typeof hslaKeys[number], (parameter: number) => number>
>

const enforceRange = (value: number, min: number, max: number) =>
  Math.max(min, Math.min(max, value))

export class HSLA {
  private _h = 0
  get h(): number {
    return this._h
  }
  set h(newH: number) {
    this._h = enforceRange(newH, 0, 360)
  }

  private _l = 0
  get l(): number {
    return this._l
  }
  set l(newL: number) {
    this._l = enforceRange(newL, 0, 100)
  }

  private _s = 0
  get s(): number {
    return this._s
  }
  set s(newS: number) {
    this._s = enforceRange(newS, 0, 100)
  }

  private _a = 0
  get a(): number {
    return this._a
  }
  set a(newA: number) {
    this._a = enforceRange(newA, 0, 100)
  }

  constructor(h: number, s: number, l: number, a = 1) {
    this.h = h
    this.s = s
    this.l = l
    this.a = a
  }

  toCssValue() {
    return `hsla(${this.h},${this.s}%,${this.l}%,${this.a})`
  }

  getVariant(modifiers: ColorModifiers) {
    const [h, s, l, a] = hslaKeys.map(key => {
      const value = this[key]
      const modifier = modifiers[key]

      return modifier ? modifier(value) : value
    })

    return new HSLA(h, s, l, a)
  }
}


이를 CSS 값으로 변환하기 위해 각 구성 요소를 가져와 CSS HSLA 함수로 변환하는 방법이 있습니다.

새로운 색상 변형을 얻으려면 getVariant 방법이 있습니다. 수정자가 있는 객체를 수신합니다. 여기서 수정자는 이전 구성 요소 값을 수신하고 새 값을 반환하는 함수입니다.

구성 요소를 범위 내에 유지하기 위해 세터를 사용합니다. 채도를 120% 퍼센트로 만들려고 하면 enforceRange 함수를 활용하여 S setter를 100%로 변환합니다.

My app에는 몇 가지 기본 색상만 있으며 저는 HSLA 클래스를 사용하여 모든 색상을 정의합니다. 여기에는 기본 밝기 또는 배경 채도와 같이 꽤 많은 색상에서 공유하는 몇 가지 변수가 있습니다.

import { HSLA } from "./HSLA"

const primaryHue = 210
const primarySecondHue = 41
const primaryThirdHue = 6
const primarySaturation = 92
const primaryLightness = 52
const lightnessIncrease = 5

export const backgroundHue = 214
const backgroundSaturation = 42
const backgroundLightness = 10

const transparentSaturation = 60
const transparentLightness = 88

export const regularTextAlpha = 0.9

export const colors = {
  primary: new HSLA(primaryHue, primarySaturation, primaryLightness),
  attention: new HSLA(primarySecondHue, primarySaturation, primaryLightness),
  alert: new HSLA(primaryThirdHue, primarySaturation, primaryLightness),
  success: new HSLA(130, primarySaturation, primaryLightness),

  background: new HSLA(
    backgroundHue,
    backgroundSaturation,
    backgroundLightness + lightnessIncrease
  ),
  backgroundDark: new HSLA(
    backgroundHue,
    backgroundSaturation,
    backgroundLightness,
    1
  ),
  backgroundLight: new HSLA(
    backgroundHue,
    backgroundSaturation,
    backgroundLightness + lightnessIncrease * 2
  ),

  text: new HSLA(
    backgroundHue,
    transparentSaturation,
    transparentLightness,
    regularTextAlpha
  ),

  backgroundDimGlass: new HSLA(
    backgroundHue,
    transparentSaturation,
    transparentLightness,
    0.5
  ),
  backgroundGlass: new HSLA(
    backgroundHue,
    transparentSaturation,
    transparentLightness,
    0.15
  ),

  overlay: new HSLA(backgroundHue, backgroundSaturation, 1, 0.8),

  white: new HSLA(0, 0, 256, 1),
} as const

export type Colors = typeof colors

export type ColorName = keyof typeof colors

styled-components Theme 유형에 해당 색상을 포함하려면 유형 선언 파일을 만들고 기본 테마를 확장할 수 있습니다.

import "styled-components"

import { Colors } from "ui/colors"

declare module "styled-components" {
  export interface DefaultTheme {
    colors: Colors
  }
}


그런 다음 theme 객체를 생성하고 ThemeProvider 에 전달하고 스타일 구성 요소에서 색상을 사용할 수 있습니다.

import { DefaultTheme, ThemeProvider } from "styled-components"
import { colors } from "ui/colors"

export const theme: DefaultTheme = { colors } as const

export const App = () => <ThemeProvider theme={theme}>...</ThemeProvider>


다음은 투명에 가까운 변형을 만들어 CSS 값으로 변환하여 배경을 만드는 배지 구성 요소의 예입니다.

background: ${({ theme }) => theme.colors.success.getVariant({ a: () => a * 0.2 }).toCssValue()};

좋은 웹페이지 즐겨찾기