Lily 시작하기

프레임워크를 고르고, 모노레포를 복제해서 헤드리스 라이브러리나 예제 앱을 열고, 나만의 페이지를 조합해 보세요. 안내를 따라 진행하고 싶다면 튜토리얼부터 시작하세요.

설치

Lily는 하나의 Git 모노레포에 있으며, 프레임워크마다 헤드리스 라이브러리, 도우미 패키지, 예제 앱 디렉터리가 있습니다. 가장 빠르게 써 보는 방법은 모노레포를 복제하고 사용하는 스택의 헤드리스 라이브러리를 여는 것입니다.

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-react-headless
pnpm install

다른 프레임워크도 같은 방식입니다.

  • @lilydesignsystem/html-headless — 설치 불필요. .html 파일을 복사합니다
  • @lilydesignsystem/svelte-headless — pnpm install
  • @lilydesignsystem/react-headless — pnpm install
  • @lilydesignsystem/vue-headless — pnpm install
  • @lilydesignsystem/angular-headless — pnpm install
  • @lilydesignsystem/nunjucks-headless — pnpm install
  • lily-design-system-blazor-headless — dotnet build

헤드리스 라이브러리는 복제하거나 벤더링해서 쓰도록 설계되었습니다. 소스를 기준으로 삼고 필요한 것을 복사하세요. 환경설정 도우미는 추가로 빌드와 배포 파이프라인(JS 프레임워크는 npm, Blazor는 NuGet)을 갖춘 설치 가능한 패키지로도 제공됩니다.

헤드리스 컴포넌트 사용하기

헤드리스 컴포넌트는 시맨틱 HTML, ARIA, 속성을 제공하지만 CSS는 없습니다. 각 프레임워크에서의 Button은 다음과 같습니다.

HTML

<button class="button" type="button" aria-label="Save">
  Save
</button>

Svelte

<script>
  import Button from "lily-design-system-svelte-headless/components/Button/Button.svelte";
</script>

<Button onclick={save}>Save</Button>

React

import Button from "lily-design-system-react-headless/components/Button";

<Button onClick={save}>Save</Button>

Vue

<script setup>
  import Button from "lily-design-system-vue-headless/components/Button.vue";
</script>

<Button @click="save">Save</Button>

Angular

import { Button } from "@lilydesignsystem/angular-headless";

@Component({
  imports: [Button],
  template: `<lily-button (click)="save()">Save</lily-button>`,
})

Blazor

<Button OnClick="Save">Save</Button>

Nunjucks

{% from "components/button/macro.njk" import button %}

{{ button({ text: "Save", type: "button" }) }}

스타일이 적용된 예제 사용하기

예제 앱에는 CSS, 라우트, 완전한 데모 페이지가 들어 있습니다. 가장 빠르게 실험하는 방법은 SvelteKit, Next, Nuxt, Analog, Eleventy 예제 앱을 실행해서 /components의 데모를 보는 것입니다.

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-svelte-sveltekit-examples
pnpm install
pnpm run dev

그런 다음 http://localhost:5173을 열고 /components를 둘러보세요.

스타일과 디자인 토큰

각 컴포넌트는 루트 요소에 케밥 케이스 클래스 하나를 달고 렌더링됩니다. 예를 들어 <Button>은 <button class="button">을 렌더링합니다. 스타일은 원하는 대로 입히세요.

.button {
  background: var(--my-primary);
  color: #fff;
  padding: 0.75rem 1.5rem;
  border-radius: 0.5rem;
}
.button:hover { background: var(--my-primary-hover); }

Lily의 기본 색상 팔레트(예제 앱에서 사용)는 다음과 같습니다.

  • 기본: #2563eb
  • 위험: #dc2626
  • 경고: #f59e0b
  • 성공: #16a34a
  • 페이지 배경: #f9fafb
  • 카드 배경: #ffffff

이것들은 제안일 뿐 필수가 아닙니다. 여러분 브랜드의 팔레트로 바꿔도 Lily는 문제없이 따라옵니다.

기성 테마

CSS를 처음부터 쓰고 싶지 않으신가요? Lily에는 57가지 독립 참조 테마가 themes/ 디렉터리에 포함되어 있습니다. 각각은 Lily 클래스 훅을 겨냥한 스타일시트 하나이며, 연결하기만 하면 스타일이 적용됩니다.

<link rel="stylesheet" href="/assets/themes/united-kingdom-government-digital-service.css" />

제공되는 테마는 다음과 같습니다.

  • 공공 부문 — NHS England, NHS Scotland, NHS Wales (각각 환자용과 실무자용 변형), GOV.UK GDS, U.S. Web Design System.
  • 벤더에서 영감을 받은 것 — Adobe Spectrum, Mozilla Protocol.
  • 범용 — light, dark, nord, dracula, wireframe 등 서른 가지가 넘는 테마.

테마 선택자는 :where(...)를 쓰므로 명시도에서는 항상 여러분의 CSS가 이깁니다. 런타임 전환을 위해 아래의 theme-picker 도우미와 함께 쓰거나 테마 설정 튜토리얼을 따라 해 보세요.

환경설정 도우미

각 프레임워크에는 작은 선택기가 여덟 개 있으며, 각각 독립된 lily-design-system-{framework}-{package} 패키지입니다(이를 조립하는 picker-bar도 있습니다). 각각은 팝업(리스트박스, 링크 목록, 검색 폼, date-time-picker의 경우 날짜 선택 대화 상자)을 여는 헤드리스 아이콘 버튼이며, 네이티브 <select>가 아니고, SSR에 안전하며, CSS는 포함하지 않습니다.

  • theme-picker — 관리되는 <link>를 교체해서 런타임에 테마 스타일시트를 불러오고, 문서에 data-theme를 설정하며, 선택적으로 localStorage에 저장합니다.
  • locale-picker — lang과 dir(자동 RTL 감지 포함)를 설정해서 i18n 라이브러리가 따라가게 합니다. 번역 자체는 하지 않습니다.
  • text-size-picker — 문서에 data-text-size를 설정합니다. 각 값을 글꼴 크기에 대응시키는 것은 여러분의 CSS입니다.
  • motion-picker — 방문자의 동작 줄이기 설정에서 출발해 문서에 data-motion을 설정합니다. 무엇을 억제할지는 여러분의 CSS와 스크립트가 정합니다.
  • search-picker — 검색 필드를 여는 아이콘 버튼. 제출하면 검색 페이지로 이동합니다. 환경설정이 아니라 동작을 담당합니다.
  • link-picker — 앱이 정의하는 페이지 링크(홈, 회사 소개, 문의하기, 개인정보 처리방침 등)의 메뉴를 여는 홈 아이콘. 환경설정이 아니라 동작을 담당합니다.
  • share-picker — 네이티브 공유 시트 또는 사용 측이 제공한 대상 목록과 URL 복사를 엽니다. 환경설정이 아니라 동작을 담당합니다. 아무것도 적용하지 않고 아무것도 저장하지 않습니다.
  • date-time-picker — 날짜, 시간 또는 둘 다를 위한 텍스트 필드와 APG 날짜 선택 대화 상자. 환경설정이 아니라 폼 값을 담당합니다. ISO 문자열이 <input type="date">와 오가며 변환됩니다.
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-svelte-theme-picker

Svelte 카탈로그가 기준입니다. React, Vue, Angular, HTML, Nunjucks, Web Components, Blazor 포트는 규약 하나하나까지 일치합니다. 도우미 튜토리얼을 참고하세요.

접근성

컴포넌트는 WCAG 2.2 AAA를 목표로 합니다. 다음 패턴을 따릅니다.

  • 범용 <div>보다 시맨틱 HTML 요소.
  • 레이블과 입력을 연결하는 <label for="id">.
  • 상호 참조를 위한 aria-labelledby / aria-describedby.
  • 오류 상태를 위한 aria-invalid + aria-errormessage.
  • 동적 콘텐츠를 위한 role="alert"와 aria-live.
  • 상태를 위한 aria-pressed, aria-expanded, aria-current.
  • 그리드를 위한 로빙 tabindex.

포커스 표시는 의도적으로 사용 측이 제공합니다. Lily는 여러분의 디자인과 충돌하는 기본 포커스 링을 그리지 않습니다. 예제 앱은 모든 경로에서 axe-core의 깨끗한 기준선을 유지합니다.

다국어화

모든 레이블, 플레이스홀더, 오류 메시지, 버튼 문구는 속성입니다. 하드코딩된 문자열은 없습니다. 원하는 번역 프레임워크(Paraglide, i18next, vue-i18n, react-intl, .resx 파일 등 무엇이든)를 연결하세요.

날짜, 숫자, 통화는 컴포넌트가 미리 서식을 갖춘 문자열을 받습니다. Intl.DateTimeFormat / Intl.NumberFormat / 선호하는 라이브러리로 서식을 만들어 그 결과를 전달하세요.

locale-picker 도우미는 문서 루트에 lang과 dir을 설정해서 선택된 로케일을 i18n 라이브러리에 알립니다.

테스트

각 프레임워크 하위 프로젝트에는 그 프레임워크에 맞는 구성의 자체 테스트가 포함되어 있습니다.

  • HTML: 실제 브라우저에서 실행하는 WebDriverIO.
  • Svelte: Vitest + @testing-library/svelte.
  • React: Vitest + @testing-library/react.
  • Vue: Vitest + @testing-library/vue.
  • Angular: Vitest + TestBed (Analog Vite 플러그인 사용).
  • Nunjucks: 렌더 도우미가 있는 Vitest.
  • Blazor: bUnit.

테스트는 Vitest 내장 매처만 사용하며 jest-dom 매처는 쓰지 않습니다. 이렇게 하면 테스트 모음의 이식성이 유지됩니다. 예제 앱에는 Playwright 엔드투엔드 테스트, axe-core 접근성 기준선, 반응형 뷰포트 점검이 추가됩니다.

AI 에이전트

이 사이트는 루트에 llms.txt와 llms.json을 게시합니다. 이는 llms.txt 규약을 따르는 모든 도구를 위한, 가장 중요한 페이지를 엄선한 안내도입니다.

정식 모노레포에는 추가로 두 개의 Claude Skills가 있습니다. lily-design-system-skill은 이 시스템으로 개발하는 사람을 위해 Lily의 개념, 용어, 조합 패턴을 다루는 범용 스킬이고, lily-design-system-maintainer-skill은 모노레포에서 작업하는 사람을 위해 필수 파일 구성과 도구를 다루는 기술 스킬입니다. 둘 다 정식 모노레포의 루트에 있습니다.

문제 해결

컴포넌트는 렌더링되는데 스타일이 없어 보입니다

헤드리스가 의도대로 동작하는 것입니다. 컴포넌트에는 CSS가 포함되지 않습니다. 컴포넌트의 케밥 케이스 클래스(카탈로그의 모든 페이지에 표시됩니다)에 맞춰 CSS를 작성하거나 57가지 기성 테마 중 하나를 연결하세요.

테마 위에서 내 CSS가 적용되지 않는 것 같습니다

적용되어야 합니다. 테마 선택자는 명시도가 0인 :where(...)로 감싸여 있습니다. 그래도 규칙이 지는 경우, 내 스타일시트가 테마의 <link> 뒤에 로드되는지, 그리고 선택자가 실제로 컴포넌트의 클래스 훅과 일치하는지 확인하세요.

pnpm install이 피어 또는 버전 오류로 실패합니다

최신 pnpm(v10 이상)과 Node 22 이상을 사용하세요. 각 하위 프로젝트는 자체 package.json에 프레임워크 버전을 고정합니다. 전역 도구 체인이 오래되었다면 pnpm env use --global lts가 가장 빠른 해결책입니다.

스크린 리더가 컨트롤의 이름을 잘못 읽습니다

컴포넌트의 필수 label 속성을 확인하세요. 보이는 텍스트가 없는 컴포넌트에는 이것이 필수입니다. 또한 rest-props로 전달한 사용 측의 aria-label / aria-labelledby는 의도적으로 내장 연결보다 우선합니다. 각 카탈로그 페이지에 해당 컴포넌트의 ARIA 규약이 문서화되어 있습니다.

theme-picker 도우미가 스타일시트를 전환하지 않습니다

themesUrl이 브라우저가 가져올 수 있는 디렉터리를 가리키는지(themes/ 파일을 정적 자산으로 제공하세요), 그리고 themes 속성의 테마 슬러그가 파일 이름과 일치하는지 확인하세요. 도우미는 관리되는 하나의 <link data-lily-theme-picker>의 href를 교체합니다. 개발자 도구에서 살펴보면 요청되는 URL을 알 수 있습니다.

그 밖의 다른 것이 고장 났습니다

최소한의 재현 방법과 함께 github.com/LilyDesignSystem/lily-design-system에서 이슈를 열어 주세요. 또는 커뮤니티와 지원을 참고하세요.

기여하기

Lily는 젊은 프로젝트이며 협업을 환영합니다. 지금 가장 유용한 기여는 다음과 같습니다.

  • 새 컴포넌트(특히 확립된 디자인 시스템의 패턴).
  • 새 테마. 각각이 독립된 스타일시트 하나이므로 첫 풀 리퀘스트로 알맞은 범위입니다.
  • 더 나은 예제 스타일링. 가능한 것을 보여 주세요.
  • 예제 앱 문자열의 번역.
  • 최소한의 재현 방법을 갖춘 버그 보고.
  • 스크린 리더와 보조 기술을 이용한 접근성 감사.

이슈와 풀 리퀘스트는 github.com/LilyDesignSystem/lily-design-system에서 열어 주세요.

커뮤니티와 지원

  • 질문과 버그 보고 — github.com/LilyDesignSystem/lily-design-system에서 이슈를 열어 주세요.
  • 이메일 — 유지관리자가 joel@joelparkerhenderson.com 을 읽고 있으며 협업, 조언, 피드백을 환영합니다.
  • 미러 — Lily는 Codeberg와 GitLab에도 푸시되므로, 선호하는 포지에서 참여할 수 있습니다.
  • 행동 강령 — 이 프로젝트는 표준 행동 강령을 따릅니다. 친절하게, 선의를 전제로 해 주세요.

FAQ

왜 스타일이 적용된 것이 아니라 헤드리스인가요?

미리 스타일이 적용된 컴포넌트는 편리하지만, 브랜드와 맞지 않게 되는 순간까지만입니다. 헤드리스 컴포넌트는 처음에 조금 더 일이 들지만 시각 디자인을 완전히 통제할 수 있게 해 줍니다. 예제 앱과 57가지 테마가 스타일을 입히는 방법을 보여 주며, 그것을 가져다 써도 되고 완전히 바꿔도 됩니다. 더 긴 논의는 Lily를 선택하는 이유에 있습니다.

왜 컴포넌트가 이렇게 많나요?

Lily는 대부분의 앱에 필요한 패턴을 처음부터 만들지 않아도 되도록 다루는 것을 목표로 합니다. 국가별 식별자 입력이나 편집용 스크롤리텔링 같은 깊이 있는 것도 포함합니다. 카탈로그는 십여 개의 확립된 디자인 시스템과 독자적인 작업에서 가져왔습니다. 소개를 참고하세요.

Lily를 Tailwind와 함께 쓸 수 있나요?

네. 각 컴포넌트는 케밥 케이스 루트 클래스 하나와 사용 측이 제공하는 className / class를 노출합니다. 그 위에 Tailwind 유틸리티를 원하는 대로 얹으세요.

DaisyUI 같은 시맨틱 CSS 프레임워크와 함께 쓸 수 있나요?

네. 루트 요소의 케밥 케이스 클래스 이름은 시맨틱 CSS 훅으로 동작합니다. Lily를 시맨틱 프레임워크와 짝지으면 ARIA와 다국어화를 지키면서 이미 스타일이 적용된 컴포넌트를 얻을 수 있습니다.

npm 패키지가 있나요?

환경설정 도우미는 npm/NuGet 배포 파이프라인을 갖춘 패키지로 제공됩니다. 헤드리스 컴포넌트 라이브러리는 복제하거나 벤더링해서 쓰도록 설계되었으며 소스 자체가 결과물입니다. 그래서 배포하는 것을 직접 읽고, 다듬고, 소유할 수 있습니다. 헤드리스 라이브러리의 레지스트리 배포는 여전히 로드맵에 있습니다.

왜 멀티 라이선스인가요?

프로젝트마다 필요한 라이선스가 다릅니다. BSD와 MIT는 허용적이고, Apache-2.0에는 특허 허가가 있으며, GPL 계열은 카피레프트를 뒷받침합니다. 상황에 맞는 것을 고르세요.

버그를 보고하거나 기능을 요청하려면 어떻게 하나요?

GitHub 저장소에서 이슈를 열거나 joel@joelparkerhenderson.com으로 이메일을 보내 주세요.