@zukhruf/shadcn 0.3.21 → 0.3.23
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 +38 -7
- package/package.json +2 -1
- package/styles.css +11 -0
- package/theme.css +1 -650
package/README.md
CHANGED
|
@@ -81,12 +81,44 @@ Base UI:
|
|
|
81
81
|
|
|
82
82
|
## What the stylesheet adds to stock shadcn/ui
|
|
83
83
|
|
|
84
|
-
The stylesheet has
|
|
84
|
+
The stylesheet has three patches:
|
|
85
85
|
|
|
86
86
|
- **A pointer cursor on enabled buttons.** In Tailwind CSS 4, a button has the default cursor of the browser, not the pointer. The upgrade guide of Tailwind CSS gives a rule that sets the pointer again. The patch is that rule, in `@layer base`.
|
|
87
87
|
- **A cap on the height of a dialog.** A dialog is never taller than the window minus `2rem`, and it scrolls when its content is taller. Thus the buttons at the bottom of a tall dialog stay on the screen. The rule is `max-height: calc(100dvh - 2rem); overflow-y: auto` on `[data-slot="dialog-content"]`. The patch is in `@layer components`.
|
|
88
|
+
- **The width of the mobile sidebar.** On a small screen, the sidebar is in a `Sheet`. The class `data-[side=left]:w-3/4` of the `Sheet` wins over the class `w-(--sidebar-width)` of the sidebar. Thus the sidebar was 3/4 of the window: 292.5px, not 288px, in a window of 390px. The patch sets `width: var(--sidebar-width)` on `[data-slot="sidebar"][data-mobile="true"][data-side]`.
|
|
88
89
|
|
|
89
|
-
|
|
90
|
+
The cursor and the cap are in layers before `utilities`. Thus a utility class of the app, for example `cursor-wait` or `max-h-none`, still changes them.
|
|
91
|
+
|
|
92
|
+
The width patch is in `@layer utilities`, because only a rule in that layer wins over a utility class. Its selector has three attributes, so it wins over the two parts of `data-[side=left]:w-3/4`. The sidebar does not give its `className` to the mobile `Sheet`, so a utility class of the app cannot get to that element. To change the mobile width, write a rule outside of a layer.
|
|
93
|
+
|
|
94
|
+
## Links that look like buttons
|
|
95
|
+
|
|
96
|
+
A control that goes to a different page must stay a link. Do not write `<Button render={<Link />} nativeButton={false}>`. This makes an `<a>` with `role="button"`. A screen reader then calls the link a button, and the Space key activates it.
|
|
97
|
+
|
|
98
|
+
Put the classes of the button on the link:
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { cn } from 'cn';
|
|
102
|
+
|
|
103
|
+
import { buttonVariants } from '@zukhruf/shadcn';
|
|
104
|
+
|
|
105
|
+
<Link
|
|
106
|
+
href="/settings"
|
|
107
|
+
className={cn(buttonVariants({ variant: 'outline', size: 'sm' }))}
|
|
108
|
+
>
|
|
109
|
+
Settings
|
|
110
|
+
</Link>;
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Use `cn` around `buttonVariants`. `Button` merges the classes that conflict through `cn`, which uses tailwind-merge. Without `cn`, the classes that conflict stay on the link, and the link looks different from a button. In one app, the link had a radius of 10px, not 8px, and it was 2px wider than the button.
|
|
114
|
+
|
|
115
|
+
## Use the components well
|
|
116
|
+
|
|
117
|
+
- **Use a component of the package first.** Before you write a new component, look for one in this package. Use it when it does the job.
|
|
118
|
+
- **Keep your own components in the app.** A component that you make from the components of this package belongs to the app. Do not add it to this package. The sync writes over the generated source, and the package holds only the components of shadcn/ui.
|
|
119
|
+
- **Remove the outline of a `Card` with `ring-0`.** `Card` draws its outline with `ring-1`, not with a border. Thus `border-0` does not remove the outline.
|
|
120
|
+
- **Use the standard names of the theme variables.** Set `--primary`, `--background` and the other variables of the [theme](#theme). Do not add a brand prefix, for example `--acme-primary`. The components read only the standard names.
|
|
121
|
+
- **Show an error at the place where it occurs.** Show a form error or a field error next to the field or the action that failed, for example with `FieldError`. Show the error of a background task or of a mutation as a toast. Use `toast` and `Toaster` of this package, which use the toast of Base UI.
|
|
90
122
|
|
|
91
123
|
## Your own components
|
|
92
124
|
|
|
@@ -136,7 +168,7 @@ src/
|
|
|
136
168
|
hooks/ generated: the hooks that the components use
|
|
137
169
|
lib/ generated: the helpers that the components use
|
|
138
170
|
index.ts generated: the entry
|
|
139
|
-
theme.css generated: the CSS variables
|
|
171
|
+
theme.css generated: the CSS variables and the dark variant; imports shadcn/tailwind.css
|
|
140
172
|
styles.css written by hand: imports theme.css, registers dist, holds the patches
|
|
141
173
|
components.json the configuration of the shadcn CLI
|
|
142
174
|
```
|
|
@@ -156,12 +188,11 @@ The sync does these steps, in this order:
|
|
|
156
188
|
|
|
157
189
|
1. It resets `theme.css` to one line: `@import "tw-animate-css";`.
|
|
158
190
|
2. It runs `shadcn add index`, then `shadcn add --all`.
|
|
159
|
-
3. It
|
|
160
|
-
4. It
|
|
161
|
-
5. It formats the generated source with Prettier.
|
|
191
|
+
3. It writes `src/index.ts`: one `export *` line for each component and each hook.
|
|
192
|
+
4. It formats the generated source with Prettier.
|
|
162
193
|
|
|
163
194
|
Known facts about the sync:
|
|
164
195
|
|
|
165
|
-
-
|
|
196
|
+
- `theme.css` keeps the line `@import "shadcn/tailwind.css";`. That file holds the variants and the animations of the components, for example `data-open`. The sync does not copy it. The `shadcn` package is a dependency of this package, so npm installs the file with it, and a new version of `shadcn` gets to each app through npm.
|
|
166
197
|
- `src` does not import `date-fns`, but `date-fns` stays a dependency. The `calendar` item of the registry declares it.
|
|
167
198
|
- One sync in four failed one time, and the cause is not known. A second run passed.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zukhruf/shadcn",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.23",
|
|
4
4
|
"description": "Every shadcn/ui component for Base UI with the nova preset, as one package: import the components from one entry and the styles from one stylesheet.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
"react-is": "^19.3.1",
|
|
77
77
|
"react-resizable-panels": "^4.14.5",
|
|
78
78
|
"recharts": "^3.8.0",
|
|
79
|
+
"shadcn": "^4.21.5",
|
|
79
80
|
"shiki": "^4.5.0",
|
|
80
81
|
"tw-animate-css": "^1.4.0"
|
|
81
82
|
},
|
package/styles.css
CHANGED
|
@@ -16,3 +16,14 @@
|
|
|
16
16
|
overflow-y: auto;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* the mobile sidebar is a Sheet, whose data-[side=…]:w-3/4 (0,2,0) beats the
|
|
22
|
+
* sidebar's w-(--sidebar-width) (0,1,0). Only a utilities-layer rule can beat
|
|
23
|
+
* a utility; (0,3,0) wins without relying on source order.
|
|
24
|
+
*/
|
|
25
|
+
@layer utilities {
|
|
26
|
+
[data-slot='sidebar'][data-mobile='true'][data-side] {
|
|
27
|
+
width: var(--sidebar-width);
|
|
28
|
+
}
|
|
29
|
+
}
|
package/theme.css
CHANGED
|
@@ -1,654 +1,5 @@
|
|
|
1
1
|
@import 'tw-animate-css';
|
|
2
|
-
|
|
3
|
-
@theme inline {
|
|
4
|
-
@keyframes accordion-down {
|
|
5
|
-
from {
|
|
6
|
-
height: 0;
|
|
7
|
-
}
|
|
8
|
-
to {
|
|
9
|
-
height: var(
|
|
10
|
-
--radix-accordion-content-height,
|
|
11
|
-
var(--accordion-panel-height, auto)
|
|
12
|
-
);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
@keyframes accordion-up {
|
|
17
|
-
from {
|
|
18
|
-
height: var(
|
|
19
|
-
--radix-accordion-content-height,
|
|
20
|
-
var(--accordion-panel-height, auto)
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
to {
|
|
24
|
-
height: 0;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/* Custom variants */
|
|
30
|
-
@custom-variant data-open {
|
|
31
|
-
&:where([data-state='open']),
|
|
32
|
-
&:where([data-open]:not([data-open='false'])) {
|
|
33
|
-
@slot;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
@custom-variant data-closed {
|
|
38
|
-
&:where([data-state='closed']),
|
|
39
|
-
&:where([data-closed]:not([data-closed='false'])) {
|
|
40
|
-
@slot;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@custom-variant data-checked {
|
|
45
|
-
&:where([data-state='checked']),
|
|
46
|
-
&:where([data-checked]:not([data-checked='false'])) {
|
|
47
|
-
@slot;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@custom-variant data-unchecked {
|
|
52
|
-
&:where([data-state='unchecked']),
|
|
53
|
-
&:where([data-unchecked]:not([data-unchecked='false'])) {
|
|
54
|
-
@slot;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
@custom-variant data-selected {
|
|
59
|
-
&:where([data-selected='true']) {
|
|
60
|
-
@slot;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
@custom-variant data-disabled {
|
|
65
|
-
&:where([data-disabled='true']),
|
|
66
|
-
&:where([data-disabled]:not([data-disabled='false'])) {
|
|
67
|
-
@slot;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@custom-variant data-active {
|
|
72
|
-
&:where([data-state='active']),
|
|
73
|
-
&:where([data-active]:not([data-active='false'])) {
|
|
74
|
-
@slot;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
@custom-variant data-horizontal {
|
|
79
|
-
&:where([data-orientation='horizontal']) {
|
|
80
|
-
@slot;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
@custom-variant data-vertical {
|
|
85
|
-
&:where([data-orientation='vertical']) {
|
|
86
|
-
@slot;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@utility no-scrollbar {
|
|
91
|
-
-ms-overflow-style: none;
|
|
92
|
-
scrollbar-width: none;
|
|
93
|
-
|
|
94
|
-
&::-webkit-scrollbar {
|
|
95
|
-
display: none;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/* scroll-fade */
|
|
100
|
-
@property --scroll-fade-t {
|
|
101
|
-
syntax: '<length-percentage>';
|
|
102
|
-
inherits: false;
|
|
103
|
-
initial-value: 0px;
|
|
104
|
-
}
|
|
105
|
-
@property --scroll-fade-b {
|
|
106
|
-
syntax: '<length-percentage>';
|
|
107
|
-
inherits: false;
|
|
108
|
-
initial-value: 0px;
|
|
109
|
-
}
|
|
110
|
-
@property --scroll-fade-s {
|
|
111
|
-
syntax: '<length-percentage>';
|
|
112
|
-
inherits: false;
|
|
113
|
-
initial-value: 0px;
|
|
114
|
-
}
|
|
115
|
-
@property --scroll-fade-e {
|
|
116
|
-
syntax: '<length-percentage>';
|
|
117
|
-
inherits: false;
|
|
118
|
-
initial-value: 0px;
|
|
119
|
-
}
|
|
120
|
-
@property --scroll-fade-mask {
|
|
121
|
-
syntax: '*';
|
|
122
|
-
inherits: false;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
@theme inline {
|
|
126
|
-
@keyframes scroll-fade-reveal-t {
|
|
127
|
-
from {
|
|
128
|
-
--scroll-fade-t: 0px;
|
|
129
|
-
}
|
|
130
|
-
to {
|
|
131
|
-
--scroll-fade-t: var(
|
|
132
|
-
--_scroll-fade-size-t,
|
|
133
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
@keyframes scroll-fade-reveal-b {
|
|
138
|
-
from {
|
|
139
|
-
--scroll-fade-b: var(
|
|
140
|
-
--_scroll-fade-size-b,
|
|
141
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
to {
|
|
145
|
-
--scroll-fade-b: 0px;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
@keyframes scroll-fade-reveal-s {
|
|
149
|
-
from {
|
|
150
|
-
--scroll-fade-s: 0px;
|
|
151
|
-
}
|
|
152
|
-
to {
|
|
153
|
-
--scroll-fade-s: var(
|
|
154
|
-
--_scroll-fade-size-s,
|
|
155
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
@keyframes scroll-fade-reveal-e {
|
|
160
|
-
from {
|
|
161
|
-
--scroll-fade-e: var(
|
|
162
|
-
--_scroll-fade-size-e,
|
|
163
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
to {
|
|
167
|
-
--scroll-fade-e: 0px;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
@utility scroll-fade {
|
|
173
|
-
--_scroll-fade-size-t: var(
|
|
174
|
-
--scroll-fade-t-size,
|
|
175
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
176
|
-
);
|
|
177
|
-
--_scroll-fade-size-b: var(
|
|
178
|
-
--scroll-fade-b-size,
|
|
179
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
180
|
-
);
|
|
181
|
-
--scroll-fade-block: linear-gradient(
|
|
182
|
-
to bottom,
|
|
183
|
-
transparent 0,
|
|
184
|
-
#000 var(--scroll-fade-t, 0px),
|
|
185
|
-
#000 calc(100% - var(--scroll-fade-b, 0px)),
|
|
186
|
-
transparent 100%
|
|
187
|
-
);
|
|
188
|
-
-webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
|
|
189
|
-
mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
|
|
190
|
-
-webkit-mask-composite: source-in;
|
|
191
|
-
mask-composite: intersect;
|
|
192
|
-
-webkit-mask-repeat: no-repeat;
|
|
193
|
-
mask-repeat: no-repeat;
|
|
194
|
-
|
|
195
|
-
@supports (animation-timeline: scroll()) {
|
|
196
|
-
animation:
|
|
197
|
-
scroll-fade-reveal-t 1ms ease-in-out,
|
|
198
|
-
scroll-fade-reveal-b 1ms ease-in-out;
|
|
199
|
-
animation-timeline: scroll(self y), scroll(self y);
|
|
200
|
-
animation-range:
|
|
201
|
-
0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
|
|
202
|
-
calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
|
|
203
|
-
animation-fill-mode: both;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
@supports not (animation-timeline: scroll()) {
|
|
207
|
-
--scroll-fade-t: var(--_scroll-fade-size-t);
|
|
208
|
-
--scroll-fade-b: var(--_scroll-fade-size-b);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
@utility scroll-fade-y {
|
|
213
|
-
--_scroll-fade-size-t: var(
|
|
214
|
-
--scroll-fade-t-size,
|
|
215
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
216
|
-
);
|
|
217
|
-
--_scroll-fade-size-b: var(
|
|
218
|
-
--scroll-fade-b-size,
|
|
219
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
220
|
-
);
|
|
221
|
-
--scroll-fade-block: linear-gradient(
|
|
222
|
-
to bottom,
|
|
223
|
-
transparent 0,
|
|
224
|
-
#000 var(--scroll-fade-t, 0px),
|
|
225
|
-
#000 calc(100% - var(--scroll-fade-b, 0px)),
|
|
226
|
-
transparent 100%
|
|
227
|
-
);
|
|
228
|
-
-webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
|
|
229
|
-
mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
|
|
230
|
-
-webkit-mask-composite: source-in;
|
|
231
|
-
mask-composite: intersect;
|
|
232
|
-
-webkit-mask-repeat: no-repeat;
|
|
233
|
-
mask-repeat: no-repeat;
|
|
234
|
-
|
|
235
|
-
@supports (animation-timeline: scroll()) {
|
|
236
|
-
animation:
|
|
237
|
-
scroll-fade-reveal-t 1ms ease-in-out,
|
|
238
|
-
scroll-fade-reveal-b 1ms ease-in-out;
|
|
239
|
-
animation-timeline: scroll(self y), scroll(self y);
|
|
240
|
-
animation-range:
|
|
241
|
-
0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
|
|
242
|
-
calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
|
|
243
|
-
animation-fill-mode: both;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
@supports not (animation-timeline: scroll()) {
|
|
247
|
-
--scroll-fade-t: var(--_scroll-fade-size-t);
|
|
248
|
-
--scroll-fade-b: var(--_scroll-fade-size-b);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
@utility scroll-fade-x {
|
|
253
|
-
--_scroll-fade-size-s: var(
|
|
254
|
-
--scroll-fade-s-size,
|
|
255
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
256
|
-
);
|
|
257
|
-
--_scroll-fade-size-e: var(
|
|
258
|
-
--scroll-fade-e-size,
|
|
259
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
260
|
-
);
|
|
261
|
-
--scroll-fade-inline: linear-gradient(
|
|
262
|
-
to right,
|
|
263
|
-
transparent 0,
|
|
264
|
-
#000 var(--scroll-fade-s, 0px),
|
|
265
|
-
#000 calc(100% - var(--scroll-fade-e, 0px)),
|
|
266
|
-
transparent 100%
|
|
267
|
-
);
|
|
268
|
-
&:where([dir='rtl'], [dir='rtl'] *) {
|
|
269
|
-
--scroll-fade-inline: linear-gradient(
|
|
270
|
-
to left,
|
|
271
|
-
transparent 0,
|
|
272
|
-
#000 var(--scroll-fade-s, 0px),
|
|
273
|
-
#000 calc(100% - var(--scroll-fade-e, 0px)),
|
|
274
|
-
transparent 100%
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
-webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline));
|
|
278
|
-
mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline));
|
|
279
|
-
-webkit-mask-composite: source-in;
|
|
280
|
-
mask-composite: intersect;
|
|
281
|
-
-webkit-mask-repeat: no-repeat;
|
|
282
|
-
mask-repeat: no-repeat;
|
|
283
|
-
|
|
284
|
-
@supports (animation-timeline: scroll()) {
|
|
285
|
-
animation:
|
|
286
|
-
scroll-fade-reveal-s 1ms ease-in-out,
|
|
287
|
-
scroll-fade-reveal-e 1ms ease-in-out;
|
|
288
|
-
animation-timeline: scroll(self inline), scroll(self inline);
|
|
289
|
-
animation-range:
|
|
290
|
-
0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
|
|
291
|
-
calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
|
|
292
|
-
animation-fill-mode: both;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
@supports not (animation-timeline: scroll()) {
|
|
296
|
-
--scroll-fade-s: var(--_scroll-fade-size-s);
|
|
297
|
-
--scroll-fade-e: var(--_scroll-fade-size-e);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
@utility scroll-fade-t {
|
|
302
|
-
--_scroll-fade-size-t: var(
|
|
303
|
-
--scroll-fade-t-size,
|
|
304
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
305
|
-
);
|
|
306
|
-
--scroll-fade-mask: linear-gradient(
|
|
307
|
-
to bottom,
|
|
308
|
-
transparent 0,
|
|
309
|
-
#000 var(--scroll-fade-t, 0px),
|
|
310
|
-
#000 100%
|
|
311
|
-
);
|
|
312
|
-
-webkit-mask-image: var(--scroll-fade-mask);
|
|
313
|
-
mask-image: var(--scroll-fade-mask);
|
|
314
|
-
-webkit-mask-composite: source-in;
|
|
315
|
-
mask-composite: intersect;
|
|
316
|
-
-webkit-mask-repeat: no-repeat;
|
|
317
|
-
mask-repeat: no-repeat;
|
|
318
|
-
|
|
319
|
-
@supports (animation-timeline: scroll()) {
|
|
320
|
-
animation: scroll-fade-reveal-t 1ms ease-in-out;
|
|
321
|
-
animation-timeline: scroll(self y);
|
|
322
|
-
animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
|
|
323
|
-
animation-fill-mode: both;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
@supports not (animation-timeline: scroll()) {
|
|
327
|
-
--scroll-fade-t: var(--_scroll-fade-size-t);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
@utility scroll-fade-b {
|
|
332
|
-
--_scroll-fade-size-b: var(
|
|
333
|
-
--scroll-fade-b-size,
|
|
334
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
335
|
-
);
|
|
336
|
-
--scroll-fade-mask: linear-gradient(
|
|
337
|
-
to bottom,
|
|
338
|
-
#000 0,
|
|
339
|
-
#000 calc(100% - var(--scroll-fade-b, 0px)),
|
|
340
|
-
transparent 100%
|
|
341
|
-
);
|
|
342
|
-
-webkit-mask-image: var(--scroll-fade-mask);
|
|
343
|
-
mask-image: var(--scroll-fade-mask);
|
|
344
|
-
-webkit-mask-composite: source-in;
|
|
345
|
-
mask-composite: intersect;
|
|
346
|
-
-webkit-mask-repeat: no-repeat;
|
|
347
|
-
mask-repeat: no-repeat;
|
|
348
|
-
|
|
349
|
-
@supports (animation-timeline: scroll()) {
|
|
350
|
-
animation: scroll-fade-reveal-b 1ms ease-in-out;
|
|
351
|
-
animation-timeline: scroll(self y);
|
|
352
|
-
animation-range: calc(
|
|
353
|
-
100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
|
|
354
|
-
)
|
|
355
|
-
100%;
|
|
356
|
-
animation-fill-mode: both;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
@supports not (animation-timeline: scroll()) {
|
|
360
|
-
--scroll-fade-b: var(--_scroll-fade-size-b);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
@utility scroll-fade-l {
|
|
365
|
-
--_scroll-fade-size-s: var(
|
|
366
|
-
--scroll-fade-s-size,
|
|
367
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
368
|
-
);
|
|
369
|
-
--scroll-fade-mask: linear-gradient(
|
|
370
|
-
to right,
|
|
371
|
-
transparent 0,
|
|
372
|
-
#000 var(--scroll-fade-s, 0px),
|
|
373
|
-
#000 100%
|
|
374
|
-
);
|
|
375
|
-
-webkit-mask-image: var(--scroll-fade-mask);
|
|
376
|
-
mask-image: var(--scroll-fade-mask);
|
|
377
|
-
-webkit-mask-composite: source-in;
|
|
378
|
-
mask-composite: intersect;
|
|
379
|
-
-webkit-mask-repeat: no-repeat;
|
|
380
|
-
mask-repeat: no-repeat;
|
|
381
|
-
|
|
382
|
-
@supports (animation-timeline: scroll()) {
|
|
383
|
-
animation: scroll-fade-reveal-s 1ms ease-in-out;
|
|
384
|
-
animation-timeline: scroll(self x);
|
|
385
|
-
animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
|
|
386
|
-
animation-fill-mode: both;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
@supports not (animation-timeline: scroll()) {
|
|
390
|
-
--scroll-fade-s: var(--_scroll-fade-size-s);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
@utility scroll-fade-r {
|
|
395
|
-
--_scroll-fade-size-e: var(
|
|
396
|
-
--scroll-fade-e-size,
|
|
397
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
398
|
-
);
|
|
399
|
-
--scroll-fade-mask: linear-gradient(
|
|
400
|
-
to right,
|
|
401
|
-
#000 0,
|
|
402
|
-
#000 calc(100% - var(--scroll-fade-e, 0px)),
|
|
403
|
-
transparent 100%
|
|
404
|
-
);
|
|
405
|
-
-webkit-mask-image: var(--scroll-fade-mask);
|
|
406
|
-
mask-image: var(--scroll-fade-mask);
|
|
407
|
-
-webkit-mask-composite: source-in;
|
|
408
|
-
mask-composite: intersect;
|
|
409
|
-
-webkit-mask-repeat: no-repeat;
|
|
410
|
-
mask-repeat: no-repeat;
|
|
411
|
-
|
|
412
|
-
@supports (animation-timeline: scroll()) {
|
|
413
|
-
animation: scroll-fade-reveal-e 1ms ease-in-out;
|
|
414
|
-
animation-timeline: scroll(self x);
|
|
415
|
-
animation-range: calc(
|
|
416
|
-
100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
|
|
417
|
-
)
|
|
418
|
-
100%;
|
|
419
|
-
animation-fill-mode: both;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
@supports not (animation-timeline: scroll()) {
|
|
423
|
-
--scroll-fade-e: var(--_scroll-fade-size-e);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
@utility scroll-fade-s {
|
|
428
|
-
--_scroll-fade-size-s: var(
|
|
429
|
-
--scroll-fade-s-size,
|
|
430
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
431
|
-
);
|
|
432
|
-
--scroll-fade-mask: linear-gradient(
|
|
433
|
-
to right,
|
|
434
|
-
transparent 0,
|
|
435
|
-
#000 var(--scroll-fade-s, 0px),
|
|
436
|
-
#000 100%
|
|
437
|
-
);
|
|
438
|
-
&:where([dir='rtl'], [dir='rtl'] *) {
|
|
439
|
-
--scroll-fade-mask: linear-gradient(
|
|
440
|
-
to left,
|
|
441
|
-
transparent 0,
|
|
442
|
-
#000 var(--scroll-fade-s, 0px),
|
|
443
|
-
#000 100%
|
|
444
|
-
);
|
|
445
|
-
}
|
|
446
|
-
-webkit-mask-image: var(--scroll-fade-mask);
|
|
447
|
-
mask-image: var(--scroll-fade-mask);
|
|
448
|
-
-webkit-mask-composite: source-in;
|
|
449
|
-
mask-composite: intersect;
|
|
450
|
-
-webkit-mask-repeat: no-repeat;
|
|
451
|
-
mask-repeat: no-repeat;
|
|
452
|
-
|
|
453
|
-
@supports (animation-timeline: scroll()) {
|
|
454
|
-
animation: scroll-fade-reveal-s 1ms ease-in-out;
|
|
455
|
-
animation-timeline: scroll(self inline);
|
|
456
|
-
animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
|
|
457
|
-
animation-fill-mode: both;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
@supports not (animation-timeline: scroll()) {
|
|
461
|
-
--scroll-fade-s: var(--_scroll-fade-size-s);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
@utility scroll-fade-e {
|
|
466
|
-
--_scroll-fade-size-e: var(
|
|
467
|
-
--scroll-fade-e-size,
|
|
468
|
-
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
469
|
-
);
|
|
470
|
-
--scroll-fade-mask: linear-gradient(
|
|
471
|
-
to right,
|
|
472
|
-
#000 0,
|
|
473
|
-
#000 calc(100% - var(--scroll-fade-e, 0px)),
|
|
474
|
-
transparent 100%
|
|
475
|
-
);
|
|
476
|
-
&:where([dir='rtl'], [dir='rtl'] *) {
|
|
477
|
-
--scroll-fade-mask: linear-gradient(
|
|
478
|
-
to left,
|
|
479
|
-
#000 0,
|
|
480
|
-
#000 calc(100% - var(--scroll-fade-e, 0px)),
|
|
481
|
-
transparent 100%
|
|
482
|
-
);
|
|
483
|
-
}
|
|
484
|
-
-webkit-mask-image: var(--scroll-fade-mask);
|
|
485
|
-
mask-image: var(--scroll-fade-mask);
|
|
486
|
-
-webkit-mask-composite: source-in;
|
|
487
|
-
mask-composite: intersect;
|
|
488
|
-
-webkit-mask-repeat: no-repeat;
|
|
489
|
-
mask-repeat: no-repeat;
|
|
490
|
-
|
|
491
|
-
@supports (animation-timeline: scroll()) {
|
|
492
|
-
animation: scroll-fade-reveal-e 1ms ease-in-out;
|
|
493
|
-
animation-timeline: scroll(self inline);
|
|
494
|
-
animation-range: calc(
|
|
495
|
-
100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
|
|
496
|
-
)
|
|
497
|
-
100%;
|
|
498
|
-
animation-fill-mode: both;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
@supports not (animation-timeline: scroll()) {
|
|
502
|
-
--scroll-fade-e: var(--_scroll-fade-size-e);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
@utility scroll-fade-* {
|
|
507
|
-
--scroll-fade-size: calc(var(--spacing) * --value(integer));
|
|
508
|
-
--scroll-fade-size: --value([length], [percentage]);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
@utility scroll-fade-t-* {
|
|
512
|
-
--scroll-fade-t-size: calc(var(--spacing) * --value(integer));
|
|
513
|
-
--scroll-fade-t-size: --value([length], [percentage]);
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
@utility scroll-fade-b-* {
|
|
517
|
-
--scroll-fade-b-size: calc(var(--spacing) * --value(integer));
|
|
518
|
-
--scroll-fade-b-size: --value([length], [percentage]);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
@utility scroll-fade-s-* {
|
|
522
|
-
--scroll-fade-s-size: calc(var(--spacing) * --value(integer));
|
|
523
|
-
--scroll-fade-s-size: --value([length], [percentage]);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
@utility scroll-fade-e-* {
|
|
527
|
-
--scroll-fade-e-size: calc(var(--spacing) * --value(integer));
|
|
528
|
-
--scroll-fade-e-size: --value([length], [percentage]);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
@utility scroll-fade-none {
|
|
532
|
-
--scroll-fade-mask: none;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
/* shimmer */
|
|
536
|
-
@property --shimmer-angle {
|
|
537
|
-
syntax: '<angle>';
|
|
538
|
-
inherits: true;
|
|
539
|
-
initial-value: 20deg;
|
|
540
|
-
}
|
|
541
|
-
@property --shimmer-image {
|
|
542
|
-
syntax: '*';
|
|
543
|
-
inherits: false;
|
|
544
|
-
}
|
|
545
|
-
@property --shimmer-text-fill {
|
|
546
|
-
syntax: '*';
|
|
547
|
-
inherits: false;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
@theme inline {
|
|
551
|
-
@keyframes tw-shimmer {
|
|
552
|
-
from {
|
|
553
|
-
background-position: 100% 0;
|
|
554
|
-
}
|
|
555
|
-
to {
|
|
556
|
-
background-position: 0 0;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
@utility shimmer {
|
|
562
|
-
--_spread: var(--shimmer-spread, calc(3ch + 40px));
|
|
563
|
-
--_base: currentColor;
|
|
564
|
-
--_highlight: var(
|
|
565
|
-
--shimmer-color,
|
|
566
|
-
oklch(from currentColor l c h / calc(alpha* 0.2))
|
|
567
|
-
);
|
|
568
|
-
|
|
569
|
-
background-image: var(
|
|
570
|
-
--shimmer-image,
|
|
571
|
-
linear-gradient(
|
|
572
|
-
calc(90deg + var(--shimmer-angle)),
|
|
573
|
-
var(--_base) calc(50% - var(--_spread)),
|
|
574
|
-
color-mix(in oklch, var(--_highlight), var(--_base) 50%)
|
|
575
|
-
calc(50% - var(--_spread) * 0.5),
|
|
576
|
-
var(--_highlight) 50%,
|
|
577
|
-
color-mix(in oklch, var(--_highlight), var(--_base) 50%)
|
|
578
|
-
calc(50% + var(--_spread) * 0.5),
|
|
579
|
-
var(--_base) calc(50% + var(--_spread))
|
|
580
|
-
)
|
|
581
|
-
);
|
|
582
|
-
background-repeat: no-repeat;
|
|
583
|
-
background-size: calc(200% + var(--_spread) * 2) 100%;
|
|
584
|
-
background-position: 0 0;
|
|
585
|
-
background-clip: text;
|
|
586
|
-
-webkit-background-clip: text;
|
|
587
|
-
-webkit-text-fill-color: var(--shimmer-text-fill, transparent);
|
|
588
|
-
animation: tw-shimmer var(--shimmer-duration, 2s) linear infinite;
|
|
589
|
-
|
|
590
|
-
@variant dark {
|
|
591
|
-
--_highlight: var(
|
|
592
|
-
--shimmer-color,
|
|
593
|
-
oklch(from currentColor max(0.8, calc(l + 0.4)) c h / calc(alpha + 0.4))
|
|
594
|
-
);
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
&:where([dir='rtl'], [dir='rtl'] *) {
|
|
598
|
-
animation-direction: reverse;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
@media (prefers-reduced-motion: reduce) {
|
|
602
|
-
animation: none;
|
|
603
|
-
background-image: none;
|
|
604
|
-
-webkit-text-fill-color: currentColor;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
@utility shimmer-once {
|
|
609
|
-
animation-iteration-count: 1;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
@utility shimmer-reverse {
|
|
613
|
-
animation-direction: reverse;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
@utility shimmer-none {
|
|
617
|
-
--shimmer-image: none;
|
|
618
|
-
--shimmer-text-fill: currentColor;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
@utility shimmer-color-* {
|
|
622
|
-
--shimmer-color: --value(--color, [color]);
|
|
623
|
-
--shimmer-color: color-mix(
|
|
624
|
-
in oklch,
|
|
625
|
-
--value(--color, [color]) calc(--modifier(integer) * 1%),
|
|
626
|
-
transparent
|
|
627
|
-
);
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
@utility shimmer-duration-* {
|
|
631
|
-
--shimmer-duration: calc(--value(integer) * 1ms);
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
@utility shimmer-spread-* {
|
|
635
|
-
--shimmer-spread: calc(var(--spacing) * --value(integer));
|
|
636
|
-
--shimmer-spread: --value([length], [percentage]);
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
@utility shimmer-angle-* {
|
|
640
|
-
--shimmer-angle: calc(--value(integer) * 1deg);
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
/* Kept for backwards compatibility. Unlayered, so it still wins over other
|
|
644
|
-
utilities on a plain .shimmer element. Variants are handled in the utility. */
|
|
645
|
-
@media (prefers-reduced-motion: reduce) {
|
|
646
|
-
.shimmer {
|
|
647
|
-
animation: none;
|
|
648
|
-
background-image: none;
|
|
649
|
-
-webkit-text-fill-color: currentColor;
|
|
650
|
-
}
|
|
651
|
-
}
|
|
2
|
+
@import 'shadcn/tailwind.css';
|
|
652
3
|
|
|
653
4
|
@custom-variant dark (&:is(.dark *));
|
|
654
5
|
|