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