@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.
Files changed (73) hide show
  1. package/README.md +3 -3
  2. package/dist/{chunk-SZ3SV4SJ.mjs → chunk-4DHZ6MIL.mjs} +1 -1
  3. package/dist/chunk-5KOWMIWK.mjs +110 -0
  4. package/dist/{chunk-77WKG2D7.js → chunk-5UNG2O64.js} +38 -8
  5. package/dist/{chunk-MCF3EQTV.js → chunk-73BHQJW6.js} +13 -1
  6. package/dist/{chunk-U3XWNFHH.js → chunk-A3M3XQ35.js} +96 -29
  7. package/dist/chunk-BKM5VCUS.mjs +569 -0
  8. package/dist/{chunk-333YD5QI.mjs → chunk-EAATIFYL.mjs} +40 -6
  9. package/dist/{chunk-C4RZBOKH.js → chunk-EQPT6VZF.js} +1 -1
  10. package/dist/chunk-FLKEMER2.js +592 -0
  11. package/dist/{chunk-NBDPT3XQ.js → chunk-HH4X2JYO.js} +94 -15
  12. package/dist/{chunk-I4S3R6C6.js → chunk-JUB3NGJR.js} +51 -6
  13. package/dist/{chunk-GRG4USTC.mjs → chunk-JWOV5H6G.mjs} +38 -8
  14. package/dist/chunk-JWQ2OUEG.js +132 -0
  15. package/dist/{chunk-3R7PT3JG.js → chunk-LJSMPON7.js} +40 -6
  16. package/dist/chunk-N5ZNXNCO.mjs +178 -0
  17. package/dist/{chunk-DMCMWOBJ.mjs → chunk-PBXH4I5N.mjs} +51 -6
  18. package/dist/{chunk-ERL3WXNY.mjs → chunk-PZZWQ6IG.mjs} +5 -5
  19. package/dist/{chunk-GBWVIY3C.mjs → chunk-UJEIFKSK.mjs} +96 -29
  20. package/dist/chunk-WY24TZ4R.mjs +94 -0
  21. package/dist/chunk-XBNIHUSG.js +116 -0
  22. package/dist/{chunk-TDGU5Y2P.js → chunk-XOFTU3T7.js} +5 -5
  23. package/dist/{chunk-NZ7GF6RF.mjs → chunk-YOMOULLR.mjs} +13 -1
  24. package/dist/components/Accordion/index.js +2 -2
  25. package/dist/components/Accordion/index.mjs +1 -1
  26. package/dist/components/Counter/index.d.mts +12 -0
  27. package/dist/components/Counter/index.d.ts +12 -0
  28. package/dist/components/Counter/index.js +2 -2
  29. package/dist/components/Counter/index.mjs +1 -1
  30. package/dist/components/DateRangePicker/index.d.mts +7 -1
  31. package/dist/components/DateRangePicker/index.d.ts +7 -1
  32. package/dist/components/DateRangePicker/index.js +3 -3
  33. package/dist/components/DateRangePicker/index.mjs +1 -1
  34. package/dist/components/Drawer/index.d.mts +21 -1
  35. package/dist/components/Drawer/index.d.ts +21 -1
  36. package/dist/components/Drawer/index.js +2 -2
  37. package/dist/components/Drawer/index.mjs +1 -1
  38. package/dist/components/DualRangeSlider/index.js +2 -2
  39. package/dist/components/DualRangeSlider/index.mjs +1 -1
  40. package/dist/components/Footer/index.js +2 -2
  41. package/dist/components/Footer/index.mjs +1 -1
  42. package/dist/components/Input/index.js +3 -3
  43. package/dist/components/Input/index.mjs +1 -1
  44. package/dist/components/Lightbox/index.d.mts +2 -0
  45. package/dist/components/Lightbox/index.d.ts +2 -0
  46. package/dist/components/Lightbox/index.js +2 -2
  47. package/dist/components/Lightbox/index.mjs +1 -1
  48. package/dist/components/Modal/index.d.mts +12 -0
  49. package/dist/components/Modal/index.d.ts +12 -0
  50. package/dist/components/Modal/index.js +2 -2
  51. package/dist/components/Modal/index.mjs +1 -1
  52. package/dist/components/Select/index.d.mts +8 -0
  53. package/dist/components/Select/index.d.ts +8 -0
  54. package/dist/components/Select/index.js +3 -3
  55. package/dist/components/Select/index.mjs +1 -1
  56. package/dist/components/Switch/index.d.mts +41 -1
  57. package/dist/components/Switch/index.d.ts +41 -1
  58. package/dist/components/Switch/index.js +4 -4
  59. package/dist/components/Switch/index.mjs +1 -1
  60. package/dist/index.js +45 -45
  61. package/dist/index.mjs +14 -14
  62. package/dist/tailwind-preset.d.mts +2 -2
  63. package/dist/tailwind-preset.d.ts +2 -2
  64. package/dist/tailwind-preset.js +2 -2
  65. package/dist/tailwind-preset.mjs +2 -2
  66. package/package.json +14 -14
  67. package/dist/chunk-74B2EGKT.mjs +0 -99
  68. package/dist/chunk-AIA3NHCK.js +0 -373
  69. package/dist/chunk-FL3GD5FJ.mjs +0 -350
  70. package/dist/chunk-LRNSVRUN.mjs +0 -55
  71. package/dist/chunk-T4AT3YCT.js +0 -77
  72. package/dist/chunk-VWFY24XF.js +0 -89
  73. 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 [DodoDog](https://dododog.voyage) — the pet-friendly travel platform.
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 DodoDog preset and content path to your `tailwind.config.ts`:
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 DodoDog theme |
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} DodoDog. Tous droits r\xE9serv\xE9s.` })
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
- ({ className, size, variant, label, error, required, leftIcon, rightIcon, ...props }, ref) => {
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("label", { className: "block text-sm font-medium text-primary mb-1.5", children: [
53
- label,
54
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-secondary", children: " *" })
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
- style: { height },
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
- ({ images, initialIndex = 0, open, onClose, className }, ref) => {
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": "Image viewer",
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": "Close",
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
- current + 1,
78
- " / ",
79
- images.length
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": "Previous image",
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": "Next image",
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("div", { className: "absolute bottom-4 left-1/2 -translate-x-1/2 flex gap-2 max-w-[80vw] overflow-x-auto px-4 py-2", children: images.map((img, i) => /* @__PURE__ */ jsxRuntime.jsx(
133
- "button",
188
+ images.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
189
+ "div",
134
190
  {
135
- onClick: (e) => {
136
- e.stopPropagation();
137
- setCurrent(i);
138
- },
139
- className: chunkADIDI7AJ_js.cn(
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
- src: img.src,
147
- alt: img.alt,
148
- className: "w-full h-full object-cover"
149
- }
150
- )
151
- },
152
- i
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
  );