Elm을 사용한 동적 CSS 테마

8772 단어 elm

영감



일부 디자인 시스템은 플랫폼에 구애받지 않도록 구축되었기 때문에 CSS-in-JS 대신 글로벌 CSS3 변수를 사용하여 SPA(Single Page Applications) 앱을 테마로 지정하는 방법을 배우고 싶었습니다. Elm은 내가 가장 좋아하는 취미 언어이기 때문에 누군가가 돈을 지불하기 전까지는 전문적으로 사용하고 있습니다 😎

투기



이전에 CSS 테마를 사용해 본 적이 없더라도 걱정할 필요가 없습니다. 놀랍도록 간단합니다. 화면 중앙에 하나의 버튼이 있을 것이고 텍스트는 사용자가 클릭할 때 활성화될 테마를 사용자에게 알려야 합니다. 사용자가 테마를 전환할 수 있는 횟수에는 제한이 없습니다. 기본 테마는 "Solarized Light"입니다. 일반적으로 앱은 사용자 선택을 데이터베이스나 로컬 캐시에 저장하여 기억하지만 이 데모에서는 그렇지 않습니다. 말하자면, 라이브 데모here로 플레이할 수 있습니다!

참고: Dark Reader Chrome 확장 프로그램이 있는 경우 이를 끄십시오.

암호



먼저 :root CSS 의사 클래스(자세히 알아보기here ) 및 테마가 "Solarized Dark"로 변경될 때 재정의를 위한 .dark 클래스에서 기본 테마 색상을 설정해야 합니다.

:root {
  --theme-background: #fdf6e3;
  --theme-selection-background: #ece7d5;
  --theme-foreground: #657a81;
  --theme-accent1: #2aa198;
  --theme-accent2: #b58900;
}

.dark {
  --theme-background: #002b36;
  --theme-selection-background: #073642;
  --theme-foreground: #b58900;
  --theme-accent1: #d33682;
  --theme-accent2: #268bd2;
}

다음으로 Elm은 HTML 렌더링을 담당하므로 현재 테마가 무엇인지 알아야 합니다. 이 상태는 테마 변경 버튼의 렌더링 논리에서 텍스트를 변경하는 데 사용됩니다. 이제 간단한 도메인을 모델링하고 유비쿼터스 언어를 결정하겠습니다.

옵션 1:
작업 → 테마 전환

type alias Model =
    Bool

type Msg
    = ToggleTheme Bool

옵션 2:
작업 → 테마 변경

type Theme
    = SolarizedLight
    | SolarizedDark

type alias Model =
    Theme

type Msg
    = ChangeTheme Theme

두 옵션 모두 작동하지만 시각 장애인을 위한 고대비 모드 등과 같은 더 많은 테마를 추가하려는 경우 합계 유형이 더 우아하고 확장 가능하다고 주장하고 싶습니다. 따라서 옵션 2로 이동하여 버튼 렌더링을 생성해 보겠습니다. 논리.

themeButton : Model -> Html Msg
themeButton model =
    case model of
        SolarizedDark ->
            button [ class "theme-btn", onClick (ChangeTheme SolarizedLight) ]
                [ text "Toggle Light" ]

        SolarizedLight ->
            button [ class "theme-btn", onClick (ChangeTheme SolarizedDark) ]
                [ text "Toggle Dark" ]

마지막 비트는 현재 테마를 반영하기 위해 DOM에서 CSS 클래스를 조작하기 위해 좋은 오래된 Javascript에 의존합니다. 이전에 만든 .dark 클래스를 <body> 요소에 특성으로 추가해야 색상 재정의가 적용됩니다. Elm은 DOM을 직접 조작하는 것을 허용하지 않습니다(아직 알지 못했다면). 어떻게 해야 할까요?

JS(Javascript-as-a-service)와 상호 작용하는 현명한 방법인 Elmports을 입력하십시오. 고맙게도 이것이 우리가 필요로 하는 바닐라 JS의 전부입니다.

app.ports.changeTheme.subscribe(theme => {
    if (theme === "") {
        document.body.classList.remove("dark");
    } else {
        document.body.classList.add(theme);
    }
})

한 가지 더... 업데이트 기능은 방금 말한 changeTheme 메시지를 각각의 테마와 함께 방송해야 합니다.

update : Msg -> Model -> ( Model, Cmd Msg )
update msg _ =
    case msg of
        ChangeTheme theme ->
            case theme of
                SolarizedDark ->
                    ( SolarizedDark, changeTheme "dark" )

                SolarizedLight ->
                    ( SolarizedLight, changeTheme "" )

결론



ReasonReact와 같은 다른 Javascript로 컴파일 언어는 Javascript interopt에 대해 다른 철학을 가지고 있습니다. 나는 지금 당장 찬성/반대 주장을 하고 있지는 않지만, 이 작은 예가 Elm이 신뢰할 수 없는 코드를 가장자리로 밀어내는 방법을 강조하기를 바랍니다.


한스호프만 / elm-동적-css-테마


테마를 동적으로 변경하려면 CSS3 변수를 사용하십시오.

좋은 웹페이지 즐겨찾기