@salesforce/webapp-template-feature-react-authentication-experimental 1.44.0 → 1.45.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/dist/CHANGELOG.md +8 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/package-lock.json +1173 -401
- package/dist/force-app/main/default/webapplications/feature-react-authentication/package.json +1 -3
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/app.tsx +2 -5
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/auth/authHelpers.ts +73 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/{utils → components/auth}/authenticationConfig.ts +9 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/auth/{authentication-route.tsx → authenticationRouteLayout.tsx} +1 -1
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/auth/{private-route.tsx → privateRouteLayout.tsx} +1 -1
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/auth/sessionTimeout/SessionTimeoutValidator.tsx +616 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/auth/sessionTimeout/sessionTimeService.ts +161 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/auth/sessionTimeout/sessionTimeoutConfig.ts +77 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/alert.tsx +17 -13
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/button.tsx +35 -22
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/card.tsx +27 -12
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/dialog.tsx +143 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/field.tsx +157 -46
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/index.ts +1 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/input.tsx +3 -3
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/label.tsx +2 -2
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/pagination.tsx +87 -74
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/select.tsx +156 -124
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/separator.tsx +26 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/skeleton.tsx +1 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/spinner.tsx +5 -16
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/table.tsx +68 -95
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/components/ui/tabs.tsx +47 -84
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/context/AuthContext.tsx +12 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/hooks/form.tsx +1 -1
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/hooks/useCountdownTimer.ts +266 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/hooks/useRetryWithBackoff.ts +109 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/layouts/AuthAppLayout.tsx +12 -0
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/pages/ChangePassword.tsx +3 -2
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/pages/ForgotPassword.tsx +1 -1
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/pages/Login.tsx +3 -3
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/pages/Profile.tsx +3 -2
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/pages/Register.tsx +4 -5
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/pages/ResetPassword.tsx +3 -2
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/routes.tsx +5 -5
- package/dist/force-app/main/default/webapplications/feature-react-authentication/src/utils/helpers.ts +0 -74
- package/dist/package.json +1 -1
- package/package.json +3 -3
|
@@ -1,22 +1,102 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
3
|
|
|
3
4
|
import { cn } from "../../lib/utils";
|
|
4
5
|
import { Label } from "./label";
|
|
6
|
+
import { Separator } from "./separator";
|
|
7
|
+
|
|
8
|
+
function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
|
|
9
|
+
return (
|
|
10
|
+
<fieldset
|
|
11
|
+
data-slot="field-set"
|
|
12
|
+
className={cn(
|
|
13
|
+
"gap-4 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3 flex flex-col",
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function FieldLegend({
|
|
22
|
+
className,
|
|
23
|
+
variant = "legend",
|
|
24
|
+
...props
|
|
25
|
+
}: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
|
|
26
|
+
return (
|
|
27
|
+
<legend
|
|
28
|
+
data-slot="field-legend"
|
|
29
|
+
data-variant={variant}
|
|
30
|
+
className={cn(
|
|
31
|
+
"mb-1.5 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base",
|
|
32
|
+
className,
|
|
33
|
+
)}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
40
|
+
return (
|
|
41
|
+
<div
|
|
42
|
+
data-slot="field-group"
|
|
43
|
+
className={cn(
|
|
44
|
+
"gap-5 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4 group/field-group @container/field-group flex w-full flex-col",
|
|
45
|
+
className,
|
|
46
|
+
)}
|
|
47
|
+
{...props}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const fieldVariants = cva("data-[invalid=true]:text-destructive gap-2 group/field flex w-full", {
|
|
53
|
+
variants: {
|
|
54
|
+
orientation: {
|
|
55
|
+
vertical: "flex-col *:w-full [&>.sr-only]:w-auto",
|
|
56
|
+
horizontal:
|
|
57
|
+
"flex-row items-center *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
|
|
58
|
+
responsive:
|
|
59
|
+
"flex-col *:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:*:data-[slot=field-label]:flex-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
defaultVariants: {
|
|
63
|
+
orientation: "vertical",
|
|
64
|
+
},
|
|
65
|
+
});
|
|
5
66
|
|
|
6
67
|
function Field({
|
|
7
68
|
className,
|
|
8
69
|
orientation = "vertical",
|
|
9
70
|
...props
|
|
10
|
-
}: React.ComponentProps<"div"> & {
|
|
11
|
-
orientation?: "horizontal" | "vertical";
|
|
12
|
-
}) {
|
|
71
|
+
}: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
|
|
13
72
|
return (
|
|
14
73
|
<div
|
|
74
|
+
role="group"
|
|
15
75
|
data-slot="field"
|
|
16
76
|
data-orientation={orientation}
|
|
77
|
+
className={cn(fieldVariants({ orientation }), className)}
|
|
78
|
+
{...props}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
84
|
+
return (
|
|
85
|
+
<div
|
|
86
|
+
data-slot="field-content"
|
|
87
|
+
className={cn("gap-0.5 group/field-content flex flex-1 flex-col leading-snug", className)}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>) {
|
|
94
|
+
return (
|
|
95
|
+
<Label
|
|
96
|
+
data-slot="field-label"
|
|
17
97
|
className={cn(
|
|
18
|
-
"
|
|
19
|
-
|
|
98
|
+
"has-data-checked:bg-primary/5 has-data-checked:border-primary/30 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10 gap-2 group-data-[disabled=true]/field:opacity-50 has-[>[data-slot=field]]:rounded-lg has-[>[data-slot=field]]:border *:data-[slot=field]:p-2.5 group/field-label peer/field-label flex w-fit leading-snug",
|
|
99
|
+
"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col",
|
|
20
100
|
className,
|
|
21
101
|
)}
|
|
22
102
|
{...props}
|
|
@@ -24,12 +104,12 @@ function Field({
|
|
|
24
104
|
);
|
|
25
105
|
}
|
|
26
106
|
|
|
27
|
-
function
|
|
107
|
+
function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
28
108
|
return (
|
|
29
|
-
<
|
|
109
|
+
<div
|
|
30
110
|
data-slot="field-label"
|
|
31
111
|
className={cn(
|
|
32
|
-
"
|
|
112
|
+
"gap-2 text-sm font-medium group-data-[disabled=true]/field:opacity-50 flex w-fit items-center leading-snug",
|
|
33
113
|
className,
|
|
34
114
|
)}
|
|
35
115
|
{...props}
|
|
@@ -41,71 +121,102 @@ function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
|
41
121
|
return (
|
|
42
122
|
<p
|
|
43
123
|
data-slot="field-description"
|
|
44
|
-
className={cn(
|
|
124
|
+
className={cn(
|
|
125
|
+
"text-muted-foreground text-left text-sm [[data-variant=legend]+&]:-mt-1.5 leading-normal font-normal group-has-data-horizontal/field:text-balance",
|
|
126
|
+
"last:mt-0 nth-last-2:-mt-1",
|
|
127
|
+
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
|
|
128
|
+
className,
|
|
129
|
+
)}
|
|
45
130
|
{...props}
|
|
46
131
|
/>
|
|
47
132
|
);
|
|
48
133
|
}
|
|
49
134
|
|
|
50
|
-
function
|
|
135
|
+
function FieldSeparator({
|
|
136
|
+
children,
|
|
51
137
|
className,
|
|
52
|
-
errors,
|
|
53
138
|
...props
|
|
54
|
-
}: React.ComponentProps<"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (!errorMessages?.length) {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
|
|
139
|
+
}: React.ComponentProps<"div"> & {
|
|
140
|
+
children?: React.ReactNode;
|
|
141
|
+
}) {
|
|
61
142
|
return (
|
|
62
|
-
<
|
|
63
|
-
data-slot="field-
|
|
64
|
-
|
|
65
|
-
|
|
143
|
+
<div
|
|
144
|
+
data-slot="field-separator"
|
|
145
|
+
data-content={!!children}
|
|
146
|
+
className={cn(
|
|
147
|
+
"-my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2 relative",
|
|
148
|
+
className,
|
|
149
|
+
)}
|
|
66
150
|
{...props}
|
|
67
151
|
>
|
|
68
|
-
|
|
69
|
-
|
|
152
|
+
<Separator className="absolute inset-0 top-1/2" />
|
|
153
|
+
{children && (
|
|
154
|
+
<span
|
|
155
|
+
className="text-muted-foreground px-2 bg-background relative mx-auto block w-fit"
|
|
156
|
+
data-slot="field-separator-content"
|
|
157
|
+
>
|
|
158
|
+
{children}
|
|
159
|
+
</span>
|
|
160
|
+
)}
|
|
161
|
+
</div>
|
|
70
162
|
);
|
|
71
163
|
}
|
|
72
164
|
|
|
73
|
-
function
|
|
74
|
-
|
|
75
|
-
|
|
165
|
+
function FieldError({
|
|
166
|
+
className,
|
|
167
|
+
children,
|
|
168
|
+
errors,
|
|
169
|
+
...props
|
|
170
|
+
}: React.ComponentProps<"div"> & {
|
|
171
|
+
errors?: Array<{ message?: string } | undefined>;
|
|
172
|
+
}) {
|
|
173
|
+
const content = useMemo(() => {
|
|
174
|
+
if (children) {
|
|
175
|
+
return children;
|
|
176
|
+
}
|
|
76
177
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
178
|
+
if (!errors?.length) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
80
181
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
182
|
+
const uniqueErrors = [...new Map(errors.map((error) => [error?.message, error])).values()];
|
|
183
|
+
|
|
184
|
+
if (uniqueErrors?.length == 1) {
|
|
185
|
+
return uniqueErrors[0]?.message;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return (
|
|
189
|
+
<ul className="ml-4 flex list-disc flex-col gap-1">
|
|
190
|
+
{uniqueErrors.map((error, index) => error?.message && <li key={index}>{error.message}</li>)}
|
|
191
|
+
</ul>
|
|
192
|
+
);
|
|
193
|
+
}, [children, errors]);
|
|
194
|
+
|
|
195
|
+
if (!content) {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
90
198
|
|
|
91
|
-
function FieldSeparator({ className, ...props }: React.ComponentProps<"div">) {
|
|
92
199
|
return (
|
|
93
200
|
<div
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
className={cn("
|
|
201
|
+
role="alert"
|
|
202
|
+
data-slot="field-error"
|
|
203
|
+
className={cn("text-destructive text-sm font-normal", className)}
|
|
97
204
|
{...props}
|
|
98
|
-
|
|
205
|
+
>
|
|
206
|
+
{content}
|
|
207
|
+
</div>
|
|
99
208
|
);
|
|
100
209
|
}
|
|
101
210
|
|
|
102
211
|
export {
|
|
103
212
|
Field,
|
|
213
|
+
FieldLabel,
|
|
104
214
|
FieldDescription,
|
|
105
215
|
FieldError,
|
|
106
216
|
FieldGroup,
|
|
107
|
-
FieldLabel,
|
|
108
217
|
FieldLegend,
|
|
109
218
|
FieldSeparator,
|
|
110
219
|
FieldSet,
|
|
220
|
+
FieldContent,
|
|
221
|
+
FieldTitle,
|
|
111
222
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
1
3
|
import { cn } from "../../lib/utils";
|
|
2
4
|
|
|
3
5
|
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
|
@@ -6,9 +8,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
|
|
6
8
|
type={type}
|
|
7
9
|
data-slot="input"
|
|
8
10
|
className={cn(
|
|
9
|
-
"
|
|
10
|
-
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
11
|
-
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
11
|
+
"dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-lg border bg-transparent px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-3 aria-invalid:ring-3 md:text-sm file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
12
12
|
className,
|
|
13
13
|
)}
|
|
14
14
|
{...props}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import
|
|
2
|
+
import { Label as LabelPrimitive } from "radix-ui";
|
|
3
3
|
|
|
4
4
|
import { cn } from "../../lib/utils";
|
|
5
5
|
|
|
@@ -8,7 +8,7 @@ function Label({ className, ...props }: React.ComponentProps<typeof LabelPrimiti
|
|
|
8
8
|
<LabelPrimitive.Root
|
|
9
9
|
data-slot="label"
|
|
10
10
|
className={cn(
|
|
11
|
-
"
|
|
11
|
+
"gap-2 text-sm leading-none font-medium group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed",
|
|
12
12
|
className,
|
|
13
13
|
)}
|
|
14
14
|
{...props}
|
|
@@ -1,92 +1,105 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
|
|
3
2
|
|
|
4
3
|
import { cn } from "../../lib/utils";
|
|
5
|
-
import { Button
|
|
4
|
+
import { Button } from "./button";
|
|
5
|
+
import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from "lucide-react";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
|
|
8
|
+
return (
|
|
9
|
+
<nav
|
|
10
|
+
role="navigation"
|
|
11
|
+
aria-label="pagination"
|
|
12
|
+
data-slot="pagination"
|
|
13
|
+
className={cn("mx-auto flex w-full justify-center", className)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<ul
|
|
20
|
-
|
|
21
|
-
)
|
|
22
|
-
|
|
19
|
+
function PaginationContent({ className, ...props }: React.ComponentProps<"ul">) {
|
|
20
|
+
return (
|
|
21
|
+
<ul
|
|
22
|
+
data-slot="pagination-content"
|
|
23
|
+
className={cn("gap-0.5 flex items-center", className)}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
23
28
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
PaginationItem.displayName = "PaginationItem";
|
|
29
|
+
function PaginationItem({ ...props }: React.ComponentProps<"li">) {
|
|
30
|
+
return <li data-slot="pagination-item" {...props} />;
|
|
31
|
+
}
|
|
28
32
|
|
|
29
33
|
type PaginationLinkProps = {
|
|
30
34
|
isActive?: boolean;
|
|
31
|
-
} & React.ComponentProps<"
|
|
35
|
+
} & Pick<React.ComponentProps<typeof Button>, "size"> &
|
|
36
|
+
React.ComponentProps<"a">;
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
/>
|
|
46
|
-
);
|
|
47
|
-
PaginationLink.displayName = "PaginationLink";
|
|
38
|
+
function PaginationLink({ className, isActive, size = "icon", ...props }: PaginationLinkProps) {
|
|
39
|
+
return (
|
|
40
|
+
<Button asChild variant={isActive ? "outline" : "ghost"} size={size} className={cn(className)}>
|
|
41
|
+
<a
|
|
42
|
+
aria-current={isActive ? "page" : undefined}
|
|
43
|
+
data-slot="pagination-link"
|
|
44
|
+
data-active={isActive}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
</Button>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
function PaginationPrevious({
|
|
50
52
|
className,
|
|
51
|
-
|
|
53
|
+
text = "Previous",
|
|
52
54
|
...props
|
|
53
|
-
}: React.ComponentProps<typeof
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {
|
|
56
|
+
return (
|
|
57
|
+
<PaginationLink
|
|
58
|
+
aria-label="Go to previous page"
|
|
59
|
+
size="default"
|
|
60
|
+
className={cn("pl-1.5!", className)}
|
|
61
|
+
{...props}
|
|
62
|
+
>
|
|
63
|
+
<ChevronLeftIcon data-icon="inline-start" className="cn-rtl-flip" />
|
|
64
|
+
<span className="hidden sm:block">{text}</span>
|
|
65
|
+
</PaginationLink>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
65
68
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
function PaginationNext({
|
|
70
|
+
className,
|
|
71
|
+
text = "Next",
|
|
72
|
+
...props
|
|
73
|
+
}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {
|
|
74
|
+
return (
|
|
75
|
+
<PaginationLink
|
|
76
|
+
aria-label="Go to next page"
|
|
77
|
+
size="default"
|
|
78
|
+
className={cn("pr-1.5!", className)}
|
|
79
|
+
{...props}
|
|
80
|
+
>
|
|
81
|
+
<span className="hidden sm:block">{text}</span>
|
|
82
|
+
<ChevronRightIcon data-icon="inline-end" className="cn-rtl-flip" />
|
|
83
|
+
</PaginationLink>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
function PaginationEllipsis({ className, ...props }: React.ComponentProps<"span">) {
|
|
88
|
+
return (
|
|
89
|
+
<span
|
|
90
|
+
aria-hidden
|
|
91
|
+
data-slot="pagination-ellipsis"
|
|
92
|
+
className={cn(
|
|
93
|
+
"size-8 [&_svg:not([class*='size-'])]:size-4 flex items-center justify-center",
|
|
94
|
+
className,
|
|
95
|
+
)}
|
|
96
|
+
{...props}
|
|
97
|
+
>
|
|
98
|
+
<MoreHorizontalIcon />
|
|
99
|
+
<span className="sr-only">More pages</span>
|
|
100
|
+
</span>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
90
103
|
|
|
91
104
|
export {
|
|
92
105
|
Pagination,
|