File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
08-14
08-14
08-14
08-18
08-19
08-19
// FoxTable — 시안: 통합관리자페이지 디자인시스템(KE9UILWhB8qTBe14uXUn4F)
// tbl-basic (425:5781) · tbl-list (391:4283) · tbl-form (391:4389)
//
// 마크업 계약 (React 밖 소비자용):
// <table class="fox-table fox-table--basic">
// <caption class="fox-table__caption">…</caption> <!-- 선택 · 눈에 안 보인다 -->
// <thead class="fox-table__head">
// <tr class="fox-table-row fox-table-row--head">
// <th class="fox-table-cell fox-table-cell--head" scope="col">…</th>
// </tr>
// </thead>
// <tbody class="fox-table__body">
// <tr class="fox-table-row">
// <th class="fox-table-cell fox-table-cell--head" scope="row">…</th>
// <td class="fox-table-cell fox-table-cell--body">…</td>
// </tr>
// </tbody>
// </table>
//
// 세 타입은 뼈대가 같고 여백·글자·기본 정렬만 다르다. 그 차이를 클래스가 아니라 커스텀
// 프로퍼티로 내려보낸다 — 칸에 `.fox-table--basic .fox-table-cell`처럼 후손 선택자를 쓰면
// 표 안에 표가 들어갔을 때 바깥 표의 규칙이 안쪽까지 덮어쓴다. 커스텀 프로퍼티는 안쪽
// 표가 자기 값으로 다시 덮으므로 그 문제가 없다.
//
// 좁은 화면에서 `list`는 한 줄이 카드로 접히고 `form`은 레이블이 입력 위로 올라간다
// (시안 device 축). 표 요소를 `display: block`으로 바꿔 만드는데, 그러면 표 의미가 사라져
// 스크린리더가 행·열을 읽지 못한다. 그래서 `list`의 칸은 `label`을 함께 받아 카드에서
// 열 이름을 글자로 보여 준다.
//
// 토큰이 아닌 값:
// - form 머리칸의 최소 크기 12rem×4.8rem: 시안 값이나 Figma가 변수로 export하지
// 않는다(사용자 승인).
// - line-height / letter-spacing: 시안 텍스트 스타일의 값이나 Figma가 변수로
// export하지 않는다.
// - border-collapse / table-layout / display 전환: 구조 규칙.
@use "abstracts" as fox;
.fox-table {
// 타입이 칸에 내려보내는 값. 기본은 시안 basic이다.
--fox-table-cell-padding-inline: #{fox.padding(5)};
--fox-table-head-padding-block: #{fox.padding(3)};
--fox-table-body-padding-block: #{fox.padding(6)};
--fox-table-head-font-size: #{fox.font-size(heading-2xsm)};
--fox-table-head-font-family: #{fox.font-family(title)};
--fox-table-head-font-weight: #{fox.font-weight(bold)};
--fox-table-head-line-height: 1.4;
--fox-table-head-align: center;
--fox-table-body-align: center;
--fox-table-head-min-inline-size: 0;
--fox-table-cell-min-block-size: 0;
inline-size: 100%;
border-collapse: collapse;
border-block-start: fox.border(1) solid fox.color(border-neutral-subtler);
// 목록표는 줄이 촘촘하다.
&--list {
--fox-table-body-padding-block: #{fox.padding(3)};
}
// 입력표는 레이블 열이 왼쪽에 서고 여백이 넓다.
&--form {
--fox-table-cell-padding-inline: #{fox.padding(6)};
--fox-table-head-padding-block: #{fox.padding(6)};
--fox-table-body-padding-block: #{fox.padding(3)};
--fox-table-head-font-size: #{fox.font-size(label-md)};
--fox-table-head-font-family: #{fox.font-family(body)};
--fox-table-head-font-weight: #{fox.font-weight(medium)};
--fox-table-head-line-height: 1;
--fox-table-head-align: start;
--fox-table-body-align: start;
// 시안 값이나 변수로 export되지 않는다 — 파일 상단 참고.
--fox-table-head-min-inline-size: 12rem;
--fox-table-cell-min-block-size: 4.8rem;
}
// 표가 무엇을 담는지 스크린리더에만 알린다.
&__caption {
position: absolute;
inline-size: fox.border(1);
block-size: fox.border(1);
margin: calc(-1 * #{fox.border(1)});
padding: 0;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
// ── 좁은 화면 ─────────────────────────────────────────────────────────────
@include fox.mobile {
// 목록표는 한 줄이 카드가 된다. 머리행은 카드마다 열 이름이 붙으므로 감춘다.
&--list {
border-block-start: none;
.fox-table__head {
display: none;
}
.fox-table__body,
.fox-table-row,
.fox-table-cell {
display: block;
inline-size: 100%;
}
.fox-table-row {
border-block-end: fox.border(1) solid fox.color(border-neutral-subtler);
}
.fox-table-cell {
border-block-end: none;
}
}
// 입력표는 레이블이 입력 위로 올라간다.
&--form {
.fox-table__body,
.fox-table-row,
.fox-table-cell {
display: block;
inline-size: 100%;
}
.fox-table-row {
border-block-end: fox.border(1) solid fox.color(border-neutral-subtler);
}
.fox-table-cell {
border-block-end: none;
}
.fox-table-cell--head {
min-inline-size: 0;
background: fox.color(surface-neutral-default);
}
}
}
}