# UI 가이드라인 Wagtail의 사용자 인터페이스는 다음으로 구축됩니다: - **HTML**: [Django 템플릿](inv:django#ref/templates/language) 사용 - **CSS**: [Sass](https://sass-lang.com/)와 [Tailwind](https://tailwindcss.com/) 사용 - **JavaScript**: [TypeScript](https://www.typescriptlang.org/) 사용 - **SVG**: 아이콘용으로, [SVGO](https://jakearchibald.github.io/svgomg/)로 축소됨 ## 린팅 및 포맷팅 사용 가능한 명령어는 다음과 같습니다: - `make lint` 는 모든 린팅을 실행하고, `make lint-server` 는 템플릿을, `make lint-client` 는 JS/CSS를 린팅합니다. - `make format` 은 모든 포맷팅과 린팅 문제 수정을 실행합니다. `make format-server` 와 `make format-client` 도 있습니다. 더 세분화된 옵션을 원한다면 `Makefile` 작업과 `package.json` 스크립트를 살펴보세요. ## HTML 가이드라인 포맷팅에는 [djhtml](https://github.com/rtts/djhtml)을, 린팅에는 [Curlylint](https://www.curlylint.org/)를 사용합니다. - [유효하고](https://validator.w3.org/nu/), [의미 있는](https://html5doctor.com/element-index/) HTML을 작성하세요. - [ARIA 저작 관행](https://w3c.github.io/aria-practices/), 특히 [나쁜 ARIA보다 ARIA 없는 것이 낫다](https://w3c.github.io/aria-practices/#no_aria_better_bad_aria)를 따르세요. - ID는 의미론에만 사용하고, 클래스는 스타일링에, `data-` 속성은 JavaScript 동작에 사용하세요. - 속성은 `id` 를 먼저, 그 다음 `class`, 그리고 다른 `data-` 또는 기타 속성은 Stimulus `data-controller` 를 먼저 정렬하세요. - 주석에는 HTML 대신 [Django 템플릿 구문](inv:django#template-comments)을 사용하세요. ## CSS 가이드라인 포맷팅에는 [Prettier](https://prettier.io/)를, 린팅에는 [Stylelint](https://stylelint.io/)를 사용합니다. - 우리는 [BEM](https://getbem.com/)과 [ITCSS](https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/)를 따르며, [Tailwind](https://tailwindcss.com/)로 만든 많은 유틸리티를 사용합니다. - 우리가 선호하는 코드 스타일을 자세히 설명하는 [stylelint-config-wagtail](https://github.com/wagtail/stylelint-config-wagtail) 구성에 익숙해지세요. - `font-size` 에는 `rem` 을 사용하세요. 텍스트에 대한 절대적인 제어를 제공하기 때문입니다. 또한, 단위 없는 `line-height` 가 선호되는데, 이는 부모 요소의 백분율 값을 상속하지 않고 대신 `font-size` 의 배수를 기반으로 하기 때문입니다. - 색상이나 글꼴 크기와 같은 디자인 토큰에는 항상 변수를 사용하고 특정 값을 하드코딩하지 마세요. - Wagtail 사이트 구현자가 재사용할 수 있도록 의도된 모든 스타일에 `w-` 접두사를 사용합니다. ### 스타일시트 대부분의 스타일은 단일 주 스타일시트인 `core.css` 로 결합됩니다. 잠재적인 스타일 충돌을 줄이고 뷰 간에 유틸리티 및 컴포넌트 스타일의 재사용을 장려하기 위해 모든 새 스타일에 권장되는 접근 방식입니다. `core.scss` 내의 가져오기는 ITCSS에 따라 구성됩니다. ITCSS 구조에는 두 가지 주요 예외가 있습니다: - `vendor/` 의 레거시 공급업체 CSS는 호환성 문제를 피하기 위해 주 스타일시트를 추가하기 전에 로드되었던 순서대로 가져옵니다. 가능하다면 해당 스타일을 컴포넌트로 변환하여 캐스케이드의 더 아래쪽에 로드해야 합니다. - `layouts/` 의 레거시 레이아웃 특정 스타일은 파일의 맨 끝에서 가져옵니다. 이는 이전에 여러 스타일시트에서 스타일이 로드되었던 방식과 일치합니다. 가능하다면 해당 스타일을 컴포넌트나 유틸리티로 변환하여 캐스케이드의 더 위쪽에 로드해야 합니다. 새로운 스타일을 만들 때는 항상 컴포넌트를 선호하고, `components` 폴더에 새 스타일시트를 추가하고 `core.scss` 에서 가져오세요. ### 전역 스타일 모든 스타일에 대해 다음을 사용합니다: - CSS 리셋으로 매우 오래된 버전의 `normalize.css`. - `box-sizing: border-box`, 요소는 항상 부모의 `box-sizing` 을 상속합니다. - 색상에 대한 전역 CSS 변수, 사이트 구현자가 변경할 수 있도록. - 글꼴 패밀리에 대한 전역 CSS 변수, 사이트 구현자가 변경할 수 있도록. - `--w-direction-factor` CSS 변수, 기본적으로 `1` 로 설정되고 RTL 언어의 경우 `-1` 로 설정되어 물리적 값(변환, 배경 위치)의 계산을 반전시키고 화살표와 같은 방향성 요소가 있는 아이콘 및 시각 자료를 미러링할 수 있습니다. - `--w-density-factor` CSS 변수, 사용자가 UI의 정보 밀도를 제어할 수 있도록 합니다. 기본적으로 `1` 로 설정되며, UI 요소의 간격과 크기를 줄이거나 늘리려면 더 낮거나 높은 값을 사용합니다. ### Tailwind 사용법 [Tailwind](https://tailwindcss.com/)를 사용하여 테마를 통해 디자인 토큰을 관리하고 CSS 유틸리티를 생성합니다. 다른 프로젝트에서 재사용할 수 있도록 의도된 기본 구성으로 `tailwind.config.js` 에 구성되어 있습니다. Wagtail은 Tailwind의 대부분의 핵심 플러그인을 사용하며, Tailwind의 기본 유틸리티 및 디자인 토큰 이름을 계속 사용하면서 [논리적 속성 및 값](https://rtlstyling.com/posts/rtl-styling#css-logical-properties) 스타일을 생성하도록 재정의합니다. 유틸리티 클래스와 관련하여 다음을 권장합니다: - 합리적인 최대 수를 유지하고, 유틸리티가 상호 의존적이거나 자주 함께 재사용되는 경우 대신 컴포넌트 스타일을 만듭니다. - 글꼴 크기, 두께 또는 기타 타이포그래피 고려 사항과 관련된 유틸리티를 피하세요. 대신 `typography.js` 에 정의된 상위 수준 유형 스케일을 사용하세요. ### Sass 사용법 고급 Sass 구문보다 장황한 바닐라 CSS를 선호하여 Sass 사용을 최소한으로 유지합니다. 완전히 피해야 할 특정 Sass 기능은 다음과 같습니다: - 플레이스홀더 / `@extend`. 예상치 못한 스타일 계층화를 초래합니다. - 색상 조작. 모든 색상은 CSS 변수 정의 및 문서를 일관되게 생성하기 위해 Tailwind를 통해 JavaScript에서 정의됩니다. 그리고 주의해서 사용해야 할 Sass 기능: - Sass 중첩. Sass 중첩에 특별히 의존하거나 지나치게 구체적인 선택자를 피하세요. 대부분의 스타일은 한두 수준의 중첩으로 작성할 수 있으며, 특정 UI 상태의 경우 3개, 가장 복잡한 시나리오에서만 4개입니다. - 부모 선택자 (`&`) 보간. 프로젝트 전체에서 스타일을 더 쉽게 검색할 수 있도록 클래스 이름의 보간은 드물게 사용하세요. - Sass 변수. 디자인 토큰을 재사용하기 위해 Tailwind 테마 변수를 선호하거나, 상태에 따라 특정 속성이 변경될 때 CSS 변수를 선호하세요. Sass 변수는 이러한 시나리오에 대한 더 짧은 별칭이나 로컬 컴포넌트 변수로만 사용해야 합니다. - 믹스인. 재사용 가능한 컴포넌트나 유틸리티 스타일로 작성할 수 없는 경우에만 새 믹스인을 만드세요. - Sass 수학. PostCSS를 통해 로드된 Tailwind에 정의된 대부분의 디자인 토큰을 사용하여, Sass 대신 수학 연산에 `calc` 함수를 사용합니다. ### 강제 색상 모드 Windows 고대비 모드 또는 대비 테마라고도 합니다. 사용자가 웹사이트의 스타일을 자신의 것으로 덮어써서 텍스트를 더 읽기 쉽게 만드는 Windows 기능입니다. 모든 스타일에서 이를 완전히 지원하고자 합니다. 권장되는 방법은 다음과 같습니다: - 배경색이 특정 요소의 위치를 전달하는 경우, 특히 페이지 영역 및 페이지 위에 계층화된 컴포넌트의 경우 추가 테두리를 추가하세요. - `@media (forced-colors: active)` 를 사용한 재정의는 더 간단한 대안이 없는 경우에만 사용해야 합니다. 광범위한 재정의 대신 처음부터 WHCM 지원을 위한 CSS를 작성하세요. - 절대 `forced-color-adjust: none` 을 사용하지 마세요. 다양한 사용자 정의 테마와의 호환성을 손상시키며, 컴포넌트가 작동하기 위해 특정 색상 색조에 의존하는 경우에만 필요합니다 (이는 안티패턴입니다). ## JavaScript 가이드라인 포맷팅에는 [Prettier](https://prettier.io/)를, 린팅에는 [ESLint](https://eslint.org/)를 사용합니다. - [Airbnb 스타일가이드](https://github.com/airbnb/javascript)의 다소 완화된 버전을 따릅니다. - 우리가 선호하는 코드 스타일을 자세히 설명하는 [eslint-config-wagtail](https://github.com/wagtail/eslint-config-wagtail) 구성에 익숙해지세요. (ui_guidelines_stimulus)= ## Stimulus Wagtail은 `data-` 속성을 통해 DOM 요소에 대화형 동작을 첨부하는 경량 프레임워크로 [Stimulus](https://stimulus.hotwired.dev/)를 사용합니다. ### 왜 Stimulus인가 Stimulus는 개발자가 간단한 방식으로 대화형 UI 요소를 만들 수 있게 해주는 경량 프레임워크입니다. 데이터 속성 변경을 통해 소규모 반응성을 쉽게 수행할 수 있으며, JQuery와 달리 개발자가 모든 곳에서 '초기화'할 필요가 없습니다. 또한 인라인 스크립트 태그 사용 및 전역 변수 사용에 대한 대안을 제공하여 코드베이스의 복잡성을 줄입니다. ### Stimulus를 언제 사용해야 하는가 Stimulus는 간단한 클라이언트 측 상호 작용을 위한 우리의 [선호 라이브러리](https://github.com/wagtail/rfcs/pull/78)입니다. 다음과 같은 경우에 적합합니다: - 상호 작용에 JavaScript가 필요한 경우. 그렇지 않으면 HTML과 CSS만 사용하는 것을 고려하세요. - 로직의 일부가 JavaScript뿐만 아니라 HTML 템플릿을 통해 정의되는 경우. - 상호 작용이 간단하고 React와 같은 더 무거운 라이브러리를 사용할 필요가 없는 경우. Wagtail의 관리자 인터페이스는 유사한 시나리오를 위해 jQuery도 활용합니다. 이는 레거시로 간주되며 결국 제거될 것입니다. 새로운 기능의 경우, 기존 jQuery 코드를 재사용해야 하는지 또는 Stimulus로 재구축하는 것이 더 적절한지 신중하게 고려하세요. ### Stimulus 컨트롤러를 구축하는 방법 먼저 컨트롤러의 이름을 어떻게 지을지 생각하세요. 간결하게, 이상적으로는 한두 단어로 유지하세요. 그런 다음, 1. HTML 템플릿으로 시작하여, UI의 가능한 많은 부분을 HTML만으로 구축하세요. 접근성이 좋고 CSS 가이드라인을 따르는지 확인하세요. 2. `client/src/controllers` 폴더에 컨트롤러 파일과 테스트( [](testing) 참조) 및 Storybook 스토리를 만드세요. 3. 초기화를 위해 사용할 [컨트롤러 수명 주기 메서드](https://stimulus.hotwired.dev/reference/lifecycle-callbacks#methods)가 있다면(`connect`, `initialize`) 어떤 것을 사용할지 고려하세요. 4. 관련이 있다면, 제어되는 요소가 DOM에서 제거될 때 처리하는 방법도 고려하세요 [`disconnect` 수명 주기 메서드](https://stimulus.hotwired.dev/reference/lifecycle-callbacks#disconnection). 5. [JSDoc 어노테이션](https://jsdoc.app/index.html)으로 컨트롤러 클래스와 메서드를 문서화하세요. 6. 옵션과 반응형 상태를 제공하기 위해 [값(values)](https://stimulus.hotwired.dev/reference/values)을 사용하고, 가능하다면 인스턴스 속성을 피하세요. 거짓이거나 빈 기본값을 선호하고 값을 사용할 때 Object 유형의 과도한 사용을 피하세요. 7. 작고 분리된 메서드를 중심으로 동작을 구축하고, HTML에 선언된 [Stimulus 액션](https://stimulus.hotwired.dev/reference/actions)을 사용하여 언제 호출될지 결정하세요. ### 유용한 팁 - 크거나 구체적인 컨트롤러가 많은 것보다, 함께 모인 적은 양의 '작업'을 수행하는 컨트롤러를 선호하세요. - UI 상호 작용의 핵심 동작에 대해 이벤트를 보내는 쪽으로 기울이세요. 이는 명시적인 API 없이 사용자 정의 코드가 이에 연결될 수 있는 좋은 방법을 제공하지만, 반드시 문서화해야 합니다. - 동작을 구성하기 위해 하나의 DOM 요소에 여러 컨트롤러를 연결할 수 있으며, 실용적인 경우 동작을 별도의 컨트롤러로 분리하세요. - 비기여자들을 위해 컨트롤러 사용법을 언제 문서화할지 고려하세요. - 단위 테스트를 작성할 때, 데이터 속성 변경으로 트리거된 DOM 업데이트는 비동기적(다음 `microtick`)으로 완료되므로 JSDom에서 변경 사항을 확인하려면 `await Promise` 또는 유사한 것이 필요합니다. - 컨트롤러의 식별자를 하드코딩하지 말고, 속성을 조정할 때 `this.identifier` 로 참조하세요. 이렇게 하면 컨트롤러를 변경된 식별자로 쉽게 사용하거나 나중에 다른 클래스에서 확장할 수 있습니다. ## 다국어 지원 이것은 Wagtail이 활발하게 개선하고 있는 분야이며, [진행 중인 토론](https://github.com/wagtail/wagtail/discussions/8017)이 있습니다. - 번역 문자열에 불필요한 공백이 추가되는 것을 방지하기 위해 `blocktranslate` 태그에 항상 `trimmed` 속성을 사용하세요. ### 오른쪽에서 왼쪽으로 쓰는 언어 지원 오른쪽에서 왼쪽으로 쓰는 언어를 지원하며, 특히 Wagtail 관리자 인터페이스를 수평으로 미러링된 레이아웃으로 보는 것을 지원합니다. 지원을 보장하기 위한 가이드라인은 다음과 같습니다: - 가능한 한 [논리적 속성과 값](https://rtlstyling.com/posts/rtl-styling#css-logical-properties)으로 스타일을 작성하세요. - 물리적 속성(변환, 배경 위치)으로만 작성할 수 있는 스타일의 경우, 요소나 페이지의 `dir` 속성에 따라 값이 반전되도록 `1` 또는 `-1` 과 같은 `--w-direction-factor` 변수를 사용하세요. - 마지막 수단으로, 스타일을 작성할 다른 방법이 없는 경우 `[dir='rtl']` 스타일을 사용하세요. DOM API에서는 논리적 값을 지원하지 않으므로(x축 오프셋은 항상 왼쪽에서부터), JavaScript에서 모든 위치 계산의 방향을 반전시켜야 합니다. ## 아이콘 성능과 아이콘을 CSS로 스타일링할 수 있도록 Wagtail의 아이콘에는 인라인 SVG 요소를 사용합니다. Wagtail 사용자를 위해 아이콘이 어떻게 설정되는지에 대한 정보는 [](icons)를 참조하세요. ### 아이콘 추가하기 아이콘은 [Wagtail 관리자 템플릿 폴더](https://github.com/wagtail/wagtail/tree/main/wagtail/admin/templates/wagtailadmin/icons)에 있는 SVG 파일입니다. 아이콘을 추가하거나 업데이트할 때, 1. 적절한 압축 설정으로 [SVGO](https://jakearchibald.github.io/svgomg/)를 통해 실행하세요. 2. 불필요한 속성을 수동으로 제거하세요. `viewBox` 속성을 설정하고, `width` 및 `height` 속성을 제거하세요. 3. `icon-` 접두사와 파일 이름과 일치하는 아이콘 이름으로 `id` 속성을 수동으로 추가하세요. 가능하다면 소스의 이름 그대로 아이콘을 유지하세요. 4. 느낌표로 시작하는 HTML 주석으로 라이선스 정보를 추가하거나 보존하세요: ``. Font Awesome의 경우, `` 을 원합니다. 예를 들어, ``. 5. 알파벳 순서로 `register_icons` 훅의 Wagtail 자체 구현에 아이콘을 추가하세요. 6. 스타일가이드로 가서 템플릿의 지침에 따라 Wagtail 아이콘 테이블을 복사하고, 결과를 `wagtail_icons_table.txt` 에 붙여넣으세요. 7. 아이콘에 [오른쪽에서 왼쪽으로 미러링](https://rtlstyling.com/posts/rtl-styling#bidirectional-icons)이 필요한 경우 `class="icon--directional"` 속성을 추가하세요.