Dark Mode

Shoelace 사용 가이드 - HTML

해당 페이지는 Shoelace 라이브러리에서 제공되는 UI,UX 요소들의 소개와 사용법들을 기록한 페이지입니다.
헤더에서 각 UI,UX 요소들을 정리한 페이지로 이동하여 확인할 수 있습니다.

* 보다 정확한 내용이 필요할 땐 헤더의 아이콘을 클릭해 공식 페이지를 참조하길 바랍니다.

Shoelace 라이브러리를 받아오는법

Shoelace Library를 사용하려면 HTML의 경우 head에서 cdn으로 받아올 수 있다.
head안에 아래의 cdn을 받아오는 코드를 추가해준다.

    <!-- shoelace -->
    <link
        rel="stylesheet"
        href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.1/cdn/themes/light.css"
    />
    <script
        type="module"
        src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.1/cdn/shoelace-autoloader.js"
    ></script>
                        

Shoelace 컴포넌트의 CSS Style 적용법

Shoelace 컴포넌트는 내부적으로 Shadow DOM을 사용하기 때문에, CSS 선택자 .red-color-radio 처럼 외부 스타일로 내부 요소를 직접 조작하는 건 기본적으로 불가능하다
외부 스타일은 Shadow DOM 내부까지 접근하지못함
잘못된 접근 방법※ Shoelace

        <style>
            sl-radio {
                background-color : red; /* 적용안됨 */
            }
        </style>

        <sl-radio-group value="1">
            <sl-radio value="1">Shoelace</sl-radio>
        </sl-radio-group>
                                

    Shoelace의 태그 그대로 Style을 적용하려고 했지만 적용되지 않은 모습


다른 방법으로 접근하여야한다. 2가지 방법이 있는데 아래와 같다
shoelace 컴포넌트들이 가지는 part를 이용해서 CSS의 ::part() 를 이용하는 방법
Shoelace

        <style>
            sl-radio-group.red-radio ::part(control--checked){     /* ::part를 사용하여 적용가능 */
                background-color: var(--sl-color-red-500);
                border-color: var(--sl-color-red-500);
            }
        </style>
        <sl-radio-group value="1" class="red-radio">
            <sl-radio value="1">Shoelace</sl-radio>
        </sl-radio-group>
                            

    ::part() 를 이용하여 Shoelace 내부의 Shadow DOM 까지 접근하여 스타일이 적용된 모습

css의 속성 선택자 sl-component[속성='~'] 를 이용하는 방법
Option 1 Option 2 Option 3

        <style>
            .red-select sl-option::part(base):hover{
                /* hover된 option */
                background-color: var(--sl-color-red-200);
            }
            .red-select sl-option[tabindex="0"]::part(base),
            .red-select sl-option[tabindex="0"]::part(base):hover {
                /* 선택된 option */
                background-color: var(--sl-color-red-500);
            }
        </style>

        <sl-select
        class="red-select"
        label="Shoelace">
            <sl-option value="option-1">Option 1</sl-option>
            <sl-option value="option-2">Option 2</sl-option>
            <sl-option value="option-3">Option 3</sl-option>
        </sl-select>
                            

    sl-component[속성=''] 를 이용하여 접근 하여 내부DOM을 특정하여 스타일이 적용된 모습

다크모드 사용법

Shoelace에서는 DarkMode를 사용하는 방법을 제공하고있다.
단, 아래의 단계가 필요하다.
우선 Shoelace에서 제공하는 Light & Dark Theme를 위한 CSS를 받아준다

    <!-- shoelace Light & Dark Theme -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.1/cdn/themes/light.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.1/cdn/themes/dark.css">
                            
전역으로 사용하는 reset.css에 다음과 같이 Light-Theme일때의 색상과 Dark-Theme일때의 색상을 명시해준다

    reset.css
        
    /* 라이트 모드 컬러 */
    .sl-theme-light {
        /* background - color */
        --bg-color: #ffffff;

        /* text - color */
        --text-body-color: #555555;
        --text-title-color: #1d1d1d;
        --text-disable-color: #8e8e8e;

        /* border color */
        --border-gray-color: rgb(136, 136, 136);

        /* button color */
        --button-primary-color : rgb(59, 105, 255);

        /* icon color */
        --icon-color: var(--sl-color-neutral-700);
    }

    /* 다크 모드 컬러 */
    .sl-theme-dark {
        /* background - color */
        --bg-color: #202020;

        /* text - color */
        --text-body-color: #bdbdbd;
        --text-title-color: #eeeeee;
        --text-disable-color: #8e8e8e;

        /* border color */
        --border-gray-color: #888;

        /* button color */
        --button-primary-color :rgb(75, 132, 255);

        /* icon color */
        --icon-color: var(--sl-color-neutral-900);
    }
                        
위에서 선언한 컬러를 전역으로 사용하기위해 동일하게 reset.css에서 아래와같이 기본 html 요소들에 스타일을 적용시킨다.

    reset.css                        
                            
    /* 실제 적용되는 부분 */
    body {
        background-color: var(--bg-color);
        color: var(--text-body-color);
        transition: background-color 0.3s ease, color 0.3s ease;
    }

    h1,h2,h3,h4,h5,p,span,small,div{
        color: var(--text-title-color);
    }
                        
페이지에서 Theme의 변경을 저장하고 적용시키기 위해서는 JS가 필요하다.
아래의 script를 추가하여 페이지에서 적용될 수 있게 한다.

    /** 라이트 모드 , 다크 모드를 바꾸기위한 script */

    /* DOM */
    const html = document.documentElement;
    const darkModeSwitch = document.getElementById('darkModeSwitch');

    /* function */
    const getLocalStorage_darkMode = () => {
        let mode = window.localStorage.getItem('isDarkMode');
        if(mode === null){ //localStorage가 없다 = 첫 방문

            /* 초기 테마 설정 (시스템 테마 감지) */
            mode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
        }

        if(darkModeSwitch !== null)
        {
            darkModeSwitch.checked = mode === 'dark' ? true : false;
        }
        setTheme(mode)
    }

    const getCurrentTheme = () => {
        // 현재 테마 확인
        return html.classList.contains('sl-theme-dark') ? 'dark' : 'light';
    };

    const setTheme = (mode) => {
        // 테마 설정 함수
        html.classList.remove('sl-theme-light', 'sl-theme-dark');
        html.classList.add(`sl-theme-${mode}`);

        window.localStorage.setItem('isDarkMode', mode);
    };

    /* Event */
    darkModeSwitch?.addEventListener('sl-change', () => {
        // 토글 이벤트 연결
        const isDarkMode = darkModeSwitch.checked;
        setTheme(isDarkMode ? 'dark' : 'light');
    });

    /* init */
    getLocalStorage_darkMode()