ViewComponent
GitLab v19.4요약
ViewComponent는 Vue 같은 JavaScript 프레임워크 없이도 Ruby on Rails에서 재사용 가능하고 테스트 가능하며 캡슐화된 뷰 컴포넌트를 만들기 위한 프레임워크입니다. 자세한 내용은 공식 문서 또는 소개 영상을 참고합니다.
ViewComponent는 Vue 같은 JavaScript 프레임워크 없이도 Ruby on Rails에서 재사용 가능하고 테스트 가능하며 캡슐화된 뷰 컴포넌트를 만들기 위한 프레임워크입니다. 서버 측에서 렌더링되며 Haml 같은 템플릿 언어와 자연스럽게 함께 사용할 수 있습니다.
자세한 내용은 공식 문서 또는 소개 영상을 참고합니다.
Lookbook으로 컴포넌트 탐색#
ViewComponent 미리보기를 탐색하고 조작할 수 있도록 http://gdk.test:3000/rails/lookbook에 Lookbook이 제공됩니다(개발 모드에서만 사용 가능).
Pajamas 컴포넌트#
Pajamas 디자인 시스템의 일부 컴포넌트는
app/components/pajamas에서 ViewComponent로 제공됩니다.
이러한 컴포넌트는 아직 만드는 중이므로 모든 Pajamas 컴포넌트가 ViewComponent로 제공되지는 않습니다. 필요한 컴포넌트가 아직 제공되지 않는다면 Design Systems 팀에 문의합니다.
사용 가능한 컴포넌트#
이 목록은 최선을 다해 정리한 것입니다. 전체 목록은 app/components/pajamas에서 확인할 수 있습니다. 컴포넌트를 더 직접적으로 살펴보려면 Lookbook(http://gdk.test:3000/rails/lookbook)도 참고합니다.
Alert#
Pajamas::AlertComponent는 Pajamas Alert 사양을 따릅니다.
예시:
기본적으로 닫을 수 있는 정보 알림을 만듭니다.
= render Pajamas::AlertComponent.new(title: "Almost done!")
변형, 지속성 등을 설정할 수 있습니다.
= render Pajamas::AlertComponent.new(title: "All done!",
variant: :success,
dismissible: :false)
전체 옵션 목록은 소스를 참고합니다.
Banner#
Pajamas::BannerComponent는 Pajamas Banner 사양을 따릅니다.
예시:
가장 단순한 형태의 배너 컴포넌트는 다음과 같습니다.
= render Pajamas::BannerComponent.new(button_text: 'Learn more', button_link: example_path,
svg_path: 'illustrations/example.svg') do |c|
- c.with_title { 'Hello world!' }
%p Content of your banner goes here...
더 세밀하게 제어해야 한다면 svg_path 대신 illustration 슬롯을,
button_text 및 button_link 대신 primary_action 슬롯을 사용할 수 있습니다.
= render Pajamas::BannerComponent.new do |c|
- c.with_illustration do
= custom_icon('my_inline_svg')
- c.with_title do
Hello world!
- c.with_primary_action do
= render 'my_button_in_a_partial'
전체 옵션 목록은 소스를 참고합니다.
Button#
Pajamas::ButtonComponent는 Pajamas Button 사양을 따릅니다.
예시:
버튼 컴포넌트에는 옵션이 많지만 모두 적절한 기본값이 있으므로, 가장 단순한 버튼은 다음과 같습니다.
= render Pajamas::ButtonComponent.new do |c|
= _('Button text goes here')
다음 예시는 사용 가능한 옵션 대부분을 보여줍니다.
= render Pajamas::ButtonComponent.new(category: :secondary,
variant: :danger,
size: :small,
type: :submit,
disabled: true,
loading: false,
block: true) do |c|
Button text goes here
다음과 같이 버튼처럼 보이는 <a> 태그도 만들 수 있습니다.
= render Pajamas::ButtonComponent.new(href: root_path) do |c|
Go home
전체 옵션 목록은 소스를 참고합니다.
Card#
Pajamas::CardComponent는 Pajamas Card 사양을 따릅니다.
예시:
카드에는 필수 body 슬롯 하나와 선택적 header, footer 슬롯이 있습니다.
= render Pajamas::CardComponent.new do |c|
- c.with_header do
I'm the header.
- c.with_body do
%p Multiple line
%p body content.
- c.with_footer do
Footer goes here.
이러한 슬롯이나 카드 자체에 커스텀 속성을 추가하려면 다음 옵션을 사용합니다.
= render Pajamas::CardComponent.new(card_options: {id: "my-id"}, body_options: {data: { count: 1 }})
header_options와 footer_options도 사용할 수 있습니다.
전체 옵션 목록은 소스를 참고합니다.
Checkbox tag#
Pajamas::CheckboxTagComponent는 Pajamas Checkbox 사양을 따릅니다.
name 인수와 label 슬롯은 필수입니다.
예시는 다음과 같습니다.
= render Pajamas::CheckboxTagComponent.new(name: 'project[initialize_with_sast]',
checkbox_options: { data: { testid: 'initialize-with-sast-checkbox' } }) do |c|
- c.with_label do
= s_('ProjectsNew|Enable Static Application Security Testing (SAST)')
- c.with_help_text do
= s_('ProjectsNew|Analyze your source code for known security vulnerabilities.')
= link_to _('Learn more.'), help_page_path('user/application_security/sast/_index.md'), target: '_blank', rel: 'noopener noreferrer'
레거시 추적 파라미터(track_action, track_label, track_property)는 더 이상 사용되지 않습니다. 자세한 내용은 마이그레이션 가이드를 참고합니다.
전체 옵션 목록은 소스를 참고합니다.
Checkbox#
Pajamas::CheckboxComponent는 Pajamas Checkbox 사양을 따릅니다.
Pajamas::CheckboxComponent는 GitLab UI 폼 빌더가 내부적으로 사용하며, form 인수로 ActionView::Helpers::FormBuilder 인스턴스를 전달해야 합니다.
이 ViewComponent를 렌더링할 때는 gitlab_ui_checkbox_component 메서드를 사용하는 편이 좋습니다.
ActionView::Helpers::FormBuilder 인스턴스 없이 체크박스를 사용하려면 CheckboxTagComponent를 사용합니다.
전체 옵션 목록은 소스를 참고합니다.
Select#
Pajamas::SelectComponent는 Pajamas Select 사양을 따릅니다. Vue의 GlFormSelect와 같은 마크업(gl-form-select 요소를 감싸는 .gl-form-select-wrapper)을 렌더링하므로, 드롭다운 셰브런은 래퍼가 그리고 컨트롤 전체를 클릭할 수 있습니다.
예시:
= render Pajamas::SelectComponent.new(name: :role,
choices: [['Guest', 10], ['Reporter', 20]],
selected: 20,
width: :md)
choices 인수는 options_for_select와 같은 선택지를 받습니다. GlFormSelect와 마찬가지로 이 컴포넌트는 컨트롤만 렌더링하므로, for 값이 select의 id와 일치하는 레이블과 함께 사용합니다.
전체 옵션 목록은 소스를 참고합니다.
Experiment badge#
Pajamas::ExperimentBadgeComponent는 Pajamas Experiment Badge 사양을 따릅니다.
예시:
기본적으로 실험 배지를 만듭니다.
= render Pajamas::ExperimentBadgeComponent.new
베타 배지도 만들 수 있습니다.
= render Pajamas::ExperimentBadgeComponent.new(type: :beta)
이 컴포넌트에는 실험 기능이나 베타 기능이 무엇인지 설명하는 팝오버가 포함됩니다. 팝오버 위치는 조정할 수 있습니다.
= render Pajamas::ExperimentBadgeComponent.new(type: :experiment, popover_placement: 'top')
전체 옵션 목록은 소스를 참고합니다.
Toggle#
Pajamas::ToggleComponent는 Pajamas Toggle 사양을 따릅니다.
= render Pajamas::ToggleComponent.new(classes: 'js-force-push-toggle',
label: s_("ProtectedBranch|Toggle allowed to force push"),
is_checked: protected_branch.allow_force_push,
label_position: :hidden) do
Leverage this block to render a rich help text. To render a plain text help text, prefer the `help` parameter.
토글 ViewComponent는 Vue.js 컴포넌트에 의존한다는 점에서 특별합니다.
이 컴포넌트를 실제로 초기화하려면 ~/toggles의 initToggle 헬퍼를 호출해야 합니다.
전체 옵션 목록은 소스를 참고합니다.
Layouts#
레이아웃 컴포넌트로 GitLab에서 쓰이는 일반적인 레이아웃 패턴을 만들 수 있습니다.
사용 가능한 컴포넌트#
Page heading#
페이지 제목과 선택적 작업 버튼을 갖춘 표준 페이지 헤더입니다.
예시:
= render ::Layouts::PageHeadingComponent.new(_('Page title')) do |c|
- c.with_actions do
= buttons
전체 옵션 목록은 소스를 참고합니다.
Index layout#
제목, 알림, 콘텐츠 영역 사이의 간격을 정하는 레이아웃입니다. 선택적 페이지 제목, 알림, 본문 콘텐츠 섹션으로 인덱스 페이지에 일관된 구조를 제공합니다.
예시:
= render ::Layouts::IndexLayout.new(heading: _('Page title'), description: _('Page description')) do |c|
- c.with_alerts do
= render Pajamas::AlertComponent.new(title: 'Alert message')
= render 'items_table'
이 컴포넌트는 다음 슬롯을 지원합니다.
heading: 커스텀 제목 마크업(내부적으로PageHeadingComponent사용)description: 커스텀 설명 콘텐츠(내부적으로PageHeadingComponent사용)alerts: 페이지 알림 컨테이너(비어 있으면 공간을 차지하지 않음)content: 페이지 콘텐츠
전체 옵션 목록은 소스를 참고합니다.
Vue 사용법과 동적 패널 및 패널 작업을 포함한 전체 가이드는 페이지 레이아웃 및 패널을 참고합니다.
Detail layout#
제목, 알림, 콘텐츠 영역 사이의 간격을 정하는 레이아웃입니다. 선택적 페이지 제목, 알림, 사이드바, 본문 콘텐츠 섹션으로 상세 페이지에 일관된 구조를 제공합니다.
예시:
= render ::Layouts::DetailLayout.new(heading: _('Page title'), description: _('Page description')) do |c|
- c.with_alerts do
= render Pajamas::AlertComponent.new(title: 'Alert message')
- c.with_sidebar do
= render 'sidebar'
= render 'items_table'
이 컴포넌트는 다음 슬롯을 지원합니다.
heading: 커스텀 제목 마크업(내부적으로PageHeadingComponent사용)description: 커스텀 설명 콘텐츠(내부적으로PageHeadingComponent사용)alerts: 페이지 알림 컨테이너(비어 있으면 공간을 차지하지 않음)sidebar: 페이지 사이드바content: 페이지 콘텐츠
전체 옵션 목록은 소스를 참고합니다.
Vue 사용법과 동적 패널 및 패널 작업을 포함한 전체 가이드는 페이지 레이아웃 및 패널을 참고합니다.
CRUD component#
생성, 조회, 수정, 삭제 같은 사용자 작업이 있는 표나 목록을 담는 목록 컨테이너입니다.
예시:
= render ::Layouts::CrudComponent.new(_('CRUD title'), icon: 'ICONNAME', count: COUNT) do |c|
- c.with_description do
= description
- c.with_actions do
= buttons
- c.with_form do
= add item form
- c.with_body do
= body
- c.with_pagination do
= pagination component
- c.with_footer do
= optional footer
전체 옵션 목록은 소스를 참고합니다.
Horizontal section#
상당수의 설정 페이지는 제목과 설명이 왼쪽에, 설정 필드가 오른쪽에 놓이는 레이아웃을 사용합니다. Layouts::HorizontalSectionComponent로 이 레이아웃을 만들 수 있습니다.
예시:
= render ::Layouts::HorizontalSectionComponent.new(options: { class: 'gl-mb-6' }) do |c|
- c.with_title { _('Naming, visibility') }
- c.with_description do
= _('Update your group name, description, avatar, and visibility.')
= link_to _('Learn more about groups.'), help_page_path('user/group/_index.md')
- c.with_body do
.form-group.gl-form-group
= f.label :name, _('New group name')
= f.text_field :name
전체 옵션 목록은 소스를 참고합니다.
Settings block#
관련 설정을 묶는 설정 블록(아코디언)입니다.
예시:
= render ::Layouts::SettingsBlock.new(_('Settings block heading')) do |c|
- c.with_description do
= description
- c.with_body do
= body
전체 옵션 목록은 소스를 참고합니다.
Settings section#
위의 SettingsBlock과 마찬가지로 관련 설정을 한데 묶는 컴포넌트입니다. SettingsBlock과 달리 아코디언 기능은 제공하지 않습니다. 고정 헤더를 사용합니다.
예시:
= render ::Layouts::SettingsSection.new(_('Settings section heading')) do |c|
- c.with_description do
= description
- c.with_body do
= body
전체 옵션 목록은 소스를 참고합니다.
모범 사례#
- Haml로 새 뷰를 만들 때는 CSS 클래스를 붙인 일반 Haml 태그를 만들기보다 제공되는 컴포넌트를 사용합니다.
- 기존 Haml 뷰를 변경하다가 예를 들어 여전히 일반 Haml로 구현된 버튼을 발견하면, ViewComponent를 사용하도록 마이그레이션하는 방안을 검토합니다.
- 새 컴포넌트를 만들기로 했다면 해당 컴포넌트의 미리보기도 함께 만드는 방안을 검토합니다. 다른 사람이 Lookbook에서 컴포넌트를 찾는 데 도움이 되고, 여러 상태를 테스트하기도 훨씬 쉬워집니다.
미리보기 레이아웃#
ViewComponent 미리보기에 커스텀 레이아웃이 필요하다면 레이아웃 코드를 다음 경로에 두는 방안을 검토합니다.
- 레이아웃 HAML 파일은
app/views/layouts/lookbook - 커스텀 JavaScript 코드는
app/assets/javascripts/entrypoints/lookbook - 커스텀 SASS 코드는
app/assets/stylesheets/lookbook
JavaScript와 SASS 코드는 레이아웃에 직접 포함해야 합니다.