@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.
Files changed (92) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +244 -73
  3. package/dist/avatar.d.ts +58 -0
  4. package/dist/avatar.js +84 -0
  5. package/dist/breadcrumb.d.ts +47 -0
  6. package/dist/breadcrumb.js +120 -0
  7. package/dist/button-CYt2Zw3D.d.ts +64 -0
  8. package/dist/button.d.ts +54 -0
  9. package/dist/button.js +19 -0
  10. package/dist/chunk-2RIWL363.js +27 -0
  11. package/dist/chunk-2TQSHVXA.js +12 -0
  12. package/dist/chunk-7EOSDFS3.js +10 -0
  13. package/dist/chunk-C2HKIPLQ.js +118 -0
  14. package/dist/chunk-CAJLW6K2.js +16 -0
  15. package/dist/chunk-CZJZYN54.js +36 -0
  16. package/dist/chunk-EE4V6XMB.js +35 -0
  17. package/dist/chunk-EFHRRLAW.js +211 -0
  18. package/dist/chunk-GLB75NT3.js +21 -0
  19. package/dist/chunk-GX2YEJ43.js +36 -0
  20. package/dist/chunk-LTOLV67A.js +19 -0
  21. package/dist/chunk-LZMX27IZ.js +10 -0
  22. package/dist/chunk-NIIDYIZA.js +1 -0
  23. package/dist/chunk-Q4PPM2SU.js +97 -0
  24. package/dist/chunk-WVE2E37B.js +20 -0
  25. package/dist/chunk-XRZHP6BD.js +92 -0
  26. package/dist/disclosure.d.ts +72 -0
  27. package/dist/disclosure.js +221 -0
  28. package/dist/display.d.ts +111 -0
  29. package/dist/display.js +237 -0
  30. package/dist/floating.d.ts +81 -0
  31. package/dist/floating.js +231 -0
  32. package/dist/hooks.d.ts +33 -0
  33. package/dist/hooks.js +55 -0
  34. package/dist/icons/lucide.d.ts +77 -0
  35. package/dist/icons/lucide.js +135 -0
  36. package/dist/icons/mui-map.d.ts +1268 -0
  37. package/dist/icons/mui-map.js +352 -0
  38. package/dist/icons.d.ts +48 -0
  39. package/dist/icons.js +19 -0
  40. package/dist/index.d.ts +240 -5
  41. package/dist/index.js +242 -15
  42. package/dist/input.d.ts +14 -0
  43. package/dist/input.js +8 -0
  44. package/dist/layout/mui-map.d.ts +80 -0
  45. package/dist/layout/mui-map.js +104 -0
  46. package/dist/layout.d.ts +89 -0
  47. package/dist/layout.js +455 -0
  48. package/dist/lib.d.ts +11 -0
  49. package/dist/lib.js +6 -0
  50. package/dist/menu.d.ts +105 -0
  51. package/dist/menu.js +56 -0
  52. package/dist/modal.d.ts +105 -0
  53. package/dist/modal.js +273 -0
  54. package/dist/motion.css +295 -0
  55. package/dist/pagination.d.ts +82 -0
  56. package/dist/pagination.js +211 -0
  57. package/dist/presets.d.ts +97 -0
  58. package/dist/presets.js +94 -0
  59. package/dist/progress.d.ts +70 -0
  60. package/dist/progress.js +138 -0
  61. package/dist/react.d.ts +81 -0
  62. package/dist/react.js +281 -0
  63. package/dist/responsive-YJBnvsjt.d.ts +69 -0
  64. package/dist/scroll-area.d.ts +30 -0
  65. package/dist/scroll-area.js +80 -0
  66. package/dist/shared-Fkx-sjPt.d.ts +15 -0
  67. package/dist/spinner.d.ts +18 -0
  68. package/dist/spinner.js +39 -0
  69. package/dist/split-button.d.ts +32 -0
  70. package/dist/split-button.js +54 -0
  71. package/dist/stepper.d.ts +27 -0
  72. package/dist/stepper.js +104 -0
  73. package/dist/styles.css +24 -0
  74. package/dist/table.d.ts +52 -0
  75. package/dist/table.js +124 -0
  76. package/dist/theme.d.ts +111 -0
  77. package/dist/theme.js +414 -0
  78. package/dist/toast.d.ts +77 -0
  79. package/dist/toast.js +203 -0
  80. package/dist/toggle.d.ts +55 -0
  81. package/dist/toggle.js +88 -0
  82. package/dist/tokens.css +337 -0
  83. package/dist/transition.d.ts +51 -0
  84. package/dist/transition.js +79 -0
  85. package/dist/types-BBudf463.d.ts +39 -0
  86. package/dist/typography/mui-map.d.ts +91 -0
  87. package/dist/typography/mui-map.js +62 -0
  88. package/dist/typography.d.ts +90 -0
  89. package/dist/typography.js +193 -0
  90. package/dist/useSignal-C-3ZGURN.d.ts +21 -0
  91. package/dist/variants-De0c0ucO.d.ts +60 -0
  92. package/package.json +173 -18
@@ -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 };