@azmr/ui 0.1.0 → 0.3.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 +171 -0
- package/dist/avatar.d.ts +58 -0
- package/dist/avatar.js +84 -0
- package/dist/breadcrumb.d.ts +47 -0
- package/dist/breadcrumb.js +120 -0
- package/dist/button-CYt2Zw3D.d.ts +64 -0
- package/dist/button.d.ts +54 -0
- package/dist/button.js +19 -0
- package/dist/chunk-2RIWL363.js +27 -0
- package/dist/chunk-2TQSHVXA.js +12 -0
- package/dist/chunk-7EOSDFS3.js +10 -0
- package/dist/chunk-C2HKIPLQ.js +118 -0
- package/dist/chunk-CAJLW6K2.js +16 -0
- package/dist/chunk-CZJZYN54.js +36 -0
- package/dist/chunk-EE4V6XMB.js +35 -0
- package/dist/chunk-EFHRRLAW.js +211 -0
- package/dist/chunk-GLB75NT3.js +21 -0
- package/dist/chunk-GX2YEJ43.js +36 -0
- package/dist/chunk-LTOLV67A.js +19 -0
- package/dist/chunk-LZMX27IZ.js +10 -0
- package/dist/chunk-NIIDYIZA.js +1 -0
- package/dist/chunk-Q4PPM2SU.js +97 -0
- package/dist/chunk-WVE2E37B.js +20 -0
- package/dist/chunk-XRZHP6BD.js +92 -0
- package/dist/disclosure.d.ts +72 -0
- package/dist/disclosure.js +221 -0
- package/dist/display.d.ts +111 -0
- package/dist/display.js +237 -0
- package/dist/features-dom-MCGKRLN5.js +7 -0
- package/dist/features-max-COBTQCO6.js +7 -0
- package/dist/floating.d.ts +81 -0
- package/dist/floating.js +231 -0
- package/dist/hooks.d.ts +33 -0
- package/dist/hooks.js +55 -0
- package/dist/icons/lucide.d.ts +77 -0
- package/dist/icons/lucide.js +135 -0
- package/dist/icons/mui-map.d.ts +1268 -0
- package/dist/icons/mui-map.js +352 -0
- package/dist/icons.d.ts +48 -0
- package/dist/icons.js +19 -0
- package/dist/index.d.ts +238 -3
- package/dist/index.js +242 -15
- package/dist/input.d.ts +14 -0
- package/dist/input.js +8 -0
- package/dist/layout/mui-map.d.ts +80 -0
- package/dist/layout/mui-map.js +104 -0
- package/dist/layout.d.ts +89 -0
- package/dist/layout.js +455 -0
- package/dist/lib.d.ts +11 -0
- package/dist/lib.js +6 -0
- package/dist/menu.d.ts +105 -0
- package/dist/menu.js +56 -0
- package/dist/modal.d.ts +105 -0
- package/dist/modal.js +273 -0
- package/dist/motion.css +295 -0
- package/dist/motion.d.ts +49 -0
- package/dist/motion.js +48 -0
- package/dist/pagination.d.ts +82 -0
- package/dist/pagination.js +211 -0
- package/dist/presets.d.ts +97 -0
- package/dist/presets.js +94 -0
- package/dist/progress.d.ts +70 -0
- package/dist/progress.js +138 -0
- package/dist/react.d.ts +81 -0
- package/dist/react.js +281 -0
- package/dist/responsive-YJBnvsjt.d.ts +69 -0
- package/dist/scroll-area.d.ts +30 -0
- package/dist/scroll-area.js +80 -0
- package/dist/shared-Fkx-sjPt.d.ts +15 -0
- package/dist/spinner.d.ts +18 -0
- package/dist/spinner.js +39 -0
- package/dist/split-button.d.ts +32 -0
- package/dist/split-button.js +54 -0
- package/dist/stepper.d.ts +27 -0
- package/dist/stepper.js +104 -0
- package/dist/styles.css +24 -0
- package/dist/table.d.ts +52 -0
- package/dist/table.js +124 -0
- package/dist/theme.d.ts +111 -0
- package/dist/theme.js +414 -0
- package/dist/toast.d.ts +77 -0
- package/dist/toast.js +203 -0
- package/dist/toggle.d.ts +55 -0
- package/dist/toggle.js +88 -0
- package/dist/tokens.css +337 -0
- package/dist/transition.d.ts +51 -0
- package/dist/transition.js +79 -0
- package/dist/types-BBudf463.d.ts +39 -0
- package/dist/typography/mui-map.d.ts +91 -0
- package/dist/typography/mui-map.js +62 -0
- package/dist/typography.d.ts +90 -0
- package/dist/typography.js +193 -0
- package/dist/useSignal-C-3ZGURN.d.ts +21 -0
- package/dist/variants-De0c0ucO.d.ts +60 -0
- package/package.json +179 -13
package/dist/motion.css
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Motion presets. CSS-first: every preset is a class, driven by the motion tokens (duration and easing
|
|
3
|
+
* come from tokens.css, so a theme or reduced motion changes them everywhere).
|
|
4
|
+
*
|
|
5
|
+
* Rules (checked by tests):
|
|
6
|
+
* - Keyframes animate only transform, scale, opacity, clip-path and (for the SVG tick) stroke-dashoffset;
|
|
7
|
+
* collapse animates grid-template-rows. Nothing here animates width, height, margin or position.
|
|
8
|
+
* - Under prefers-reduced-motion every slide and scale becomes a plain fade, and the rest stop.
|
|
9
|
+
*
|
|
10
|
+
* Use the classes directly (`motion-fade-in`) or through `motionPresets` from `@azmr/ui/presets`.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
@keyframes azmr-fade-in {
|
|
14
|
+
from {
|
|
15
|
+
opacity: 0;
|
|
16
|
+
}
|
|
17
|
+
to {
|
|
18
|
+
opacity: 1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@keyframes azmr-fade-out {
|
|
23
|
+
from {
|
|
24
|
+
opacity: 1;
|
|
25
|
+
}
|
|
26
|
+
to {
|
|
27
|
+
opacity: 0;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@keyframes azmr-scale-in {
|
|
32
|
+
from {
|
|
33
|
+
opacity: 0;
|
|
34
|
+
transform: scale(0.95);
|
|
35
|
+
}
|
|
36
|
+
to {
|
|
37
|
+
opacity: 1;
|
|
38
|
+
transform: scale(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@keyframes azmr-scale-out {
|
|
43
|
+
from {
|
|
44
|
+
opacity: 1;
|
|
45
|
+
transform: scale(1);
|
|
46
|
+
}
|
|
47
|
+
to {
|
|
48
|
+
opacity: 0;
|
|
49
|
+
transform: scale(0.95);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@keyframes azmr-slide-up-in {
|
|
54
|
+
from {
|
|
55
|
+
opacity: 0;
|
|
56
|
+
transform: translateY(0.5rem);
|
|
57
|
+
}
|
|
58
|
+
to {
|
|
59
|
+
opacity: 1;
|
|
60
|
+
transform: translateY(0);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@keyframes azmr-slide-up-out {
|
|
65
|
+
from {
|
|
66
|
+
opacity: 1;
|
|
67
|
+
transform: translateY(0);
|
|
68
|
+
}
|
|
69
|
+
to {
|
|
70
|
+
opacity: 0;
|
|
71
|
+
transform: translateY(-0.5rem);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@keyframes azmr-slide-down-in {
|
|
76
|
+
from {
|
|
77
|
+
opacity: 0;
|
|
78
|
+
transform: translateY(-0.5rem);
|
|
79
|
+
}
|
|
80
|
+
to {
|
|
81
|
+
opacity: 1;
|
|
82
|
+
transform: translateY(0);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@keyframes azmr-slide-down-out {
|
|
87
|
+
from {
|
|
88
|
+
opacity: 1;
|
|
89
|
+
transform: translateY(0);
|
|
90
|
+
}
|
|
91
|
+
to {
|
|
92
|
+
opacity: 0;
|
|
93
|
+
transform: translateY(0.5rem);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@keyframes azmr-slide-left-in {
|
|
98
|
+
from {
|
|
99
|
+
opacity: 0;
|
|
100
|
+
transform: translateX(0.5rem);
|
|
101
|
+
}
|
|
102
|
+
to {
|
|
103
|
+
opacity: 1;
|
|
104
|
+
transform: translateX(0);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@keyframes azmr-slide-left-out {
|
|
109
|
+
from {
|
|
110
|
+
opacity: 1;
|
|
111
|
+
transform: translateX(0);
|
|
112
|
+
}
|
|
113
|
+
to {
|
|
114
|
+
opacity: 0;
|
|
115
|
+
transform: translateX(-0.5rem);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@keyframes azmr-slide-right-in {
|
|
120
|
+
from {
|
|
121
|
+
opacity: 0;
|
|
122
|
+
transform: translateX(-0.5rem);
|
|
123
|
+
}
|
|
124
|
+
to {
|
|
125
|
+
opacity: 1;
|
|
126
|
+
transform: translateX(0);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@keyframes azmr-slide-right-out {
|
|
131
|
+
from {
|
|
132
|
+
opacity: 1;
|
|
133
|
+
transform: translateX(0);
|
|
134
|
+
}
|
|
135
|
+
to {
|
|
136
|
+
opacity: 0;
|
|
137
|
+
transform: translateX(0.5rem);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@keyframes azmr-shimmer {
|
|
142
|
+
from {
|
|
143
|
+
transform: translateX(-100%);
|
|
144
|
+
}
|
|
145
|
+
to {
|
|
146
|
+
transform: translateX(100%);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@keyframes azmr-check-draw {
|
|
151
|
+
from {
|
|
152
|
+
stroke-dashoffset: 24;
|
|
153
|
+
}
|
|
154
|
+
to {
|
|
155
|
+
stroke-dashoffset: 0;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* Enter eases out (arrives fast, settles); exit is shorter and eases in. */
|
|
160
|
+
.motion-fade-in {
|
|
161
|
+
animation: azmr-fade-in var(--motion-duration-base) var(--motion-ease-decelerate) both;
|
|
162
|
+
}
|
|
163
|
+
.motion-fade-out {
|
|
164
|
+
animation: azmr-fade-out var(--motion-duration-fast) var(--motion-ease-accelerate) both;
|
|
165
|
+
}
|
|
166
|
+
.motion-scale-in {
|
|
167
|
+
animation: azmr-scale-in var(--motion-duration-base) var(--motion-ease-decelerate) both;
|
|
168
|
+
}
|
|
169
|
+
.motion-scale-out {
|
|
170
|
+
animation: azmr-scale-out var(--motion-duration-fast) var(--motion-ease-accelerate) both;
|
|
171
|
+
}
|
|
172
|
+
.motion-slide-up-in {
|
|
173
|
+
animation: azmr-slide-up-in var(--motion-duration-base) var(--motion-ease-decelerate) both;
|
|
174
|
+
}
|
|
175
|
+
.motion-slide-up-out {
|
|
176
|
+
animation: azmr-slide-up-out var(--motion-duration-fast) var(--motion-ease-accelerate) both;
|
|
177
|
+
}
|
|
178
|
+
.motion-slide-down-in {
|
|
179
|
+
animation: azmr-slide-down-in var(--motion-duration-base) var(--motion-ease-decelerate) both;
|
|
180
|
+
}
|
|
181
|
+
.motion-slide-down-out {
|
|
182
|
+
animation: azmr-slide-down-out var(--motion-duration-fast) var(--motion-ease-accelerate) both;
|
|
183
|
+
}
|
|
184
|
+
.motion-slide-left-in {
|
|
185
|
+
animation: azmr-slide-left-in var(--motion-duration-base) var(--motion-ease-decelerate) both;
|
|
186
|
+
}
|
|
187
|
+
.motion-slide-left-out {
|
|
188
|
+
animation: azmr-slide-left-out var(--motion-duration-fast) var(--motion-ease-accelerate) both;
|
|
189
|
+
}
|
|
190
|
+
.motion-slide-right-in {
|
|
191
|
+
animation: azmr-slide-right-in var(--motion-duration-base) var(--motion-ease-decelerate) both;
|
|
192
|
+
}
|
|
193
|
+
.motion-slide-right-out {
|
|
194
|
+
animation: azmr-slide-right-out var(--motion-duration-fast) var(--motion-ease-accelerate) both;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/*
|
|
198
|
+
* Collapse: animates grid-template-rows between 0fr and 1fr, so the height is never measured in
|
|
199
|
+
* JavaScript. The inner element must be able to shrink to nothing.
|
|
200
|
+
*/
|
|
201
|
+
.motion-collapse {
|
|
202
|
+
display: grid;
|
|
203
|
+
grid-template-rows: 0fr;
|
|
204
|
+
transition: grid-template-rows var(--motion-duration-base) var(--motion-ease-standard);
|
|
205
|
+
}
|
|
206
|
+
.motion-collapse[data-state="open"] {
|
|
207
|
+
grid-template-rows: 1fr;
|
|
208
|
+
}
|
|
209
|
+
.motion-collapse-inner {
|
|
210
|
+
min-height: 0;
|
|
211
|
+
overflow: hidden;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* Stagger: each item enters a step after the one before it. `--stagger-index` is set by <Stagger>. */
|
|
215
|
+
.motion-stagger > .motion-stagger-item {
|
|
216
|
+
animation: azmr-slide-up-in var(--motion-duration-base) var(--motion-ease-decelerate) both;
|
|
217
|
+
animation-delay: calc(var(--stagger-index, 0) * var(--motion-stagger-step));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Skeleton shimmer: a soft highlight sweeps across, moved with transform only. */
|
|
221
|
+
.motion-shimmer {
|
|
222
|
+
position: relative;
|
|
223
|
+
overflow: hidden;
|
|
224
|
+
}
|
|
225
|
+
.motion-shimmer::after {
|
|
226
|
+
content: "";
|
|
227
|
+
position: absolute;
|
|
228
|
+
inset: 0;
|
|
229
|
+
transform: translateX(-100%);
|
|
230
|
+
background: linear-gradient(
|
|
231
|
+
90deg,
|
|
232
|
+
transparent,
|
|
233
|
+
color-mix(in oklab, var(--foreground) 8%, transparent),
|
|
234
|
+
transparent
|
|
235
|
+
);
|
|
236
|
+
animation: azmr-shimmer var(--motion-duration-ambient) var(--motion-ease-standard) infinite;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* Success tick: the stroke draws itself. The path has pathLength 24. */
|
|
240
|
+
.motion-check path {
|
|
241
|
+
stroke-dasharray: 24;
|
|
242
|
+
stroke-dashoffset: 0;
|
|
243
|
+
animation: azmr-check-draw var(--motion-duration-slow) var(--motion-ease-decelerate) both;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/* Page transitions (React <ViewTransition>, the View Transitions API): a cross-fade, opacity only. */
|
|
247
|
+
::view-transition-old(root) {
|
|
248
|
+
animation: azmr-fade-out var(--motion-duration-fast) var(--motion-ease-accelerate) both;
|
|
249
|
+
}
|
|
250
|
+
::view-transition-new(root) {
|
|
251
|
+
animation: azmr-fade-in var(--motion-duration-base) var(--motion-ease-decelerate) both;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/* Reduced motion: no movement. Slides and scales become a fade; the rest stop or finish at once. */
|
|
255
|
+
@media (prefers-reduced-motion: reduce) {
|
|
256
|
+
.motion-slide-up-in,
|
|
257
|
+
.motion-slide-down-in,
|
|
258
|
+
.motion-slide-left-in,
|
|
259
|
+
.motion-slide-right-in,
|
|
260
|
+
.motion-scale-in {
|
|
261
|
+
animation-name: azmr-fade-in;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.motion-slide-up-out,
|
|
265
|
+
.motion-slide-down-out,
|
|
266
|
+
.motion-slide-left-out,
|
|
267
|
+
.motion-slide-right-out,
|
|
268
|
+
.motion-scale-out {
|
|
269
|
+
animation-name: azmr-fade-out;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.motion-stagger > .motion-stagger-item {
|
|
273
|
+
animation-name: azmr-fade-in;
|
|
274
|
+
animation-delay: 0s;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.motion-shimmer::after {
|
|
278
|
+
animation: none;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.motion-check path {
|
|
282
|
+
animation: none;
|
|
283
|
+
stroke-dashoffset: 0;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.motion-collapse {
|
|
287
|
+
transition: none;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
::view-transition-group(*),
|
|
291
|
+
::view-transition-old(*),
|
|
292
|
+
::view-transition-new(*) {
|
|
293
|
+
animation-duration: var(--motion-duration-instant);
|
|
294
|
+
}
|
|
295
|
+
}
|
package/dist/motion.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export { AnimatePresence, Reorder, animate, m, useAnimate, useDragControls, useInView, useMotionValue, useSpring, useTransform } from 'motion/react';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
interface MotionProviderProps {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
/**
|
|
8
|
+
* What the `m` components can do. `dom` (default): animation, variants, hover, tap and exit. `max`
|
|
9
|
+
* adds layout animation, drag and reorder, at a larger download. Either loads on demand.
|
|
10
|
+
*/
|
|
11
|
+
features?: "dom" | "max";
|
|
12
|
+
/** Forbid the full `motion` component inside (use `m`), so the whole bundle is never pulled in by accident. Default true. */
|
|
13
|
+
strict?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Sets up the `motion` library the cheap way: `LazyMotion` loads the animation features after first
|
|
17
|
+
* render instead of in your main bundle, and `MotionConfig reducedMotion="user"` makes every
|
|
18
|
+
* animation inside follow the system setting (movement is skipped, fades still play). Wrap the part
|
|
19
|
+
* of the app that uses `m`.
|
|
20
|
+
*/
|
|
21
|
+
declare function MotionProvider({ children, features, strict }: MotionProviderProps): react.JSX.Element;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Spring presets for the `transition` prop of an `m` element. Springs suit movement that follows a
|
|
25
|
+
* gesture (a dropped item settling); for plain enters and exits prefer the CSS presets, which are
|
|
26
|
+
* cheaper and follow the motion tokens.
|
|
27
|
+
*/
|
|
28
|
+
declare const springs: {
|
|
29
|
+
/** Soft and slow to settle: a panel gliding into place. */
|
|
30
|
+
readonly gentle: {
|
|
31
|
+
readonly type: "spring";
|
|
32
|
+
readonly stiffness: 120;
|
|
33
|
+
readonly damping: 20;
|
|
34
|
+
};
|
|
35
|
+
/** Quick with no wobble: a control responding. */
|
|
36
|
+
readonly snappy: {
|
|
37
|
+
readonly type: "spring";
|
|
38
|
+
readonly stiffness: 300;
|
|
39
|
+
readonly damping: 30;
|
|
40
|
+
};
|
|
41
|
+
/** A visible overshoot: a playful confirmation. Use sparingly. */
|
|
42
|
+
readonly bouncy: {
|
|
43
|
+
readonly type: "spring";
|
|
44
|
+
readonly stiffness: 400;
|
|
45
|
+
readonly damping: 15;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export { MotionProvider, type MotionProviderProps, springs };
|
package/dist/motion.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/motion/library/index.ts
|
|
4
|
+
import {
|
|
5
|
+
AnimatePresence,
|
|
6
|
+
animate,
|
|
7
|
+
m,
|
|
8
|
+
Reorder,
|
|
9
|
+
useAnimate,
|
|
10
|
+
useDragControls,
|
|
11
|
+
useInView,
|
|
12
|
+
useMotionValue,
|
|
13
|
+
useSpring,
|
|
14
|
+
useTransform
|
|
15
|
+
} from "motion/react";
|
|
16
|
+
|
|
17
|
+
// src/motion/library/provider.tsx
|
|
18
|
+
import { LazyMotion, MotionConfig } from "motion/react";
|
|
19
|
+
import { jsx } from "react/jsx-runtime";
|
|
20
|
+
var loadDom = () => import("./features-dom-MCGKRLN5.js").then((module) => module.default);
|
|
21
|
+
var loadMax = () => import("./features-max-COBTQCO6.js").then((module) => module.default);
|
|
22
|
+
function MotionProvider({ children, features = "dom", strict = true }) {
|
|
23
|
+
return /* @__PURE__ */ jsx(MotionConfig, { reducedMotion: "user", children: /* @__PURE__ */ jsx(LazyMotion, { features: features === "max" ? loadMax : loadDom, strict, children }) });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/motion/library/springs.ts
|
|
27
|
+
var springs = {
|
|
28
|
+
/** Soft and slow to settle: a panel gliding into place. */
|
|
29
|
+
gentle: { type: "spring", stiffness: 120, damping: 20 },
|
|
30
|
+
/** Quick with no wobble: a control responding. */
|
|
31
|
+
snappy: { type: "spring", stiffness: 300, damping: 30 },
|
|
32
|
+
/** A visible overshoot: a playful confirmation. Use sparingly. */
|
|
33
|
+
bouncy: { type: "spring", stiffness: 400, damping: 15 }
|
|
34
|
+
};
|
|
35
|
+
export {
|
|
36
|
+
AnimatePresence,
|
|
37
|
+
MotionProvider,
|
|
38
|
+
Reorder,
|
|
39
|
+
animate,
|
|
40
|
+
m,
|
|
41
|
+
springs,
|
|
42
|
+
useAnimate,
|
|
43
|
+
useDragControls,
|
|
44
|
+
useInView,
|
|
45
|
+
useMotionValue,
|
|
46
|
+
useSpring,
|
|
47
|
+
useTransform
|
|
48
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, ReactElement, LiHTMLAttributes, AnchorHTMLAttributes, ButtonHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
type PageRangeItem = number | "start-ellipsis" | "end-ellipsis";
|
|
5
|
+
interface PageRangeOptions {
|
|
6
|
+
/** The current page, 1-based. Out-of-range values are clamped. */
|
|
7
|
+
page: number;
|
|
8
|
+
/** How many pages there are. */
|
|
9
|
+
pageCount: number;
|
|
10
|
+
/** Pages shown either side of the current one. Default 1. */
|
|
11
|
+
siblingCount?: number;
|
|
12
|
+
/** Pages always shown at each end. Default 1. */
|
|
13
|
+
boundaryCount?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The page numbers to show for a paginator, with `"start-ellipsis"` and `"end-ellipsis"` where pages
|
|
17
|
+
* are skipped: `[1, "start-ellipsis", 4, 5, 6, "end-ellipsis", 10]`. Pure, so a data grid can reuse it.
|
|
18
|
+
*
|
|
19
|
+
* With the defaults the result is 7 long once there are more than 7 pages, so the control does not
|
|
20
|
+
* change width as you page. A skipped run of exactly one page is shown as that page rather than as an
|
|
21
|
+
* ellipsis, which would save no space.
|
|
22
|
+
*/
|
|
23
|
+
declare function getPageRange({ page, pageCount, siblingCount, boundaryCount, }: PageRangeOptions): PageRangeItem[];
|
|
24
|
+
|
|
25
|
+
declare const PaginationNav: react.ForwardRefExoticComponent<HTMLAttributes<HTMLElement> & {
|
|
26
|
+
label?: string;
|
|
27
|
+
} & react.RefAttributes<HTMLElement>>;
|
|
28
|
+
declare const PaginationList: react.ForwardRefExoticComponent<HTMLAttributes<HTMLUListElement> & react.RefAttributes<HTMLUListElement>>;
|
|
29
|
+
declare const PaginationItem: react.ForwardRefExoticComponent<LiHTMLAttributes<HTMLLIElement> & react.RefAttributes<HTMLLIElement>>;
|
|
30
|
+
type LinkBase = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href"> & Omit<ButtonHTMLAttributes<HTMLButtonElement>, "onClick" | "type">;
|
|
31
|
+
interface PaginationLinkProps extends LinkBase {
|
|
32
|
+
/** The current page: filled, and `aria-current="page"`. */
|
|
33
|
+
isActive?: boolean;
|
|
34
|
+
/** Where it goes. Without one it renders a `<button>` (for client state). */
|
|
35
|
+
href?: string;
|
|
36
|
+
onClick?: () => void;
|
|
37
|
+
/** Cannot be used. A link loses its `href` and is announced as disabled; a button is `disabled`. */
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
/** Square (a page number) or sized for text (Previous and Next). Default `icon`. */
|
|
40
|
+
size?: "icon" | "md";
|
|
41
|
+
/** Render your router's `Link` instead of an `<a>`. */
|
|
42
|
+
render?: ReactElement;
|
|
43
|
+
}
|
|
44
|
+
/** One page control: a link when it has an `href`, otherwise a button. */
|
|
45
|
+
declare const PaginationLink: react.ForwardRefExoticComponent<PaginationLinkProps & react.RefAttributes<HTMLElement>>;
|
|
46
|
+
declare function PaginationEllipsis({ label, className, ...props }: HTMLAttributes<HTMLSpanElement> & {
|
|
47
|
+
label?: string;
|
|
48
|
+
}): react.JSX.Element;
|
|
49
|
+
interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, "onChange"> {
|
|
50
|
+
/** The current page, 1-based. */
|
|
51
|
+
page: number;
|
|
52
|
+
pageCount: number;
|
|
53
|
+
/** Link mode: where each page goes. Works in Server Components. Wins over `onPageChange`. */
|
|
54
|
+
hrefFor?: (page: number) => string;
|
|
55
|
+
/** Button mode: called with the page that was chosen. For client state. */
|
|
56
|
+
onPageChange?: (page: number) => void;
|
|
57
|
+
/** Render your router's `Link`: `renderLink={(href) => <NextLink href={href} />}`. */
|
|
58
|
+
renderLink?: (href: string) => ReactElement;
|
|
59
|
+
/** Pages shown either side of the current one. Default 1. */
|
|
60
|
+
siblingCount?: number;
|
|
61
|
+
/** Pages always shown at each end. Default 1. */
|
|
62
|
+
boundaryCount?: number;
|
|
63
|
+
/** Show Previous and Next. Default true. */
|
|
64
|
+
showPrevNext?: boolean;
|
|
65
|
+
/** The landmark's name. Default "Pagination". */
|
|
66
|
+
label?: string;
|
|
67
|
+
/** Names the controls, for translation. */
|
|
68
|
+
labels?: {
|
|
69
|
+
previous?: string;
|
|
70
|
+
next?: string;
|
|
71
|
+
page?: (page: number) => string;
|
|
72
|
+
more?: string;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A page control. Give it `hrefFor` and it is a set of real links that work without JavaScript (and
|
|
77
|
+
* in Server Components); give it `onPageChange` and it is a set of buttons for client state. Either
|
|
78
|
+
* way the current page is `aria-current="page"` and Previous and Next are disabled at the ends.
|
|
79
|
+
*/
|
|
80
|
+
declare function Pagination({ page, pageCount, hrefFor, onPageChange, renderLink, siblingCount, boundaryCount, showPrevNext, label, labels, ...props }: PaginationProps): react.JSX.Element | null;
|
|
81
|
+
|
|
82
|
+
export { type PageRangeItem, type PageRangeOptions, Pagination, PaginationEllipsis, PaginationItem, PaginationLink, type PaginationLinkProps, PaginationList, PaginationNav, type PaginationProps, getPageRange };
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderElement
|
|
3
|
+
} from "./chunk-LTOLV67A.js";
|
|
4
|
+
import {
|
|
5
|
+
Icon
|
|
6
|
+
} from "./chunk-Q4PPM2SU.js";
|
|
7
|
+
import {
|
|
8
|
+
cn
|
|
9
|
+
} from "./chunk-7EOSDFS3.js";
|
|
10
|
+
|
|
11
|
+
// src/components/pagination/page-range.ts
|
|
12
|
+
var range = (from, to) => Array.from({ length: Math.max(to - from + 1, 0) }, (_, i) => from + i);
|
|
13
|
+
function getPageRange({
|
|
14
|
+
page,
|
|
15
|
+
pageCount,
|
|
16
|
+
siblingCount = 1,
|
|
17
|
+
boundaryCount = 1
|
|
18
|
+
}) {
|
|
19
|
+
const count = Math.floor(pageCount);
|
|
20
|
+
if (!(count >= 1)) return [];
|
|
21
|
+
const current = Number.isFinite(page) ? Math.floor(page) : 1;
|
|
22
|
+
const sibling = Math.max(0, Math.floor(siblingCount));
|
|
23
|
+
const boundary = Math.max(0, Math.floor(boundaryCount));
|
|
24
|
+
const startPages = range(1, Math.min(boundary, count));
|
|
25
|
+
const endPages = range(Math.max(count - boundary + 1, boundary + 1), count);
|
|
26
|
+
const siblingsStart = Math.max(
|
|
27
|
+
Math.min(current - sibling, count - boundary - sibling * 2 - 1),
|
|
28
|
+
boundary + 2
|
|
29
|
+
);
|
|
30
|
+
const siblingsEnd = Math.min(
|
|
31
|
+
Math.max(current + sibling, boundary + sibling * 2 + 2),
|
|
32
|
+
endPages.length > 0 ? endPages[0] - 2 : count - 1
|
|
33
|
+
);
|
|
34
|
+
const items = [
|
|
35
|
+
...startPages,
|
|
36
|
+
siblingsStart > boundary + 2 ? "start-ellipsis" : boundary + 1 < count - boundary ? boundary + 1 : null,
|
|
37
|
+
...range(siblingsStart, siblingsEnd),
|
|
38
|
+
siblingsEnd < count - boundary - 1 ? "end-ellipsis" : count - boundary > boundary ? count - boundary : null,
|
|
39
|
+
...endPages
|
|
40
|
+
];
|
|
41
|
+
return items.filter((item) => item !== null);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/components/pagination/pagination.tsx
|
|
45
|
+
import { ChevronLeft, ChevronRight, Ellipsis } from "lucide-react";
|
|
46
|
+
import {
|
|
47
|
+
forwardRef
|
|
48
|
+
} from "react";
|
|
49
|
+
|
|
50
|
+
// src/components/button/variants.ts
|
|
51
|
+
import { cva } from "class-variance-authority";
|
|
52
|
+
var buttonVariants = cva(
|
|
53
|
+
[
|
|
54
|
+
"relative inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium",
|
|
55
|
+
"h-(--density-control-height) px-(--density-control-padding-x)",
|
|
56
|
+
"transition-colors duration-(--motion-duration-fast) ease-standard",
|
|
57
|
+
"outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
58
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
59
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
60
|
+
],
|
|
61
|
+
{
|
|
62
|
+
variants: {
|
|
63
|
+
variant: {
|
|
64
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
65
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
66
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
67
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
68
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
69
|
+
success: "bg-success text-success-foreground hover:bg-success/90",
|
|
70
|
+
warning: "bg-warning text-warning-foreground hover:bg-warning/90",
|
|
71
|
+
info: "bg-info text-info-foreground hover:bg-info/90",
|
|
72
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
73
|
+
},
|
|
74
|
+
size: {
|
|
75
|
+
sm: "h-8 px-3 text-xs",
|
|
76
|
+
md: "",
|
|
77
|
+
lg: "h-11 px-6",
|
|
78
|
+
icon: "size-(--density-control-height) p-0"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
defaultVariants: { variant: "default", size: "md" }
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// src/components/pagination/pagination.tsx
|
|
86
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
87
|
+
var PaginationNav = forwardRef(function PaginationNav2({ label = "Pagination", ...props }, ref) {
|
|
88
|
+
return /* @__PURE__ */ jsx("nav", { ref, "aria-label": label, ...props });
|
|
89
|
+
});
|
|
90
|
+
var PaginationList = forwardRef(
|
|
91
|
+
function PaginationList2({ className, ...props }, ref) {
|
|
92
|
+
return /* @__PURE__ */ jsx(
|
|
93
|
+
"ul",
|
|
94
|
+
{
|
|
95
|
+
ref,
|
|
96
|
+
className: cn("flex flex-row flex-wrap items-center gap-1", className),
|
|
97
|
+
...props
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
var PaginationItem = forwardRef(
|
|
103
|
+
function PaginationItem2(props, ref) {
|
|
104
|
+
return /* @__PURE__ */ jsx("li", { ref, ...props });
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
var PaginationLink = forwardRef(function PaginationLink2({ isActive, href, onClick, disabled, size = "icon", render, className, children, ...props }, ref) {
|
|
108
|
+
const cls = cn(
|
|
109
|
+
buttonVariants({ variant: isActive ? "default" : "ghost", size }),
|
|
110
|
+
disabled && "pointer-events-none opacity-50",
|
|
111
|
+
className
|
|
112
|
+
);
|
|
113
|
+
const common = { ref, "aria-current": isActive ? "page" : void 0, ...props, className: cls };
|
|
114
|
+
if (href !== void 0 || render) {
|
|
115
|
+
return renderElement(
|
|
116
|
+
// A disabled control must not be navigable, so it never takes the router element (whose own `href` would win).
|
|
117
|
+
disabled ? void 0 : render,
|
|
118
|
+
"a",
|
|
119
|
+
disabled ? { ...common, "aria-disabled": "true" } : { ...common, href, onClick },
|
|
120
|
+
children
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
return renderElement(
|
|
124
|
+
void 0,
|
|
125
|
+
"button",
|
|
126
|
+
{ ...common, type: "button", disabled, onClick: disabled || isActive ? void 0 : onClick },
|
|
127
|
+
children
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
function PaginationEllipsis({
|
|
131
|
+
label = "More pages",
|
|
132
|
+
className,
|
|
133
|
+
...props
|
|
134
|
+
}) {
|
|
135
|
+
return /* @__PURE__ */ jsxs(
|
|
136
|
+
"span",
|
|
137
|
+
{
|
|
138
|
+
"data-azmr-ellipsis": "",
|
|
139
|
+
className: cn("flex size-(--density-control-height) items-center justify-center", className),
|
|
140
|
+
...props,
|
|
141
|
+
children: [
|
|
142
|
+
/* @__PURE__ */ jsx(Icon, { icon: Ellipsis }),
|
|
143
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: label })
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
function Pagination({
|
|
149
|
+
page,
|
|
150
|
+
pageCount,
|
|
151
|
+
hrefFor,
|
|
152
|
+
onPageChange,
|
|
153
|
+
renderLink,
|
|
154
|
+
siblingCount,
|
|
155
|
+
boundaryCount,
|
|
156
|
+
showPrevNext = true,
|
|
157
|
+
label,
|
|
158
|
+
labels,
|
|
159
|
+
...props
|
|
160
|
+
}) {
|
|
161
|
+
const items = getPageRange({ page, pageCount, siblingCount, boundaryCount });
|
|
162
|
+
if (items.length === 0) return null;
|
|
163
|
+
const count = Math.floor(pageCount);
|
|
164
|
+
const current = Math.min(Math.max(Math.floor(page) || 1, 1), count);
|
|
165
|
+
const pageLabel = labels?.page ?? ((p) => `Page ${p}`);
|
|
166
|
+
const control = (target, extra, children) => {
|
|
167
|
+
const href = hrefFor?.(target);
|
|
168
|
+
return /* @__PURE__ */ jsx(
|
|
169
|
+
PaginationLink,
|
|
170
|
+
{
|
|
171
|
+
...href !== void 0 ? { href, render: renderLink?.(href) } : { onClick: () => onPageChange?.(target) },
|
|
172
|
+
...extra,
|
|
173
|
+
children
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
};
|
|
177
|
+
return /* @__PURE__ */ jsx(PaginationNav, { label, ...props, children: /* @__PURE__ */ jsxs(PaginationList, { children: [
|
|
178
|
+
showPrevNext && /* @__PURE__ */ jsx(PaginationItem, { children: control(
|
|
179
|
+
current - 1,
|
|
180
|
+
{
|
|
181
|
+
size: "md",
|
|
182
|
+
disabled: current <= 1,
|
|
183
|
+
"aria-label": labels?.previous ?? "Previous page"
|
|
184
|
+
},
|
|
185
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
186
|
+
/* @__PURE__ */ jsx(Icon, { icon: ChevronLeft }),
|
|
187
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Previous" })
|
|
188
|
+
] })
|
|
189
|
+
) }),
|
|
190
|
+
items.map(
|
|
191
|
+
(item) => typeof item === "number" ? /* @__PURE__ */ jsx(PaginationItem, { children: control(item, { isActive: item === current, "aria-label": pageLabel(item) }, item) }, item) : /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(PaginationEllipsis, { label: labels?.more }) }, item)
|
|
192
|
+
),
|
|
193
|
+
showPrevNext && /* @__PURE__ */ jsx(PaginationItem, { children: control(
|
|
194
|
+
current + 1,
|
|
195
|
+
{ size: "md", disabled: current >= count, "aria-label": labels?.next ?? "Next page" },
|
|
196
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
197
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Next" }),
|
|
198
|
+
/* @__PURE__ */ jsx(Icon, { icon: ChevronRight })
|
|
199
|
+
] })
|
|
200
|
+
) })
|
|
201
|
+
] }) });
|
|
202
|
+
}
|
|
203
|
+
export {
|
|
204
|
+
Pagination,
|
|
205
|
+
PaginationEllipsis,
|
|
206
|
+
PaginationItem,
|
|
207
|
+
PaginationLink,
|
|
208
|
+
PaginationList,
|
|
209
|
+
PaginationNav,
|
|
210
|
+
getPageRange
|
|
211
|
+
};
|