Grommet은 HPE와 관련된 React 프레임워크이며 자체 기본 테마를 제공합니다. 별도의 grommet-theme-hpe 패키지는 HPE 디자인 스타일을 적용하는 애플리케이션을 위해 hpe를 내보냅니다. 이 참조에서는 기본 프레임워크와 명시적으로 설정한 예시를 안내합니다. 보라색 브랜드 색상과 민트색 포커스 색상은 기본 테마에서 가져온 것이며, 현재 HPE 브랜드 팔레트를 나타내지 않습니다.
설정에서는 애플리케이션 글꼴로 Arial을 지정하고 문서에 나온 기본 브랜드 및 포커스 색상을 다시 사용합니다. 그 외 모든 컴포넌트 규칙은 Grommet을 상속합니다. 실제 HPE 제품에서는 승인된 hpe 테마를 전달할 수 있습니다. 이 경우 테마 재정의로 기본값이 달라질 수 있으므로 결과에 반영된 간격과 타이포그래피를 확인하세요.
기본 생성기는 24픽셀에서 시작합니다. 기본 중간 가장자리 간격은 24px이지만, 작은 화면 중단점에서는 중간 간격이 12px로 바뀝니다. 따라서 반응형 패딩을 사용하는 Box는 JSX에 중간 크기가 지정되어 있어도 작아질 수 있습니다. 스케일과 중단점 재정의를 함께 확인하고, 중간 크기가 항상 24픽셀이라고 단정하지 마세요.
기본 생성기는 간격 입력값을 바탕으로 18픽셀 글꼴과 24픽셀 줄 높이를 도출합니다. 독점 브랜드 글꼴을 다운로드했다고 오해하지 않도록 예시에서는 해당 조합과 Arial을 명시적으로 사용합니다. 제목에는 Grommet Heading을, 본문에는 Text를 사용해 컴포넌트 내부 구현을 CSS에서 다시 작성하지 않고 테마가 각 역할에 맞는 값을 적용하도록 합니다.
Form이 폼의 통합 계약을 관리합니다. 제어 패턴에서는 value와 onChange를 호출자가 담당합니다. 각 FormField와 자식 입력 요소의 name은 해당 값의 키를 지정합니다. 예약 객체에는 name과 pool이 들어 있습니다. 용량 슬라이더는 제출 전에 실시간 다이어그램을 갱신하므로 별도의 숫자로 관리합니다.
예제 풀의 옵션은 Production과 Development입니다. 따라서 제어되는 값은 문자열입니다. 객체 옵션으로 전환한다면 labelKey를 설정하고, reduce와 함께 valueKey를 선택적으로 설정한 다음 저장된 값이 해당 설정과 일치하도록 유지하세요. Select의 onChange는 네이티브 range input 이벤트와 달리 value/option 객체를 전달합니다.
onSearch를 전달하면 Select에 검색 필드를 표시할 수 있습니다. 이 prop을 전달한다고 해서 모든 옵션이 자동으로 필터링되는 것은 아닙니다. 검색을 닫거나 지웠을 때 원래 옵션을 복원할 수 있도록 필터링되지 않은 원본 목록을 별도로 유지하세요. 두 풀을 사용하는 이 예제에서는 의도적으로 검색 기능을 생략했습니다.
Meter에는 사용 예정량과 max=100이 전달됩니다. 이 예시용 플래너에서는 예제 풀의 기존 사용량이 35단위이며, 예약 제안량은 5~60단위입니다. 예제의 분모가 100이어서 백분율과 수치가 우연히 일치합니다. 데이터 계약이 다른 총량에서도 유지되도록 코드에는 max를 명시적으로 전달합니다.
원형 표시, 사용 예정량 레이블, 잔여 단위는 모두 동일한 숫자 슬라이더 값에서 계산됩니다. 네이티브 RangeInput은 DOM 이벤트를 내보내므로 산술 연산 전에 event.target.value를 Number로 변환하세요. 그렇지 않으면 문자열에 35를 더했을 때 화면상 그럴듯하지만 잘못된 합계가 나올 수 있습니다.
Grommet의 full=true는 자체 뷰포트와 내부 스크롤을 제어하는 애플리케이션을 위한 설정입니다. 이 플래너에는 문서가 길어질 수 있도록 full="min"을 사용합니다. 그러면 휴대전화에서 고정 높이 셸 아래에 양식과 유효성 검사 메시지가 갇히는 일을 방지할 수 있습니다.
range 컨트롤에는 항상 표시되는 레이블과 단위가 있습니다. 원형 표시는 사용 예정량과 총용량을 담은 a11yTitle을 받습니다. 인접한 텍스트에도 같은 숫자를 표시해 색이 있는 호에만 정보가 의존하지 않도록 합니다. 오류 문구에는 예약 관련 문제가 명시되며 해당 필드 옆에 표시됩니다.
클라이언트 프로젝트에 grommet, styled-components, React runtime을 설치하세요. Grommet을 마운트한 다음 ResponsiveContext를 사용하는 하위 컴포넌트, 제어되는 Form, FormField/TextInput/Select, RangeInput, Meter를 마운트합니다. 기본 레이블 스타일 버튼 동작을 명확히 유지하려면 children 대신 Button label을 사용하세요.
전체 문서를 index.html로 저장한 다음 브라우저에서 여세요. 기본 Grommet의 치수와 색상을 HTML/CSS로 독립적으로 해석하고 Arial 글꼴을 명시적으로 선택했습니다. 별도 HPE 테마는 사용하지 않습니다.
html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Capacity reservation — Grommet study</title><style>*{box-sizing:border-box}body{margin:0;background:white;color:#444;font:18px/24px Arial,sans-serif}header{padding:24px 36px;border-bottom:1px solid #ddd;display:flex;gap:12px;align-items:center}.mark{width:22px;height:22px;border:4px solid #7d4cdb;border-radius:50%}main{max-width:1050px;margin:auto;padding:36px}h1{font-size:36px;line-height:42px;margin:12px 0 24px;color:#222}h2{font-size:24px;line-height:30px;margin:0 0 12px}.intro{max-width:650px;margin-bottom:36px}.layout{display:grid;grid-template-columns:minmax(0,1fr) 310px;gap:48px}label{display:block;font-weight:600;margin-bottom:12px}input,select,button{font:inherit;max-width:100%}input[type=text],select{width:100%;border:1px solid #888;border-radius:4px;background:transparent;padding:12px;color:#444}input:focus-visible,select:focus-visible,button:focus-visible{outline:3px solid #6fffb0;outline-offset:3px}.field{margin-bottom:24px}input[type=range]{width:100%;accent-color:#7d4cdb}.limits{display:flex;justify-content:space-between;font-size:14px;color:#666;margin-top:6px}button{border:2px solid #7d4cdb;border-radius:24px;background:#7d4cdb;color:white;padding:10px 24px;font-weight:600;cursor:pointer}button:hover{background:#6839c0}aside{background:#f2f2f2;padding:24px;border-radius:12px;align-self:start;text-align:center}.ring{width:192px;height:192px;border-radius:50%;background:conic-gradient(#7d4cdb var(--used),#dadada 0);margin:24px auto;display:grid;place-items:center;position:relative}.ring:before{content:'';position:absolute;inset:12px;background:#f2f2f2;border-radius:50%}.ring span{position:relative;font-size:36px;font-weight:bold}.ring small{display:block;font-size:14px;font-weight:400;line-height:20px}.legend{text-align:left;border-top:1px solid #ddd;padding-top:12px;font-size:14px}.legend div{display:flex;justify-content:space-between;margin:8px 0}.error{font-size:14px;color:#b30000;margin-top:6px}#result{background:#f2f2f2;border-left:4px solid #7d4cdb;padding:24px;margin-top:36px}footer{font-size:12px;line-height:18px;color:#666;border-top:1px solid #ddd;padding:24px 36px}@media(max-width:700px){main{padding:24px}.layout{grid-template-columns:1fr;gap:24px}h1{font-size:30px;line-height:36px}header,footer{padding:24px}.intro{margin-bottom:24px}}</style><header><span class="mark" aria-hidden="true"></span><strong>Capacity planner</strong></header><main><h1>Plan a reservation</h1><p class="intro">Explore a proposed allocation before preparing a local plan. This model contains 100 capacity units.</p><div class="layout"><form id="form" novalidate><div class="field"><label for="name">Reservation name</label><input id="name" type="text" required aria-describedby="error"><div class="error" id="error" hidden></div></div><div class="field"><label for="pool">Capacity pool</label><select id="pool"><option>Production</option><option>Development</option></select></div><div class="field"><label for="units">Requested allocation: <output id="requested">20</output> units</label><input id="units" type="range" min="5" max="60" step="5" value="20"><div class="limits"><span>5 units</span><span>60 units</span></div></div><button type="submit">Prepare plan</button><p style="font-size:14px;color:#666">No infrastructure will be provisioned.</p></form><aside><h2>Projected usage</h2><div class="ring" id="ring" style="--used:55%" role="img" aria-label="55 of 100 units projected usage"><span><output id="used">55</output><small>of 100 units</small></span></div><div class="legend"><div><span>Already used</span><strong>35</strong></div><div><span>Proposed reservation</span><strong id="proposed">20</strong></div><div><span>Remaining</span><strong id="remaining">45</strong></div></div></aside></div><section id="result" hidden><h2>Prepared local plan</h2><p id="snapshot" role="status"></p><p style="font-size:14px">This snapshot changes only when you prepare the plan again.</p></section></main><footer>Independent base Grommet HTML/CSS interpretation. Base purple/mint palette and spacing; Arial is an application font choice. This is not the separate HPE branded theme.</footer><script>
const $=id=>document.getElementById(id);$('units').oninput=()=>{const units=Number($('units').value),used=35+units;$('requested').textContent=$('proposed').textContent=units;$('used').textContent=used;$('remaining').textContent=100-used;$('ring').style.setProperty('--used',used+'%');$('ring').setAttribute('aria-label',used+' of 100 units projected usage')};$('form').onsubmit=e=>{e.preventDefault();const name=$('name').value.trim();if(name.length<3){$('error').textContent='Use at least three characters for the reservation name.';$('error').hidden=false;$('name').setAttribute('aria-invalid','true');$('name').focus();return}$('error').hidden=true;$('name').removeAttribute('aria-invalid');$('snapshot').textContent=name+' · '+$('pool').value+' · '+$('units').value+' units. Prepared in this local demonstration.';$('result').hidden=false};
</script></html>
루트 요소가 있는 프로젝트용 클라이언트 main.jsx입니다. 기본 Grommet에 애플리케이션 글꼴과 브랜드 재정의를 명시적으로 선언합니다. HPE 테마를 암묵적으로 적용하지 않습니다. 공식 문서에서 API을 확인했으며, 여기서는 네이티브 컴파일을 검증하지 않았습니다.
HPE 브랜드 테마로 명시적으로 전환
의도한 디자인 대상이 HPE 테마일 때만 별도 패키지를 사용하고, 설치된 릴리스의 값과 다시 대조하세요.
jsx
// npm install grommet-theme-hpe
import { Grommet } from 'grommet';
import { hpe } from 'grommet-theme-hpe';
// Wrap the Planner from the full setup example:
<Grommet theme={hpe} themeMode="light" full="min"><Planner /></Grommet>
루트 요소가 있는 프로젝트용 클라이언트 main.jsx입니다. 기본 Grommet에 애플리케이션 글꼴과 브랜드 재정의를 명시적으로 선언합니다. HPE 테마를 암묵적으로 적용하지 않습니다. 공식 문서에서 API을 확인했으며, 여기서는 네이티브 컴파일을 검증하지 않았습니다.
제공된 기본 Grommet 예약 플래너를 제어되는 Form, 이름이 지정된 FormField, Select, RangeInput, max를 명시한 Meter로 구현하세요. 기본 테마 값은 grommet-theme-hpe와 구분하세요. 슬라이더 값을 숫자로 변환하고, 단위를 표시하며, 이름을 검증하고, 로컬 계획 스냅샷만 생성하세요.
05
HPE Grommet 디자인 시스템 소스 및 범위
기본 Grommet을 독립적으로 구현하기 위한 참조입니다. HPE 브랜드 테마 적용은 별도로 설명합니다. 용량 수치는 가상의 로컬 데이터이며, 인프라 지표나 프로비저닝을 나타내지 않습니다.