@cntyclub/ui-react 0.1.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/dist/chunk-HDGMSYQS.js +26461 -0
- package/dist/chunk-HDGMSYQS.js.map +1 -0
- package/dist/chunk-PR4QN5HX.js +39 -0
- package/dist/chunk-PR4QN5HX.js.map +1 -0
- package/dist/form.d.ts +175 -0
- package/dist/form.js +5207 -0
- package/dist/form.js.map +1 -0
- package/dist/index.d.ts +1462 -0
- package/dist/index.js +81862 -0
- package/dist/index.js.map +1 -0
- package/dist/input-CZvh825j.d.ts +24 -0
- package/dist/qr-code-styling-3Y6LZH6V.js +1123 -0
- package/dist/qr-code-styling-3Y6LZH6V.js.map +1 -0
- package/package.json +79 -0
- package/src/components/form/checkbox-group-field.tsx +101 -0
- package/src/components/form/date-field.tsx +79 -0
- package/src/components/form/date-range-field.tsx +106 -0
- package/src/components/form/form-context.ts +10 -0
- package/src/components/form/form.tsx +54 -0
- package/src/components/form/number-field.tsx +69 -0
- package/src/components/form/select-field.tsx +76 -0
- package/src/components/form/submit-button.tsx +28 -0
- package/src/components/form/text-field.tsx +107 -0
- package/src/components/layout/dashboard-header.tsx +54 -0
- package/src/components/layout/dashboard-panel.tsx +34 -0
- package/src/components/theme-provider.tsx +403 -0
- package/src/components/ui/accordion.tsx +69 -0
- package/src/components/ui/alert-dialog.tsx +169 -0
- package/src/components/ui/alert.tsx +80 -0
- package/src/components/ui/animated-theme-toggler.tsx +265 -0
- package/src/components/ui/app-store-buttons.tsx +182 -0
- package/src/components/ui/aspect-ratio.tsx +23 -0
- package/src/components/ui/autocomplete.tsx +296 -0
- package/src/components/ui/avatar-group.tsx +95 -0
- package/src/components/ui/avatar.tsx +285 -0
- package/src/components/ui/badge-group.tsx +160 -0
- package/src/components/ui/badge.tsx +172 -0
- package/src/components/ui/breadcrumb.tsx +112 -0
- package/src/components/ui/button.tsx +77 -0
- package/src/components/ui/calendar.tsx +137 -0
- package/src/components/ui/card.tsx +244 -0
- package/src/components/ui/carousel.tsx +258 -0
- package/src/components/ui/chart.tsx +379 -0
- package/src/components/ui/checkbox-group.tsx +16 -0
- package/src/components/ui/checkbox.tsx +82 -0
- package/src/components/ui/collapsible.tsx +45 -0
- package/src/components/ui/combobox.tsx +411 -0
- package/src/components/ui/command.tsx +264 -0
- package/src/components/ui/context-menu.tsx +271 -0
- package/src/components/ui/credit-card.tsx +214 -0
- package/src/components/ui/dialog.tsx +196 -0
- package/src/components/ui/drawer.tsx +135 -0
- package/src/components/ui/empty.tsx +127 -0
- package/src/components/ui/featured-icon.tsx +149 -0
- package/src/components/ui/field.tsx +88 -0
- package/src/components/ui/fieldset.tsx +29 -0
- package/src/components/ui/form.tsx +17 -0
- package/src/components/ui/frame.tsx +82 -0
- package/src/components/ui/generic-empty.tsx +142 -0
- package/src/components/ui/group.tsx +97 -0
- package/src/components/ui/horizontal-scroll-fader.tsx +228 -0
- package/src/components/ui/input-group.tsx +102 -0
- package/src/components/ui/input-otp.tsx +96 -0
- package/src/components/ui/input.tsx +66 -0
- package/src/components/ui/item.tsx +198 -0
- package/src/components/ui/kbd.tsx +30 -0
- package/src/components/ui/label.tsx +28 -0
- package/src/components/ui/menu.tsx +312 -0
- package/src/components/ui/menubar.tsx +93 -0
- package/src/components/ui/meter.tsx +67 -0
- package/src/components/ui/multi-select.tsx +308 -0
- package/src/components/ui/navigation-menu.tsx +143 -0
- package/src/components/ui/number-field.tsx +160 -0
- package/src/components/ui/pagination-controls.tsx +74 -0
- package/src/components/ui/pagination.tsx +149 -0
- package/src/components/ui/popover.tsx +119 -0
- package/src/components/ui/preview-card.tsx +55 -0
- package/src/components/ui/progress.tsx +289 -0
- package/src/components/ui/qr-code.tsx +150 -0
- package/src/components/ui/radio-group.tsx +103 -0
- package/src/components/ui/resizable.tsx +56 -0
- package/src/components/ui/scroll-area.tsx +90 -0
- package/src/components/ui/scroller.tsx +38 -0
- package/src/components/ui/section-header.tsx +118 -0
- package/src/components/ui/select.tsx +181 -0
- package/src/components/ui/separator.tsx +23 -0
- package/src/components/ui/sheet.tsx +224 -0
- package/src/components/ui/sidebar.tsx +744 -0
- package/src/components/ui/skeleton.tsx +16 -0
- package/src/components/ui/slider.tsx +108 -0
- package/src/components/ui/smooth-scroll.tsx +143 -0
- package/src/components/ui/social-button.tsx +247 -0
- package/src/components/ui/spinner-on-demand.tsx +32 -0
- package/src/components/ui/spinner.tsx +18 -0
- package/src/components/ui/stat.tsx +187 -0
- package/src/components/ui/stepper.tsx +167 -0
- package/src/components/ui/switch.tsx +56 -0
- package/src/components/ui/table.tsx +126 -0
- package/src/components/ui/tabs.tsx +90 -0
- package/src/components/ui/tag.tsx +229 -0
- package/src/components/ui/target-countdown.tsx +46 -0
- package/src/components/ui/text-editor.tsx +313 -0
- package/src/components/ui/textarea.tsx +51 -0
- package/src/components/ui/timeline.tsx +116 -0
- package/src/components/ui/toast.tsx +268 -0
- package/src/components/ui/toggle-group.tsx +101 -0
- package/src/components/ui/toggle.tsx +45 -0
- package/src/components/ui/toolbar.tsx +89 -0
- package/src/components/ui/tooltip.tsx +102 -0
- package/src/components/ui/vertical-scroll-fader.tsx +250 -0
- package/src/components/ui/video-player.tsx +275 -0
- package/src/components/upload/avatar-upload-base.tsx +131 -0
- package/src/components/upload/image-upload-base.tsx +112 -0
- package/src/form.ts +17 -0
- package/src/index.ts +125 -0
- package/src/lib/hooks/use-callback-ref.ts +15 -0
- package/src/lib/hooks/use-first-render.ts +11 -0
- package/src/lib/hooks/use-hover.ts +53 -0
- package/src/lib/hooks/use-is-tab-active.ts +17 -0
- package/src/lib/hooks/use-media-query.ts +164 -0
- package/src/lib/utils/css.ts +6 -0
- package/src/styles.css +300 -0
- package/src/types/helpers.ts +24 -0
- package/src/types/react.d.ts +7 -0
package/src/styles.css
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Country Club UI Kit — design system stylesheet (Tailwind CSS v4).
|
|
3
|
+
*
|
|
4
|
+
* Usage (in your app's global CSS):
|
|
5
|
+
*
|
|
6
|
+
* @import "tailwindcss";
|
|
7
|
+
* @import "@countryclub/ui-react/styles.css";
|
|
8
|
+
* @source "../node_modules/@countryclub/ui-react/src";
|
|
9
|
+
*
|
|
10
|
+
* Dark mode is driven by the `data-theme="dark"` attribute on <html>.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
@import "tw-animate-css";
|
|
14
|
+
|
|
15
|
+
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
|
|
16
|
+
|
|
17
|
+
@theme inline {
|
|
18
|
+
--animate-skeleton: skeleton 2s -1s infinite linear;
|
|
19
|
+
--animate-qr-scan: qr-scan 2.6s ease-in-out infinite alternate;
|
|
20
|
+
--color-warning-foreground: var(--warning-foreground);
|
|
21
|
+
--color-warning: var(--warning);
|
|
22
|
+
--color-success-foreground: var(--success-foreground);
|
|
23
|
+
--color-success: var(--success);
|
|
24
|
+
--color-info-foreground: var(--info-foreground);
|
|
25
|
+
--color-info: var(--info);
|
|
26
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
27
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
28
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
29
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
30
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
31
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
32
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
33
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
34
|
+
--color-sidebar: var(--sidebar);
|
|
35
|
+
--color-chart-5: var(--chart-5);
|
|
36
|
+
--color-chart-4: var(--chart-4);
|
|
37
|
+
--color-chart-3: var(--chart-3);
|
|
38
|
+
--color-chart-2: var(--chart-2);
|
|
39
|
+
--color-chart-1: var(--chart-1);
|
|
40
|
+
--color-ring: var(--ring);
|
|
41
|
+
--color-input: var(--input);
|
|
42
|
+
--color-border: var(--border);
|
|
43
|
+
--color-destructive: var(--destructive);
|
|
44
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
45
|
+
--color-accent: var(--accent);
|
|
46
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
47
|
+
--color-muted: var(--muted);
|
|
48
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
49
|
+
--color-secondary: var(--secondary);
|
|
50
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
51
|
+
--color-primary: var(--primary);
|
|
52
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
53
|
+
--color-popover: var(--popover);
|
|
54
|
+
--color-card-foreground: var(--card-foreground);
|
|
55
|
+
--color-card: var(--card);
|
|
56
|
+
--color-foreground: var(--foreground);
|
|
57
|
+
--color-background: var(--background);
|
|
58
|
+
--color-brand: var(--brand);
|
|
59
|
+
--color-page-bg: var(--color-page-bg);
|
|
60
|
+
--radius-xs: calc(var(--radius) - 8px);
|
|
61
|
+
--radius-sm: calc(var(--radius) - 6px);
|
|
62
|
+
--radius-md: calc(var(--radius) - 4px);
|
|
63
|
+
--radius-lg: calc(var(--radius) - 2px);
|
|
64
|
+
--radius: var(--radius);
|
|
65
|
+
--radius-xl: calc(var(--radius) + 2px);
|
|
66
|
+
--radius-2xl: calc(var(--radius) + 6px);
|
|
67
|
+
--radius-3xl: calc(var(--radius) + 14px);
|
|
68
|
+
--radius-4xl: calc(var(--radius) + 22px);
|
|
69
|
+
@keyframes skeleton {
|
|
70
|
+
to {
|
|
71
|
+
background-position: -200% 0;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/* The scan band is half the overlay tall with its line at its own center;
|
|
75
|
+
-50% → 150% makes that line sweep exactly edge-to-edge. */
|
|
76
|
+
@keyframes qr-scan {
|
|
77
|
+
from {
|
|
78
|
+
transform: translateY(-50%);
|
|
79
|
+
}
|
|
80
|
+
to {
|
|
81
|
+
transform: translateY(150%);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
--font-sans: "DM Sans", sans-serif;
|
|
85
|
+
--font-serif: "Fraunces", sans-serif;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@utility text-xl {
|
|
89
|
+
@apply font-serif;
|
|
90
|
+
|
|
91
|
+
&.font-sans {
|
|
92
|
+
@apply font-sans;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@utility text-2xl {
|
|
97
|
+
@apply font-serif;
|
|
98
|
+
|
|
99
|
+
&.font-sans {
|
|
100
|
+
@apply font-sans;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@utility text-3xl {
|
|
105
|
+
@apply font-serif;
|
|
106
|
+
|
|
107
|
+
&.font-sans {
|
|
108
|
+
@apply font-sans;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@utility text-4xl {
|
|
113
|
+
@apply font-serif;
|
|
114
|
+
|
|
115
|
+
&.font-sans {
|
|
116
|
+
@apply font-sans;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@utility text-5xl {
|
|
121
|
+
@apply font-serif;
|
|
122
|
+
|
|
123
|
+
&.font-sans {
|
|
124
|
+
@apply font-sans;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@utility text-6xl {
|
|
129
|
+
@apply font-serif;
|
|
130
|
+
|
|
131
|
+
&.font-sans {
|
|
132
|
+
@apply font-sans;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@utility text-7xl {
|
|
137
|
+
@apply font-serif;
|
|
138
|
+
|
|
139
|
+
&.font-sans {
|
|
140
|
+
@apply font-sans;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@utility text-8xl {
|
|
145
|
+
@apply font-serif;
|
|
146
|
+
|
|
147
|
+
&.font-sans {
|
|
148
|
+
@apply font-sans;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@utility text-9xl {
|
|
153
|
+
@apply font-serif;
|
|
154
|
+
|
|
155
|
+
&.font-sans {
|
|
156
|
+
@apply font-sans;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
:root,
|
|
161
|
+
[data-theme="light"] {
|
|
162
|
+
--radius: 0.625rem;
|
|
163
|
+
--accent: rgb(12 10 9 / 0.04);
|
|
164
|
+
--accent-foreground: #120f0e;
|
|
165
|
+
--background: #fffefc;
|
|
166
|
+
--border: rgb(12 10 9 / 0.08);
|
|
167
|
+
--card: #fffefc;
|
|
168
|
+
--card-foreground: #120f0e;
|
|
169
|
+
--destructive: #bf4a37;
|
|
170
|
+
--foreground: #120f0e;
|
|
171
|
+
--info: #4a6fa5;
|
|
172
|
+
--info-foreground: #355280;
|
|
173
|
+
--input: rgb(12 10 9 / 0.1);
|
|
174
|
+
--muted: rgb(12 10 9 / 0.04);
|
|
175
|
+
--muted-foreground: #78716c;
|
|
176
|
+
--popover: #fffefc;
|
|
177
|
+
--popover-foreground: #120f0e;
|
|
178
|
+
--primary: #120f0e;
|
|
179
|
+
--primary-foreground: #fffefc;
|
|
180
|
+
--ring: rgb(12 10 9 / 0.25);
|
|
181
|
+
--secondary: rgb(12 10 9 / 0.04);
|
|
182
|
+
--secondary-foreground: #44403c;
|
|
183
|
+
--success: #3d7a4f;
|
|
184
|
+
--success-foreground: #2d5a3a;
|
|
185
|
+
--warning: #c48a1a;
|
|
186
|
+
--warning-foreground: #92600a;
|
|
187
|
+
--destructive-foreground: #943728;
|
|
188
|
+
--chart-1: #ea580c;
|
|
189
|
+
--chart-2: #0d9488;
|
|
190
|
+
--chart-3: #164e63;
|
|
191
|
+
--chart-4: #fbbf24;
|
|
192
|
+
--chart-5: #f59e0b;
|
|
193
|
+
--sidebar: #f6f4ef;
|
|
194
|
+
--sidebar-foreground: #78716c;
|
|
195
|
+
--sidebar-primary: #92600a;
|
|
196
|
+
--sidebar-primary-foreground: #fffefc;
|
|
197
|
+
--sidebar-accent: rgb(12 10 9 / 0.04);
|
|
198
|
+
--sidebar-accent-foreground: #120f0e;
|
|
199
|
+
--sidebar-border: rgb(12 10 9 / 0.06);
|
|
200
|
+
--sidebar-ring: #d4a84b;
|
|
201
|
+
--brand: #d4a84b;
|
|
202
|
+
--color-page-bg: #f6f4ef;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
[data-theme="dark"] {
|
|
206
|
+
--destructive-foreground: #e8877a;
|
|
207
|
+
--accent: rgb(250 249 246 / 0.04);
|
|
208
|
+
--accent-foreground: #e7e5e4;
|
|
209
|
+
--background: #0c0a09;
|
|
210
|
+
--border: rgb(250 249 246 / 0.06);
|
|
211
|
+
--card: #120f0e;
|
|
212
|
+
--card-foreground: #faf9f6;
|
|
213
|
+
--destructive: #d4644f;
|
|
214
|
+
--foreground: #faf9f6;
|
|
215
|
+
--info: #7ba3d4;
|
|
216
|
+
--info-foreground: #a3c1e8;
|
|
217
|
+
--input: rgb(250 249 246 / 0.08);
|
|
218
|
+
--muted: rgb(250 249 246 / 0.04);
|
|
219
|
+
--muted-foreground: #a8a29e;
|
|
220
|
+
--popover: #120f0e;
|
|
221
|
+
--popover-foreground: #faf9f6;
|
|
222
|
+
--primary: #faf9f6;
|
|
223
|
+
--primary-foreground: #0c0a09;
|
|
224
|
+
--ring: rgb(250 249 246 / 0.25);
|
|
225
|
+
--secondary: rgb(250 249 246 / 0.04);
|
|
226
|
+
--secondary-foreground: #e7e5e4;
|
|
227
|
+
--success: #5aad6b;
|
|
228
|
+
--success-foreground: #7bc98a;
|
|
229
|
+
--warning: #e5b84a;
|
|
230
|
+
--warning-foreground: #f0cc6d;
|
|
231
|
+
--chart-1: #1d4ed8;
|
|
232
|
+
--chart-2: #10b981;
|
|
233
|
+
--chart-3: #f59e0b;
|
|
234
|
+
--chart-4: #a855f7;
|
|
235
|
+
--chart-5: #f43f5e;
|
|
236
|
+
--sidebar: #141110;
|
|
237
|
+
--sidebar-foreground: #a8a29e;
|
|
238
|
+
--sidebar-primary: #d4a84b;
|
|
239
|
+
--sidebar-primary-foreground: #0c0a09;
|
|
240
|
+
--sidebar-accent: rgb(250 249 246 / 0.04);
|
|
241
|
+
--sidebar-accent-foreground: #faf9f6;
|
|
242
|
+
--sidebar-border: rgb(250 249 246 / 0.05);
|
|
243
|
+
--sidebar-ring: #d4a84b;
|
|
244
|
+
--brand: #92600a;
|
|
245
|
+
--color-page-bg: #141110;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@layer base {
|
|
249
|
+
* {
|
|
250
|
+
@apply border-border outline-ring/50;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
body {
|
|
254
|
+
@apply relative m-0 font-sans text-foreground;
|
|
255
|
+
background-color: var(--color-page-bg);
|
|
256
|
+
-webkit-font-smoothing: antialiased;
|
|
257
|
+
-moz-osx-font-smoothing: grayscale;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
iframe {
|
|
261
|
+
color-scheme: normal;
|
|
262
|
+
@apply rounded-lg outline-border;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
@layer utilities {
|
|
267
|
+
/* Forces Tailwind to emit the breakpoint variables that
|
|
268
|
+
`useSubscribeBreakpoints` reads at runtime. Do not remove. */
|
|
269
|
+
.__force-breakpoints {
|
|
270
|
+
content: var(--breakpoint-sm) var(--breakpoint-md) var(--breakpoint-lg)
|
|
271
|
+
var(--breakpoint-xl) var(--breakpoint-2xl);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/*
|
|
276
|
+
* Animated theme toggle (View Transitions API), used by <AnimatedThemeToggler>.
|
|
277
|
+
* Everything is scoped to `html[data-theme-vt="active"]`, which the component
|
|
278
|
+
* sets only while a toggle is in flight — so any other root view transitions
|
|
279
|
+
* in a consuming app (e.g. route transitions) are left untouched.
|
|
280
|
+
*/
|
|
281
|
+
html[data-theme-vt="active"]::view-transition-old(root),
|
|
282
|
+
html[data-theme-vt="active"]::view-transition-new(root) {
|
|
283
|
+
animation: none;
|
|
284
|
+
mix-blend-mode: normal;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/*
|
|
288
|
+
* Start the incoming (new theme) snapshot fully clipped at the toggle origin.
|
|
289
|
+
* Without this there's a one-frame flash of the new theme between the
|
|
290
|
+
* pseudo-elements being created and the JS clip-path animation attaching on
|
|
291
|
+
* `transition.ready`. The component sets --theme-vt-x / --theme-vt-y; the WAAPI
|
|
292
|
+
* animation then takes over from this same collapsed origin (no visible seam).
|
|
293
|
+
*/
|
|
294
|
+
html[data-theme-vt="active"]::view-transition-new(root) {
|
|
295
|
+
clip-path: circle(0 at var(--theme-vt-x, 50%) var(--theme-vt-y, 50%));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
html[data-theme-vt="active"]::view-transition-group(root) {
|
|
299
|
+
animation-duration: var(--theme-toggle-vt-duration, 400ms);
|
|
300
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type AsChildProps<T extends keyof React.JSX.IntrinsicElements> = {
|
|
2
|
+
asChild?: boolean;
|
|
3
|
+
children?: React.ReactNode;
|
|
4
|
+
} & React.PropsWithoutRef<React.JSX.IntrinsicElements[T]>;
|
|
5
|
+
|
|
6
|
+
export type OmitUnknown<T> = {
|
|
7
|
+
[K in keyof T as unknown extends T[K] ? never : K]: T[K];
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type TailOptional<P extends any[]> = P extends [...infer H, infer T]
|
|
11
|
+
? [...H] | [...H, T]
|
|
12
|
+
: never[];
|
|
13
|
+
|
|
14
|
+
export type RequiredSubset<T, K extends keyof T> = Required<Pick<T, K>> &
|
|
15
|
+
Omit<T, K>;
|
|
16
|
+
export type Tail<P extends any[], H extends any[]> = P extends H
|
|
17
|
+
? void
|
|
18
|
+
: P extends [...H, infer T]
|
|
19
|
+
? T
|
|
20
|
+
: void;
|
|
21
|
+
|
|
22
|
+
export type NotNullValues<T> = {
|
|
23
|
+
[K in keyof T]: Exclude<T[K], null>;
|
|
24
|
+
};
|