zdp-design-system 0.43.8

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.
Files changed (110) hide show
  1. package/CHANGELOG.md +449 -0
  2. package/LICENSE +21 -0
  3. package/README.md +568 -0
  4. package/THIRD_PARTY_NOTICES.md +34 -0
  5. package/dist/code.ts +2 -0
  6. package/dist/combobox.ts +9 -0
  7. package/dist/command.ts +1 -0
  8. package/dist/components/Accordion.svelte +97 -0
  9. package/dist/components/Avatar.svelte +90 -0
  10. package/dist/components/Badge.svelte +61 -0
  11. package/dist/components/Breadcrumb.svelte +97 -0
  12. package/dist/components/Button.svelte +163 -0
  13. package/dist/components/Callout.svelte +81 -0
  14. package/dist/components/Card.svelte +151 -0
  15. package/dist/components/CardHeader.svelte +58 -0
  16. package/dist/components/Checkbox.svelte +135 -0
  17. package/dist/components/CodeBlock.svelte +247 -0
  18. package/dist/components/Combobox.svelte +552 -0
  19. package/dist/components/CommandField.svelte +230 -0
  20. package/dist/components/ConfirmAction.svelte +307 -0
  21. package/dist/components/Container.svelte +63 -0
  22. package/dist/components/Dialog.svelte +303 -0
  23. package/dist/components/Disclosure.svelte +176 -0
  24. package/dist/components/Divider.svelte +41 -0
  25. package/dist/components/EmptyState.svelte +79 -0
  26. package/dist/components/ErrorText.svelte +18 -0
  27. package/dist/components/Field.svelte +38 -0
  28. package/dist/components/Grid.svelte +76 -0
  29. package/dist/components/HelpText.svelte +17 -0
  30. package/dist/components/Icon.svelte +45 -0
  31. package/dist/components/IconButton.svelte +162 -0
  32. package/dist/components/IdentityChip.svelte +130 -0
  33. package/dist/components/Inline.svelte +85 -0
  34. package/dist/components/InlineCode.svelte +27 -0
  35. package/dist/components/Input.svelte +109 -0
  36. package/dist/components/Kbd.svelte +63 -0
  37. package/dist/components/KeyValue.svelte +73 -0
  38. package/dist/components/Label.svelte +43 -0
  39. package/dist/components/Link.svelte +70 -0
  40. package/dist/components/LocaleSwitcher.svelte +209 -0
  41. package/dist/components/Menu.svelte +491 -0
  42. package/dist/components/Page.svelte +36 -0
  43. package/dist/components/PageHeader.svelte +93 -0
  44. package/dist/components/Pagination.svelte +297 -0
  45. package/dist/components/Popover.svelte +208 -0
  46. package/dist/components/Progress.svelte +111 -0
  47. package/dist/components/Radio.svelte +132 -0
  48. package/dist/components/Section.svelte +52 -0
  49. package/dist/components/SegmentedControl.svelte +190 -0
  50. package/dist/components/Select.svelte +88 -0
  51. package/dist/components/ShareDock.svelte +304 -0
  52. package/dist/components/Sheet.svelte +332 -0
  53. package/dist/components/ShortcutHint.svelte +52 -0
  54. package/dist/components/Skeleton.svelte +82 -0
  55. package/dist/components/SkipLink.svelte +40 -0
  56. package/dist/components/SortHeader.svelte +138 -0
  57. package/dist/components/Spinner.svelte +82 -0
  58. package/dist/components/Stack.svelte +62 -0
  59. package/dist/components/StatusToast.svelte +133 -0
  60. package/dist/components/Surface.svelte +53 -0
  61. package/dist/components/Switch.svelte +152 -0
  62. package/dist/components/Table.svelte +94 -0
  63. package/dist/components/TableToolbar.svelte +195 -0
  64. package/dist/components/Tabs.svelte +205 -0
  65. package/dist/components/TermSheet.svelte +392 -0
  66. package/dist/components/TermTrigger.svelte +70 -0
  67. package/dist/components/TextScaleControl.svelte +219 -0
  68. package/dist/components/Textarea.svelte +106 -0
  69. package/dist/components/ThemeToggle.svelte +148 -0
  70. package/dist/components/Toast.svelte +180 -0
  71. package/dist/components/Toolbar.svelte +83 -0
  72. package/dist/components/Tooltip.svelte +199 -0
  73. package/dist/components/VisuallyHidden.svelte +18 -0
  74. package/dist/disclosure.ts +11 -0
  75. package/dist/focusable.ts +36 -0
  76. package/dist/identity.ts +5 -0
  77. package/dist/index.d.ts +106 -0
  78. package/dist/index.js +76 -0
  79. package/dist/index.ts +106 -0
  80. package/dist/menu.ts +12 -0
  81. package/dist/modal-layer.ts +108 -0
  82. package/dist/pagination.ts +10 -0
  83. package/dist/preferences.js +14 -0
  84. package/dist/preferences.ts +36 -0
  85. package/dist/progress.ts +4 -0
  86. package/dist/schemas/design-tokens.schema.json +119 -0
  87. package/dist/segmented.ts +8 -0
  88. package/dist/share.d.ts +48 -0
  89. package/dist/share.js +115 -0
  90. package/dist/share.ts +99 -0
  91. package/dist/sheet.ts +3 -0
  92. package/dist/shortcuts.js +125 -0
  93. package/dist/shortcuts.ts +153 -0
  94. package/dist/styles/brand-fonts.css +10 -0
  95. package/dist/styles/components.css +4686 -0
  96. package/dist/styles/expressive-fonts.css +2 -0
  97. package/dist/styles/index.css +2 -0
  98. package/dist/styles/locale-fonts.css +4 -0
  99. package/dist/styles/tokens.css +413 -0
  100. package/dist/table-tools.ts +10 -0
  101. package/dist/term.ts +16 -0
  102. package/dist/theme.ts +2 -0
  103. package/dist/toast.ts +14 -0
  104. package/dist/tokens/zdp.tokens.json +241 -0
  105. package/dist/tokens.js +122 -0
  106. package/dist/tokens.ts +123 -0
  107. package/docs/CONSUMER_CONTRACT.md +482 -0
  108. package/docs/EXTERNAL_UI_ADOPTION.md +141 -0
  109. package/docs/INTERACTIVE_PRIMITIVE_AUDIT.md +127 -0
  110. package/package.json +78 -0
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ export let label: string | null = null;
3
+ export let size: 'sm' | 'md' = 'md';
4
+ export let ariaLabel: string | null = null;
5
+ export let title: string | null = null;
6
+ </script>
7
+
8
+ {#if ariaLabel}
9
+ <span class="zdp-kbd__sr-label">{ariaLabel}</span>
10
+ {/if}
11
+ <kbd
12
+ class={`zdp-kbd zdp-kbd--${size}`}
13
+ aria-hidden={ariaLabel ? 'true' : undefined}
14
+ title={title ?? undefined}
15
+ >
16
+ {#if label !== null}
17
+ {label}
18
+ {:else}
19
+ <slot />
20
+ {/if}
21
+ </kbd>
22
+
23
+ <style>
24
+ .zdp-kbd {
25
+ background: var(--zdp-color-surface-raised);
26
+ border: var(--zdp-control-border-width) solid var(--zdp-color-line-subtle);
27
+ border-radius: var(--zdp-radius-sm);
28
+ box-sizing: border-box;
29
+ color: var(--zdp-color-ink-muted);
30
+ display: inline-grid;
31
+ font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;
32
+ font-weight: var(--zdp-font-weight-medium);
33
+ line-height: 1;
34
+ min-height: 1.45em;
35
+ min-width: 1.45em;
36
+ padding: 0 0.35em;
37
+ place-items: center;
38
+ -webkit-user-select: none;
39
+ user-select: none;
40
+ vertical-align: middle;
41
+ white-space: nowrap;
42
+ }
43
+
44
+ .zdp-kbd__sr-label {
45
+ block-size: 1px;
46
+ clip: rect(0 0 0 0);
47
+ clip-path: inset(50%);
48
+ inline-size: 1px;
49
+ margin: -1px;
50
+ overflow: hidden;
51
+ padding: 0;
52
+ position: absolute;
53
+ white-space: nowrap;
54
+ }
55
+
56
+ .zdp-kbd--sm {
57
+ font-size: 0.78em;
58
+ }
59
+
60
+ .zdp-kbd--md {
61
+ font-size: 0.86em;
62
+ }
63
+ </style>
@@ -0,0 +1,73 @@
1
+ <script lang="ts">
2
+ export let columns: 'one' | 'two' = 'one';
3
+ export let density: 'default' | 'compact' = 'default';
4
+ export let labelledBy: string | null = null;
5
+ </script>
6
+
7
+ <dl
8
+ class={`zdp-key-value zdp-key-value--columns-${columns} zdp-key-value--density-${density}`}
9
+ aria-labelledby={labelledBy ?? undefined}
10
+ >
11
+ <slot />
12
+ </dl>
13
+
14
+ <style>
15
+ .zdp-key-value {
16
+ border: 1px solid var(--zdp-color-line-subtle);
17
+ border-radius: var(--zdp-control-radius);
18
+ color: var(--zdp-color-ink-normal);
19
+ display: grid;
20
+ font-family: var(--zdp-font-family-sans);
21
+ font-size: var(--zdp-type-body-small-size);
22
+ line-height: var(--zdp-type-body-small-line-height);
23
+ margin: 0;
24
+ min-width: 0;
25
+ }
26
+
27
+ .zdp-key-value :global(dt),
28
+ .zdp-key-value :global(dd) {
29
+ border-block-start: 1px solid var(--zdp-color-line-subtle);
30
+ margin: 0;
31
+ min-width: 0;
32
+ padding: var(--zdp-space-3) var(--zdp-space-4);
33
+ }
34
+
35
+ .zdp-key-value :global(dt:first-child),
36
+ .zdp-key-value :global(dt:first-child + dd) {
37
+ border-block-start: 0;
38
+ }
39
+
40
+ .zdp-key-value :global(dt) {
41
+ color: var(--zdp-color-ink-muted);
42
+ font-weight: var(--zdp-font-weight-medium);
43
+ }
44
+
45
+ .zdp-key-value :global(dd) {
46
+ color: var(--zdp-color-ink-strong);
47
+ overflow-wrap: var(--zdp-i18n-overflow-wrap);
48
+ }
49
+
50
+ .zdp-key-value--columns-two {
51
+ grid-template-columns: minmax(10rem, 0.42fr) minmax(0, 1fr);
52
+ }
53
+
54
+ .zdp-key-value--columns-one {
55
+ grid-template-columns: 1fr;
56
+ }
57
+
58
+ .zdp-key-value--density-compact :global(dt),
59
+ .zdp-key-value--density-compact :global(dd) {
60
+ padding: var(--zdp-space-2) var(--zdp-space-3);
61
+ }
62
+
63
+ @media (max-width: 42rem) {
64
+ .zdp-key-value--columns-two {
65
+ grid-template-columns: 1fr;
66
+ }
67
+
68
+ .zdp-key-value--columns-two :global(dd) {
69
+ border-block-start: 0;
70
+ padding-block-start: 0;
71
+ }
72
+ }
73
+ </style>
@@ -0,0 +1,43 @@
1
+ <script lang="ts">
2
+ export let forId: string | null = null;
3
+ export let required = false;
4
+ export let requiredLabel = 'Required';
5
+ </script>
6
+
7
+ <label class="zdp-label" for={forId ?? undefined}>
8
+ <slot />
9
+ {#if required}
10
+ <span class="zdp-label__required" aria-hidden="true">*</span>
11
+ <span class="zdp-label__required-text">({requiredLabel})</span>
12
+ {/if}
13
+ </label>
14
+
15
+ <style>
16
+ .zdp-label {
17
+ color: var(--zdp-color-ink-strong);
18
+ font-family: var(--zdp-font-family-sans);
19
+ font-size: var(--zdp-type-label-size);
20
+ font-weight: var(--zdp-font-weight-medium);
21
+ line-height: var(--zdp-type-label-line-height);
22
+ }
23
+
24
+ .zdp-label__required {
25
+ color: var(--zdp-color-accent-danger);
26
+ margin-left: var(--zdp-space-1);
27
+ -webkit-user-select: none;
28
+ user-select: none;
29
+ }
30
+
31
+ .zdp-label__required-text {
32
+ border: 0;
33
+ clip: rect(0 0 0 0);
34
+ clip-path: inset(50%);
35
+ height: 1px;
36
+ margin: -1px;
37
+ overflow: hidden;
38
+ padding: 0;
39
+ position: absolute;
40
+ white-space: nowrap;
41
+ width: 1px;
42
+ }
43
+ </style>
@@ -0,0 +1,70 @@
1
+ <script lang="ts">
2
+ export let href: string;
3
+ export let tone: 'primary' | 'muted' = 'primary';
4
+ export let target: '_self' | '_blank' | '_parent' | '_top' | undefined = undefined;
5
+ export let rel: string | undefined = undefined;
6
+ export let ariaCurrent:
7
+ | 'page'
8
+ | 'step'
9
+ | 'location'
10
+ | 'date'
11
+ | 'time'
12
+ | 'true'
13
+ | true
14
+ | false
15
+ | undefined = undefined;
16
+ export let ariaKeyShortcuts: string | null = null;
17
+
18
+ $: resolvedRel = target === '_blank' ? rel ?? 'noopener noreferrer' : rel;
19
+ $: resolvedAriaCurrent =
20
+ ariaCurrent === true ? 'true' : ariaCurrent === false ? undefined : ariaCurrent;
21
+ </script>
22
+
23
+ <a
24
+ class={`zdp-link zdp-link--${tone}`}
25
+ {href}
26
+ {target}
27
+ rel={resolvedRel}
28
+ aria-current={resolvedAriaCurrent}
29
+ aria-keyshortcuts={ariaKeyShortcuts ?? undefined}
30
+ >
31
+ <slot />
32
+ </a>
33
+
34
+ <style>
35
+ .zdp-link {
36
+ border-bottom: var(--zdp-control-focus-underline-width) solid transparent;
37
+ color: var(--zdp-color-ink-normal);
38
+ font-family: var(--zdp-font-family-sans);
39
+ font-weight: var(--zdp-font-weight-medium);
40
+ overflow-wrap: var(--zdp-i18n-overflow-wrap);
41
+ text-decoration-line: none;
42
+ transition:
43
+ background-color var(--zdp-motion-fast) ease,
44
+ border-color var(--zdp-motion-fast) ease,
45
+ color var(--zdp-motion-fast) ease;
46
+ }
47
+
48
+ .zdp-link:hover {
49
+ color: var(--zdp-color-ink-strong);
50
+ }
51
+
52
+ .zdp-link:focus-visible {
53
+ background: var(--zdp-color-focus-surface);
54
+ border-bottom-color: var(--zdp-color-focus-line);
55
+ color: var(--zdp-color-focus-text);
56
+ outline: 0;
57
+ }
58
+
59
+ .zdp-link[aria-current] {
60
+ color: var(--zdp-color-ink-strong);
61
+ }
62
+
63
+ .zdp-link--primary {
64
+ color: var(--zdp-color-ink-normal);
65
+ }
66
+
67
+ .zdp-link--muted {
68
+ color: var(--zdp-color-ink-muted);
69
+ }
70
+ </style>
@@ -0,0 +1,209 @@
1
+ <script lang="ts" context="module">
2
+ let nextLocaleSwitcherInstanceId = 0;
3
+ </script>
4
+
5
+ <script lang="ts">
6
+ import {
7
+ zdpLocaleSwitcherOptions,
8
+ type ZdpLocaleSwitcherOption,
9
+ type ZdpLocaleSwitcherSize
10
+ } from '../preferences';
11
+
12
+ export let value = 'en';
13
+ export let options: readonly ZdpLocaleSwitcherOption[] = zdpLocaleSwitcherOptions;
14
+ export let ariaLabel = 'Language';
15
+ export let idPrefix: string | null = null;
16
+ export let size: ZdpLocaleSwitcherSize = 'md';
17
+ export let disabled = false;
18
+ export let onChange:
19
+ | ((event: MouseEvent | KeyboardEvent, option: ZdpLocaleSwitcherOption) => void)
20
+ | null = null;
21
+
22
+ const fallbackIdPrefix = `zdp-locale-switcher-${++nextLocaleSwitcherInstanceId}`;
23
+
24
+ $: enabledOptions = options.filter((option) => !option.disabled);
25
+ $: activeOption =
26
+ enabledOptions.find((option) => option.value === value) ?? enabledOptions[0] ?? options[0] ?? null;
27
+ $: activeValue = activeOption?.value ?? value;
28
+ $: resolvedIdPrefix = toDomId(idPrefix ?? fallbackIdPrefix);
29
+
30
+ function selectOption(event: MouseEvent | KeyboardEvent, option: ZdpLocaleSwitcherOption): void {
31
+ if (disabled || option.disabled) {
32
+ return;
33
+ }
34
+
35
+ const previousValue = value;
36
+ value = option.value;
37
+
38
+ if (previousValue !== option.value) {
39
+ onChange?.(event, option);
40
+ }
41
+ }
42
+
43
+ function handleKeydown(event: KeyboardEvent): void {
44
+ if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) {
45
+ return;
46
+ }
47
+
48
+ const target = event.currentTarget as HTMLElement;
49
+ const controls = Array.from(target.querySelectorAll<HTMLButtonElement>('[role="radio"]:not(:disabled)'));
50
+
51
+ if (controls.length === 0) {
52
+ return;
53
+ }
54
+
55
+ event.preventDefault();
56
+
57
+ const currentIndex = Math.max(
58
+ 0,
59
+ controls.findIndex((control) => control.getAttribute('aria-checked') === 'true')
60
+ );
61
+ const nextIndex = getNextIndex(event.key, currentIndex, controls.length);
62
+ const nextControl = controls[nextIndex];
63
+
64
+ nextControl.focus();
65
+ nextControl.click();
66
+ }
67
+
68
+ function getNextIndex(key: string, currentIndex: number, length: number): number {
69
+ if (key === 'Home') {
70
+ return 0;
71
+ }
72
+
73
+ if (key === 'End') {
74
+ return length - 1;
75
+ }
76
+
77
+ if (key === 'ArrowLeft') {
78
+ return (currentIndex - 1 + length) % length;
79
+ }
80
+
81
+ return (currentIndex + 1) % length;
82
+ }
83
+
84
+ function optionId(option: ZdpLocaleSwitcherOption): string {
85
+ return `${resolvedIdPrefix}-option-${toDomId(option.value)}`;
86
+ }
87
+
88
+ function toDomId(value: string): string {
89
+ return value.trim().replace(/[^a-zA-Z0-9_-]+/g, '-') || 'option';
90
+ }
91
+ </script>
92
+
93
+ <div
94
+ class={`zdp-locale-switcher zdp-locale-switcher--${size}`}
95
+ role="radiogroup"
96
+ aria-label={ariaLabel}
97
+ aria-disabled={disabled ? 'true' : undefined}
98
+ tabindex="-1"
99
+ data-zdp-locale-switcher
100
+ data-zdp-locale-value={activeValue}
101
+ onkeydown={handleKeydown}
102
+ >
103
+ {#each options as option (option.value)}
104
+ <button
105
+ class={`zdp-locale-switcher__item ${
106
+ option.value === activeValue ? 'zdp-locale-switcher__item--selected' : ''
107
+ }`}
108
+ id={optionId(option)}
109
+ type="button"
110
+ role="radio"
111
+ lang={option.lang ?? undefined}
112
+ aria-label={option.ariaLabel ?? option.label}
113
+ aria-checked={option.value === activeValue}
114
+ tabindex={option.value === activeValue ? 0 : -1}
115
+ disabled={disabled || option.disabled}
116
+ data-zdp-locale-option
117
+ data-zdp-locale-option-value={option.value}
118
+ onclick={(event) => selectOption(event, option)}
119
+ >
120
+ <span class="zdp-locale-switcher__label" aria-hidden="true">
121
+ {option.shortLabel ?? option.label}
122
+ </span>
123
+ </button>
124
+ {/each}
125
+ </div>
126
+
127
+ <style>
128
+ .zdp-locale-switcher {
129
+ align-items: center;
130
+ background: var(--zdp-color-surface-panel);
131
+ border: var(--zdp-control-border-width) solid var(--zdp-color-line-subtle);
132
+ border-radius: var(--zdp-control-radius);
133
+ box-sizing: border-box;
134
+ color: var(--zdp-color-ink-normal);
135
+ display: inline-flex;
136
+ flex: 0 0 auto;
137
+ font-family: var(--zdp-font-family-sans);
138
+ gap: var(--zdp-space-1);
139
+ max-width: 100%;
140
+ min-width: 0;
141
+ padding: var(--zdp-space-1);
142
+ }
143
+
144
+ .zdp-locale-switcher__item {
145
+ align-items: center;
146
+ background: transparent;
147
+ border: var(--zdp-control-border-width) solid transparent;
148
+ border-radius: var(--zdp-control-radius);
149
+ box-sizing: border-box;
150
+ color: var(--zdp-color-ink-muted);
151
+ cursor: pointer;
152
+ display: inline-grid;
153
+ font-family: var(--zdp-font-family-sans);
154
+ font-weight: var(--zdp-font-weight-semibold);
155
+ justify-content: center;
156
+ letter-spacing: 0;
157
+ line-height: 1;
158
+ min-width: 0;
159
+ padding: 0 var(--zdp-space-2);
160
+ place-items: center;
161
+ text-align: center;
162
+ transition:
163
+ background-color var(--zdp-motion-fast) ease,
164
+ border-color var(--zdp-motion-fast) ease,
165
+ color var(--zdp-motion-fast) ease;
166
+ -webkit-user-select: none;
167
+ user-select: none;
168
+ }
169
+
170
+ .zdp-locale-switcher--sm .zdp-locale-switcher__item {
171
+ height: var(--zdp-control-icon-sm);
172
+ min-width: calc(var(--zdp-control-icon-sm) + var(--zdp-space-2));
173
+ }
174
+
175
+ .zdp-locale-switcher--md .zdp-locale-switcher__item {
176
+ height: var(--zdp-control-icon-md);
177
+ min-width: calc(var(--zdp-control-icon-md) + var(--zdp-space-2));
178
+ }
179
+
180
+ .zdp-locale-switcher__item:hover:not(:disabled):not([aria-checked='true']) {
181
+ background: var(--zdp-color-surface-raised);
182
+ border-color: var(--zdp-color-line-strong);
183
+ color: var(--zdp-color-ink-strong);
184
+ }
185
+
186
+ .zdp-locale-switcher__item:focus-visible {
187
+ border-color: var(--zdp-color-focus-line);
188
+ outline: var(--zdp-control-focus-outline-width) solid var(--zdp-color-focus-surface);
189
+ outline-offset: var(--zdp-control-focus-outline-offset);
190
+ }
191
+
192
+ .zdp-locale-switcher__item--selected,
193
+ .zdp-locale-switcher__item[aria-checked='true'] {
194
+ background: var(--zdp-color-accent-primary-soft);
195
+ border-color: var(--zdp-color-accent-primary-strong);
196
+ color: var(--zdp-color-ink-strong);
197
+ }
198
+
199
+ .zdp-locale-switcher__item:disabled {
200
+ cursor: not-allowed;
201
+ opacity: 0.56;
202
+ }
203
+
204
+ .zdp-locale-switcher__label {
205
+ display: inline-block;
206
+ line-height: 1;
207
+ white-space: nowrap;
208
+ }
209
+ </style>