@iyulab/data-components 0.7.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,223 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.0] - 2026-08-02
4
+
5
+ ### Fixed
6
+
7
+ - ★**URichTable 의 다크 테마가 Firefox·Safari 에서 동작하지 않던 문제.**
8
+
9
+ 툴바·표 헤더·상세 행·페이지네이션의 다크 배경이 `:host-context([theme="dark"])` 로만
10
+ 선언돼 있었는데, 그 선택자는 **Firefox·Safari 에서 미지원**이다. 두 브라우저에서는
11
+ 그 색이 적용된 적이 없다 — 라이트용 밝은 회색이 다크 화면에 그대로 남았다.
12
+
13
+ 우회가 아니라 원인을 없앴다: `@iyulab/components` 1.18.0 의 **`--u-bg-color-raised`**
14
+ 가 그 면을 표현하므로 base 규칙 하나로 두 테마가 성립하고, **다크 전용 블록이 통째로
15
+ 사라졌다**(이 파일의 다크 규칙 3 → **0**). 토큰 층은 브라우저를 가리지 않는다.
16
+
17
+ - ★**`@iyulab/data-components/init` 이 게시본에 존재하지 않던 문제.**
18
+ `exports['./init']` 이 선언돼 있고 `src/init.ts` 도 있는데, **빌드 진입점 목록에 없어서**
19
+ `dist/init.js` 가 한 번도 생성되지 않았다(타입 선언 `dist/init.d.ts` 만 남아 더 눈에 띄지
20
+ 않았다). 이 서브패스를 임포트하는 소비자는 `ERR_MODULE_NOT_FOUND` 를 받는다.
21
+
22
+ ⚠**이 리포 안에서는 아무 증상이 없다** — 로컬은 상대 경로로 소스를 직접 읽는다.
23
+ 게시본을 설치한 쪽에서만 드러나는 부류이며, 같은 성질의 결함이 과거에 네 번의 릴리스를
24
+ 지나 잠복한 적이 있다. 모노레포 `npm run doctor` 에 **게시 계약 스윕**을 추가해 12개
25
+ 패키지 전부를 대조하도록 했다.
26
+
27
+ ### Changed
28
+
29
+ - ⚠**`@iyulab/components` 의존 범위를 `^1.18.0` 으로 올린다.** 이 버전은 1.18.0 이 신설한
30
+ `--u-bg-color-raised` 를 쓴다. 1.15.0~1.17.0 과 짝지으면 토큰이 없어 폴백(`#FAFAFA`)이
31
+ 발동하는데, 그 값은 라이트 기준이라 **다크에서 툴바·헤더가 밝은 회색으로 칠해진다.**
32
+ 범위를 올리지 않으면 조용히 깨지는 조합이 생긴다.
33
+ - 다크 툴바·헤더·상세 행·페이지네이션이 `#1E1E1E` → **`#2A2A2A`** 로 한 단 밝아진다.
34
+ 기존 오버라이드가 해결하려던 증상(*"툴바·헤더가 배경에 묻힌다"*)에 대해 바탕 대비가
35
+ 1.15 → **1.42** 로 개선된다.
36
+ - 다크 페이지네이션 버튼이 `#2A2A2A` → **`#1E1E1E`** 로 한 단 안쪽이 된다. 크롬 면 위의
37
+ **컨트롤**이므로 입력 계열 토큰(`--u-input-bg-color`)을 쓴다 — 면과 같은 단이면 묻힌다.
38
+ - 라이트 표 헤더가 `#F5F5F5` → **`#FAFAFA`** 로 툴바와 같은 단이 된다. 두 단의 실측 수요는
39
+ 라이트 한쪽뿐이었고, 헤더는 이미 2px 테두리로 분리돼 있다.
40
+
41
+ ## [0.8.1] - 2026-08-02
42
+
43
+ ### Fixed
44
+
45
+ - ★**토큰 폴백 리터럴 108곳이 정본 시트와 어긋나 있던 문제.** 세 부류가 섞여 있었다:
46
+
47
+ 1. **다른 팔레트가 박혀 있던 것** (~80곳) — `#3b82f6`·`#e2e8f0`·`#94a3b8`·`#0f172a`·
48
+ `#ef4444`·`#10b981` 등. `@iyulab/components` 의 값이었던 적이 **한 번도 없다.**
49
+ 시트를 로드하지 않은 소비자에게는 이 패키지만 전혀 다른 색 체계로 보였다.
50
+ 2. ★★**다크 시트 값이 라이트 폴백으로 구워져 있던 것** (4곳) —
51
+ `--u-neutral-200: #1E1E1E`·`--u-neutral-300: #2A2A2A`. 시트가 없는 **라이트 화면에
52
+ 다크 회색**이 칠해진다. 폴백 정본은 light 여야 한다.
53
+ 3. 1.16.0 의 역할 단 재매핑을 받지 못한 것 (~24곳).
54
+
55
+ 특히 `--u-txt-color-weak` 12곳은 `#94a3b8`(흰 배경 대비 **2.56**, AA 미달 — 시트 값 #757575 는 4.61)이었다 —
56
+ 업스트림이 1.15.0 에서 바로 이 토큰의 AA 미달을 고쳤는데, 이 패키지의 폴백은 그 수정을
57
+ 받은 적이 없었다.
58
+
59
+ ⚠**이 결함은 개발 환경에서 절대 드러나지 않는다.** 토큰 시트가 있으면 폴백은 아예
60
+ 평가되지 않는다 — 깨지는 곳은 시트를 로드하지 않은 소비자의 화면이고, 우리가 보지
61
+ 못하는 자리다. 모노레포 루트의 `npm run tokens:sync` 가 이제 정본 시트와 대조한다.
62
+
63
+ ## [0.8.0] - 2026-08-02
64
+
65
+ ### Changed
66
+
67
+ - **UDataView 가 역할 토큰만 읽는다.** 다크 전용 규칙 92줄을 제거하고, 팔레트 참조
68
+ 4곳을 역할 토큰으로 옮겼다(`--u-blue-600` → `--u-primary-color`, `--u-blue-200` →
69
+ `--u-primary-color-weakest`). **두 테마의 계산색은 그대로다** — 브라우저에서
70
+ 변경 전후 계산값 스냅샷을 대조해 확인했다.
71
+
72
+ 제거한 다크 블록의 24개 선언은 전부 base 규칙과 **같은 토큰**을 가리키고 있었다.
73
+ 역할 토큰(`--u-bg-color`, `--u-border-color`, `--u-txt-color-weak` …)은 두 테마에서
74
+ 서로 다른 팔레트 단에 매핑돼 있어(예: `--u-bg-color` = neutral-0 라이트 /
75
+ neutral-100 다크) 테마 보정이 이미 토큰 층에 들어 있다. 따라서 그 블록은 토큰 시트가
76
+ 로드된 환경에서 계산값을 하나도 바꾸지 못했다.
77
+
78
+ - **USimpleSheet 의 다크 블록을 24개 선언 → 6개로 줄였다.** 지운 것은 base 와 같은 토큰을
79
+ 가리켜 계산값을 바꾸지 못하던 규칙들이다. **남긴 6개는 죽은 규칙이 아니다** — 유채색
80
+ 표면(계산 셀·선택된 열 헤더·강조된 드롭다운 항목)이며, 역할 층에 유채색 표면 토큰이
81
+ 없어서 손으로 메운 보정이다. 비활성화하면 실제로 색이 달라짐을 확인했다.
82
+ - **USimpleSheet 그림자 2곳이 `--u-shadow-color-*` 를 읽는다.** 종전에는 라이트/다크가
83
+ 각각 하드코딩된 `rgba(0,0,0,0.15)` / `0.5` 였다. 역할 토큰은 테마별로 불투명도가
84
+ 튜닝돼 있다(0.16/0.45, 0.12/0.35) — 다크에서 그림자가 아주 조금 옅어진다.
85
+ - **USimpleSheet 읽기전용 셀이 `--u-bg-color-disabled` 를 읽는다.** 이 토큰의 테마별
86
+ 매핑(neutral-50 라이트 / neutral-100 다크)이 종전 다크 블록이 손으로 쓴 단과 **정확히
87
+ 같다** — 그래서 해당 다크 규칙이 불필요해졌다. 계산색은 두 테마 모두 그대로다.
88
+
89
+ ### Added
90
+
91
+ - **UI 문구를 프로퍼티로 열었다** — URichTable 의 `loadingMessage`·`filterPlaceholder`·
92
+ `filterAllLabel`·`addRowLabel`·`pageInfoFormatter`, USimpleSheet 의 `noMatchMessage`.
93
+ 종전에는 `emptyMessage` 하나만 열려 있고 나머지는 한국어로 하드코딩돼 있었다.
94
+ `pageInfoFormatter` 만 함수인 것은 **언어마다 어순이 달라** 템플릿 문자열로는 열 수
95
+ 없기 때문이다.
96
+
97
+ ⚠로케일 레지스트리를 도입하지는 않았다 — 이 패키지에 없는 레이어를 새로 들이는
98
+ 일이고, 현재 수요가 그것을 요구할 만큼 모이지 않았다. 기존 `emptyMessage` 어법을
99
+ 따르는 순수 가산이다.
100
+
101
+ ### Changed
102
+
103
+ - **업스트림 토큰 채택 (`@iyulab/components` 1.15.0).** 이 릴리스에서 소비 측 우회 둘이
104
+ 사라졌다:
105
+ - **보조 텍스트 AA 우회 해제** — URichTable 4곳이 역할 토큰을 피해 고정값을 쓰고
106
+ 있었다(`--u-txt-color-weak` 가 라이트에서 2.68 로 AA 미달이었기 때문). 업스트림이
107
+ neutral-600(4.61)으로 고쳐져 **역할 토큰으로 되돌렸다.** 그 넷을 위해 남겨 둔
108
+ 다크 규칙도 함께 사라졌다 — 이제 이 색은 테마 오버라이드를 따른다.
109
+ - **유채색 표면 토큰 채택** — `--u-primary-bg-color`·`--u-success-bg-color`·
110
+ `--u-danger-bg-color` 로 옮겼다. 이 토큰들은 두 테마가 **같은 세기**가 되도록
111
+ 짝지어져 있어(라이트 shade-0 ↔ 다크 shade-100), 손으로 쓰던 다크 보정 2개가
112
+ 불필요해졌다. **다크에서 선택된 행·계산 셀 틴트가 제 세기로 보인다** —
113
+ 종전에는 팔레트 유채색이 다크에서 짓눌려 절반 이하로 옅었다.
114
+
115
+ ⇒ 다크 전용 규칙이 **8 → 3**, 팔레트 직접 참조가 **40 → 31** 로 줄었다.
116
+
117
+ ### Fixed
118
+
119
+ - **URichTable 템플릿에 인라인으로 박혀 있던 색 3곳**(행 메뉴 `⋯`, 행 오류 줄, 새 행
120
+ 표시)을 클래스 + 역할 토큰으로 옮겼다. `style="…#94a3b8"` 형태라 **스타일 시트만
121
+ 훑는 정리에는 보이지 않는 자리**였다. 색이 조금 바뀐다 — 행 오류 줄 배경
122
+ `#FEF2F2` → `#FFEBEE`, 행 메뉴 `#94A3B8` → `#9E9E9E`, 새 행 표시 `#86EFAC` →
123
+ `#A5D6A7`. (이 셋은 계산색 스냅샷이 덮지 못한다 — 렌더 조건이 내부 상태다.)
124
+
125
+ - ★**URichTable 에서 `_id` 없는 행을 넘기면 한 행 선택이 전체 선택으로 번지던 문제.**
126
+ 선택·확장·행 오류 상태가 전부 `_id` 로 추적되는데 그 값을 **어디서도 부여하지 않아**,
127
+ 소비자가 넣지 않으면 모든 행이 `undefined` 로 같은 키를 갖게 됐다. 이제 `_id` 가 없으면
128
+ **위치로 식별하고 개발 경고**를 낸다. 위치 기반 식별은 데이터가 재정렬·재페이징되면
129
+ 선택이 다른 행으로 옮겨가므로 안전망일 뿐이다 — 정렬·필터·페이지가 소비자 책임인
130
+ 컴포넌트이니 `_id` 를 주는 것이 옳다.
131
+
132
+ ### Documentation
133
+
134
+ - **`docs/URichTable.md` 신설.** 종전에는 README 가 *"문서 작성 예정"* 이라며 `types.ts`
135
+ 를 가리키고 있었다. 타입만으로는 드러나지 않는 두 계약을 먼저 적었다 — ⑴ `data` 는
136
+ 그대로 렌더되며 **정렬·필터·페이지는 소비자 책임**이다(헤더 클릭은 이벤트만 낸다),
137
+ ⑵ 각 행에 `_id` 가 필요하다. 속성·이벤트 9종·키보드/클립보드 표 포함.
138
+ - **README 의 Theming 절을 실제 동작에 맞게 고쳤다** — 토큰 시트가 필요하다는 것,
139
+ 없을 때의 폴백 규약, 브랜드 색 한 줄 변경, 그리고 알려진 제약 둘(AA 미달, Chromium
140
+ 한정 규칙)을 명시했다.
141
+
142
+ - **`--u-blue-50` 은 토큰 시트에 정의가 없다.** USimpleSheet 4곳(계산 셀·선택 셀·강조된
143
+ 드롭다운 항목)이 이 이름을 참조해 **두 테마 모두에서** 항상 리터럴 폴백으로 떨어지고
144
+ 있었다 — 즉 토큰 층과 무관하게 고정색이었다. 팔레트의 틴트 끝인 `--u-blue-0` 로
145
+ 고쳤다. **라이트에서 색이 바뀐다**: `#EFF6FF` → `#E3F2FD`. 다크는 종전과 동일하다.
146
+
147
+ - ★**URichTable 이 디자인 토큰을 읽기 시작한다 — 라이트 재도색.** 이 컴포넌트는 base
148
+ 레이어가 토큰을 **하나도** 쓰지 않고 고정 hex 를 박아 두었다. 즉 라이트에서 테마·브랜드
149
+ 설정에 전혀 반응하지 않았고, 다크는 그 위에 얹은 별도 재구현(57개 선언)이었다.
150
+ base 를 역할 토큰으로 옮기면서 다크 블록은 **2개 규칙**만 남았다.
151
+
152
+ **라이트에서 색이 바뀐다** — 주요 항목:
153
+
154
+ | 자리 | 전 | 후 |
155
+ |---|---|---|
156
+ | 테두리 | `#E2E8F0` | `#E0E0E0` (`--u-border-color`) |
157
+ | 입력 테두리 | `#D1D5DB` | `#E0E0E0` (`--u-input-border-color`) |
158
+ | 툴바·페이지네이션 배경 | `#F8FAFC` | `#FAFAFA` |
159
+ | 헤더 배경 | `#F1F5F9` | `#F5F5F5` |
160
+ | 주 버튼 | `#3B82F6` | `#1E88E5` (`--u-primary-color`) |
161
+ | 성공 버튼 | `#10B981` | `#43A047` (`--u-success-color`) |
162
+ | 선택된 행 | `#EFF6FF` | `#E3F2FD` |
163
+ | 편집·필터 행 | `#FEFCE8` | `#FFFDE7` |
164
+ | 오류 행 | `#FEF2F2` | `#FFEBEE` |
165
+ | 새 행 | `#F0FDF4` | `#E8F5E9` |
166
+
167
+ ⇒ 이제 `:root { --u-primary-color: … }` 한 줄로 이 표의 버튼·강조색이 따라온다.
168
+
169
+ **다크에서는 성공 버튼만 바뀐다**(green-500 → `--u-success-color`). 나머지가 종전
170
+ 값 그대로임을 계산색 스냅샷으로 확인했다 — 두 테마 × 14개 선택자(상태 틴트 포함:
171
+ 선택된 행·필터 줄·새 행). 스냅샷이 덮지 못한 자리는 `tbody tr.error`(내부 상태 필요)
172
+ 와 `.dropdown-item.highlighted` 두 곳이다.
173
+
174
+ ⚠**`:host` 가 이제 글자색을 정한다.** 종전에는 base 에 `color` 선언이 없어 페이지에서
175
+ **상속**받았고, 다크 블록만 그것을 덮었다. 이제 base 가 `--u-txt-color` 를 읽는다.
176
+ 토큰 시트를 쓰는 환경에서는 개선이지만, 시트 없이 페이지 글자색을 직접 지정하던
177
+ 소비자는 그 상속을 잃는다 — 필요하면 `--u-txt-color` 를 지정하세요.
178
+
179
+ ⚠**Firefox/Safari 에서 다크가 동작하기 시작한다.** 종전에는 다크가 전부
180
+ `:host-context()` 안에 있었고 그 선택자는 Chromium 전용이라, 다른 브라우저에서는
181
+ **다크 모드가 아예 적용되지 않았다.** 이제 색의 대부분이 토큰 층에서 테마를 따르므로
182
+ 전 브라우저에서 동작한다. 남은 2개 규칙(표면 높이·보조 텍스트)만 Chromium 한정으로
183
+ 남는다.
184
+
185
+ ### Removed
186
+
187
+ - **UDataView 의 `theme` 속성이 더 이상 색을 바꾸지 않는다.**
188
+ 토큰 시트를 로드한 환경에서는 원래부터 효과가 없었다(위 참조). 시트를 로드하지 않는
189
+ 환경에서는 요소에 `theme="dark"` 를 걸면 다크 고정값이 적용됐으나, 이제는 적용되지
190
+ 않는다 — 토큰 미공급 시 폴백은 라이트 기준 고정값이라는 규약을 따른다.
191
+ **다크가 필요하면 토큰 시트를 로드할 것**(`@iyulab/components/styles/tokens.css`).
192
+ 문서 단위 다크(`<html theme="dark">`)는 종전과 동일하게 동작한다.
193
+
194
+ ### Added
195
+
196
+ - 브라우저 테스트 프로젝트(playwright chromium). 계산색을 실제로 측정한다 —
197
+ 기존 유닛 테스트는 스타일 **문자열**에서 셀렉터를 세므로, 규칙이 적혀 있음은 보여도
198
+ 그 규칙이 무언가를 바꾸는지는 말하지 못한다. 위 24개 선언이 정확히 그 사각에 있었다.
199
+ - `data-view-colors.browser.test.ts` — 두 테마 계산색 스냅샷 회귀망
200
+ - `theme-resolution.browser.test.ts` — 역할 토큰의 테마별 매핑, 팔레트 틴트 비대칭
201
+
202
+ ### Known issues
203
+
204
+ - **유채색에는 테마 보정 층이 없다.** 역할 토큰의 중립 계열 17종은 두 테마에서 다른
205
+ 팔레트 단에 매핑되지만, `--u-primary/success/danger/warning-*` 는 양 테마가 같은 단을
206
+ 가리킨다. 그런데 팔레트의 틴트 세기는 계열마다 비대칭이다 — 바탕 대비 델타 실측:
207
+ 중립은 다크가 라이트의 1.34~1.62배, 청색은 0.38~0.54배, 적색은 0.25~0.58배,
208
+ 황색은 4.2~6.1배. 그래서 유채색 표면을 쓰는 컴포넌트는 다크 보정을 손으로 써야 한다.
209
+ - **"주색 위의 글자" 역할 토큰이 없다.** 활성 뷰 버튼은 다크에서 대비 3.45 이며
210
+ 흰 글자였다면 6.09 다. 팔레트를 직접 바꾸면 게시된 시각이 움직이므로 보류했다.
211
+ - **UI 문자열이 한국어로 하드코딩돼 있다** — `URichTable` 의 `로딩 중...`·`필터...`·
212
+ `전체`·`전체 N건 중 X-Y 표시`, `USimpleSheet` 의 `일치하는 항목 없음`. `emptyMessage`
213
+ 만 프로퍼티로 열려 있고 나머지는 소비자가 바꿀 수 없다. 이 패키지에는 로케일 레이어가
214
+ 없어 단순 프로퍼티 추가로 갈지 로케일 레지스트리를 도입할지가 설계 결정이다.
215
+ - ★**`--u-txt-color-weak` 의 라이트 매핑이 WCAG AA 에 미달한다** — neutral-500(#9E9E9E)
216
+ = 흰 배경 대비 **2.68**(AA 기준 4.5). 다크는 neutral-700 = **5.43** 으로 정상이므로
217
+ **라이트 한쪽만의 결함**이다. 그래서 URichTable 의 보조 텍스트 4곳은 역할 토큰으로
218
+ 옮기지 못했다(옮기면 4.76 → 2.68 로 후퇴). 업스트림에서 라이트 매핑을
219
+ **neutral-600(4.61)** 으로 한 단 내리면 해소된다.
220
+
3
221
  ## [0.7.1] - 2026-08-01
4
222
 
5
223
  ### Documentation
package/README.md CHANGED
@@ -124,12 +124,12 @@ const sheet = document.querySelector('u-simple-sheet'); // USimpleSheet | null
124
124
 
125
125
  - [USimpleSheet](./docs/USimpleSheet.md)
126
126
  - [UDataView](./docs/UDataView.md)
127
- - URichTable — 문서 작성 예정([types.ts](./src/components/u-rich-table/types.ts) 참고)
127
+ - [URichTable](./docs/URichTable.md)
128
128
  - [UDataGrid 마이그레이션 가이드](./docs/migrating-from-datagrid.md)
129
129
 
130
130
  ## Theming
131
131
 
132
- `@iyulab/components`의 테마 시스템을 사용합니다. 라이트/다크 모드 자동 지원.
132
+ `@iyulab/components`의 디자인 토큰을 읽습니다. **토큰 시트가 문서에 있어야 테마가 동작합니다.**
133
133
 
134
134
  ```typescript
135
135
  import { Theme } from '@iyulab/components';
@@ -138,6 +138,40 @@ Theme.init({ default: 'system' });
138
138
  Theme.set('dark'); // 'light' | 'dark' | 'system'
139
139
  ```
140
140
 
141
+ `Theme.init()`을 쓰지 않는다면 정적 진입점을 대신 임포트하세요:
142
+
143
+ ```typescript
144
+ import '@iyulab/components/styles/tokens.css';
145
+ ```
146
+
147
+ ### 토큰 시트가 없으면
148
+
149
+ 컴포넌트는 렌더되지만 **라이트 기준 고정값**으로 그려지며, 다크 테마와 테마 변수
150
+ 오버라이드가 적용되지 않습니다. 이는 의도된 폴백 규약입니다.
151
+
152
+ ### 브랜드 색 바꾸기
153
+
154
+ 색은 역할 토큰을 통해 읽으므로, 주색 한 줄로 버튼·선택 강조·포커스가 함께 따라옵니다:
155
+
156
+ ```css
157
+ :root { --u-primary-color: #7B1FA2; }
158
+ ```
159
+
160
+ ### 알려진 제약
161
+
162
+ - **표면 높이를 뜻하는 토큰이 없습니다** — 배경 역할 토큰은 상호작용 상태 이름
163
+ (`-hover`/`-active`/`-disabled`)뿐이라 "바탕보다 한 단 올라온 면"을 표현할 수 없습니다.
164
+ 라이트에서는 팔레트 음영이 흰 바탕 위에서 충분히 읽히지만 다크에서는 거의 검정이라,
165
+ 툴바·표 헤더 등 몇 자리는 `:host-context()`로 보정합니다. **이 선택자는
166
+ Firefox/Safari에서 동작하지 않습니다** — 해당 브라우저에서 그 면들이 배경에 묻힙니다.
167
+ 그 밖의 색은 전 브라우저에서 테마를 따릅니다.
168
+ - **경고(노랑) 표면에는 역할 토큰이 없습니다** — 라이트 황색 틴트가 거의 보이지 않아
169
+ 두 테마의 세기를 맞출 단 짝이 없습니다(업스트림 미해결). 필터 줄·편집 중 행은
170
+ 팔레트를 직접 읽습니다.
171
+
172
+ > `--u-txt-color-weak`의 WCAG AA 미달(2.68)은 `@iyulab/components` 1.15.0에서
173
+ > 해소됐습니다(4.61). 이 패키지가 쓰던 우회도 함께 제거됐습니다.
174
+
141
175
  ## License
142
176
 
143
177
  MIT
@@ -1,6 +1,5 @@
1
- import { css, unsafeCSS } from "lit";
2
- //#region src/components/data-view/UDataView.styles.ts
3
- var baseStyles = css`
1
+ import { css } from "lit";
2
+ var styles = [css`
4
3
  :host {
5
4
  display: block;
6
5
  width: 100%;
@@ -19,8 +18,8 @@ var baseStyles = css`
19
18
  align-items: center;
20
19
  justify-content: space-between;
21
20
  padding: 0.75rem;
22
- background: var(--u-bg-color, #fff);
23
- border: 1px solid var(--u-border-color, #e2e8f0);
21
+ background: var(--u-bg-color, #FFFFFF);
22
+ border: 1px solid var(--u-border-color, #E0E0E0);
24
23
  border-radius: 8px;
25
24
  }
26
25
 
@@ -30,13 +29,18 @@ var baseStyles = css`
30
29
  }
31
30
 
32
31
  .view-toggles u-button[active] {
33
- background: var(--u-blue-600, #1E88E5);
34
- color: var(--u-neutral-0, #fff);
32
+ background: var(--u-primary-color, #1976D2);
33
+ /* 예외 1 — "주색 위의 글자" 역할 토큰이 없다.
34
+ 역할 층의 유채색은 전경 5단(--u-primary-color-*)뿐이고, 그 위에 얹는 글자색을
35
+ 가리키는 토큰은 없다. 실측: 라이트 #FFFFFF/#1E88E5 = 3.68, 다크 #000000/#2A659D
36
+ = 3.45 — 다크는 흰 글자였다면 6.09 였다. 즉 현재 값이 최선이 아니지만, 팔레트를
37
+ 직접 바꾸면 게시된 시각이 움직이므로 토큰 추가 결정까지 현행을 유지한다. */
38
+ color: var(--u-neutral-0, #FFFFFF);
35
39
  }
36
40
 
37
41
  .info {
38
42
  font-size: 0.875rem;
39
- color: var(--u-txt-color-weak, #64748b);
43
+ color: var(--u-txt-color-weak, #757575);
40
44
  font-weight: 500;
41
45
  }
42
46
 
@@ -56,8 +60,8 @@ var baseStyles = css`
56
60
 
57
61
  /* Card Styles */
58
62
  .card {
59
- background: var(--u-bg-color, #fff);
60
- border: 1px solid var(--u-border-color, #e2e8f0);
63
+ background: var(--u-bg-color, #FFFFFF);
64
+ border: 1px solid var(--u-border-color, #E0E0E0);
61
65
  border-radius: 8px;
62
66
  padding: 1.25rem;
63
67
  cursor: pointer;
@@ -65,15 +69,15 @@ var baseStyles = css`
65
69
  }
66
70
 
67
71
  .card:hover {
68
- border-color: var(--u-blue-600, #1E88E5);
72
+ border-color: var(--u-primary-color, #1976D2);
69
73
  box-shadow: 0 4px 12px var(--u-shadow-color-weak, rgba(0, 0, 0, 0.08));
70
74
  transform: translateY(-2px);
71
75
  }
72
76
 
73
77
  .card.selected {
74
- border-color: var(--u-blue-600, #1E88E5);
78
+ border-color: var(--u-primary-color, #1976D2);
75
79
  background: var(--u-bg-color-active, #EEEEEE);
76
- box-shadow: 0 0 0 3px var(--u-blue-200, #90CAF9);
80
+ box-shadow: 0 0 0 3px var(--u-primary-color-weakest, #90CAF9);
77
81
  }
78
82
 
79
83
  .card-content {
@@ -91,14 +95,14 @@ var baseStyles = css`
91
95
  .card-field .label {
92
96
  font-size: 0.875rem;
93
97
  font-weight: 600;
94
- color: var(--u-txt-color-weak, #64748b);
98
+ color: var(--u-txt-color-weak, #757575);
95
99
  min-width: 80px;
96
100
  flex-shrink: 0;
97
101
  }
98
102
 
99
103
  .card-field .value {
100
104
  font-size: 0.9375rem;
101
- color: var(--u-txt-color, #0f172a);
105
+ color: var(--u-txt-color, #212121);
102
106
  word-break: break-word;
103
107
  }
104
108
 
@@ -116,18 +120,23 @@ var baseStyles = css`
116
120
  /* Table */
117
121
  .table-wrapper {
118
122
  overflow-x: auto;
119
- border: 1px solid var(--u-border-color, #e2e8f0);
123
+ border: 1px solid var(--u-border-color, #E0E0E0);
120
124
  border-radius: 8px;
121
125
  }
122
126
 
123
127
  table {
124
128
  width: 100%;
125
129
  border-collapse: collapse;
126
- background: var(--u-bg-color, #fff);
130
+ background: var(--u-bg-color, #FFFFFF);
127
131
  }
128
132
 
129
133
  thead {
130
- background: var(--u-neutral-50, #f8fafc);
134
+ /* 예외 2 — 표면 높이 축이 없다.
135
+ 배경 역할 토큰은 상호작용 상태 이름(-hover/-active/-disabled)뿐이라,
136
+ "바탕보다 한 단 올라온 면"을 뜻하는 토큰이 없다. 헤더에 -hover 를 쓰면
137
+ 마우스 상태를 뜻하게 되므로 팔레트를 직접 읽는다. neutral-50 은 두 테마에서
138
+ 각각 #FAFAFA/#0A0A0A 로 반전되므로 다크 보정은 필요 없다. */
139
+ background: var(--u-neutral-50, #FAFAFA);
131
140
  position: sticky;
132
141
  top: 0;
133
142
  z-index: 10;
@@ -138,8 +147,8 @@ var baseStyles = css`
138
147
  text-align: left;
139
148
  font-size: 0.875rem;
140
149
  font-weight: 600;
141
- color: var(--u-txt-color-weak, #64748b);
142
- border-bottom: 2px solid var(--u-border-color, #e2e8f0);
150
+ color: var(--u-txt-color-weak, #757575);
151
+ border-bottom: 2px solid var(--u-border-color, #E0E0E0);
143
152
  white-space: nowrap;
144
153
  }
145
154
 
@@ -157,13 +166,13 @@ var baseStyles = css`
157
166
  }
158
167
 
159
168
  tbody tr:not(:last-child) {
160
- border-bottom: 1px solid var(--u-border-color-weak, #f1f5f9);
169
+ border-bottom: 1px solid var(--u-border-color-weak, #EEEEEE);
161
170
  }
162
171
 
163
172
  td {
164
173
  padding: 0.875rem 1rem;
165
174
  font-size: 0.9375rem;
166
- color: var(--u-txt-color, #0f172a);
175
+ color: var(--u-txt-color, #212121);
167
176
  }
168
177
 
169
178
  /* Empty State */
@@ -172,91 +181,9 @@ var baseStyles = css`
172
181
  align-items: center;
173
182
  justify-content: center;
174
183
  min-height: 300px;
175
- color: var(--u-txt-color-weak, #64748b);
184
+ color: var(--u-txt-color-weak, #757575);
176
185
  font-size: 1rem;
177
186
  }
178
- `;
179
- var DARK_PREFIXES = [
180
- ":host([theme=\"dark\"])",
181
- ":host-context([theme=\"dark\"])",
182
- ":host-context([data-theme=\"dark\"])"
183
- ];
184
- var darkRules = (host) => `
185
- ${host} .toolbar {
186
- background: var(--u-bg-color, #121212);
187
- border-color: var(--u-border-color, #3D3D3D);
188
- }
189
-
190
- ${host} .view-toggles u-button[active] {
191
- background: var(--u-blue-600, #87B8F5);
192
- color: var(--u-neutral-0, #000);
193
- }
194
-
195
- ${host} .info {
196
- color: var(--u-txt-color-weak, #8A8A8A);
197
- }
198
-
199
- ${host} .card {
200
- background: var(--u-bg-color, #121212);
201
- border-color: var(--u-border-color, #3D3D3D);
202
- }
203
-
204
- ${host} .card:hover {
205
- border-color: var(--u-blue-600, #87B8F5);
206
- box-shadow: 0 4px 12px var(--u-shadow-color-weak, rgba(0, 0, 0, 0.25));
207
- }
208
-
209
- ${host} .card.selected {
210
- border-color: var(--u-blue-600, #87B8F5);
211
- background: var(--u-bg-color-active, #3D3D3D);
212
- box-shadow: 0 0 0 3px var(--u-blue-200, #2B4F7E);
213
- }
214
-
215
- ${host} .card-field .label {
216
- color: var(--u-txt-color-weak, #8A8A8A);
217
- }
218
-
219
- ${host} .card-field .value {
220
- color: var(--u-txt-color, #D4D4D4);
221
- }
222
-
223
- ${host} .table-wrapper {
224
- border-color: var(--u-border-color, #3D3D3D);
225
- }
226
-
227
- ${host} table {
228
- background: var(--u-bg-color, #121212);
229
- }
230
-
231
- ${host} thead {
232
- background: var(--u-neutral-50, #0A0A0A);
233
- }
234
-
235
- ${host} th {
236
- color: var(--u-txt-color-weak, #8A8A8A);
237
- border-bottom-color: var(--u-border-color, #3D3D3D);
238
- }
239
-
240
- ${host} tbody tr:hover {
241
- background: var(--u-bg-color-hover, #2A2A2A);
242
- }
243
-
244
- ${host} tbody tr.selected {
245
- background: var(--u-bg-color-active, #3D3D3D);
246
- }
247
-
248
- ${host} tbody tr:not(:last-child) {
249
- border-bottom-color: var(--u-border-color-weak, #2A2A2A);
250
- }
251
-
252
- ${host} td {
253
- color: var(--u-txt-color, #D4D4D4);
254
- }
255
-
256
- ${host} .empty {
257
- color: var(--u-txt-color-weak, #8A8A8A);
258
- }
259
- `;
260
- var styles = [baseStyles, unsafeCSS(DARK_PREFIXES.map(darkRules).join("\n"))];
187
+ `];
261
188
  //#endregion
262
189
  export { styles };
@@ -48,6 +48,8 @@ export declare class USimpleSheet extends UElement {
48
48
  cols: number;
49
49
  /** 읽기 전용 모드 */
50
50
  readonly: boolean;
51
+ /** 드롭다운에 일치 항목이 없을 때 문구 */
52
+ noMatchMessage: string;
51
53
  /**
52
54
  * 명시 테마. 'dark'이면 다크 스타일을 적용합니다.
53
55
  * 미설정 시 조상 컨텍스트의 theme/data-theme 속성에 따릅니다 (:host-context, Chromium 한정).
@@ -25,6 +25,7 @@ var USimpleSheet = class USimpleSheet extends UElement {
25
25
  this.rows = 20;
26
26
  this.cols = 10;
27
27
  this.readonly = false;
28
+ this.noMatchMessage = "일치하는 항목 없음";
28
29
  this._sel = null;
29
30
  this._editing = null;
30
31
  this._editVal = "";
@@ -611,7 +612,7 @@ var USimpleSheet = class USimpleSheet extends UElement {
611
612
  </div>
612
613
  ` : noMatch && isStrict ? html`
613
614
  <div class="cell-dropdown">
614
- <div class="dropdown-empty">일치하는 항목 없음</div>
615
+ <div class="dropdown-empty">${this.noMatchMessage}</div>
615
616
  </div>
616
617
  ` : ""}
617
618
  ` : this._formatValue(value, c, r)}
@@ -924,6 +925,7 @@ __decorate([property({ type: Array }), __decorateMetadata("design:type", Array)]
924
925
  __decorate([property({ type: Number }), __decorateMetadata("design:type", Object)], USimpleSheet.prototype, "rows", void 0);
925
926
  __decorate([property({ type: Number }), __decorateMetadata("design:type", Object)], USimpleSheet.prototype, "cols", void 0);
926
927
  __decorate([property({ type: Boolean }), __decorateMetadata("design:type", Object)], USimpleSheet.prototype, "readonly", void 0);
928
+ __decorate([property({ type: String }), __decorateMetadata("design:type", Object)], USimpleSheet.prototype, "noMatchMessage", void 0);
927
929
  __decorate([property({
928
930
  type: String,
929
931
  reflect: true