zdp-design-system 0.43.8 → 0.45.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
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - Added layer and mobile-safe viewport tokens, then moved overlay z-index and `100vh`/`100vw` sizing to named token usage across Svelte components and static utilities.
6
+ - Strengthened package checks for overlay token usage and overrideable default labels.
7
+ - Documented that repeated mobile keyboard, long option, async option, grouped option, virtualized list, or collision pressure should move Menu, Popover, and Combobox flows to Sheet or a headless spike.
8
+ - Added `AdSlot` plus static `.zdp-ad-slot` utilities for provider-neutral ad or sponsorship placement reservation while keeping provider scripts, consent, slot ids, `ads.txt`, personalized ads, and automatic content insertion in consuming apps.
9
+ - Documented the dependency adoption policy: active ZDP sibling consumers may keep `file:../zdp-design-system`, while standalone consumers, public templates, and external examples should use the npm package from `^0.45.0`.
10
+ - Added a single-component consumer fixture proof so the root barrel keeps tree-shaking unused component exports out of Button-only bundles.
11
+
5
12
  ## 0.43.8
6
13
 
7
14
  - Added a publish-readiness check for package metadata, export targets, dist entries, and packaged public documents before npm release work.
package/README.md CHANGED
@@ -23,6 +23,8 @@ Default component text is English. 제품별 화면은 필요한 모든 user-fac
23
23
 
24
24
  - `type`: body, body small, page title, title, label, caption, control, data에 쓰는 기본 크기와 줄높이
25
25
  - `breakpoint`: mobile, tablet, desktop, wide 기준 폭
26
+ - `layer`: behind, floating, toast, sheet, dialog, skip-link 계층 기준
27
+ - `viewport`: mobile-safe overlay clamp와 safe-area inset 기준
26
28
  - `control`: 버튼, 아이콘 버튼, 입력류가 공유할 높이, radius, border width, hit target, 선택 컨트롤 전용 mark, indicator, switch, scrollbar 크기
27
29
  - `focus`: 키보드 사용자가 현재 위치를 놓치지 않도록 하는 sunlit focus highlight, dark text, dark line
28
30
  - `selection`: 드래그로 선택한 텍스트가 브라우저 기본 파란색 대신 theme surface와 readable text로 보이게 하는 selection 색
@@ -66,7 +68,7 @@ Tailwind Plus와 Tailwind UI 계열은 파생/재배포 리스크 때문에 ZDP
66
68
  - Viewports는 ZDP Mobile, Tablet, Desktop, Wide 프리셋으로 mobile/tablet/desktop 폭을 확인한다.
67
69
  - Accessibility addon은 CI 실패 게이트로 유지한다. 새 story는 a11y 위반을 남긴 채 merge하지 않는다.
68
70
  - Interaction play는 `Tabs`, `Dialog`, `ConfirmAction`처럼 키보드와 상태 전이가 중요한 컴포넌트에 먼저 붙인다.
69
- - Theme / Locale Stress story는 light/dark, ZDP Mobile 폭, 긴 한국어/영어/중국어/힌디어 문장, focus-visible 상태를 한 번에 확인한다.
71
+ - Theme / Locale Stress story는 light/dark, ZDP Mobile 폭, 긴 한국어/영어/중국어/힌디어/베트남어/러시아어/말레이어/태국어 문장, focus-visible 상태를 한 번에 확인한다.
70
72
 
71
73
  ## 패키지 표면
72
74
 
@@ -99,6 +101,8 @@ import 'zdp-design-system/expressive-fonts.css';
99
101
 
100
102
  패키지 export는 `dist/` 산출물을 가리킨다. root runtime entry는 `dist/index.js`, type entry는 `dist/index.d.ts`다. 원천은 `src/lib`, `src/styles`, `tokens/zdp.tokens.json`, `src/lib/share.ts`이고 `bun run package:build`가 소비자용 `dist/` 표면을 다시 만든다. 소비 저장소와 문서 예시는 `zdp-design-system` public export만 쓰고 내부 `src/` 경로를 직접 import하지 않는다.
101
103
 
104
+ ZDP monorepo 안의 active sibling 소비처는 `file:../zdp-design-system` 의존성을 유지할 수 있다. 이 방식은 release 전 변경을 같이 검증하기 위한 local workspace 계약이므로 CI에서 sibling checkout과 `bun run package:build`를 먼저 수행해야 한다. sibling checkout을 전제로 하지 않는 standalone consumer, public template, external example은 npm registry의 `zdp-design-system: ^0.45.0`을 기본으로 쓴다.
105
+
102
106
  ## 소비 컴포넌트 계약
103
107
 
104
108
  - Breadcrumb는 현재 위치 탐색을 `nav`로 표현하고, 제품 라우팅 판단은 소비 앱이 한다.
@@ -108,6 +112,7 @@ import 'zdp-design-system/expressive-fonts.css';
108
112
  - Avatar와 IdentityChip은 사람, 팀, 계정의 짧은 식별 표면이다.
109
113
  - CommandField는 검색 입력 primitive이며 shortcut keycap, `ariaKeyShortcuts`, `ariaAutocomplete`, result id 연결, 입력 keydown callback은 제공하되 실제 검색 로직, 결과 목록, command palette 실행은 소비 앱이 소유한다.
110
114
  - Combobox는 검색 가능한 단일 선택 입력의 frame, listbox, keyboard navigation, disabled option skip, hidden submitted value만 제공한다. 실제 필터링, async search, command 실행, 권한 판단은 소비 앱이 계속 소유한다.
115
+ - AdSlot은 광고나 후원 자리의 reserved layout, accessible label, placement/state data attribute만 제공한다. provider script, consent, slot id, ads.txt, personalized ads 판단은 소비 앱이 계속 소유한다.
111
116
  - InlineCode와 CodeBlock은 문서, 보안, 아키텍처 화면의 코드 표면이다.
112
117
  - Icon은 장식용 glyph 기본값을 갖고, 의미 있는 아이콘은 소비 컴포넌트가 접근성 이름을 제공한다.
113
118
  - Link는 일반 텍스트 링크이며 버튼처럼 보이는 destructive action으로 쓰지 않는다.
@@ -142,6 +147,7 @@ Svelte 또는 Tauri(Svelte) 표면은 컴포넌트를 직접 가져온다.
142
147
  <script lang="ts">
143
148
  import {
144
149
  Accordion,
150
+ AdSlot,
145
151
  Avatar,
146
152
  Badge,
147
153
  Breadcrumb,
@@ -456,6 +462,7 @@ Astro는 `styles.css`를 전역으로 불러오고, Svelte island가 필요한
456
462
  | 시트 / 드로어 | `.zdp-sheet` |
457
463
  | 상태 알림 | `.zdp-toast` `.zdp-status-toast` |
458
464
  | 로딩 / 진행 | `.zdp-progress` `.zdp-spinner` `.zdp-skeleton` |
465
+ | 광고 / 후원 자리 | `.zdp-ad-slot` `.zdp-ad-slot--inline|banner|rail|between-sections` |
459
466
  | 아이콘 | `.zdp-icon` `.zdp-icon--sm|md` |
460
467
  | 표 | `.zdp-table-wrap` `.zdp-table` `.zdp-sort-header` `.zdp-table-toolbar` |
461
468
  | 페이지네이션 | `.zdp-pagination` |
@@ -506,8 +513,8 @@ preview/index.html
506
513
  - `styles.css`는 Pretendard Variable dynamic subset을 로드하고, sans/display stack은 `"Pretendard Variable", Pretendard`를 최우선으로 둔다.
507
514
  - `brand-fonts.css`는 선택형 public export이며 `font.family.brand`와 `.zdp-brand-wordmark`가 쓰는 Playwrite AU VIC Guides를 로드한다. 일반 문서 제목, 제품 UI heading, 표, 본문에는 `brand` stack을 쓰지 않는다.
508
515
  - `expressive-fonts.css`는 선택형 public export이며 `font.family.expressionScript`, `font.family.expressionInscription`, `font.family.expressionSketch`, `font.family.expressionEditorial`, `font.family.expressionSans`, `font.family.expressionKeyboard`가 쓰는 표현용 Google Fonts를 로드한다. 기본 앱 UI, 표, 긴 본문, 일반 Tooltip에는 자동 적용하지 않는다.
509
- - `locale-fonts.css`는 선택형 public export이며 Manrope, Noto Sans SC, Noto Sans Devanagari, Noto Sans JP 웹폰트를 로드한다. 모든 소비 앱이 반드시 가져갈 필요는 없다.
510
- - `:lang(en|es|fr|de|pt|id)`는 Manrope/Inter 라틴 스택, `:lang(ko)`는 Pretendard 한국어 스택, `:lang(zh)`는 Noto Sans SC/시스템 중국어 스택, `:lang(hi)`는 Noto Sans Devanagari/시스템 데바나가리 스택, `:lang(ja)`는 Noto Sans JP/시스템 일본어 스택으로 덮어쓴다.
516
+ - `locale-fonts.css`는 선택형 public export이며 Manrope, Noto Sans SC, Noto Sans Devanagari, Noto Sans JP, Noto Sans Thai 웹폰트를 로드한다. 모든 소비 앱이 반드시 가져갈 필요는 없다.
517
+ - `:lang(en|es|fr|vi|ru|id|ms)`는 Manrope/Inter 라틴 스택, `:lang(ko)`는 Pretendard 한국어 스택, `:lang(zh)`는 Noto Sans SC/시스템 중국어 스택, `:lang(hi)`는 Noto Sans Devanagari/시스템 데바나가리 스택, `:lang(ja)`는 Noto Sans JP/시스템 일본어 스택, `:lang(th)`는 Noto Sans Thai/시스템 태국어 스택으로 덮어쓴다.
511
518
  - Flutter, native shell, 문서 생성기는 JSON 토큰의 hex 값을 기본 입력으로 쓰고 필요할 때 OKLCH를 별도 변환한다.
512
519
 
513
520
  ## Flat UI 계약
@@ -0,0 +1,3 @@
1
+ export type ZdpAdSlotPlacement = 'inline' | 'banner' | 'rail' | 'between-sections';
2
+
3
+ export type ZdpAdSlotState = 'pending' | 'filled' | 'empty' | 'blocked';
@@ -0,0 +1,135 @@
1
+ <script lang="ts">
2
+ import type { ZdpAdSlotPlacement, ZdpAdSlotState } from '../ad-slot';
3
+
4
+ type DescribedBy = string | readonly string[] | null;
5
+
6
+ export let placement: ZdpAdSlotPlacement = 'inline';
7
+ export let state: ZdpAdSlotState = 'pending';
8
+ export let label = 'Advertisement';
9
+ export let fallbackText: string | null = null;
10
+ export let minHeight: string | null = null;
11
+ export let reserved = true;
12
+ export let id: string | null = null;
13
+ export let describedBy: DescribedBy = null;
14
+
15
+ // Only blocked/empty states render a neutral fallback; provider markup stays consumer-owned.
16
+ $: showFallback = state === 'blocked' || state === 'empty';
17
+ $: resolvedFallbackText = fallbackText ?? label;
18
+ $: reservedHeight = reserved ? minHeight ?? defaultMinHeight(placement) : null;
19
+ $: ariaDescribedBy = normalizeIdRefs(describedBy);
20
+
21
+ function defaultMinHeight(currentPlacement: ZdpAdSlotPlacement): string {
22
+ switch (currentPlacement) {
23
+ case 'banner':
24
+ return '5.5rem';
25
+ case 'rail':
26
+ return '12rem';
27
+ case 'between-sections':
28
+ return '4rem';
29
+ default:
30
+ return '4rem';
31
+ }
32
+ }
33
+
34
+ function normalizeIdRefs(value: DescribedBy): string | null {
35
+ if (value === null) {
36
+ return null;
37
+ }
38
+
39
+ if (typeof value === 'string') {
40
+ const normalized = value.trim();
41
+ return normalized ? normalized : null;
42
+ }
43
+
44
+ const normalized = value.map((entry) => entry.trim()).filter(Boolean);
45
+ return normalized.length > 0 ? normalized.join(' ') : null;
46
+ }
47
+ </script>
48
+
49
+ <aside
50
+ class={`zdp-ad-slot zdp-ad-slot--${placement} zdp-ad-slot--${state}${reserved ? ' zdp-ad-slot--reserved' : ''}`}
51
+ id={id ?? undefined}
52
+ aria-label={label}
53
+ aria-describedby={ariaDescribedBy ?? undefined}
54
+ data-zdp-ad-slot
55
+ data-zdp-ad-placement={placement}
56
+ data-zdp-ad-state={state}
57
+ data-zdp-ad-reserved={reserved ? 'true' : 'false'}
58
+ style:min-height={reservedHeight}
59
+ >
60
+ {#if showFallback}
61
+ <p class="zdp-ad-slot__fallback">{resolvedFallbackText}</p>
62
+ {/if}
63
+ <slot />
64
+ </aside>
65
+
66
+ <style>
67
+ .zdp-ad-slot {
68
+ align-content: center;
69
+ align-items: center;
70
+ background: var(--zdp-color-surface-panel);
71
+ border: var(--zdp-control-border-width) solid var(--zdp-color-line-subtle);
72
+ border-radius: var(--zdp-control-radius);
73
+ box-sizing: border-box;
74
+ color: var(--zdp-color-ink-muted);
75
+ display: grid;
76
+ font-family: var(--zdp-font-family-sans);
77
+ justify-items: stretch;
78
+ min-width: 0;
79
+ overflow-wrap: var(--zdp-i18n-overflow-wrap);
80
+ padding: var(--zdp-space-3);
81
+ }
82
+
83
+ .zdp-ad-slot--reserved {
84
+ overflow: hidden;
85
+ }
86
+
87
+ .zdp-ad-slot--banner {
88
+ inline-size: 100%;
89
+ }
90
+
91
+ .zdp-ad-slot--between-sections {
92
+ inline-size: 100%;
93
+ }
94
+
95
+ .zdp-ad-slot--rail {
96
+ align-content: start;
97
+ block-size: 100%;
98
+ inline-size: 100%;
99
+ }
100
+
101
+ .zdp-ad-slot--filled {
102
+ color: var(--zdp-color-ink-normal);
103
+ padding: 0;
104
+ }
105
+
106
+ .zdp-ad-slot--filled :global(*) {
107
+ margin: 0;
108
+ max-inline-size: 100%;
109
+ min-width: 0;
110
+ }
111
+
112
+ .zdp-ad-slot__fallback {
113
+ color: var(--zdp-color-ink-muted);
114
+ font-size: var(--zdp-type-caption-size);
115
+ justify-self: center;
116
+ line-height: var(--zdp-type-caption-line-height);
117
+ margin: 0;
118
+ text-align: center;
119
+ }
120
+
121
+ .zdp-ad-slot--blocked {
122
+ border-color: var(--zdp-color-line-strong);
123
+ border-style: dashed;
124
+ }
125
+
126
+ .zdp-ad-slot--empty .zdp-ad-slot__fallback {
127
+ opacity: 0.72;
128
+ }
129
+
130
+ @media (max-width: 48rem) {
131
+ .zdp-ad-slot--rail {
132
+ block-size: auto;
133
+ }
134
+ }
135
+ </style>
@@ -476,13 +476,13 @@
476
476
  font-family: var(--zdp-font-family-sans);
477
477
  inline-size: 100%;
478
478
  left: 0;
479
- max-block-size: min(18rem, calc(100vh - var(--zdp-space-8)));
479
+ max-block-size: min(18rem, calc(var(--zdp-viewport-block) - var(--zdp-space-8)));
480
480
  min-width: 0;
481
481
  overflow: auto;
482
482
  padding: var(--zdp-space-1);
483
483
  position: absolute;
484
484
  top: calc(100% + var(--zdp-space-2));
485
- z-index: 40;
485
+ z-index: var(--zdp-layer-floating);
486
486
  }
487
487
 
488
488
  .zdp-combobox__listbox {
@@ -208,7 +208,7 @@
208
208
  position: absolute;
209
209
  top: 0;
210
210
  width: calc(var(--zdp-confirm-action-progress) * 100%);
211
- z-index: -1;
211
+ z-index: var(--zdp-layer-behind);
212
212
  }
213
213
 
214
214
  .zdp-confirm-action__thumb {
@@ -162,13 +162,14 @@
162
162
  display: grid;
163
163
  inset: 0;
164
164
  justify-items: center;
165
- padding: var(--zdp-space-4);
165
+ padding-block: max(var(--zdp-space-4), var(--zdp-viewport-safe-block-start)) max(var(--zdp-space-4), var(--zdp-viewport-safe-block-end));
166
+ padding-inline: max(var(--zdp-space-4), var(--zdp-viewport-safe-inline-start)) max(var(--zdp-space-4), var(--zdp-viewport-safe-inline-end));
166
167
  position: fixed;
167
- z-index: 1000;
168
+ z-index: var(--zdp-layer-dialog);
168
169
  }
169
170
 
170
171
  .zdp-dialog__backdrop {
171
- background: rgb(47 36 24 / 0.42);
172
+ background: var(--zdp-color-backdrop-dialog);
172
173
  border: 0;
173
174
  cursor: pointer;
174
175
  inset: 0;
@@ -177,10 +178,6 @@
177
178
  position: fixed;
178
179
  }
179
180
 
180
- :global([data-zdp-theme="dark"]) .zdp-dialog__backdrop {
181
- background: rgb(10 8 5 / 0.72);
182
- }
183
-
184
181
  .zdp-dialog__panel {
185
182
  background: var(--zdp-color-surface-panel);
186
183
  border: var(--zdp-control-border-width) solid var(--zdp-color-line-strong);
@@ -189,7 +186,7 @@
189
186
  color: var(--zdp-color-ink-normal);
190
187
  display: grid;
191
188
  gap: var(--zdp-space-4);
192
- max-height: min(42rem, calc(100vh - var(--zdp-space-8)));
189
+ max-height: min(42rem, calc(var(--zdp-viewport-block) - var(--zdp-space-8)));
193
190
  min-width: 0;
194
191
  overflow: auto;
195
192
  padding: var(--zdp-space-5);
@@ -292,11 +289,12 @@
292
289
  @media (max-width: 520px) {
293
290
  .zdp-dialog {
294
291
  align-items: end;
295
- padding: var(--zdp-space-3);
292
+ padding-block: max(var(--zdp-space-3), var(--zdp-viewport-safe-block-start)) max(var(--zdp-space-3), var(--zdp-viewport-safe-block-end));
293
+ padding-inline: max(var(--zdp-space-3), var(--zdp-viewport-safe-inline-start)) max(var(--zdp-space-3), var(--zdp-viewport-safe-inline-end));
296
294
  }
297
295
 
298
296
  .zdp-dialog__panel {
299
- max-height: calc(100vh - var(--zdp-space-6));
297
+ max-height: calc(var(--zdp-viewport-block) - var(--zdp-space-6));
300
298
  padding: var(--zdp-space-4);
301
299
  }
302
300
  }
@@ -377,13 +377,13 @@
377
377
  font-family: var(--zdp-font-family-sans);
378
378
  gap: var(--zdp-space-1);
379
379
  inline-size: max-content;
380
- max-block-size: min(24rem, calc(100vh - var(--zdp-space-8)));
381
- max-inline-size: min(18rem, calc(100vw - var(--zdp-space-6)));
380
+ max-block-size: min(24rem, calc(var(--zdp-viewport-block) - var(--zdp-space-8)));
381
+ max-inline-size: min(18rem, calc(var(--zdp-viewport-inline) - var(--zdp-space-6)));
382
382
  min-inline-size: 12rem;
383
383
  overflow: auto;
384
384
  padding: var(--zdp-space-1);
385
385
  position: absolute;
386
- z-index: 40;
386
+ z-index: var(--zdp-layer-floating);
387
387
  }
388
388
 
389
389
  .zdp-menu__panel:focus-visible {
@@ -148,13 +148,13 @@
148
148
  font-family: var(--zdp-font-family-sans);
149
149
  gap: var(--zdp-space-3);
150
150
  inline-size: max-content;
151
- max-block-size: min(24rem, calc(100vh - var(--zdp-space-8)));
152
- max-inline-size: min(22rem, calc(100vw - var(--zdp-space-6)));
151
+ max-block-size: min(24rem, calc(var(--zdp-viewport-block) - var(--zdp-space-8)));
152
+ max-inline-size: min(22rem, calc(var(--zdp-viewport-inline) - var(--zdp-space-6)));
153
153
  min-inline-size: 12rem;
154
154
  overflow: auto;
155
155
  padding: var(--zdp-space-3);
156
156
  position: absolute;
157
- z-index: 40;
157
+ z-index: var(--zdp-layer-floating);
158
158
  }
159
159
 
160
160
  .zdp-popover__panel:focus-visible {
@@ -136,12 +136,12 @@
136
136
  .zdp-share-dock {
137
137
  color: var(--zdp-color-ink-normal);
138
138
  font-family: var(--zdp-font-family-sans);
139
- z-index: 20;
139
+ z-index: var(--zdp-layer-share-dock);
140
140
  }
141
141
 
142
142
  .zdp-share-dock--side {
143
143
  position: fixed;
144
- right: max(var(--zdp-space-3), calc((100vw - var(--zdp-breakpoint-desktop)) / 2 + var(--zdp-space-4)));
144
+ right: max(var(--zdp-space-3), var(--zdp-viewport-safe-inline-end), calc((var(--zdp-viewport-inline) - var(--zdp-breakpoint-desktop)) / 2 + var(--zdp-space-4)));
145
145
  top: 40vh;
146
146
  }
147
147
 
@@ -242,9 +242,9 @@
242
242
 
243
243
  @media (max-width: 57.5rem) {
244
244
  .zdp-share-dock--side {
245
- bottom: var(--zdp-space-3);
246
- left: var(--zdp-space-3);
247
- right: var(--zdp-space-3);
245
+ bottom: max(var(--zdp-space-3), var(--zdp-viewport-safe-block-end));
246
+ left: max(var(--zdp-space-3), var(--zdp-viewport-safe-inline-start));
247
+ right: max(var(--zdp-space-3), var(--zdp-viewport-safe-inline-end));
248
248
  top: auto;
249
249
  }
250
250
 
@@ -252,7 +252,7 @@
252
252
  display: flex;
253
253
  flex-wrap: wrap;
254
254
  justify-content: center;
255
- max-inline-size: calc(100vw - var(--zdp-space-6));
255
+ max-inline-size: calc(var(--zdp-viewport-inline) - var(--zdp-space-6));
256
256
  }
257
257
 
258
258
  .zdp-share-dock--rail {
@@ -292,7 +292,7 @@
292
292
  @media (max-width: 42rem) {
293
293
  .zdp-share-dock--side,
294
294
  .zdp-share-dock--bottom {
295
- bottom: var(--zdp-space-2);
295
+ bottom: max(var(--zdp-space-2), var(--zdp-viewport-safe-block-end));
296
296
  }
297
297
 
298
298
  .zdp-share-dock__list {
@@ -156,18 +156,14 @@
156
156
  }
157
157
 
158
158
  .zdp-sheet__backdrop {
159
- background: rgb(47 36 24 / 0.32);
159
+ background: var(--zdp-color-backdrop-sheet);
160
160
  border: 0;
161
161
  cursor: pointer;
162
162
  inset: 0;
163
163
  margin: 0;
164
164
  padding: 0;
165
165
  position: fixed;
166
- z-index: 940;
167
- }
168
-
169
- :global([data-zdp-theme="dark"]) .zdp-sheet__backdrop {
170
- background: rgb(10 8 5 / 0.66);
166
+ z-index: var(--zdp-layer-sheet);
171
167
  }
172
168
 
173
169
  .zdp-sheet {
@@ -178,27 +174,28 @@
178
174
  display: grid;
179
175
  font-family: var(--zdp-font-family-sans);
180
176
  gap: var(--zdp-space-4);
181
- max-block-size: calc(100vh - var(--zdp-space-6));
177
+ max-block-size: calc(var(--zdp-viewport-block) - var(--zdp-space-6) - var(--zdp-viewport-safe-block-start) - var(--zdp-viewport-safe-block-end));
182
178
  min-width: 0;
183
179
  overflow: auto;
184
- padding: var(--zdp-space-5);
180
+ padding-block: var(--zdp-space-5) max(var(--zdp-space-5), var(--zdp-viewport-safe-block-end));
181
+ padding-inline: max(var(--zdp-space-5), var(--zdp-viewport-safe-inline-start)) max(var(--zdp-space-5), var(--zdp-viewport-safe-inline-end));
185
182
  position: fixed;
186
- z-index: 941;
183
+ z-index: calc(var(--zdp-layer-sheet) + 1);
187
184
  }
188
185
 
189
186
  .zdp-sheet--right,
190
187
  .zdp-sheet--left {
191
- block-size: calc(100vh - var(--zdp-space-6));
188
+ block-size: calc(var(--zdp-viewport-block) - var(--zdp-space-6) - var(--zdp-viewport-safe-block-start) - var(--zdp-viewport-safe-block-end));
192
189
  border-radius: var(--zdp-control-radius);
193
- inset-block: var(--zdp-space-3);
190
+ inset-block: max(var(--zdp-space-3), var(--zdp-viewport-safe-block-start)) max(var(--zdp-space-3), var(--zdp-viewport-safe-block-end));
194
191
  }
195
192
 
196
193
  .zdp-sheet--right {
197
- inset-inline-end: var(--zdp-space-3);
194
+ inset-inline-end: max(var(--zdp-space-3), var(--zdp-viewport-safe-inline-end));
198
195
  }
199
196
 
200
197
  .zdp-sheet--left {
201
- inset-inline-start: var(--zdp-space-3);
198
+ inset-inline-start: max(var(--zdp-space-3), var(--zdp-viewport-safe-inline-start));
202
199
  }
203
200
 
204
201
  .zdp-sheet--bottom {
@@ -207,19 +204,19 @@
207
204
  border-radius: var(--zdp-control-radius) var(--zdp-control-radius) 0 0;
208
205
  inset-block-end: 0;
209
206
  inset-inline: 0;
210
- max-block-size: min(34rem, calc(100vh - var(--zdp-space-6)));
207
+ max-block-size: min(34rem, calc(var(--zdp-viewport-block) - var(--zdp-space-6) - var(--zdp-viewport-safe-block-start) - var(--zdp-viewport-safe-block-end)));
211
208
  }
212
209
 
213
210
  .zdp-sheet--sm {
214
- inline-size: min(24rem, calc(100vw - var(--zdp-space-6)));
211
+ inline-size: min(24rem, calc(var(--zdp-viewport-inline) - var(--zdp-space-6) - var(--zdp-viewport-safe-inline-start) - var(--zdp-viewport-safe-inline-end)));
215
212
  }
216
213
 
217
214
  .zdp-sheet--md {
218
- inline-size: min(30rem, calc(100vw - var(--zdp-space-6)));
215
+ inline-size: min(30rem, calc(var(--zdp-viewport-inline) - var(--zdp-space-6) - var(--zdp-viewport-safe-inline-start) - var(--zdp-viewport-safe-inline-end)));
219
216
  }
220
217
 
221
218
  .zdp-sheet--lg {
222
- inline-size: min(38rem, calc(100vw - var(--zdp-space-6)));
219
+ inline-size: min(38rem, calc(var(--zdp-viewport-inline) - var(--zdp-space-6) - var(--zdp-viewport-safe-inline-start) - var(--zdp-viewport-safe-inline-end)));
223
220
  }
224
221
 
225
222
  .zdp-sheet--bottom.zdp-sheet--sm,
@@ -229,7 +226,7 @@
229
226
  }
230
227
 
231
228
  .zdp-sheet--bottom.zdp-sheet--lg {
232
- max-block-size: min(42rem, calc(100vh - var(--zdp-space-6)));
229
+ max-block-size: min(42rem, calc(var(--zdp-viewport-block) - var(--zdp-space-6) - var(--zdp-viewport-safe-block-start) - var(--zdp-viewport-safe-block-end)));
233
230
  }
234
231
 
235
232
  .zdp-sheet:focus-visible {
@@ -325,8 +322,9 @@
325
322
  inline-size: auto;
326
323
  inset-block: auto 0;
327
324
  inset-inline: 0;
328
- max-block-size: min(34rem, calc(100vh - var(--zdp-space-6)));
329
- padding: var(--zdp-space-4);
325
+ max-block-size: min(34rem, calc(var(--zdp-viewport-block) - var(--zdp-space-6) - var(--zdp-viewport-safe-block-start) - var(--zdp-viewport-safe-block-end)));
326
+ padding-block: var(--zdp-space-4) max(var(--zdp-space-4), var(--zdp-viewport-safe-block-end));
327
+ padding-inline: max(var(--zdp-space-4), var(--zdp-viewport-safe-inline-start)) max(var(--zdp-space-4), var(--zdp-viewport-safe-inline-end));
330
328
  }
331
329
  }
332
330
  </style>
@@ -28,7 +28,7 @@
28
28
  border-color var(--zdp-motion-fast) ease,
29
29
  color var(--zdp-motion-fast) ease,
30
30
  opacity var(--zdp-motion-fast) ease;
31
- z-index: 10000;
31
+ z-index: var(--zdp-layer-skip-link);
32
32
  }
33
33
 
34
34
  .zdp-skip-link:focus-visible {
@@ -79,10 +79,10 @@
79
79
  box-sizing: border-box;
80
80
  display: grid;
81
81
  gap: var(--zdp-space-3);
82
- inline-size: min(28rem, calc(100vw - var(--zdp-space-6)));
82
+ inline-size: min(28rem, calc(var(--zdp-viewport-inline) - var(--zdp-space-6)));
83
83
  max-inline-size: 100%;
84
84
  pointer-events: none;
85
- z-index: 50;
85
+ z-index: var(--zdp-layer-toast);
86
86
  }
87
87
 
88
88
  .zdp-status-toast :global(.zdp-toast) {
@@ -102,23 +102,23 @@
102
102
  }
103
103
 
104
104
  .zdp-status-toast--top-start {
105
- left: var(--zdp-space-4);
106
- top: var(--zdp-space-4);
105
+ left: max(var(--zdp-space-4), var(--zdp-viewport-safe-inline-start));
106
+ top: max(var(--zdp-space-4), var(--zdp-viewport-safe-block-start));
107
107
  }
108
108
 
109
109
  .zdp-status-toast--top-end {
110
- right: var(--zdp-space-4);
111
- top: var(--zdp-space-4);
110
+ right: max(var(--zdp-space-4), var(--zdp-viewport-safe-inline-end));
111
+ top: max(var(--zdp-space-4), var(--zdp-viewport-safe-block-start));
112
112
  }
113
113
 
114
114
  .zdp-status-toast--bottom-start {
115
- bottom: var(--zdp-space-4);
116
- left: var(--zdp-space-4);
115
+ bottom: max(var(--zdp-space-4), var(--zdp-viewport-safe-block-end));
116
+ left: max(var(--zdp-space-4), var(--zdp-viewport-safe-inline-start));
117
117
  }
118
118
 
119
119
  .zdp-status-toast--bottom-end {
120
- bottom: var(--zdp-space-4);
121
- right: var(--zdp-space-4);
120
+ bottom: max(var(--zdp-space-4), var(--zdp-viewport-safe-block-end));
121
+ right: max(var(--zdp-space-4), var(--zdp-viewport-safe-inline-end));
122
122
  }
123
123
 
124
124
  @media (max-width: 42rem) {
@@ -126,8 +126,8 @@
126
126
  .zdp-status-toast--top-end,
127
127
  .zdp-status-toast--bottom-start,
128
128
  .zdp-status-toast--bottom-end {
129
- left: var(--zdp-space-3);
130
- right: var(--zdp-space-3);
129
+ left: max(var(--zdp-space-3), var(--zdp-viewport-safe-inline-start));
130
+ right: max(var(--zdp-space-3), var(--zdp-viewport-safe-inline-end));
131
131
  }
132
132
  }
133
133
  </style>
@@ -217,34 +217,31 @@
217
217
  display: grid;
218
218
  font-family: var(--zdp-font-family-sans);
219
219
  gap: var(--zdp-space-4);
220
- max-block-size: calc(100vh - var(--zdp-space-6));
220
+ max-block-size: calc(var(--zdp-viewport-block) - var(--zdp-space-6) - var(--zdp-viewport-safe-block-start) - var(--zdp-viewport-safe-block-end));
221
221
  overflow: auto;
222
- padding: var(--zdp-space-5);
222
+ padding-block: var(--zdp-space-5) max(var(--zdp-space-5), var(--zdp-viewport-safe-block-end));
223
+ padding-inline: max(var(--zdp-space-5), var(--zdp-viewport-safe-inline-start)) max(var(--zdp-space-5), var(--zdp-viewport-safe-inline-end));
223
224
  position: fixed;
224
- z-index: 901;
225
+ z-index: calc(var(--zdp-layer-term-sheet) + 1);
225
226
  }
226
227
 
227
228
  .zdp-term-sheet__backdrop {
228
- background: rgb(47 36 24 / 0.28);
229
+ background: var(--zdp-color-backdrop-term-sheet);
229
230
  border: 0;
230
231
  cursor: pointer;
231
232
  inset: 0;
232
233
  margin: 0;
233
234
  padding: 0;
234
235
  position: fixed;
235
- z-index: 900;
236
- }
237
-
238
- :global([data-zdp-theme="dark"]) .zdp-term-sheet__backdrop {
239
- background: rgb(10 8 5 / 0.64);
236
+ z-index: var(--zdp-layer-term-sheet);
240
237
  }
241
238
 
242
239
  .zdp-term-sheet--right {
243
- block-size: calc(100vh - var(--zdp-space-6));
240
+ block-size: calc(var(--zdp-viewport-block) - var(--zdp-space-6) - var(--zdp-viewport-safe-block-start) - var(--zdp-viewport-safe-block-end));
244
241
  border-radius: var(--zdp-control-radius);
245
- inline-size: min(28rem, calc(100vw - var(--zdp-space-6)));
246
- inset-block: var(--zdp-space-3);
247
- inset-inline-end: var(--zdp-space-3);
242
+ inline-size: min(28rem, calc(var(--zdp-viewport-inline) - var(--zdp-space-6) - var(--zdp-viewport-safe-inline-start) - var(--zdp-viewport-safe-inline-end)));
243
+ inset-block: max(var(--zdp-space-3), var(--zdp-viewport-safe-block-start)) max(var(--zdp-space-3), var(--zdp-viewport-safe-block-end));
244
+ inset-inline-end: max(var(--zdp-space-3), var(--zdp-viewport-safe-inline-end));
248
245
  }
249
246
 
250
247
  .zdp-term-sheet--bottom {
@@ -253,7 +250,7 @@
253
250
  border-radius: var(--zdp-control-radius) var(--zdp-control-radius) 0 0;
254
251
  inset-block-end: 0;
255
252
  inset-inline: 0;
256
- max-block-size: min(34rem, calc(100vh - var(--zdp-space-6)));
253
+ max-block-size: min(34rem, calc(var(--zdp-viewport-block) - var(--zdp-space-6) - var(--zdp-viewport-safe-block-start) - var(--zdp-viewport-safe-block-end)));
257
254
  }
258
255
 
259
256
  .zdp-term-sheet:focus-visible {
@@ -385,8 +382,9 @@
385
382
  inline-size: auto;
386
383
  inset-block: auto 0;
387
384
  inset-inline: 0;
388
- max-block-size: min(34rem, calc(100vh - var(--zdp-space-6)));
389
- padding: var(--zdp-space-4);
385
+ max-block-size: min(34rem, calc(var(--zdp-viewport-block) - var(--zdp-space-6) - var(--zdp-viewport-safe-block-start) - var(--zdp-viewport-safe-block-end)));
386
+ padding-block: var(--zdp-space-4) max(var(--zdp-space-4), var(--zdp-viewport-safe-block-end));
387
+ padding-inline: max(var(--zdp-space-4), var(--zdp-viewport-safe-inline-start)) max(var(--zdp-space-4), var(--zdp-viewport-safe-inline-end));
390
388
  }
391
389
  }
392
390
  </style>
@@ -129,7 +129,7 @@
129
129
  -webkit-user-select: none;
130
130
  user-select: none;
131
131
  white-space: nowrap;
132
- z-index: 30;
132
+ z-index: var(--zdp-layer-floating);
133
133
  }
134
134
 
135
135
  .zdp-tooltip--top {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { default as Accordion } from './components/Accordion.svelte';
2
+ export { default as AdSlot } from './components/AdSlot.svelte';
2
3
  export { default as Avatar } from './components/Avatar.svelte';
3
4
  export { default as Badge } from './components/Badge.svelte';
4
5
  export { default as Breadcrumb } from './components/Breadcrumb.svelte';
@@ -68,6 +69,7 @@ export type { ZdpComboboxOption, ZdpComboboxSize } from './combobox';
68
69
  export type { ZdpCommandFieldSize } from './command';
69
70
  export type { ZdpCodeBlockSize, ZdpCodeBlockTone } from './code';
70
71
  export type { ZdpAccordionItem, ZdpAccordionMode, ZdpDisclosureHeadingLevel } from './disclosure';
72
+ export type { ZdpAdSlotPlacement, ZdpAdSlotState } from './ad-slot';
71
73
  export type {
72
74
  ZdpAvatarSize,
73
75
  ZdpAvatarTone,
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { default as Accordion } from './components/Accordion.svelte';
2
+ export { default as AdSlot } from './components/AdSlot.svelte';
2
3
  export { default as Avatar } from './components/Avatar.svelte';
3
4
  export { default as Badge } from './components/Badge.svelte';
4
5
  export { default as Breadcrumb } from './components/Breadcrumb.svelte';