01 Monday Vibe 디자인 시스템 인터페이스 미리보기 행 상태를 수정하고 선택한 항목을 완료 처리하세요. 요약 수치는 로컬에서 업데이트됩니다.
검증된 Vibe 라이트 테마 팔레트, 간격 및 타이포그래피 크기를 바탕으로 독립적으로 해석한 HTML/CSS 구현이며, 시스템 대체 글꼴을 사용합니다. ·
구현 레퍼런스 02
Monday Vibe 디자인 시스템 디자인 참조 Vibe 4 공개 소스 및 @vibe/core 통합. 아래 값은 검증된 라이트 테마 및 스타일 정의입니다. 보드 레이블 색상은 시맨틱 성공/오류 역할과 구분됩니다. 기본 예제에서는 애플리케이션에서 직접 관리하는 HTML 표 안에 실제 Vibe Button 컨트롤을 사용합니다.
이름 / 규칙 값 / 구성 용도 --space-22px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-44px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-88px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-1212px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-1616px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-2020px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-2424px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-3232px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-4040px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-4848px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-6464px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다. --space-8080px애플리케이션 간격에 사용하세요. 숫자로 된 토큰 이름은 현재 소스에 표기된 이름을 따릅니다.
이름 / 규칙 값 / 구성 용도 --primary-color#0073ea 기본 작업 --primary-hover-color#0060b9 기본 작업에 마우스를 올렸을 때 --primary-selected-color#cce5ff 선택된 콘텐츠 배경 --primary-text-color#323338 기본 가독성 텍스트 --secondary-text-color#676879 보조 레이블. --primary-background-color#ffffff 기본 표면입니다. --allgrey-background-color#f6f7fb 애플리케이션 배경 --ui-border-color#c3c6d4 컨트롤 경계선 --positive-color#00854d 시맨틱 긍정 작업 --negative-color#d83a52 시맨틱 부정 작업
이름 / 규칙 값 / 구성 용도 --color-done-green#00c875 카테고리형 완료 레이블이며, 시맨틱 긍정 색상이 아닙니다. --color-working_orange#fdab3d 카테고리형 진행 중 레이블입니다. 정확한 소스 이름에 밑줄이 포함되어 있습니다. --color-stuck-red#df2f4a 카테고리형 막힘 레이블 --color-dark_purple#784bd1 그룹 식별 색상 예시
이름 / 규칙 값 / 구성 용도 --font-familyFigtree, Roboto, Noto script fallbacks, sans-serif본문 글꼴 계열. 글꼴 파일은 별도로 설치됩니다. --title-font-familyPoppins, Roboto, Noto script fallbacks, sans-serif제목 글꼴 계열 --font-h1-medium600 32px/40px; title family보드 제목 --font-h2-medium600 24px/30px; title family그룹 제목 --font-h3-medium600 18px/24px; title family간결한 하위 섹션 --font-text1-normal400 16px/22px; body family일반 콘텐츠 --font-text2-normal400 14px/20px; body family밀도 높은 행 콘텐츠 --font-text3-normal400 12px/16px; body family보조 정보
이름 / 규칙 값 / 구성 용도 --border-radius-44px소형 컨트롤 --border-radius-88px중형 컨테이너 --border-radius-1212px사용 가능한 숫자형 모서리 단계 --border-radius-1616px대형 컨테이너 --border-radius-smallvar(--border-radius-4)이름이 지정된 소형 별칭 --border-radius-mediumvar(--border-radius-8)이름이 지정된 중형 별칭 --border-radius-bigvar(--border-radius-16)이름이 지정된 대형 별칭
이름 / 규칙 값 / 구성 용도 kindDefault: primary이 예제에서 사용하는 3차 작업을 포함한 시각적 강조 sizeDefault: medium간결한 행 작업에는 small을 사용하세요. typeDefault: button폼 제출을 위해 submit을 명시적으로 설정하세요. disabledboolean선택된 행이 없으면 일괄 작업을 비활성화합니다. loadingboolean실제 대기 중인 작업이 있을 때 로더를 표시합니다. activeboolean시각적 활성 상태입니다. 토글이라면 aria-pressed도 함께 노출하세요. onClickReact mouse-event callback여기서 애플리케이션 상태를 업데이트하세요. aria-pressedARIA pressed state버튼 토글을 사용하는 경우 행 토글 선택 상태를 전달하세요.
03 Monday Vibe 디자인 시스템 완벽 가이드 실제 인터페이스를 위해 이 시스템을 선택하고 적용하고 검토하는 실용 가이드.
DESIGN-monday-vibe.md 완전한 안내와 구현 시작점, 소스 링크.
가이드 다운로드 Monday Vibe 디자인 시스템 현재 Vibe 진입점을 기준으로 구축하기 핵심 컴포넌트와 토큰 CSS은 별도로 가져옵니다 Vibe 4는 @vibe/core를 통해 이름이 지정된 React 컴포넌트를, @vibe/core/tokens를 통해 CSS 변수를 제공합니다. 새 클라이언트 애플리케이션에서는 두 항목을 모두 가져오세요. 컴포넌트가 자체 스타일을 삽입하더라도 토큰 파일에서 제공하는 변수에 의존할 수 있습니다. 보드 예제는 네이티브 테이블 구조와 실제 Vibe Button 컨트롤을 사용하며, 행 데이터와 선택 상태는 애플리케이션에서 관리합니다.
지원 사양 읽기
이전 패키지 세대와 혼용하지 마세요 이전 monday-ui-react-core 패키지는 Vibe 2에 속합니다. Vibe 3는 신규 기능이 아닌 중요 수정 사항을 중심으로 유지 관리됩니다. 이 가이드에서는 현재 Vibe 4 인터페이스와 번호가 지정된 간격 변수를 사용합니다. 이 연동은 monday.com SDK 클라이언트가 아니며 계정, 워크스페이스 또는 항목 API과 연결되지 않습니다.
지원 사양 읽기
Monday Vibe 디자인 시스템 액션 색상과 보드 레이블은 서로 다른 역할을 합니다 컨트롤에는 의미에 맞는 역할을 사용하세요 주요 액션에는 기본 역할과 이에 대응하는 호버 색상을 사용합니다. 선택 상태에는 선택 배경을, 일반 텍스트에는 기본 및 보조 텍스트 역할을 사용하세요. 본문 배경만 따로 바꾸지 말고 테마 값을 서로 연관된 세트로 사용하세요. 이 예제는 검증된 밝은 테마 안에서 구성합니다.
지원 사양 읽기
완료 셀은 성공 버튼이 아닙니다 소스에는 의미 기반 피드백 색상과 함께 보드의 범주별 색상도 포함되어 있습니다. 완료 상태의 녹색은 #00c875이고, 의미상 긍정 색상은 #00854d입니다. 행 상태 셀에는 보드 색상과 대비가 충분한 읽기 쉬운 텍스트를 사용하고, 진행 중, 막힘, 완료라는 단어를 그대로 표시해 색상만으로 상태를 설명하지 않도록 합니다.
지원 사양 읽기
Monday Vibe 디자인 시스템 완전한 글꼴 단축 속성 사용하기 제목과 작업 행에는 서로 다른 서체를 적용합니다 소스에서는 제목에 Poppins를, 본문 콘텐츠에 Figtree를 지정하고 스크립트에 맞는 대체 글꼴을 함께 사용합니다. 현재 h1-medium 단축 표기는 600 32px/40px이고, text2-normal은 400 14px/20px입니다. 두께, 크기, 줄 높이, 글꼴 계열이 함께 유지되도록 CSS font 속성에 단축 표기를 적용하세요. 소스에는 이전 제목 별칭도 포함되어 있으므로 크기가 다른 별칭으로 임의 대체하지 마세요.
지원 사양 읽기
글꼴 파일을 계획적으로 불러오세요 Vibe는 권장 글꼴 파일을 자동으로 가져오지 않습니다. 문서에 안내된 Figtree/Poppins 스타일시트 링크를 애플리케이션 HTML에 추가하거나, 적절한 라이선스가 적용된 파일을 직접 호스팅하세요. 오프라인 예제에서는 시스템 대체 글꼴을 명시적으로 사용하므로, monday.com의 타이포그래피를 정확히 재현한다고 볼 수 없으며 하나의 해석으로 이해해야 합니다.
지원 사양 읽기
Monday Vibe 디자인 시스템 컨트롤을 지나치게 좁히지 않은 컴팩트 보드 번호가 지정된 간격으로 리듬을 만드세요 서로 붙어 있는 툴바 액션에는 --space-8을, 패널 안쪽 여백에는 --space-16을, 보드 영역 사이에는 --space-24를 사용하세요. 모두 현재 소스에 있는 정확한 이름입니다. 이러한 배치는 이 애플리케이션을 위해 선택한 값입니다. 간격 척도에는 세밀한 정렬을 위한 2픽셀 단위부터 레이아웃 구성을 위한 최대 80픽셀 값까지 포함되어 있습니다.
지원 사양 읽기
모서리 모양으로 영역을 구분하세요 구현 참고 사항 작은 별칭은 4픽셀, 중간은 8픽셀, 큰 값은 16픽셀에 해당합니다. 바깥쪽 보드에는 중간 값을 적용하고 테이블 셀은 각지고 정렬된 상태로 유지하세요. 색상이 있는 셀을 모두 배지처럼 둥글게 만들면 조밀한 열 관계를 훑어보기 어려워집니다.
지원 사양 읽기
Monday Vibe 디자인 시스템 일괄 작업 툴바가 있는 편집 가능한 테이블 데이터 구조를 명확하게 유지하세요 각 작업 항목에는 변경되지 않는 id, 제목, 담당자, 상태가 있습니다. 네이티브 열 제목으로 각 값의 의미를 설명합니다. 행 체크박스를 선택하면 해당 id가 Set에 추가되고, 상태를 변경할 때는 배열을 직접 수정하지 않고 일치하는 객체를 교체합니다. 선택 항목 완료 액션은 같은 Set을 읽어 선택한 행만 업데이트합니다. 완료 요약은 행 데이터에서 계산합니다.
선택 Set이 비어 있으면 기본 일괄 작업 버튼을 비활성화합니다. 행별 보조 액션은 예시를 위해 로컬 상태를 순환하며 변경합니다. 초기화 액션은 초기 행 데이터를 복원하고 선택 상태를 지웁니다. 지원 사양 읽기
Monday Vibe 디자인 시스템 실제 Button API을 통해 상태를 노출하세요 비활성, 로딩, 눌림은 서로 다른 상태입니다 네이티브 예제에서는 일괄 작업을 사용할 수 없을 때 disabled를 적용합니다. 실제 원격 작업이 없으므로 로딩이나 성공 상태는 표시하지 않습니다. 실제 데이터 저장 계층을 연결한다면 요청 수명 주기에 맞춰 loading을 설정하고, 확인을 받은 뒤에만 성공 상태를 업데이트하세요. Button 소스에는 시각적 표현을 위한 active와 토글 의미를 위한 aria-pressed도 제공됩니다. 둘은 서로 대체할 수 없습니다.
지원 사양 읽기
로컬 수정 사항을 서비스에 반영했다고 표현하지 마세요 실시간 메시지는 로컬에서 변경한 항목 수를 알립니다. monday.com 보드가 업데이트되었다고 말하지 않습니다. 페이지를 새로 고치면 초기 샘플 데이터가 다시 표시됩니다. 프로덕션 연동에는 디자인 시스템 계층 외부에서 명시적인 워크스페이스 권한, 오류 처리, 동기화가 필요합니다.
지원 사양 읽기
Monday Vibe 디자인 시스템 화면 너비가 달라져도 행의 의미를 유지하세요 예제가 화면 크기에 맞게 자연스럽게 재배치되도록 하세요 오프라인 보드는 좁은 화면에서 각 행을 레이블이 있는 항목 카드로 쌓아 표시합니다. 담당자와 상태를 계속 이해할 수 있도록 열 이름도 보이는 레이블로 반복합니다. 이는 애플리케이션 레이아웃의 선택이며 Vibe가 모든 테이블을 자동으로 변환한다는 뜻은 아닙니다. 더 조밀한 데이터에는 레이블이 있는 가로 오버플로 영역 안에 의미 구조를 유지한 테이블을 사용하는 방법도 있습니다.
지원 사양 읽기
전역 박스 크기 설정은 필수입니다 라이브러리를 사용하기 전에 요소와 의사 요소에 border-box를 적용하세요. 이 설정이 없으면 고정 너비 셀에 패딩이 더해져 의도한 크기를 초과할 수 있으며, 특히 조밀한 열 안에 버튼이 중첩된 경우 문제가 두드러집니다. 바깥쪽 컨테이너는 유연하게 유지하고 툴바 액션은 줄 바꿈을 허용하세요.
지원 사양 읽기
Monday Vibe 디자인 시스템 선택과 상태에는 각각 별도의 이름이 필요합니다 모든 행 컨트롤에 레이블을 지정하세요 선택 체크박스의 접근 가능한 이름에 작업 항목 제목이 포함됩니다. 각 상태 변경 작업에는 항목 이름과 현재 상태가 함께 표시됩니다. 정중한 상태 메시지로 일괄 작업 결과를 알립니다. 키보드 사용자는 기본 컨트롤로 행을 선택하고 일괄 작업을 실행한 뒤 보드를 초기화할 수 있습니다. 페이지에서 스프레드시트의 화살표 키 동작을 임의로 구현하지 않습니다.
디자인 핸드오프를 선택하고 일괄 작업을 사용할 수 있게 되는지 확인합니다. 선택을 완료하고 상태 텍스트와 계산된 개수가 일치하는지 확인합니다. 초기화한 뒤 데이터와 체크박스 선택이 모두 초기 상태로 돌아가는지 확인합니다. 지원 사양 읽기
Monday Vibe 디자인 시스템: 완전한 클라이언트 측 진입점 설치, 가져오기, 마운트 아래 설정은 루트 요소가 있는 React 클라이언트 프로젝트의 main.jsx 진입점입니다. react, react-dom, @vibe/core@4를 설치하고 토큰 CSS을 한 번 불러온 다음, 나열된 전역 스타일시트를 적용합니다. 현재 패키지는 ES 모듈 내보내기를 사용합니다. 서버 측 스타일 추출은 실험 기능으로 문서화되어 있으므로 이 시작 예제에서는 클라이언트 렌더링을 사용합니다.
지원 사양 읽기
Monday Vibe 디자인 시스템 컴포넌트 예제 완전한 독립형 인터랙티브 예제 전체 문서를 index.html로 저장하고 브라우저에서 엽니다. 검증된 Vibe 라이트 테마의 팔레트, 간격, 타이포그래피 치수를 바탕으로 독립적으로 해석한 HTML/CSS입니다. 시스템 대체 글꼴을 사용합니다.
html 코드 복사
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Weekly delivery — Vibe study</title><style>*{box-sizing:border-box}body{margin:0;background:#f6f7fb;color:#323338;font:14px/20px Arial,sans-serif}button,input{font:inherit}button{cursor:pointer;border:0;border-radius:4px;padding:8px 16px;background:white;color:#323338}button:hover{background:#e7e9ef}button:disabled{opacity:.45;cursor:not-allowed}button:focus-visible,input:focus-visible{outline:3px solid #0073ea;outline-offset:2px}.shell{display:grid;grid-template-columns:180px minmax(0,1fr);min-height:600px}aside{padding:24px 16px;border-right:1px solid #d0d4e4;background:#fff}.brand{font-size:20px;font-weight:bold;margin-bottom:40px}.brand span{color:#0073ea}aside p{font-size:12px;color:#676879}aside strong{display:block;background:#cce5ff;padding:12px;border-radius:4px;color:#323338}main{padding:32px;min-width:0}h1{font-size:32px;line-height:40px;font-weight:600;margin:0 0 8px}.sub{color:#676879}.overview{margin:24px 0;display:grid;grid-template-columns:1fr 2fr;gap:24px;align-items:center}.count{font-size:32px;line-height:40px}.count small{font-size:14px;color:#676879}.bar{display:flex;border-radius:8px;overflow:hidden;height:16px;background:#e7e9ef}.bar span{transition:width .15s}.legend{display:flex;gap:16px;font-size:12px;margin-top:8px}.legend span:before{content:'●';color:var(--c);margin-right:4px}.tools{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:24px}.primary{background:#0073ea;color:white}.primary:hover{background:#0060b9}h2{font-size:18px;line-height:24px;color:#784bd1;font-weight:600}.board{border-left:6px solid #784bd1;border-radius:8px;background:white;overflow:hidden}.row,.head{display:grid;grid-template-columns:36px minmax(180px,1fr) 90px 130px;align-items:center;min-height:52px;border-bottom:1px solid #d0d4e4}.head{color:#676879;min-height:36px;font-size:12px}.row>*{padding:12px}.head>*{padding:8px}.row label{display:flex;align-items:center;justify-content:center}.row input{accent-color:#0073ea}.row .status{border-radius:0;height:100%;font-weight:500}.status[data-status=Working]{background:#fdab3d}.status[data-status=Stuck]{background:#df2f4a;color:white}.status[data-status=Done]{background:#00c875}.person{display:inline-flex;align-items:center;gap:8px}.avatar{width:24px;height:24px;border-radius:50%;background:#eceff8;display:inline-grid;place-items:center;font-size:11px}.row.selected{background:#f0f7ff}#message{min-height:24px;margin-top:16px;color:#676879}.mobile-label{display:none}footer{padding:16px 24px;color:#676879;font-size:11px;border-top:1px solid #d0d4e4}@media(max-width:800px){.shell{grid-template-columns:1fr}aside{display:none}main{padding:24px}}@media(max-width:560px){main{padding:16px}.overview{grid-template-columns:1fr;gap:12px}.head{display:none}.row{grid-template-columns:36px 1fr}.row .person,.row .status{grid-column:2}.row .status{margin:0 12px 12px;width:calc(100% - 24px);border-radius:4px}.mobile-label{display:inline;color:#676879;margin-right:8px}.row{padding:8px 0}.legend{flex-wrap:wrap}}</style><div class="shell"><aside><div class="brand"><span>▰</span> workroom</div><p>TEAM WORKSPACE</p><strong>Weekly delivery</strong><p>Sample project<br>No external account</p></aside><main><h1>Weekly delivery</h1><div class="sub">A shared view of the work moving this week.</div><section class="overview" aria-label="Completion summary"><div class="count"><span id="done">1</span><small> / 3 completed</small></div><div><div class="bar" aria-hidden="true"><span id="working-bar" style="background:#fdab3d"></span><span id="stuck-bar" style="background:#df2f4a"></span><span id="done-bar" style="background:#00c875"></span></div><div class="legend"><span style="--c:#fdab3d">Working</span><span style="--c:#df2f4a">Stuck</span><span style="--c:#00c875">Done</span></div></div></section><div class="tools"><button class="primary" id="complete" disabled>Complete selected</button><button id="reset">Reset board</button><span id="selection" style="padding:8px;color:#676879">0 selected</span></div><h2>▼ This week</h2><div class="board"><div class="head" aria-hidden="true"><span></span><span>Item</span><span>Owner</span><span>Status</span></div><div id="rows"></div></div><p id="message" role="status">Select items or click a status to change it locally.</p></main></div><footer>Independent Vibe 4 HTML/CSS study. Published light-theme and board-label colors; system fallback fonts. No monday.com workspace connection.</footer><script>
const initial=[{id:1,title:'Design handoff',owner:'Maya',status:'Working'},{id:2,title:'Accessibility review',owner:'Theo',status:'Stuck'},{id:3,title:'Release notes',owner:'Sam',status:'Done'}],states=['Working','Stuck','Done'];let items=structuredClone(initial),selection=new Set();const $=id=>document.getElementById(id);function totals(){$('done').textContent=items.filter(x=>x.status==='Done').length;for(const state of states)$(state.toLowerCase()+'-bar').style.width=items.filter(x=>x.status===state).length/items.length*100+'%';$('complete').disabled=!selection.size;$('selection').textContent=selection.size+' selected'}function render(){$('rows').replaceChildren();for(const item of items){const row=document.createElement('div');row.className='row'+(selection.has(item.id)?' selected':'');const label=document.createElement('label'),check=document.createElement('input');check.type='checkbox';check.checked=selection.has(item.id);check.setAttribute('aria-label','Select '+item.title);check.onchange=()=>{check.checked?selection.add(item.id):selection.delete(item.id);row.classList.toggle('selected',check.checked);totals()};label.append(check);const name=document.createElement('span');name.textContent=item.title;const person=document.createElement('span');person.className='person';const av=document.createElement('span');av.className='avatar';av.setAttribute('aria-hidden','true');av.textContent=item.owner[0];const pl=document.createElement('span');pl.className='mobile-label';pl.textContent='Owner';person.append(pl,av,document.createTextNode(item.owner));const status=document.createElement('button');status.className='status';status.dataset.status=item.status;status.textContent=item.status;status.setAttribute('aria-label',item.title+': '+item.status+'. Change status');status.onclick=()=>{item.status=states[(states.indexOf(item.status)+1)%states.length];status.dataset.status=item.status;status.textContent=item.status;status.setAttribute('aria-label',item.title+': '+item.status+'. Change status');totals();$('message').textContent=item.title+' is now '+item.status+' locally.'};row.append(label,name,person,status);$('rows').append(row)}totals()}
$('complete').onclick=()=>{let n=selection.size;items.forEach(x=>{if(selection.has(x.id))x.status='Done'});selection.clear();render();$('message').textContent=n+' local items completed.'};$('reset').onclick=()=>{items=structuredClone(initial);selection.clear();render();$('message').textContent='Board reset.'};render();
</script></html>
코드 참조
일괄 작업 도구 모음은 예시 작업의 상태를 변경합니다. 레이블 색상은 이 보드의 워크플로를 나타내며 Vibe의 의미 기반 액션 토큰을 대체하지 않습니다. 전체 네이티브 구현 엔트리 셋업의 전체 구현을 집중적인 API 설명과 함께 여기에 모았습니다. 셋업에 문서화된 패키지 및 빌드 전제 조건을 따르세요.
jsx 코드 복사
// npm install react react-dom @vibe/core@4
// main.jsx in a client React project with <div id="root"></div>
import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
import { Button } from '@vibe/core';
import '@vibe/core/tokens';
import './board.css';
const initial=[{id:1,title:'Design handoff',owner:'Maya',status:'Working'},
{id:2,title:'Accessibility review',owner:'Theo',status:'Stuck'},
{id:3,title:'Release notes',owner:'Sam',status:'Done'}];
const states=['Working','Stuck','Done'];
function Board(){
const [items,setItems]=useState(initial),[selected,setSelected]=useState(new Set()),[message,setMessage]=useState('');
const toggle=id=>setSelected(old=>{const next=new Set(old);next.has(id)?next.delete(id):next.add(id);return next});
const complete=()=>{setItems(old=>old.map(item=>selected.has(item.id)?{...item,status:'Done'}:item));setMessage(selected.size+' local items completed');setSelected(new Set())};
return <main className="board"><h1>Weekly delivery</h1>
<p>{items.filter(x=>x.status==='Done').length} of {items.length} items completed</p>
<div className="toolbar"><Button disabled={!selected.size} onClick={complete}>Complete selected</Button>
<Button kind="tertiary" onClick={()=>{setItems(initial);setSelected(new Set());setMessage('Board reset')}}>Reset</Button></div>
<div className="table-scroll" role="region" aria-label="Delivery items" tabIndex={0}>
<table><thead><tr><th>Select</th><th>Item</th><th>Owner</th><th>Status</th></tr></thead><tbody>
{items.map(item=><tr key={item.id}><td><input type="checkbox" aria-label={'Select '+item.title} checked={selected.has(item.id)} onChange={()=>toggle(item.id)}/></td>
<th scope="row">{item.title}</th><td>{item.owner}</td><td><Button kind="tertiary" size="small" aria-label={item.title+': '+item.status+'. Change status'} onClick={()=>setItems(old=>old.map(x=>x.id===item.id?{...x,status:states[(states.indexOf(x.status)+1)%states.length]}:x))}>{item.status}</Button></td></tr>)}
</tbody></table></div><p role="status">{message}</p></main>
}
createRoot(document.getElementById('root')).render(<Board/>); 코드 참조
로컬 보드 전체 진입점입니다. 컴포넌트 예제의 board.css를 추가합니다. 글꼴은 자동으로 번들에 포함되지 않습니다. 공식 소스를 기준으로 네이티브 패키지 API을 확인했지만, 이 환경에서는 패키지 예제를 컴파일하지 않았습니다. 토큰 기반 보드 스타일시트 레이아웃과 타이포그래피에는 tokens 내보내기를 사용합니다. 상위 영역은 좁은 화면에서도 의미 구조를 갖춘 표를 사용할 수 있게 합니다.
CSS 코드 복사
*,*::before,*::after{box-sizing:border-box}
body{margin:0;background:var(--allgrey-background-color);color:var(--primary-text-color);font:var(--font-text2-normal)}
.board{max-width:960px;margin:auto;padding:var(--space-24)}
h1{font:var(--font-h1-medium)}
.toolbar{display:flex;flex-wrap:wrap;gap:var(--space-8);margin-bottom:var(--space-16)}
.table-scroll{overflow:auto;border:1px solid var(--layout-border-color);border-radius:var(--border-radius-medium)}
table{width:100%;min-width:560px;border-collapse:collapse;background:var(--primary-background-color)}
th,td{text-align:left;padding:var(--space-12);border-bottom:1px solid var(--layout-border-color)} 코드 참조
실제 Vibe 변수로 구성한 애플리케이션 CSS입니다. 내장 미리보기에서는 독립적으로 반응형 해석을 적용한 HTML을 사용합니다. 애플리케이션 HTML의 글꼴 로딩 권장 글꼴 두 가지를 명시적으로 불러옵니다. CSS 토큰 가져오기만으로는 글꼴이 다운로드되지 않습니다.
html 코드 복사
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Figtree:wght@400;500;600;700&family=Poppins:wght@400;500;600;700&display=swap"> 코드 참조
외부 스타일시트 대신 라이선스가 있는 글꼴을 자체 호스팅하도록 설정할 수 있습니다. 04
Monday Vibe 디자인 시스템 에이전트 설정 구현 시작점 로컬 보드 전체 진입점입니다. 컴포넌트 예제의 board.css를 추가합니다. 글꼴은 자동으로 번들에 포함되지 않습니다. 공식 소스를 기준으로 네이티브 패키지 API을 확인했지만, 이 환경에서는 패키지 예제를 컴파일하지 않았습니다.
jsx 예제 복사
// npm install react react-dom @vibe/core@4
// main.jsx in a client React project with <div id="root"></div>
import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
import { Button } from '@vibe/core';
import '@vibe/core/tokens';
import './board.css';
const initial=[{id:1,title:'Design handoff',owner:'Maya',status:'Working'},
{id:2,title:'Accessibility review',owner:'Theo',status:'Stuck'},
{id:3,title:'Release notes',owner:'Sam',status:'Done'}];
const states=['Working','Stuck','Done'];
function Board(){
const [items,setItems]=useState(initial),[selected,setSelected]=useState(new Set()),[message,setMessage]=useState('');
const toggle=id=>setSelected(old=>{const next=new Set(old);next.has(id)?next.delete(id):next.add(id);return next});
const complete=()=>{setItems(old=>old.map(item=>selected.has(item.id)?{...item,status:'Done'}:item));setMessage(selected.size+' local items completed');setSelected(new Set())};
return <main className="board"><h1>Weekly delivery</h1>
<p>{items.filter(x=>x.status==='Done').length} of {items.length} items completed</p>
<div className="toolbar"><Button disabled={!selected.size} onClick={complete}>Complete selected</Button>
<Button kind="tertiary" onClick={()=>{setItems(initial);setSelected(new Set());setMessage('Board reset')}}>Reset</Button></div>
<div className="table-scroll" role="region" aria-label="Delivery items" tabIndex={0}>
<table><thead><tr><th>Select</th><th>Item</th><th>Owner</th><th>Status</th></tr></thead><tbody>
{items.map(item=><tr key={item.id}><td><input type="checkbox" aria-label={'Select '+item.title} checked={selected.has(item.id)} onChange={()=>toggle(item.id)}/></td>
<th scope="row">{item.title}</th><td>{item.owner}</td><td><Button kind="tertiary" size="small" aria-label={item.title+': '+item.status+'. Change status'} onClick={()=>setItems(old=>old.map(x=>x.id===item.id?{...x,status:states[(states.indexOf(x.status)+1)%states.length]}:x))}>{item.status}</Button></td></tr>)}
</tbody></table></div><p role="status">{message}</p></main>
}
createRoot(document.getElementById('root')).render(<Board/>); 프로젝트를 위한 프롬프트 에이전트 프롬프트 프롬프트 복사
제공된 Vibe 4 전달 보드를 구현합니다. @vibe/core/tokens를 가져오고, 현재 버전의 번호형 간격 변수를 사용하며, 완전한 글꼴 단축 표기법을 적용합니다. 의미 기반 피드백 색상과 보드 레이블 색상은 구분합니다. 행 선택, 상태 편집, 계산된 완료 개수를 로컬에서 구현합니다. 일괄 작업 버튼에는 disabled를 사용하고 원격 저장을 흉내 내지 않습니다. 05
Monday Vibe 디자인 시스템 출처 및 범위 Vibe 4를 참고한 독립적인 보드 예제입니다. monday.com 계정, 워크스페이스 데이터 또는 SDK 연결은 없습니다. 네이티브 시작 예제는 실제 Vibe Button 컨트롤과 애플리케이션에서 관리하는 표 마크업을 사용합니다.