Initial commit: HMDesignSystem baseline
This commit is contained in:
commit
b6a0a61103
486 files changed
+68432
No files matched your search
@@ -0,0 +1,94 @@
|
||||
<!doctype html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>HM Dashboard Status Contract - Static HTML</title>
|
||||
<link rel="stylesheet" href="../../packages/ui/dist/theme.css" />
|
||||
<link rel="stylesheet" href="../../src/patterns/dashboard-status-contract.css" />
|
||||
<style>
|
||||
@font-face { font-family: "Noto Sans KR"; src: url("../../public/fonts/NotoSansKR-variable.ttf") format("truetype"); font-weight: 100 900; }
|
||||
:root {
|
||||
--dashboard-work-progress: var(--hm-dashboard-status-active);
|
||||
--dashboard-work-hold: var(--hm-dashboard-status-hold);
|
||||
--dashboard-work-issue: var(--hm-dashboard-status-issue);
|
||||
--dashboard-work-surface: var(--hm-sem-palette-green-dark-2);
|
||||
}
|
||||
body { margin: 0; min-width: 960px; background: var(--hm-sem-bg-content); color: var(--hm-sem-fg-primary); font-family: "Noto Sans KR", sans-serif; }
|
||||
main { max-width: 1120px; margin: 0 auto; padding: 32px; }
|
||||
.panel { padding: 24px; border-radius: var(--hm-radius-container); background: var(--hm-sem-bg-surface); box-shadow: var(--hm-card-shadow); }
|
||||
.toolbar, .filters, .badges { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||
.toolbar { justify-content: space-between; margin-bottom: 20px; }
|
||||
.filters { padding: 10px; border-radius: var(--hm-radius-container); background: var(--dashboard-work-surface); }
|
||||
button { min-height: 32px; padding: 0 12px; border: 1px solid color-mix(in srgb, var(--hm-sem-palette-black) 50%, transparent); border-radius: var(--hm-radius-input); background: color-mix(in srgb, var(--hm-sem-palette-black) 35%, transparent); color: var(--hm-sem-palette-white); font: inherit; cursor: pointer; }
|
||||
button:hover { background: color-mix(in srgb, var(--hm-sem-palette-black) 55%, transparent); }
|
||||
button:focus-visible { outline: var(--hm-dashboard-nav-focus-outline); }
|
||||
button[aria-pressed="true"] { background: color-mix(in srgb, var(--hm-sem-palette-green-dark-2) 90%, transparent); border-color: var(--hm-sem-palette-green-light-4); }
|
||||
button[data-filter="issue"] { background: color-mix(in srgb, var(--hm-sem-action-destructive) 25%, transparent); }
|
||||
[data-slot="badge"] { background: color-mix(in srgb, var(--hm-sem-palette-green-dark-2) 90%, transparent); }
|
||||
[data-slot="badge"][data-status] { color: var(--dashboard-status-color); border-color: color-mix(in srgb, var(--hm-sem-palette-black) 50%, transparent); }
|
||||
[data-status="active"] { --dashboard-status-color: var(--dashboard-work-progress); }
|
||||
[data-status="hold"] { --dashboard-status-color: var(--dashboard-work-hold); }
|
||||
[data-status="done"] { --dashboard-status-color: var(--hm-dashboard-status-done); }
|
||||
[data-status="issue"][data-issue="true"] { --dashboard-status-color: var(--dashboard-work-issue); }
|
||||
.count { margin-left: auto; color: var(--hm-sem-fg-secondary); }
|
||||
.result { margin-top: 16px; }
|
||||
[hidden] { display: none !important; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<section class="panel" aria-labelledby="title">
|
||||
<div class="toolbar">
|
||||
<div><h1 id="title">Dashboard 업무 상태</h1><p id="summary" role="status">전체 업무 0건</p></div>
|
||||
<div class="filters" role="group" aria-label="업무 상태 필터" data-status-filter-group></div>
|
||||
</div>
|
||||
<div class="result" aria-live="polite"><div class="badges" id="results" aria-label="필터 결과"></div><p id="empty" hidden>조건에 맞는 업무가 없습니다.</p></div>
|
||||
</section>
|
||||
</main>
|
||||
<script>
|
||||
const contract = {
|
||||
filters: ["all", "active", "hold", "done", "issue"],
|
||||
labels: { all: "전체", active: "진행", hold: "보류", done: "완료", issue: "이슈" },
|
||||
records: [
|
||||
{ name: "대시보드 화면 검토", status: "active" },
|
||||
{ name: "업무 자료 정리", status: "hold", issue: true },
|
||||
{ name: "현장 점검 보고", status: "done" },
|
||||
],
|
||||
};
|
||||
const state = { selected: "all" };
|
||||
const matches = (record, filter) => filter === "all" || (filter === "issue" ? record.issue === true : record.status === filter);
|
||||
const count = (filter) => contract.records.filter((record) => matches(record, filter)).length;
|
||||
const group = document.querySelector("[data-status-filter-group]");
|
||||
const results = document.querySelector("#results");
|
||||
const summary = document.querySelector("#summary");
|
||||
const empty = document.querySelector("#empty");
|
||||
function render() {
|
||||
group.replaceChildren(...contract.filters.map((filter) => {
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.dataset.filter = filter;
|
||||
button.dataset.status = filter;
|
||||
if (filter === "issue") button.dataset.issue = "true";
|
||||
button.setAttribute("aria-pressed", String(state.selected === filter));
|
||||
button.setAttribute("aria-controls", "results");
|
||||
button.textContent = `${contract.labels[filter]} ${count(filter)}건`;
|
||||
button.addEventListener("click", () => { state.selected = filter; render(); });
|
||||
return button;
|
||||
}));
|
||||
const filtered = contract.records.filter((record) => matches(record, state.selected));
|
||||
results.replaceChildren(...filtered.map((record) => {
|
||||
const item = document.createElement("span");
|
||||
item.dataset.slot = "badge";
|
||||
item.dataset.status = record.status;
|
||||
if (record.issue) item.dataset.issue = "true";
|
||||
item.textContent = `${record.name} · ${contract.labels[record.status]}${record.issue ? " · 이슈" : ""}`;
|
||||
return item;
|
||||
}));
|
||||
summary.textContent = `${contract.labels[state.selected]} 업무 ${filtered.length}건`;
|
||||
empty.hidden = filtered.length !== 0;
|
||||
}
|
||||
render();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user