@azmr/ui 0.0.1 → 0.2.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/LICENSE +1 -1
- package/README.md +244 -73
- 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/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 +240 -5
- 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/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 +173 -18
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
|
+
}
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { SVGProps, HTMLAttributes, ReactNode, ElementType, ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
interface AnimatedCheckProps extends Omit<SVGProps<SVGSVGElement>, "ref" | "children"> {
|
|
5
|
+
/** Pixel size (width and height). Default 24. */
|
|
6
|
+
size?: number;
|
|
7
|
+
/** Accessible name. When set the tick is an image ("Saved"); without it the tick is decorative. */
|
|
8
|
+
label?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A tick that draws itself, for a success moment. It uses the current text colour, so
|
|
12
|
+
* `className="text-success"` colours it. Under reduced motion it is drawn at once. Server-safe.
|
|
13
|
+
*/
|
|
14
|
+
declare const AnimatedCheck: react.ForwardRefExoticComponent<AnimatedCheckProps & react.RefAttributes<SVGSVGElement>>;
|
|
15
|
+
|
|
16
|
+
interface CollapseProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
17
|
+
/** Whether the content is showing. */
|
|
18
|
+
open: boolean;
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Shows and hides content with a height animation that is **not measured in JavaScript**: it
|
|
23
|
+
* animates `grid-template-rows` between `0fr` and `1fr`. Server-safe, and instant under reduced
|
|
24
|
+
* motion.
|
|
25
|
+
*
|
|
26
|
+
* The content stays mounted while closed, so it keeps its state and can animate; while closed it is
|
|
27
|
+
* `inert` and `aria-hidden`, so it cannot be focused or read. You own the trigger: give it
|
|
28
|
+
* `aria-expanded` and `aria-controls` pointing at this element's `id`. For a ready-made disclosure
|
|
29
|
+
* with all of that wired, use `Collapsible` or `Accordion`.
|
|
30
|
+
*/
|
|
31
|
+
declare const Collapse: react.ForwardRefExoticComponent<CollapseProps & react.RefAttributes<HTMLDivElement>>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The preset classes from `@azmr/ui/styles.css`. Spelled out in full so the Tailwind scanner finds
|
|
35
|
+
* them in `dist`, and so a typo is a type error. Every class is defined in `motion.css` and every
|
|
36
|
+
* motion class there is listed here (a test keeps the two in step).
|
|
37
|
+
*
|
|
38
|
+
* `enter` eases out and runs on `--motion-duration-base`; `exit` is shorter and eases in. Under
|
|
39
|
+
* `prefers-reduced-motion` the slides and scales become a plain fade.
|
|
40
|
+
*/
|
|
41
|
+
declare const motionPresets: {
|
|
42
|
+
readonly fade: {
|
|
43
|
+
readonly enter: "motion-fade-in";
|
|
44
|
+
readonly exit: "motion-fade-out";
|
|
45
|
+
};
|
|
46
|
+
readonly scale: {
|
|
47
|
+
readonly enter: "motion-scale-in";
|
|
48
|
+
readonly exit: "motion-scale-out";
|
|
49
|
+
};
|
|
50
|
+
readonly slideUp: {
|
|
51
|
+
readonly enter: "motion-slide-up-in";
|
|
52
|
+
readonly exit: "motion-slide-up-out";
|
|
53
|
+
};
|
|
54
|
+
readonly slideDown: {
|
|
55
|
+
readonly enter: "motion-slide-down-in";
|
|
56
|
+
readonly exit: "motion-slide-down-out";
|
|
57
|
+
};
|
|
58
|
+
readonly slideLeft: {
|
|
59
|
+
readonly enter: "motion-slide-left-in";
|
|
60
|
+
readonly exit: "motion-slide-left-out";
|
|
61
|
+
};
|
|
62
|
+
readonly slideRight: {
|
|
63
|
+
readonly enter: "motion-slide-right-in";
|
|
64
|
+
readonly exit: "motion-slide-right-out";
|
|
65
|
+
};
|
|
66
|
+
/** A grid-template-rows collapse. Use `Collapse`. */
|
|
67
|
+
readonly collapse: {
|
|
68
|
+
readonly root: "motion-collapse";
|
|
69
|
+
readonly inner: "motion-collapse-inner";
|
|
70
|
+
};
|
|
71
|
+
/** A staggered list. Use `Stagger`. */
|
|
72
|
+
readonly stagger: {
|
|
73
|
+
readonly container: "motion-stagger";
|
|
74
|
+
readonly item: "motion-stagger-item";
|
|
75
|
+
};
|
|
76
|
+
/** A sweeping highlight for loading placeholders. Put it on a rounded, overflow-clipped box. */
|
|
77
|
+
readonly shimmer: "motion-shimmer";
|
|
78
|
+
/** An SVG tick that draws itself. Use `AnimatedCheck`. */
|
|
79
|
+
readonly checkDraw: "motion-check";
|
|
80
|
+
};
|
|
81
|
+
type MotionPresetName = keyof typeof motionPresets;
|
|
82
|
+
|
|
83
|
+
interface StaggerProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
84
|
+
children: ReactNode;
|
|
85
|
+
/** The element to render. Default `div`; use `ul` or `ol` for a list. */
|
|
86
|
+
as?: ElementType;
|
|
87
|
+
/** The last index that gets its own delay, so a long list does not take forever to appear. Default 12. */
|
|
88
|
+
max?: number;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Makes the children of a list enter one after another. Each child gets a `--stagger-index`, and the
|
|
92
|
+
* delay is `index x --motion-stagger-step` (40 ms), capped at `max`. Under reduced motion the step is
|
|
93
|
+
* zero and they fade in together. Only elements are staggered; text is left alone. Server-safe.
|
|
94
|
+
*/
|
|
95
|
+
declare function Stagger({ as, max, className, children, ...props }: StaggerProps): ReactElement<any, string | react.JSXElementConstructor<any>>;
|
|
96
|
+
|
|
97
|
+
export { AnimatedCheck, type AnimatedCheckProps, Collapse, type CollapseProps, type MotionPresetName, Stagger, type StaggerProps, motionPresets };
|