ionbase-ui 0.4.0 → 0.6.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/README.md +2 -0
- package/dist/components/FullCard.d.ts +65 -0
- package/dist/components/FullCard.d.ts.map +1 -0
- package/dist/components/FullCard.js +41 -0
- package/dist/components/FullCard.js.map +1 -0
- package/dist/components/Header.d.ts +43 -11
- package/dist/components/Header.d.ts.map +1 -1
- package/dist/components/Header.js +61 -9
- package/dist/components/Header.js.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/styles/full-card.css +287 -0
- package/dist/styles/header.css +138 -35
- package/dist/styles/index.css +1 -0
- package/dist/styles/tokens/base.css +24 -23
- package/dist/styles/tokens/elevation.css +6 -6
- package/dist/styles/tokens/theme-dark.css +2 -1
- package/dist/styles/tokens/typography.css +3 -3
- package/dist/tokens/index.d.ts +200 -194
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +165 -160
- package/dist/tokens/index.js.map +1 -1
- package/package.json +1 -1
package/dist/styles/header.css
CHANGED
|
@@ -1,31 +1,46 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Header
|
|
3
3
|
*
|
|
4
|
-
* Measured from Figma `Header` (
|
|
4
|
+
* Measured from Figma `Header` (69:335). Four Device variants, two axes:
|
|
5
5
|
*
|
|
6
|
-
* Desktop
|
|
7
|
-
* Tablet
|
|
8
|
-
* Mobile
|
|
6
|
+
* Desktop 56 tall, padding 8 / 64, end-slot gap 12
|
|
7
|
+
* Tablet 56 tall, padding 8 / 24, end-slot gap 8
|
|
8
|
+
* Mobile-Closed 64 tall, padding 12 / 16, toggle only
|
|
9
|
+
* Mobile-Open as Mobile-Closed, plus the dropped Menu-Container
|
|
9
10
|
*
|
|
10
|
-
* WHY
|
|
11
|
+
* WHY DEVICE IS A MEDIA QUERY AND OPEN IS A PROP
|
|
11
12
|
*
|
|
12
|
-
* Device is the one variant axis in the whole system
|
|
13
|
-
*
|
|
13
|
+
* Device is the one variant axis in the whole system the browser already knows
|
|
14
|
+
* the answer to. Every other component takes its variant from the caller
|
|
14
15
|
* because the caller is the only one who knows; a header is Mobile because the
|
|
15
16
|
* viewport is narrow, and asking React to duplicate that is how the two get out
|
|
16
|
-
* of step.
|
|
17
|
-
*
|
|
17
|
+
* of step. Breakpoints match the Breakpoint collection's own container widths —
|
|
18
|
+
* Tablet below 1216, Mobile below 896.
|
|
18
19
|
*
|
|
19
|
-
*
|
|
20
|
+
* Open/Closed is the opposite: nothing in CSS knows it, so it is a prop, and it
|
|
21
|
+
* arrives here as `[data-open]`.
|
|
22
|
+
*
|
|
23
|
+
* Note the header is taller on Mobile (64) than on Desktop and Tablet (56).
|
|
20
24
|
* That looks inverted but is deliberate in the design: touch targets need the
|
|
21
25
|
* height more than the desktop pointer does.
|
|
26
|
+
*
|
|
27
|
+
* ONE TREE, TWO LAYOUTS
|
|
28
|
+
*
|
|
29
|
+
* `__menu` is `display: contents` above the mobile breakpoint, so `__center`
|
|
30
|
+
* and `__end` are flex items of the bar itself; below it, the same element
|
|
31
|
+
* becomes the absolutely positioned Menu-Container. The slots are therefore
|
|
32
|
+
* rendered once, never duplicated across breakpoints.
|
|
22
33
|
*/
|
|
23
34
|
.ion-header {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
--ion-header-
|
|
27
|
-
--ion-header-
|
|
35
|
+
/* Desktop is the base; the two narrower breakpoints override downward, so a
|
|
36
|
+
* new rung is added in one place rather than three. */
|
|
37
|
+
--ion-header-height: calc(var(--spacing-48) + var(--spacing-8)); /* 56 */
|
|
38
|
+
--ion-header-padding-y: var(--spacing-8);
|
|
39
|
+
--ion-header-padding-x: var(--spacing-64);
|
|
40
|
+
--ion-header-center-gap: var(--spacing-8);
|
|
41
|
+
--ion-header-end-gap: var(--spacing-12);
|
|
28
42
|
|
|
43
|
+
position: relative;
|
|
29
44
|
display: flex;
|
|
30
45
|
align-items: center;
|
|
31
46
|
justify-content: space-between;
|
|
@@ -43,20 +58,18 @@
|
|
|
43
58
|
font-family: var(--font-family-sans);
|
|
44
59
|
}
|
|
45
60
|
|
|
46
|
-
@media (width
|
|
61
|
+
@media (width < 1216px) {
|
|
47
62
|
.ion-header {
|
|
48
|
-
--ion-header-padding-x: var(--spacing-
|
|
63
|
+
--ion-header-padding-x: var(--spacing-24);
|
|
64
|
+
--ion-header-end-gap: var(--spacing-8);
|
|
49
65
|
}
|
|
50
66
|
}
|
|
51
67
|
|
|
52
|
-
@media (width
|
|
68
|
+
@media (width < 896px) {
|
|
53
69
|
.ion-header {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
--ion-header-
|
|
57
|
-
--ion-header-padding-y: var(--spacing-8);
|
|
58
|
-
--ion-header-padding-x: var(--spacing-64);
|
|
59
|
-
--ion-header-end-gap: var(--spacing-12);
|
|
70
|
+
--ion-header-height: var(--spacing-64);
|
|
71
|
+
--ion-header-padding-y: var(--spacing-12);
|
|
72
|
+
--ion-header-padding-x: var(--spacing-16);
|
|
60
73
|
}
|
|
61
74
|
}
|
|
62
75
|
|
|
@@ -69,27 +82,117 @@
|
|
|
69
82
|
}
|
|
70
83
|
|
|
71
84
|
/*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
85
|
+
* Above the mobile breakpoint the wrapper contributes no box of its own — its
|
|
86
|
+
* two children are laid out by the bar. `display: contents` is what makes the
|
|
87
|
+
* single-tree approach possible; without it the slots would need to be either
|
|
88
|
+
* duplicated or moved by script.
|
|
75
89
|
*/
|
|
90
|
+
.ion-header__menu {
|
|
91
|
+
display: contents;
|
|
92
|
+
}
|
|
93
|
+
|
|
76
94
|
.ion-header__center {
|
|
77
|
-
display:
|
|
95
|
+
display: flex;
|
|
78
96
|
align-items: center;
|
|
79
|
-
gap: var(--
|
|
80
|
-
flex: 1 1 auto;
|
|
97
|
+
gap: var(--ion-header-center-gap);
|
|
81
98
|
min-width: 0;
|
|
82
99
|
}
|
|
83
100
|
|
|
84
|
-
@media (width >= 1216px) {
|
|
85
|
-
.ion-header__center {
|
|
86
|
-
display: flex;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
101
|
.ion-header__end {
|
|
91
102
|
display: flex;
|
|
92
103
|
align-items: center;
|
|
93
104
|
gap: var(--ion-header-end-gap);
|
|
94
105
|
flex-shrink: 0;
|
|
95
106
|
}
|
|
107
|
+
|
|
108
|
+
/*
|
|
109
|
+
* The Mobile-Closed / Mobile-Open toggle. Figma builds it from the Icon Button
|
|
110
|
+
* component (Secondary, Small, Square) but the Header owns the instance, so the
|
|
111
|
+
* geometry is stated here rather than reached for across components: 32 square,
|
|
112
|
+
* radius/sm, 16px icon.
|
|
113
|
+
*/
|
|
114
|
+
.ion-header__toggle {
|
|
115
|
+
display: none;
|
|
116
|
+
align-items: center;
|
|
117
|
+
justify-content: center;
|
|
118
|
+
flex-shrink: 0;
|
|
119
|
+
width: var(--spacing-32);
|
|
120
|
+
height: var(--spacing-32);
|
|
121
|
+
padding: 0;
|
|
122
|
+
color: var(--icon-default);
|
|
123
|
+
background-color: var(--surface-default);
|
|
124
|
+
border: var(--border-width-default) solid var(--border-strong);
|
|
125
|
+
border-radius: var(--radius-sm);
|
|
126
|
+
box-shadow: var(--ion-shadow-raised-lifted-xs);
|
|
127
|
+
cursor: pointer;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.ion-header__toggle > svg {
|
|
131
|
+
width: var(--icon-size-sm);
|
|
132
|
+
height: var(--icon-size-sm);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.ion-header__toggle:focus-visible {
|
|
136
|
+
outline: var(--border-width-thick) solid var(--ring-focus);
|
|
137
|
+
outline-offset: var(--spacing-2);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@media (width < 896px) {
|
|
141
|
+
.ion-header__toggle {
|
|
142
|
+
display: inline-flex;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/*
|
|
146
|
+
* Menu-Container. Figma places it at y=67 against a 64-tall bar — a 3px nudge
|
|
147
|
+
* that is on no scale and matches no token, so it is anchored flush to the
|
|
148
|
+
* bar's bottom edge instead. Nothing else in the design depends on the gap.
|
|
149
|
+
*/
|
|
150
|
+
.ion-header__menu {
|
|
151
|
+
position: absolute;
|
|
152
|
+
top: 100%;
|
|
153
|
+
left: 0;
|
|
154
|
+
z-index: 1;
|
|
155
|
+
display: flex;
|
|
156
|
+
flex-direction: column;
|
|
157
|
+
gap: var(--spacing-12);
|
|
158
|
+
width: 100%;
|
|
159
|
+
padding: var(--spacing-12) var(--spacing-8);
|
|
160
|
+
background-color: var(--surface-default);
|
|
161
|
+
border: var(--border-width-default) solid var(--border-default);
|
|
162
|
+
border-radius: var(--radius-md);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.ion-header[data-open] .ion-header__menu {
|
|
166
|
+
display: flex;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.ion-header:not([data-open]) .ion-header__menu {
|
|
170
|
+
display: none;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* Both slots stack full width inside the panel; the end slot keeps its row
|
|
174
|
+
* but shares the width evenly, as the two buttons do in Figma. */
|
|
175
|
+
.ion-header__center {
|
|
176
|
+
flex-direction: column;
|
|
177
|
+
align-items: stretch;
|
|
178
|
+
width: 100%;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.ion-header__end {
|
|
182
|
+
width: 100%;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.ion-header__end > * {
|
|
186
|
+
flex: 1 1 0;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/*
|
|
191
|
+
* Forced-colors: box-shadow is dropped by the OS, so the toggle would lose its
|
|
192
|
+
* only edge. A border in ButtonText keeps it visible.
|
|
193
|
+
*/
|
|
194
|
+
@media (forced-colors: active) {
|
|
195
|
+
.ion-header__toggle {
|
|
196
|
+
border-color: ButtonText;
|
|
197
|
+
}
|
|
198
|
+
}
|
package/dist/styles/index.css
CHANGED
|
@@ -108,6 +108,28 @@
|
|
|
108
108
|
--spacing-80: 80px;
|
|
109
109
|
--spacing-96: 96px;
|
|
110
110
|
--spacing-128: 128px;
|
|
111
|
+
--scale-0: 0px;
|
|
112
|
+
--scale-1: 1px;
|
|
113
|
+
--scale-2: 2px;
|
|
114
|
+
--scale-4: 4px;
|
|
115
|
+
--scale-6: 6px;
|
|
116
|
+
--scale-8: 8px;
|
|
117
|
+
--scale-10: 10px;
|
|
118
|
+
--scale-12: 12px;
|
|
119
|
+
--scale-14: 14px;
|
|
120
|
+
--scale-16: 16px;
|
|
121
|
+
--scale-20: 20px;
|
|
122
|
+
--scale-24: 24px;
|
|
123
|
+
--scale-32: 32px;
|
|
124
|
+
--scale-full: 9999px;
|
|
125
|
+
--font-family-host-grotesk: "Host Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
126
|
+
--font-family-space-mono: "Space Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
127
|
+
--font-family-merriweather: Merriweather, Georgia, "Times New Roman", serif;
|
|
128
|
+
--font-family-stix-two-text: "STIX Two Text", Georgia, "Times New Roman", serif;
|
|
129
|
+
--font-family-sans: "Host Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
130
|
+
--font-family-serif: Merriweather, Georgia, "Times New Roman", serif;
|
|
131
|
+
--font-family-mono: "Space Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
132
|
+
--font-family-serif-display: "STIX Two Text", Georgia, "Times New Roman", serif;
|
|
111
133
|
--font-size-12: 12px;
|
|
112
134
|
--font-size-14: 14px;
|
|
113
135
|
--font-size-16: 16px;
|
|
@@ -122,14 +144,6 @@
|
|
|
122
144
|
--font-size-56: 56px;
|
|
123
145
|
--font-size-64: 64px;
|
|
124
146
|
--font-size-72: 72px;
|
|
125
|
-
--font-family-host-grotesk: "Host Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
126
|
-
--font-family-merriweather: Merriweather, Georgia, "Times New Roman", serif;
|
|
127
|
-
--font-family-space-mono: "Space Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
128
|
-
--font-family-stix-two-text: "STIX Two Text", Georgia, "Times New Roman", serif;
|
|
129
|
-
--font-family-sans: "Host Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
130
|
-
--font-family-serif: Merriweather, Georgia, "Times New Roman", serif;
|
|
131
|
-
--font-family-mono: "Space Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
132
|
-
--font-family-serif-display: "STIX Two Text", Georgia, "Times New Roman", serif;
|
|
133
147
|
--font-weight-400: 400;
|
|
134
148
|
--font-weight-500: 500;
|
|
135
149
|
--font-weight-600: 600;
|
|
@@ -138,20 +152,6 @@
|
|
|
138
152
|
--font-weight-medium: 500;
|
|
139
153
|
--font-weight-semibold: 600;
|
|
140
154
|
--font-weight-bold: 700;
|
|
141
|
-
--scale-0: 0px;
|
|
142
|
-
--scale-1: 1px;
|
|
143
|
-
--scale-2: 2px;
|
|
144
|
-
--scale-4: 4px;
|
|
145
|
-
--scale-6: 6px;
|
|
146
|
-
--scale-8: 8px;
|
|
147
|
-
--scale-10: 10px;
|
|
148
|
-
--scale-12: 12px;
|
|
149
|
-
--scale-14: 14px;
|
|
150
|
-
--scale-16: 16px;
|
|
151
|
-
--scale-20: 20px;
|
|
152
|
-
--scale-24: 24px;
|
|
153
|
-
--scale-32: 32px;
|
|
154
|
-
--scale-full: 9999px;
|
|
155
155
|
--primary-50: #ebf7ff;
|
|
156
156
|
--primary-100: #e2f1fd;
|
|
157
157
|
--primary-200: #c7e4fa;
|
|
@@ -260,7 +260,7 @@
|
|
|
260
260
|
--text-primary: #1c62e3;
|
|
261
261
|
--text-error: #ba1c1c;
|
|
262
262
|
--text-success: #0d7d38;
|
|
263
|
-
--text-warning: #
|
|
263
|
+
--text-warning: #af3e0e;
|
|
264
264
|
--text-information: #4715b2;
|
|
265
265
|
--text-link: #1541b2;
|
|
266
266
|
--text-link-hover: #0e2d8b;
|
|
@@ -271,6 +271,7 @@
|
|
|
271
271
|
--icon-secondary: #384252;
|
|
272
272
|
--icon-tertiary: #4b5563;
|
|
273
273
|
--icon-disabled: #6b7280;
|
|
274
|
+
--icon-placeholder: #9ca3b0;
|
|
274
275
|
--icon-on-color: #ffffff;
|
|
275
276
|
--icon-inverse: #f6f8f9;
|
|
276
277
|
--icon-primary: #1c62e3;
|
|
@@ -34,19 +34,19 @@
|
|
|
34
34
|
0px 8px 8px -4px rgb(0 0 0 / 4%);
|
|
35
35
|
|
|
36
36
|
--ion-shadow-raised-lifted-xs:
|
|
37
|
-
inset 0px -2px 1px 0px rgb(0 0 0 /
|
|
37
|
+
inset 0px -2px 1px 0px rgb(0 0 0 / 12%),
|
|
38
38
|
inset 0px 2px 1px 0px rgb(255 255 255 / 20%),
|
|
39
39
|
0px 1px 1px 0px rgb(7 10 13 / 6%),
|
|
40
40
|
0px 1px 2px 0px rgb(7 10 13 / 4%);
|
|
41
41
|
|
|
42
42
|
--ion-shadow-raised-lifted-sm:
|
|
43
|
-
inset 0px -3px 1px 0px rgb(0 0 0 /
|
|
43
|
+
inset 0px -3px 1px 0px rgb(0 0 0 / 15%),
|
|
44
44
|
inset 0px 3px 1px 0px rgb(255 255 255 / 20%),
|
|
45
45
|
0px 1px 2px 0px rgb(7 10 13 / 8%),
|
|
46
46
|
0px 2px 4px 0px rgb(7 10 13 / 5%);
|
|
47
47
|
|
|
48
48
|
--ion-shadow-raised-lifted-lg:
|
|
49
|
-
inset 0px -4px 2px 0px rgb(0 0 0 /
|
|
49
|
+
inset 0px -4px 2px 0px rgb(0 0 0 / 20%),
|
|
50
50
|
inset 0px 4px 2px 0px rgb(255 255 255 / 20%),
|
|
51
51
|
0px 1px 1px 0px rgb(7 10 13 / 32%),
|
|
52
52
|
0px 1px 2px 0px rgb(7 10 13 / 16%);
|
|
@@ -74,15 +74,15 @@
|
|
|
74
74
|
0px 2px 6px 0px rgb(7 10 13 / 20%);
|
|
75
75
|
|
|
76
76
|
--ion-shadow-raised-flush-xs:
|
|
77
|
-
inset 0px -2px 1px 0px rgb(0 0 0 /
|
|
77
|
+
inset 0px -2px 1px 0px rgb(0 0 0 / 12%),
|
|
78
78
|
inset 0px 2px 1px 0px rgb(255 255 255 / 20%);
|
|
79
79
|
|
|
80
80
|
--ion-shadow-raised-flush-sm:
|
|
81
|
-
inset 0px -3px 1px 0px rgb(0 0 0 /
|
|
81
|
+
inset 0px -3px 1px 0px rgb(0 0 0 / 15%),
|
|
82
82
|
inset 0px 3px 1px 0px rgb(255 255 255 / 20%);
|
|
83
83
|
|
|
84
84
|
--ion-shadow-raised-flush-lg:
|
|
85
|
-
inset 0px -4px 2px 0px rgb(0 0 0 /
|
|
85
|
+
inset 0px -4px 2px 0px rgb(0 0 0 / 20%),
|
|
86
86
|
inset 0px 4px 2px 0px rgb(255 255 255 / 20%);
|
|
87
87
|
|
|
88
88
|
--ion-shadow-raised-flush-xl:
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
--text-default: #f6f8f9;
|
|
7
7
|
--text-secondary: #dde0e4;
|
|
8
8
|
--text-tertiary: #9ca3b0;
|
|
9
|
-
--text-placeholder: #
|
|
9
|
+
--text-placeholder: #4b5563;
|
|
10
10
|
--text-on-color: #000000;
|
|
11
11
|
--text-inverse: #131923;
|
|
12
12
|
--text-primary: #609cf0;
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
--icon-default: #f0f2f4;
|
|
23
23
|
--icon-secondary: #dde0e4;
|
|
24
24
|
--icon-tertiary: #9ca3b0;
|
|
25
|
+
--icon-placeholder: #4b5563;
|
|
25
26
|
--icon-inverse: #131923;
|
|
26
27
|
--icon-primary: #609cf0;
|
|
27
28
|
--icon-error: #f56b6b;
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
.ion-text-h1 {
|
|
17
|
-
font-family: var(--font-family-
|
|
17
|
+
font-family: var(--font-family-sans);
|
|
18
18
|
font-weight: var(--font-weight-semibold);
|
|
19
19
|
font-size: var(--type-h1);
|
|
20
20
|
line-height: var(--type-h1-line-height);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
.ion-text-h2 {
|
|
24
|
-
font-family: var(--font-family-
|
|
24
|
+
font-family: var(--font-family-sans);
|
|
25
25
|
font-weight: var(--font-weight-semibold);
|
|
26
26
|
font-size: var(--type-h2);
|
|
27
27
|
line-height: var(--type-h2-line-height);
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
|
|
86
86
|
.ion-text-caption {
|
|
87
87
|
font-family: var(--font-family-sans);
|
|
88
|
-
font-weight: var(--font-weight-
|
|
88
|
+
font-weight: var(--font-weight-regular);
|
|
89
89
|
font-size: var(--type-caption);
|
|
90
90
|
line-height: var(--type-caption-line-height);
|
|
91
91
|
}
|