@dododog/ui 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/{chunk-SZ3SV4SJ.mjs → chunk-4DHZ6MIL.mjs} +1 -1
- package/dist/chunk-5KOWMIWK.mjs +110 -0
- package/dist/{chunk-77WKG2D7.js → chunk-5UNG2O64.js} +38 -8
- package/dist/{chunk-MCF3EQTV.js → chunk-73BHQJW6.js} +13 -1
- package/dist/{chunk-U3XWNFHH.js → chunk-A3M3XQ35.js} +96 -29
- package/dist/chunk-BKM5VCUS.mjs +569 -0
- package/dist/{chunk-333YD5QI.mjs → chunk-EAATIFYL.mjs} +40 -6
- package/dist/{chunk-C4RZBOKH.js → chunk-EQPT6VZF.js} +1 -1
- package/dist/chunk-FLKEMER2.js +592 -0
- package/dist/{chunk-NBDPT3XQ.js → chunk-HH4X2JYO.js} +94 -15
- package/dist/{chunk-I4S3R6C6.js → chunk-JUB3NGJR.js} +51 -6
- package/dist/{chunk-GRG4USTC.mjs → chunk-JWOV5H6G.mjs} +38 -8
- package/dist/chunk-JWQ2OUEG.js +132 -0
- package/dist/{chunk-3R7PT3JG.js → chunk-LJSMPON7.js} +40 -6
- package/dist/chunk-N5ZNXNCO.mjs +178 -0
- package/dist/{chunk-DMCMWOBJ.mjs → chunk-PBXH4I5N.mjs} +51 -6
- package/dist/{chunk-ERL3WXNY.mjs → chunk-PZZWQ6IG.mjs} +5 -5
- package/dist/{chunk-GBWVIY3C.mjs → chunk-UJEIFKSK.mjs} +96 -29
- package/dist/chunk-WY24TZ4R.mjs +94 -0
- package/dist/chunk-XBNIHUSG.js +116 -0
- package/dist/{chunk-TDGU5Y2P.js → chunk-XOFTU3T7.js} +5 -5
- package/dist/{chunk-NZ7GF6RF.mjs → chunk-YOMOULLR.mjs} +13 -1
- package/dist/components/Accordion/index.js +2 -2
- package/dist/components/Accordion/index.mjs +1 -1
- package/dist/components/Counter/index.d.mts +12 -0
- package/dist/components/Counter/index.d.ts +12 -0
- package/dist/components/Counter/index.js +2 -2
- package/dist/components/Counter/index.mjs +1 -1
- package/dist/components/DateRangePicker/index.d.mts +7 -1
- package/dist/components/DateRangePicker/index.d.ts +7 -1
- package/dist/components/DateRangePicker/index.js +3 -3
- package/dist/components/DateRangePicker/index.mjs +1 -1
- package/dist/components/Drawer/index.d.mts +21 -1
- package/dist/components/Drawer/index.d.ts +21 -1
- package/dist/components/Drawer/index.js +2 -2
- package/dist/components/Drawer/index.mjs +1 -1
- package/dist/components/DualRangeSlider/index.js +2 -2
- package/dist/components/DualRangeSlider/index.mjs +1 -1
- package/dist/components/Footer/index.js +2 -2
- package/dist/components/Footer/index.mjs +1 -1
- package/dist/components/Input/index.js +3 -3
- package/dist/components/Input/index.mjs +1 -1
- package/dist/components/Lightbox/index.d.mts +2 -0
- package/dist/components/Lightbox/index.d.ts +2 -0
- package/dist/components/Lightbox/index.js +2 -2
- package/dist/components/Lightbox/index.mjs +1 -1
- package/dist/components/Modal/index.d.mts +12 -0
- package/dist/components/Modal/index.d.ts +12 -0
- package/dist/components/Modal/index.js +2 -2
- package/dist/components/Modal/index.mjs +1 -1
- package/dist/components/Select/index.d.mts +8 -0
- package/dist/components/Select/index.d.ts +8 -0
- package/dist/components/Select/index.js +3 -3
- package/dist/components/Select/index.mjs +1 -1
- package/dist/components/Switch/index.d.mts +41 -1
- package/dist/components/Switch/index.d.ts +41 -1
- package/dist/components/Switch/index.js +4 -4
- package/dist/components/Switch/index.mjs +1 -1
- package/dist/index.js +45 -45
- package/dist/index.mjs +14 -14
- package/dist/tailwind-preset.d.mts +2 -2
- package/dist/tailwind-preset.d.ts +2 -2
- package/dist/tailwind-preset.js +2 -2
- package/dist/tailwind-preset.mjs +2 -2
- package/package.json +14 -14
- package/dist/chunk-74B2EGKT.mjs +0 -99
- package/dist/chunk-AIA3NHCK.js +0 -373
- package/dist/chunk-FL3GD5FJ.mjs +0 -350
- package/dist/chunk-LRNSVRUN.mjs +0 -55
- package/dist/chunk-T4AT3YCT.js +0 -77
- package/dist/chunk-VWFY24XF.js +0 -89
- package/dist/chunk-ZLF7IL3Y.mjs +0 -67
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @dododog/ui
|
|
2
2
|
|
|
3
|
-
React UI component library for [
|
|
3
|
+
React UI component library for [ToutouTrip](https://toutoutrip.com) — the pet-friendly travel platform.
|
|
4
4
|
|
|
5
5
|
Built with React, TypeScript, Tailwind CSS, and [class-variance-authority](https://cva.style).
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ npm install @dododog/ui
|
|
|
14
14
|
|
|
15
15
|
### Tailwind CSS
|
|
16
16
|
|
|
17
|
-
Add the
|
|
17
|
+
Add the ToutouTrip preset and content path to your `tailwind.config.ts`:
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
20
|
import type { Config } from "tailwindcss";
|
|
@@ -113,7 +113,7 @@ export default function App() {
|
|
|
113
113
|
| Export | Import path | Description |
|
|
114
114
|
|--------|-------------|-------------|
|
|
115
115
|
| Tokens | `@dododog/ui/tokens` | Design tokens (colors, spacing, etc.) |
|
|
116
|
-
| Tailwind Preset | `@dododog/ui/tailwind-preset` | Tailwind CSS preset with
|
|
116
|
+
| Tailwind Preset | `@dododog/ui/tailwind-preset` | Tailwind CSS preset with ToutouTrip theme |
|
|
117
117
|
| Utils | `@dododog/ui/utils` | Utility functions (`cn`, etc.) |
|
|
118
118
|
|
|
119
119
|
## Requirements
|
|
@@ -106,7 +106,7 @@ var Footer = React.forwardRef(
|
|
|
106
106
|
bottomExtra
|
|
107
107
|
] }),
|
|
108
108
|
tagline && /* @__PURE__ */ jsx("div", { className: "text-sm text-white/60", children: tagline }),
|
|
109
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-white/60", children: copyright || `\xA9 ${year}
|
|
109
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-white/60", children: copyright || `\xA9 ${year} ToutouTrip. Tous droits r\xE9serv\xE9s.` })
|
|
110
110
|
] }) }) })
|
|
111
111
|
] });
|
|
112
112
|
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { cn } from './chunk-IMKLN273.mjs';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var SIDE_CLASSES = {
|
|
6
|
+
right: "top-0 bottom-0 right-0 w-full max-w-md",
|
|
7
|
+
left: "top-0 bottom-0 left-0 w-full max-w-md",
|
|
8
|
+
bottom: "inset-x-0 bottom-0 w-full max-h-[90dvh] rounded-t-3xl"
|
|
9
|
+
};
|
|
10
|
+
var Drawer = React.forwardRef(
|
|
11
|
+
({
|
|
12
|
+
isOpen,
|
|
13
|
+
onClose,
|
|
14
|
+
children,
|
|
15
|
+
side = "right",
|
|
16
|
+
title,
|
|
17
|
+
labelledById,
|
|
18
|
+
className,
|
|
19
|
+
overlayClassName,
|
|
20
|
+
contentClassName,
|
|
21
|
+
closeLabel = "Fermer"
|
|
22
|
+
}, ref) => {
|
|
23
|
+
React.useEffect(() => {
|
|
24
|
+
if (!isOpen) return;
|
|
25
|
+
const handleKeyDown = (e) => {
|
|
26
|
+
if (e.key === "Escape") onClose();
|
|
27
|
+
};
|
|
28
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
29
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
30
|
+
}, [isOpen, onClose]);
|
|
31
|
+
React.useEffect(() => {
|
|
32
|
+
if (!isOpen) return;
|
|
33
|
+
const prev = document.body.style.overflow;
|
|
34
|
+
document.body.style.overflow = "hidden";
|
|
35
|
+
return () => {
|
|
36
|
+
document.body.style.overflow = prev;
|
|
37
|
+
};
|
|
38
|
+
}, [isOpen]);
|
|
39
|
+
if (!isOpen) return null;
|
|
40
|
+
return /* @__PURE__ */ jsxs(
|
|
41
|
+
"div",
|
|
42
|
+
{
|
|
43
|
+
ref,
|
|
44
|
+
className: cn("fixed inset-0 z-50", overlayClassName),
|
|
45
|
+
role: "dialog",
|
|
46
|
+
"aria-modal": "true",
|
|
47
|
+
"aria-labelledby": labelledById,
|
|
48
|
+
"aria-label": labelledById ? void 0 : title,
|
|
49
|
+
children: [
|
|
50
|
+
/* @__PURE__ */ jsx(
|
|
51
|
+
"div",
|
|
52
|
+
{
|
|
53
|
+
className: "absolute inset-0 bg-black/50 transition-opacity",
|
|
54
|
+
onClick: onClose,
|
|
55
|
+
"aria-hidden": "true"
|
|
56
|
+
}
|
|
57
|
+
),
|
|
58
|
+
/* @__PURE__ */ jsxs(
|
|
59
|
+
"div",
|
|
60
|
+
{
|
|
61
|
+
className: cn(
|
|
62
|
+
"absolute bg-white shadow-xl flex flex-col overflow-hidden",
|
|
63
|
+
SIDE_CLASSES[side],
|
|
64
|
+
className
|
|
65
|
+
),
|
|
66
|
+
children: [
|
|
67
|
+
/* @__PURE__ */ jsxs(
|
|
68
|
+
"div",
|
|
69
|
+
{
|
|
70
|
+
className: cn(
|
|
71
|
+
"flex items-center gap-2 px-4 h-16 shrink-0",
|
|
72
|
+
title ? "justify-between border-b border-gray-100" : "justify-end"
|
|
73
|
+
),
|
|
74
|
+
children: [
|
|
75
|
+
title && /* @__PURE__ */ jsx("h2", { className: "text-lg font-heading font-semibold text-primary truncate", children: title }),
|
|
76
|
+
/* @__PURE__ */ jsx(
|
|
77
|
+
"button",
|
|
78
|
+
{
|
|
79
|
+
type: "button",
|
|
80
|
+
onClick: onClose,
|
|
81
|
+
className: "p-2 hover:bg-gray-100 rounded-full transition-colors shrink-0",
|
|
82
|
+
"aria-label": closeLabel,
|
|
83
|
+
children: /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
84
|
+
/* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
|
|
85
|
+
/* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
|
|
86
|
+
] })
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsx(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
"data-drawer-content": "",
|
|
96
|
+
className: cn("flex-1 overflow-y-auto overscroll-contain", contentClassName),
|
|
97
|
+
children
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
Drawer.displayName = "Drawer";
|
|
109
|
+
|
|
110
|
+
export { Drawer };
|
|
@@ -46,31 +46,61 @@ var inputVariants = classVarianceAuthority.cva(
|
|
|
46
46
|
}
|
|
47
47
|
);
|
|
48
48
|
var Input = React__namespace.forwardRef(
|
|
49
|
-
({
|
|
49
|
+
({
|
|
50
|
+
className,
|
|
51
|
+
size,
|
|
52
|
+
variant,
|
|
53
|
+
label,
|
|
54
|
+
error,
|
|
55
|
+
required,
|
|
56
|
+
leftIcon,
|
|
57
|
+
rightIcon,
|
|
58
|
+
id,
|
|
59
|
+
"aria-describedby": ariaDescribedBy,
|
|
60
|
+
"aria-invalid": ariaInvalid,
|
|
61
|
+
"aria-required": ariaRequired,
|
|
62
|
+
...props
|
|
63
|
+
}, ref) => {
|
|
64
|
+
const generatedId = React__namespace.useId();
|
|
65
|
+
const inputId = id ?? generatedId;
|
|
66
|
+
const errorId = `${inputId}-error`;
|
|
50
67
|
const resolvedVariant = error ? "error" : variant ?? "default";
|
|
68
|
+
const describedBy = [ariaDescribedBy, error ? errorId : null].filter(Boolean).join(" ") || void 0;
|
|
51
69
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
52
|
-
label && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
53
|
-
label,
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
71
|
+
"label",
|
|
72
|
+
{
|
|
73
|
+
htmlFor: inputId,
|
|
74
|
+
className: "block text-sm font-medium text-primary mb-1.5",
|
|
75
|
+
children: [
|
|
76
|
+
label,
|
|
77
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-secondary", "aria-hidden": "true", children: " *" })
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
),
|
|
56
81
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
57
82
|
leftIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-text-muted", children: leftIcon }),
|
|
58
83
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
59
84
|
"input",
|
|
60
85
|
{
|
|
86
|
+
...props,
|
|
61
87
|
ref,
|
|
88
|
+
id: inputId,
|
|
89
|
+
required,
|
|
90
|
+
"aria-required": ariaRequired ?? (required ? true : void 0),
|
|
91
|
+
"aria-invalid": ariaInvalid ?? (error ? true : void 0),
|
|
92
|
+
"aria-describedby": describedBy,
|
|
62
93
|
className: chunkADIDI7AJ_js.cn(
|
|
63
94
|
inputVariants({ size, variant: resolvedVariant }),
|
|
64
95
|
leftIcon && "pl-10",
|
|
65
96
|
rightIcon && "pr-10",
|
|
66
97
|
className
|
|
67
|
-
)
|
|
68
|
-
...props
|
|
98
|
+
)
|
|
69
99
|
}
|
|
70
100
|
),
|
|
71
101
|
rightIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 text-text-muted", children: rightIcon })
|
|
72
102
|
] }),
|
|
73
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-red-500", children: error })
|
|
103
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: "mt-1 text-sm text-red-500", children: error })
|
|
74
104
|
] });
|
|
75
105
|
}
|
|
76
106
|
);
|
|
@@ -73,11 +73,15 @@ Accordion.displayName = "Accordion";
|
|
|
73
73
|
function AccordionItem({ title, isOpen, onToggle, children }) {
|
|
74
74
|
const contentRef = React__namespace.useRef(null);
|
|
75
75
|
const [height, setHeight] = React__namespace.useState(0);
|
|
76
|
+
const baseId = React__namespace.useId();
|
|
77
|
+
const headerId = `${baseId}-header`;
|
|
78
|
+
const panelId = `${baseId}-panel`;
|
|
76
79
|
React__namespace.useEffect(() => {
|
|
77
80
|
if (contentRef.current) {
|
|
78
81
|
setHeight(isOpen ? contentRef.current.scrollHeight : 0);
|
|
79
82
|
}
|
|
80
83
|
}, [isOpen]);
|
|
84
|
+
const inertProps = isOpen ? {} : { inert: "" };
|
|
81
85
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
82
86
|
"div",
|
|
83
87
|
{
|
|
@@ -89,8 +93,10 @@ function AccordionItem({ title, isOpen, onToggle, children }) {
|
|
|
89
93
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
90
94
|
"button",
|
|
91
95
|
{
|
|
96
|
+
id: headerId,
|
|
92
97
|
onClick: onToggle,
|
|
93
98
|
"aria-expanded": isOpen,
|
|
99
|
+
"aria-controls": panelId,
|
|
94
100
|
className: "w-full flex items-center justify-between py-5 px-5 text-left group",
|
|
95
101
|
children: [
|
|
96
102
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -106,6 +112,7 @@ function AccordionItem({ title, isOpen, onToggle, children }) {
|
|
|
106
112
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107
113
|
"div",
|
|
108
114
|
{
|
|
115
|
+
"aria-hidden": "true",
|
|
109
116
|
className: chunkADIDI7AJ_js.cn(
|
|
110
117
|
"w-7 h-7 rounded-full flex items-center justify-center shrink-0 transition-all duration-300",
|
|
111
118
|
isOpen ? "bg-secondary text-white" : "bg-gray-100 text-gray-600 group-hover:bg-secondary/10 group-hover:text-secondary"
|
|
@@ -122,7 +129,12 @@ function AccordionItem({ title, isOpen, onToggle, children }) {
|
|
|
122
129
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
123
130
|
"div",
|
|
124
131
|
{
|
|
125
|
-
|
|
132
|
+
id: panelId,
|
|
133
|
+
role: "region",
|
|
134
|
+
"aria-labelledby": headerId,
|
|
135
|
+
"aria-hidden": isOpen ? void 0 : true,
|
|
136
|
+
...inertProps,
|
|
137
|
+
style: { height, visibility: isOpen ? void 0 : "hidden" },
|
|
126
138
|
className: "overflow-hidden transition-all duration-500 ease-out",
|
|
127
139
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: contentRef, className: "pb-5 px-5 pr-12", children })
|
|
128
140
|
}
|
|
@@ -24,10 +24,30 @@ function _interopNamespace(e) {
|
|
|
24
24
|
|
|
25
25
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
26
26
|
|
|
27
|
+
var FOCUSABLE_SELECTOR = 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
27
28
|
var Lightbox = React__namespace.forwardRef(
|
|
28
|
-
({
|
|
29
|
+
({
|
|
30
|
+
images,
|
|
31
|
+
initialIndex = 0,
|
|
32
|
+
open,
|
|
33
|
+
onClose,
|
|
34
|
+
className,
|
|
35
|
+
"aria-label": ariaLabel = "Visionneuse d'images"
|
|
36
|
+
}, ref) => {
|
|
29
37
|
const [current, setCurrent] = React__namespace.useState(initialIndex);
|
|
30
38
|
const touchStartX = React__namespace.useRef(0);
|
|
39
|
+
const containerRef = React__namespace.useRef(null);
|
|
40
|
+
const setRefs = React__namespace.useCallback(
|
|
41
|
+
(node) => {
|
|
42
|
+
containerRef.current = node;
|
|
43
|
+
if (typeof ref === "function") {
|
|
44
|
+
ref(node);
|
|
45
|
+
} else if (ref) {
|
|
46
|
+
ref.current = node;
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
[ref]
|
|
50
|
+
);
|
|
31
51
|
React__namespace.useEffect(() => {
|
|
32
52
|
if (open) setCurrent(initialIndex);
|
|
33
53
|
}, [open, initialIndex]);
|
|
@@ -37,6 +57,28 @@ var Lightbox = React__namespace.forwardRef(
|
|
|
37
57
|
if (e.key === "Escape") onClose();
|
|
38
58
|
if (e.key === "ArrowLeft") setCurrent((c) => (c - 1 + images.length) % images.length);
|
|
39
59
|
if (e.key === "ArrowRight") setCurrent((c) => (c + 1) % images.length);
|
|
60
|
+
if (e.key === "Tab") {
|
|
61
|
+
const node = containerRef.current;
|
|
62
|
+
if (!node) return;
|
|
63
|
+
const items = Array.from(
|
|
64
|
+
node.querySelectorAll(FOCUSABLE_SELECTOR)
|
|
65
|
+
);
|
|
66
|
+
if (items.length === 0) {
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const first = items[0];
|
|
71
|
+
const last = items[items.length - 1];
|
|
72
|
+
const active = document.activeElement;
|
|
73
|
+
const inside = active instanceof Node && node.contains(active);
|
|
74
|
+
if (e.shiftKey && (!inside || active === first)) {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
last.focus();
|
|
77
|
+
} else if (!e.shiftKey && (!inside || active === last)) {
|
|
78
|
+
e.preventDefault();
|
|
79
|
+
first.focus();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
40
82
|
}
|
|
41
83
|
document.addEventListener("keydown", handleKeyDown);
|
|
42
84
|
document.body.style.overflow = "hidden";
|
|
@@ -45,13 +87,24 @@ var Lightbox = React__namespace.forwardRef(
|
|
|
45
87
|
document.body.style.overflow = "";
|
|
46
88
|
};
|
|
47
89
|
}, [open, images.length, onClose]);
|
|
90
|
+
React__namespace.useEffect(() => {
|
|
91
|
+
if (!open) return;
|
|
92
|
+
const previouslyFocused = document.activeElement;
|
|
93
|
+
const node = containerRef.current;
|
|
94
|
+
const target = node?.querySelector(FOCUSABLE_SELECTOR) ?? node ?? null;
|
|
95
|
+
target?.focus?.();
|
|
96
|
+
return () => {
|
|
97
|
+
previouslyFocused?.focus?.();
|
|
98
|
+
};
|
|
99
|
+
}, [open]);
|
|
48
100
|
if (!open || images.length === 0) return null;
|
|
49
101
|
const prev = () => setCurrent((c) => (c - 1 + images.length) % images.length);
|
|
50
102
|
const next = () => setCurrent((c) => (c + 1) % images.length);
|
|
51
103
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52
104
|
"div",
|
|
53
105
|
{
|
|
54
|
-
ref,
|
|
106
|
+
ref: setRefs,
|
|
107
|
+
tabIndex: -1,
|
|
55
108
|
className: chunkADIDI7AJ_js.cn(
|
|
56
109
|
"fixed inset-0 z-50 flex items-center justify-center bg-black/90",
|
|
57
110
|
className
|
|
@@ -59,14 +112,14 @@ var Lightbox = React__namespace.forwardRef(
|
|
|
59
112
|
onClick: onClose,
|
|
60
113
|
role: "dialog",
|
|
61
114
|
"aria-modal": "true",
|
|
62
|
-
"aria-label":
|
|
115
|
+
"aria-label": ariaLabel,
|
|
63
116
|
children: [
|
|
64
117
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
65
118
|
"button",
|
|
66
119
|
{
|
|
67
120
|
onClick: onClose,
|
|
68
121
|
className: "absolute top-4 right-4 z-10 w-10 h-10 rounded-full bg-white/10 backdrop-blur-sm flex items-center justify-center text-white hover:bg-white/20 transition-colors",
|
|
69
|
-
"aria-label": "
|
|
122
|
+
"aria-label": "Fermer la visionneuse",
|
|
70
123
|
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
71
124
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18" }),
|
|
72
125
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 6 12 12" })
|
|
@@ -74,9 +127,12 @@ var Lightbox = React__namespace.forwardRef(
|
|
|
74
127
|
}
|
|
75
128
|
),
|
|
76
129
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-4 left-4 z-10 px-3 py-1.5 rounded-full bg-white/10 backdrop-blur-sm text-white text-sm", children: [
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
130
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { "aria-hidden": "true", children: [
|
|
131
|
+
current + 1,
|
|
132
|
+
" / ",
|
|
133
|
+
images.length
|
|
134
|
+
] }),
|
|
135
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", "aria-live": "polite", "aria-atomic": "true", children: `Image ${current + 1} sur ${images.length}` })
|
|
80
136
|
] }),
|
|
81
137
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
82
138
|
"div",
|
|
@@ -112,7 +168,7 @@ var Lightbox = React__namespace.forwardRef(
|
|
|
112
168
|
prev();
|
|
113
169
|
},
|
|
114
170
|
className: "absolute left-4 top-1/2 -translate-y-1/2 w-12 h-12 rounded-full bg-white/10 backdrop-blur-sm flex items-center justify-center text-white hover:bg-white/20 transition-colors",
|
|
115
|
-
"aria-label": "
|
|
171
|
+
"aria-label": "Image pr\xE9c\xE9dente",
|
|
116
172
|
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m15 18-6-6 6-6" }) })
|
|
117
173
|
}
|
|
118
174
|
),
|
|
@@ -124,33 +180,44 @@ var Lightbox = React__namespace.forwardRef(
|
|
|
124
180
|
next();
|
|
125
181
|
},
|
|
126
182
|
className: "absolute right-4 top-1/2 -translate-y-1/2 w-12 h-12 rounded-full bg-white/10 backdrop-blur-sm flex items-center justify-center text-white hover:bg-white/20 transition-colors",
|
|
127
|
-
"aria-label": "
|
|
183
|
+
"aria-label": "Image suivante",
|
|
128
184
|
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 18 6-6-6-6" }) })
|
|
129
185
|
}
|
|
130
186
|
)
|
|
131
187
|
] }),
|
|
132
|
-
images.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
133
|
-
"
|
|
188
|
+
images.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
189
|
+
"div",
|
|
134
190
|
{
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
"w-16 h-12 rounded-lg overflow-hidden flex-shrink-0 border-2 transition-all",
|
|
141
|
-
i === current ? "border-white opacity-100" : "border-transparent opacity-50 hover:opacity-75"
|
|
142
|
-
),
|
|
143
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
144
|
-
"img",
|
|
191
|
+
role: "group",
|
|
192
|
+
"aria-label": "Vignettes des images",
|
|
193
|
+
className: "absolute bottom-4 left-1/2 -translate-x-1/2 flex gap-2 max-w-[80vw] overflow-x-auto px-4 py-2",
|
|
194
|
+
children: images.map((img, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
195
|
+
"button",
|
|
145
196
|
{
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
197
|
+
onClick: (e) => {
|
|
198
|
+
e.stopPropagation();
|
|
199
|
+
setCurrent(i);
|
|
200
|
+
},
|
|
201
|
+
"aria-label": `Afficher l'image ${i + 1} : ${img.alt}`,
|
|
202
|
+
"aria-current": i === current ? "true" : void 0,
|
|
203
|
+
className: chunkADIDI7AJ_js.cn(
|
|
204
|
+
"w-16 h-12 rounded-lg overflow-hidden flex-shrink-0 border-2 transition-all",
|
|
205
|
+
i === current ? "border-white opacity-100" : "border-transparent opacity-50 hover:opacity-75"
|
|
206
|
+
),
|
|
207
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
208
|
+
"img",
|
|
209
|
+
{
|
|
210
|
+
src: img.src,
|
|
211
|
+
alt: "",
|
|
212
|
+
"aria-hidden": "true",
|
|
213
|
+
className: "w-full h-full object-cover"
|
|
214
|
+
}
|
|
215
|
+
)
|
|
216
|
+
},
|
|
217
|
+
i
|
|
218
|
+
))
|
|
219
|
+
}
|
|
220
|
+
)
|
|
154
221
|
]
|
|
155
222
|
}
|
|
156
223
|
);
|