Skip to content

Commit 486a6f3

Browse files
committed
fix(data-view): UDataView fallback 없는 var(--u-*) 24개에 컨텍스트별 fallback 부여
형제 USimpleSheet/URichTable의 NT-5 자가-테마 패턴을 UDataView에도 적용: base 규칙엔 light fallback, 별도 다크 셀렉터 블록(:host([theme=dark]) + :host-context 2종)엔 dark fallback. 토큰 미공급 시에도 자가-테마되어 외부 --u-* 다크 토큰 공급(로컬 shim) 없이도 정상 다크 렌더. light 회귀 없음: fallback은 토큰 미공급 시에만 발동(공급 앱은 영향 없음), light/dark 컨텍스트별로 정확한 값 분리. ISSUE-20260619 해소 (UDataView가 누락된 NT-5 자가-테마 완결).
1 parent 29a5115 commit 486a6f3

2 files changed

Lines changed: 128 additions & 27 deletions

File tree

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@iyulab/data-components",
33
"description": "iyulab data visualization components",
4-
"version": "0.6.0",
4+
"version": "0.6.1",
55
"keywords": [
66
"iyulab",
77
"web-components",

‎src/components/data-view/UDataView.styles.ts‎

Lines changed: 127 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
import { css } from 'lit';
1+
import { css, unsafeCSS } from 'lit';
22

3-
export const styles = css`
3+
/* ── Base (light) ──
4+
모든 --u-* 토큰에 light fallback을 부여해 토큰 미공급 환경에서도 자가-테마된다.
5+
외부에서 --u-* 가 공급되면 그 값이 우선한다. 형제 컴포넌트(USimpleSheet/
6+
URichTable)의 NT-5 자가-테마 패턴과 동일한 slate 계열 light fallback을 사용한다. */
7+
const baseStyles = css`
48
:host {
59
display: block;
610
width: 100%;
@@ -19,8 +23,8 @@ export const styles = css`
1923
align-items: center;
2024
justify-content: space-between;
2125
padding: 0.75rem;
22-
background: var(--u-bg-color);
23-
border: 1px solid var(--u-border-color);
26+
background: var(--u-bg-color, #fff);
27+
border: 1px solid var(--u-border-color, #e2e8f0);
2428
border-radius: 8px;
2529
}
2630
@@ -30,13 +34,13 @@ export const styles = css`
3034
}
3135
3236
.view-toggles u-button[active] {
33-
background: var(--u-blue-600);
34-
color: var(--u-neutral-0);
37+
background: var(--u-blue-600, #1E88E5);
38+
color: var(--u-neutral-0, #fff);
3539
}
3640
3741
.info {
3842
font-size: 0.875rem;
39-
color: var(--u-txt-color-weak);
43+
color: var(--u-txt-color-weak, #64748b);
4044
font-weight: 500;
4145
}
4246
@@ -56,24 +60,24 @@ export const styles = css`
5660
5761
/* Card Styles */
5862
.card {
59-
background: var(--u-bg-color);
60-
border: 1px solid var(--u-border-color);
63+
background: var(--u-bg-color, #fff);
64+
border: 1px solid var(--u-border-color, #e2e8f0);
6165
border-radius: 8px;
6266
padding: 1.25rem;
6367
cursor: pointer;
6468
transition: all 0.15s ease;
6569
}
6670
6771
.card:hover {
68-
border-color: var(--u-blue-600);
69-
box-shadow: 0 4px 12px var(--u-shadow-color-weak);
72+
border-color: var(--u-blue-600, #1E88E5);
73+
box-shadow: 0 4px 12px var(--u-shadow-color-weak, rgba(0, 0, 0, 0.08));
7074
transform: translateY(-2px);
7175
}
7276
7377
.card.selected {
74-
border-color: var(--u-blue-600);
75-
background: var(--u-bg-color-active);
76-
box-shadow: 0 0 0 3px var(--u-blue-200);
78+
border-color: var(--u-blue-600, #1E88E5);
79+
background: var(--u-bg-color-active, #EEEEEE);
80+
box-shadow: 0 0 0 3px var(--u-blue-200, #90CAF9);
7781
}
7882
7983
.card-content {
@@ -91,14 +95,14 @@ export const styles = css`
9195
.card-field .label {
9296
font-size: 0.875rem;
9397
font-weight: 600;
94-
color: var(--u-txt-color-weak);
98+
color: var(--u-txt-color-weak, #64748b);
9599
min-width: 80px;
96100
flex-shrink: 0;
97101
}
98102
99103
.card-field .value {
100104
font-size: 0.9375rem;
101-
color: var(--u-txt-color);
105+
color: var(--u-txt-color, #0f172a);
102106
word-break: break-word;
103107
}
104108
@@ -116,18 +120,18 @@ export const styles = css`
116120
/* Table */
117121
.table-wrapper {
118122
overflow-x: auto;
119-
border: 1px solid var(--u-border-color);
123+
border: 1px solid var(--u-border-color, #e2e8f0);
120124
border-radius: 8px;
121125
}
122126
123127
table {
124128
width: 100%;
125129
border-collapse: collapse;
126-
background: var(--u-bg-color);
130+
background: var(--u-bg-color, #fff);
127131
}
128132
129133
thead {
130-
background: var(--u-neutral-50);
134+
background: var(--u-neutral-50, #f8fafc);
131135
position: sticky;
132136
top: 0;
133137
z-index: 10;
@@ -138,8 +142,8 @@ export const styles = css`
138142
text-align: left;
139143
font-size: 0.875rem;
140144
font-weight: 600;
141-
color: var(--u-txt-color-weak);
142-
border-bottom: 2px solid var(--u-border-color);
145+
color: var(--u-txt-color-weak, #64748b);
146+
border-bottom: 2px solid var(--u-border-color, #e2e8f0);
143147
white-space: nowrap;
144148
}
145149
@@ -149,21 +153,21 @@ export const styles = css`
149153
}
150154
151155
tbody tr:hover {
152-
background: var(--u-bg-color-hover);
156+
background: var(--u-bg-color-hover, #F5F5F5);
153157
}
154158
155159
tbody tr.selected {
156-
background: var(--u-bg-color-active);
160+
background: var(--u-bg-color-active, #EEEEEE);
157161
}
158162
159163
tbody tr:not(:last-child) {
160-
border-bottom: 1px solid var(--u-border-color-weak);
164+
border-bottom: 1px solid var(--u-border-color-weak, #f1f5f9);
161165
}
162166
163167
td {
164168
padding: 0.875rem 1rem;
165169
font-size: 0.9375rem;
166-
color: var(--u-txt-color);
170+
color: var(--u-txt-color, #0f172a);
167171
}
168172
169173
/* Empty State */
@@ -172,7 +176,104 @@ export const styles = css`
172176
align-items: center;
173177
justify-content: center;
174178
min-height: 300px;
175-
color: var(--u-txt-color-weak);
179+
color: var(--u-txt-color-weak, #64748b);
176180
font-size: 1rem;
177181
}
178182
`;
183+
184+
/* ── Dark mode ──
185+
외부에서 --u-* 변수가 제공되면 그 값을 사용하고, 없으면 dark fallback을 적용한다.
186+
다크 규칙은 아래 3가지 컨텍스트에서 동일하게 적용된다:
187+
- :host([theme="dark"]) — 1급 theme 속성 (전 브라우저)
188+
- :host-context([theme="dark"]) — 조상 theme 속성, Theme 유틸 호환 (Chromium)
189+
- :host-context([data-theme="dark"]) — 조상 data-theme 속성만 쓰는 앱 (Chromium)
190+
191+
셀렉터 리스트로 결합하면 :host-context 미지원 브라우저(Firefox/Safari)가
192+
리스트 전체를 무효화하므로, 프리픽스별 개별 규칙으로 생성한다. */
193+
const DARK_PREFIXES = [
194+
':host([theme="dark"])',
195+
':host-context([theme="dark"])',
196+
':host-context([data-theme="dark"])',
197+
];
198+
199+
const darkRules = (host: string) => `
200+
${host} .toolbar {
201+
background: var(--u-bg-color, #121212);
202+
border-color: var(--u-border-color, #3D3D3D);
203+
}
204+
205+
${host} .view-toggles u-button[active] {
206+
background: var(--u-blue-600, #87B8F5);
207+
color: var(--u-neutral-0, #000);
208+
}
209+
210+
${host} .info {
211+
color: var(--u-txt-color-weak, #8A8A8A);
212+
}
213+
214+
${host} .card {
215+
background: var(--u-bg-color, #121212);
216+
border-color: var(--u-border-color, #3D3D3D);
217+
}
218+
219+
${host} .card:hover {
220+
border-color: var(--u-blue-600, #87B8F5);
221+
box-shadow: 0 4px 12px var(--u-shadow-color-weak, rgba(0, 0, 0, 0.25));
222+
}
223+
224+
${host} .card.selected {
225+
border-color: var(--u-blue-600, #87B8F5);
226+
background: var(--u-bg-color-active, #3D3D3D);
227+
box-shadow: 0 0 0 3px var(--u-blue-200, #2B4F7E);
228+
}
229+
230+
${host} .card-field .label {
231+
color: var(--u-txt-color-weak, #8A8A8A);
232+
}
233+
234+
${host} .card-field .value {
235+
color: var(--u-txt-color, #D4D4D4);
236+
}
237+
238+
${host} .table-wrapper {
239+
border-color: var(--u-border-color, #3D3D3D);
240+
}
241+
242+
${host} table {
243+
background: var(--u-bg-color, #121212);
244+
}
245+
246+
${host} thead {
247+
background: var(--u-neutral-50, #0A0A0A);
248+
}
249+
250+
${host} th {
251+
color: var(--u-txt-color-weak, #8A8A8A);
252+
border-bottom-color: var(--u-border-color, #3D3D3D);
253+
}
254+
255+
${host} tbody tr:hover {
256+
background: var(--u-bg-color-hover, #2A2A2A);
257+
}
258+
259+
${host} tbody tr.selected {
260+
background: var(--u-bg-color-active, #3D3D3D);
261+
}
262+
263+
${host} tbody tr:not(:last-child) {
264+
border-bottom-color: var(--u-border-color-weak, #2A2A2A);
265+
}
266+
267+
${host} td {
268+
color: var(--u-txt-color, #D4D4D4);
269+
}
270+
271+
${host} .empty {
272+
color: var(--u-txt-color-weak, #8A8A8A);
273+
}
274+
`;
275+
276+
export const styles = [
277+
baseStyles,
278+
unsafeCSS(DARK_PREFIXES.map(darkRules).join('\n')),
279+
];

0 commit comments

Comments
 (0)