|
1 | | -import { css } from 'lit'; |
| 1 | +import { css, unsafeCSS } from 'lit'; |
2 | 2 |
|
3 | | -export const styles = css` |
| 3 | +const baseStyles = css` |
4 | 4 | :host { |
5 | 5 | display: block; |
6 | 6 | width: 100%; |
@@ -281,124 +281,145 @@ export const styles = css` |
281 | 281 | cursor: default; |
282 | 282 | } |
283 | 283 |
|
284 | | - /* ── Dark mode ── |
285 | | - 외부에서 --u-* CSS 변수가 제공되면 그 값을 사용하고, |
286 | | - 제공되지 않으면 자체 dark fallback 값을 적용한다. */ |
| 284 | +`; |
287 | 285 |
|
288 | | - :host-context([theme="dark"]) .sheet-container { |
| 286 | +/* ── Dark mode ── |
| 287 | + 외부에서 --u-* CSS 변수가 제공되면 그 값을 사용하고, |
| 288 | + 제공되지 않으면 자체 dark fallback 값을 적용한다. |
| 289 | +
|
| 290 | + 다크 규칙은 아래 3가지 컨텍스트에서 동일하게 적용된다: |
| 291 | + - :host([theme="dark"]) — 1급 theme 속성 (전 브라우저) |
| 292 | + - :host-context([theme="dark"]) — 조상 theme 속성, Theme 유틸 호환 (Chromium) |
| 293 | + - :host-context([data-theme="dark"]) — 조상 data-theme 속성만 쓰는 앱 (Chromium) |
| 294 | +
|
| 295 | + 셀렉터 리스트로 결합하면 :host-context 미지원 브라우저(Firefox/Safari)가 |
| 296 | + 리스트 전체를 무효화하므로, 프리픽스별 개별 규칙으로 생성한다. */ |
| 297 | +const DARK_PREFIXES = [ |
| 298 | + ':host([theme="dark"])', |
| 299 | + ':host-context([theme="dark"])', |
| 300 | + ':host-context([data-theme="dark"])', |
| 301 | +]; |
| 302 | + |
| 303 | +const darkRules = (host: string) => ` |
| 304 | + ${host} .sheet-container { |
289 | 305 | background: var(--u-bg-color, #121212); |
290 | 306 | border-color: var(--u-border-color, #3D3D3D); |
291 | 307 | } |
292 | 308 |
|
293 | | - :host-context([theme="dark"]) .sheet-container:focus-within { |
| 309 | + ${host} .sheet-container:focus-within { |
294 | 310 | border-color: var(--u-blue-500, #6ba3e3); |
295 | 311 | box-shadow: 0 0 0 2px var(--u-blue-100, #1e3a5f); |
296 | 312 | } |
297 | 313 |
|
298 | | - :host-context([theme="dark"]) .corner { |
| 314 | + ${host} .corner { |
299 | 315 | background: var(--u-neutral-100, #121212); |
300 | 316 | border-color: var(--u-border-color, #3D3D3D); |
301 | 317 | } |
302 | 318 |
|
303 | | - :host-context([theme="dark"]) .corner:hover { |
| 319 | + ${host} .corner:hover { |
304 | 320 | background: var(--u-neutral-200, #1E1E1E); |
305 | 321 | } |
306 | 322 |
|
307 | | - :host-context([theme="dark"]) .col-header { |
| 323 | + ${host} .col-header { |
308 | 324 | background: var(--u-neutral-100, #121212); |
309 | 325 | color: var(--u-txt-color-weak, #8A8A8A); |
310 | 326 | border-color: var(--u-border-color, #3D3D3D); |
311 | 327 | } |
312 | 328 |
|
313 | | - :host-context([theme="dark"]) .col-header.col-selected { |
| 329 | + ${host} .col-header.col-selected { |
314 | 330 | background: var(--u-blue-100, #1e3a5f); |
315 | 331 | color: var(--u-blue-800, #c2deff); |
316 | 332 | } |
317 | 333 |
|
318 | | - :host-context([theme="dark"]) .row-num { |
| 334 | + ${host} .row-num { |
319 | 335 | background: var(--u-neutral-50, #0A0A0A); |
320 | 336 | color: var(--u-txt-color-weak, #8A8A8A); |
321 | 337 | border-right-color: var(--u-border-color, #3D3D3D); |
322 | 338 | border-bottom-color: var(--u-border-color-weak, #2A2A2A); |
323 | 339 | } |
324 | 340 |
|
325 | | - :host-context([theme="dark"]) .row-num.row-selected { |
| 341 | + ${host} .row-num.row-selected { |
326 | 342 | background: var(--u-blue-100, #1e3a5f); |
327 | 343 | color: var(--u-blue-800, #c2deff); |
328 | 344 | } |
329 | 345 |
|
330 | | - :host-context([theme="dark"]) .cell { |
| 346 | + ${host} .cell { |
331 | 347 | color: var(--u-txt-color, #D4D4D4); |
332 | 348 | border-right-color: var(--u-border-color-weak, #2A2A2A); |
333 | 349 | border-bottom-color: var(--u-border-color-weak, #2A2A2A); |
334 | 350 | } |
335 | 351 |
|
336 | | - :host-context([theme="dark"]) .cell.cell-readonly { |
| 352 | + ${host} .cell.cell-readonly { |
337 | 353 | background: var(--u-neutral-100, #1E1E1E); |
338 | 354 | color: var(--u-txt-color-weak, #8A8A8A); |
339 | 355 | } |
340 | 356 |
|
341 | | - :host-context([theme="dark"]) .cell.cell-readonly.selected { |
| 357 | + ${host} .cell.cell-readonly.selected { |
342 | 358 | background: var(--u-neutral-200, #2A2A2A); |
343 | 359 | } |
344 | 360 |
|
345 | | - :host-context([theme="dark"]) .cell.cell-readonly.anchor { |
| 361 | + ${host} .cell.cell-readonly.anchor { |
346 | 362 | background: var(--u-neutral-100, #1E1E1E); |
347 | 363 | } |
348 | 364 |
|
349 | | - :host-context([theme="dark"]) .cell.cell-computed { |
| 365 | + ${host} .cell.cell-computed { |
350 | 366 | background: var(--u-blue-100, #1e3a5f); |
351 | 367 | color: var(--u-txt-color, #D4D4D4); |
352 | 368 | } |
353 | 369 |
|
354 | | - :host-context([theme="dark"]) .cell.cell-computed.selected { |
| 370 | + ${host} .cell.cell-computed.selected { |
355 | 371 | background: var(--u-blue-200, #2a4a6f); |
356 | 372 | } |
357 | 373 |
|
358 | | - :host-context([theme="dark"]) .cell.cell-computed.anchor { |
| 374 | + ${host} .cell.cell-computed.anchor { |
359 | 375 | background: var(--u-blue-100, #1e3a5f); |
360 | 376 | } |
361 | 377 |
|
362 | | - :host-context([theme="dark"]) .cell.selected { |
| 378 | + ${host} .cell.selected { |
363 | 379 | background: var(--u-blue-0, #0a1e3d); |
364 | 380 | } |
365 | 381 |
|
366 | | - :host-context([theme="dark"]) .cell.anchor { |
| 382 | + ${host} .cell.anchor { |
367 | 383 | background: var(--u-bg-color, #121212); |
368 | 384 | outline-color: var(--u-blue-500, #6ba3e3); |
369 | 385 | } |
370 | 386 |
|
371 | | - :host-context([theme="dark"]) .resize-handle:hover::after { |
| 387 | + ${host} .resize-handle:hover::after { |
372 | 388 | background: var(--u-blue-500, #6ba3e3); |
373 | 389 | } |
374 | 390 |
|
375 | | - :host-context([theme="dark"]) .cell-input { |
| 391 | + ${host} .cell-input { |
376 | 392 | background: var(--u-bg-color, #121212); |
377 | 393 | color: var(--u-txt-color, #D4D4D4); |
378 | 394 | outline-color: var(--u-blue-500, #6ba3e3); |
379 | 395 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5); |
380 | 396 | } |
381 | 397 |
|
382 | | - :host-context([theme="dark"]) .cell-dropdown { |
| 398 | + ${host} .cell-dropdown { |
383 | 399 | background: var(--u-bg-color, #121212); |
384 | 400 | border-color: var(--u-border-color, #3D3D3D); |
385 | 401 | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); |
386 | 402 | } |
387 | 403 |
|
388 | | - :host-context([theme="dark"]) .dropdown-item { |
| 404 | + ${host} .dropdown-item { |
389 | 405 | color: var(--u-txt-color, #D4D4D4); |
390 | 406 | } |
391 | 407 |
|
392 | | - :host-context([theme="dark"]) .dropdown-item:hover { |
| 408 | + ${host} .dropdown-item:hover { |
393 | 409 | background: var(--u-neutral-100, #1E1E1E); |
394 | 410 | } |
395 | 411 |
|
396 | | - :host-context([theme="dark"]) .dropdown-item.highlighted { |
| 412 | + ${host} .dropdown-item.highlighted { |
397 | 413 | background: var(--u-blue-100, #1e3a5f); |
398 | 414 | color: var(--u-blue-800, #c2deff); |
399 | 415 | } |
400 | 416 |
|
401 | | - :host-context([theme="dark"]) .dropdown-empty { |
| 417 | + ${host} .dropdown-empty { |
402 | 418 | color: var(--u-txt-color-weak, #8A8A8A); |
403 | 419 | } |
404 | 420 | `; |
| 421 | + |
| 422 | +export const styles = [ |
| 423 | + baseStyles, |
| 424 | + unsafeCSS(DARK_PREFIXES.map(darkRules).join('\n')), |
| 425 | +]; |
0 commit comments