@puzzle-ui/ui 0.4.0 → 0.5.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 -4
- package/dist/components/actions/button/button.css +5 -2
- package/dist/components/actions/button-group/button-group.css +16 -17
- package/dist/components/data-display/badge/badge.css +15 -2
- package/dist/components/data-display/badge/index.cjs +13 -2
- package/dist/components/data-display/badge/index.cjs.map +1 -1
- package/dist/components/data-display/badge/index.d.cts +7 -2
- package/dist/components/data-display/badge/index.d.ts +7 -2
- package/dist/components/data-display/badge/index.js +13 -2
- package/dist/components/data-display/badge/index.js.map +1 -1
- package/dist/components/data-display/rating/index.cjs +84 -0
- package/dist/components/data-display/rating/index.cjs.map +1 -0
- package/dist/components/data-display/rating/index.d.cts +3 -0
- package/dist/components/data-display/rating/index.d.ts +3 -0
- package/dist/components/data-display/rating/index.js +84 -0
- package/dist/components/data-display/rating/index.js.map +1 -0
- package/dist/components/data-display/rating/rating.css +72 -0
- package/dist/components/data-display/rating/rating.types.d.cts +15 -0
- package/dist/components/data-display/rating/rating.types.d.ts +15 -0
- package/dist/components/data-display/rating/rating.utils.cjs +27 -0
- package/dist/components/data-display/rating/rating.utils.cjs.map +1 -0
- package/dist/components/data-display/rating/rating.utils.js +25 -0
- package/dist/components/data-display/rating/rating.utils.js.map +1 -0
- package/dist/components/forms/checkbox/checkbox.css +2 -10
- package/dist/components/forms/input-group/input-group.d.cts +4 -2
- package/dist/components/forms/input-group/input-group.d.ts +4 -2
- package/dist/components/forms/radio-group/index.d.cts +2 -1
- package/dist/components/forms/radio-group/index.d.ts +2 -1
- package/dist/components/forms/stepper/index.d.cts +4 -2
- package/dist/components/forms/stepper/index.d.ts +4 -2
- package/dist/components/forms/time-picker/index.cjs +108 -0
- package/dist/components/forms/time-picker/index.cjs.map +1 -0
- package/dist/components/forms/time-picker/index.d.cts +3 -0
- package/dist/components/forms/time-picker/index.d.ts +3 -0
- package/dist/components/forms/time-picker/index.js +108 -0
- package/dist/components/forms/time-picker/index.js.map +1 -0
- package/dist/components/forms/time-picker/time-picker.css +166 -0
- package/dist/components/forms/time-picker/time-picker.types.d.cts +34 -0
- package/dist/components/forms/time-picker/time-picker.types.d.ts +34 -0
- package/dist/components/forms/time-picker/time-picker.utils.cjs +25 -0
- package/dist/components/forms/time-picker/time-picker.utils.cjs.map +1 -0
- package/dist/components/forms/time-picker/time-picker.utils.js +24 -0
- package/dist/components/forms/time-picker/time-picker.utils.js.map +1 -0
- package/dist/components/forms/token-input/index.cjs +189 -0
- package/dist/components/forms/token-input/index.cjs.map +1 -0
- package/dist/components/forms/token-input/index.d.cts +3 -0
- package/dist/components/forms/token-input/index.d.ts +3 -0
- package/dist/components/forms/token-input/index.js +189 -0
- package/dist/components/forms/token-input/index.js.map +1 -0
- package/dist/components/forms/token-input/token-input.css +145 -0
- package/dist/components/forms/token-input/token-input.types.d.cts +48 -0
- package/dist/components/forms/token-input/token-input.types.d.ts +48 -0
- package/dist/components/forms/token-input/token-input.utils.cjs +30 -0
- package/dist/components/forms/token-input/token-input.utils.cjs.map +1 -0
- package/dist/components/forms/token-input/token-input.utils.js +24 -0
- package/dist/components/forms/token-input/token-input.utils.js.map +1 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.css +14 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.cjs +11 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.cjs.map +1 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.js +11 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.js.map +1 -0
- package/dist/components/layout/aspect-ratio/index.cjs +16 -0
- package/dist/components/layout/aspect-ratio/index.cjs.map +1 -0
- package/dist/components/layout/aspect-ratio/index.d.cts +11 -0
- package/dist/components/layout/aspect-ratio/index.d.ts +11 -0
- package/dist/components/layout/aspect-ratio/index.js +16 -0
- package/dist/components/layout/aspect-ratio/index.js.map +1 -0
- package/dist/components/layout/container/container.css +1 -0
- package/dist/components/layout/page-layout/page-layout.css +1 -0
- package/dist/components/layout/scroll-area/index.cjs +27 -0
- package/dist/components/layout/scroll-area/index.cjs.map +1 -0
- package/dist/components/layout/scroll-area/index.d.cts +15 -0
- package/dist/components/layout/scroll-area/index.d.ts +15 -0
- package/dist/components/layout/scroll-area/index.js +27 -0
- package/dist/components/layout/scroll-area/index.js.map +1 -0
- package/dist/components/layout/scroll-area/scroll-area.css +25 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.cjs +8 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.cjs.map +1 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.d.cts +2 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.d.ts +2 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.js +8 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.js.map +1 -0
- package/dist/components/layout/section/index.cjs +10 -4
- package/dist/components/layout/section/index.cjs.map +1 -1
- package/dist/components/layout/section/index.d.cts +1 -1
- package/dist/components/layout/section/index.d.ts +1 -1
- package/dist/components/layout/section/index.js +11 -5
- package/dist/components/layout/section/index.js.map +1 -1
- package/dist/components/layout/section/section.css +9 -3
- package/dist/components/layout/section/types.d.cts +5 -5
- package/dist/components/layout/section/types.d.ts +5 -5
- package/dist/components/layout/separator/index.cjs +18 -0
- package/dist/components/layout/separator/index.cjs.map +1 -0
- package/dist/components/layout/separator/index.d.cts +17 -0
- package/dist/components/layout/separator/index.d.ts +17 -0
- package/dist/components/layout/separator/index.js +18 -0
- package/dist/components/layout/separator/index.js.map +1 -0
- package/dist/components/layout/separator/separator.css +15 -0
- package/dist/components/layout/separator/separator.utils.cjs +11 -0
- package/dist/components/layout/separator/separator.utils.cjs.map +1 -0
- package/dist/components/layout/separator/separator.utils.d.cts +2 -0
- package/dist/components/layout/separator/separator.utils.d.ts +2 -0
- package/dist/components/layout/separator/separator.utils.js +11 -0
- package/dist/components/layout/separator/separator.utils.js.map +1 -0
- package/dist/components/layout/stack/index.cjs +18 -2
- package/dist/components/layout/stack/index.cjs.map +1 -1
- package/dist/components/layout/stack/index.d.cts +8 -6
- package/dist/components/layout/stack/index.d.ts +8 -6
- package/dist/components/layout/stack/index.js +18 -2
- package/dist/components/layout/stack/index.js.map +1 -1
- package/dist/components/layout/stack/stack.css +118 -138
- package/dist/components/navigation/carousel/index.cjs +4 -1
- package/dist/components/navigation/carousel/index.cjs.map +1 -1
- package/dist/components/navigation/carousel/index.js +4 -1
- package/dist/components/navigation/carousel/index.js.map +1 -1
- package/dist/components/navigation/tabs/index.d.cts +3 -2
- package/dist/components/navigation/tabs/index.d.ts +3 -2
- package/dist/components/overlays/context-menu/context-menu.css +151 -0
- package/dist/components/overlays/context-menu/context-menu.types.d.cts +69 -0
- package/dist/components/overlays/context-menu/context-menu.types.d.ts +69 -0
- package/dist/components/overlays/context-menu/context-menu.utils.cjs +46 -0
- package/dist/components/overlays/context-menu/context-menu.utils.cjs.map +1 -0
- package/dist/components/overlays/context-menu/context-menu.utils.js +40 -0
- package/dist/components/overlays/context-menu/context-menu.utils.js.map +1 -0
- package/dist/components/overlays/context-menu/index.cjs +830 -0
- package/dist/components/overlays/context-menu/index.cjs.map +1 -0
- package/dist/components/overlays/context-menu/index.d.cts +42 -0
- package/dist/components/overlays/context-menu/index.d.ts +42 -0
- package/dist/components/overlays/context-menu/index.js +818 -0
- package/dist/components/overlays/context-menu/index.js.map +1 -0
- package/dist/components/typography/heading.cjs +6 -2
- package/dist/components/typography/heading.cjs.map +1 -1
- package/dist/components/typography/heading.d.cts +3 -2
- package/dist/components/typography/heading.d.ts +3 -2
- package/dist/components/typography/heading.js +6 -2
- package/dist/components/typography/heading.js.map +1 -1
- package/dist/components/typography/text.cjs +6 -2
- package/dist/components/typography/text.cjs.map +1 -1
- package/dist/components/typography/text.d.cts +3 -2
- package/dist/components/typography/text.d.ts +3 -2
- package/dist/components/typography/text.js +6 -2
- package/dist/components/typography/text.js.map +1 -1
- package/dist/components/utilities/preview/index.cjs +88 -20
- package/dist/components/utilities/preview/index.cjs.map +1 -1
- package/dist/components/utilities/preview/index.d.cts +6 -2
- package/dist/components/utilities/preview/index.d.ts +6 -2
- package/dist/components/utilities/preview/index.js +88 -20
- package/dist/components/utilities/preview/index.js.map +1 -1
- package/dist/components/utilities/preview/preview.css +26 -11
- package/dist/components/utilities/transition/index.d.cts +1 -1
- package/dist/components/utilities/transition/index.d.ts +1 -1
- package/dist/index.cjs +123 -97
- package/dist/index.d.cts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +8 -1
- package/package.json +6 -6
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
.puzzle-stack {
|
|
2
|
+
--stack-align-h: flex-start;
|
|
3
|
+
--stack-align-v: flex-start;
|
|
4
|
+
--stack-main-alignment: var(--stack-align-v);
|
|
5
|
+
--stack-cross-alignment: var(--stack-align-h);
|
|
2
6
|
gap: var(--puzzle-space-4, 1rem);
|
|
3
7
|
justify-content: flex-start;
|
|
4
8
|
align-items: stretch;
|
|
5
9
|
display: flex;
|
|
6
10
|
}
|
|
7
11
|
|
|
12
|
+
.puzzle-stack.has-alignment {
|
|
13
|
+
justify-content: var(--stack-main-alignment);
|
|
14
|
+
align-items: var(--stack-cross-alignment);
|
|
15
|
+
}
|
|
16
|
+
|
|
8
17
|
.puzzle-stack.nowrap {
|
|
9
18
|
flex-wrap: nowrap;
|
|
10
19
|
}
|
|
@@ -30,18 +39,20 @@
|
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
.puzzle-stack.gap-md {
|
|
33
|
-
gap: var(--puzzle-space-
|
|
42
|
+
gap: var(--puzzle-space-4, 1rem);
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
.puzzle-stack.gap-lg {
|
|
37
|
-
gap: var(--puzzle-space-
|
|
46
|
+
gap: var(--puzzle-space-8, 2rem);
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
.puzzle-stack.gap-xl {
|
|
41
|
-
gap: var(--puzzle-space-
|
|
50
|
+
gap: var(--puzzle-space-16, 4rem);
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
.puzzle-stack.direction-mobile-row {
|
|
54
|
+
--stack-main-alignment: var(--stack-align-h);
|
|
55
|
+
--stack-cross-alignment: var(--stack-align-v);
|
|
45
56
|
flex-direction: row;
|
|
46
57
|
}
|
|
47
58
|
|
|
@@ -50,6 +61,8 @@
|
|
|
50
61
|
}
|
|
51
62
|
|
|
52
63
|
.puzzle-stack.direction-mobile-col {
|
|
64
|
+
--stack-main-alignment: var(--stack-align-v);
|
|
65
|
+
--stack-cross-alignment: var(--stack-align-h);
|
|
53
66
|
flex-direction: column;
|
|
54
67
|
}
|
|
55
68
|
|
|
@@ -57,52 +70,66 @@
|
|
|
57
70
|
flex-direction: column-reverse;
|
|
58
71
|
}
|
|
59
72
|
|
|
60
|
-
.puzzle-stack.
|
|
61
|
-
|
|
73
|
+
.puzzle-stack.align-h-mobile-start {
|
|
74
|
+
--stack-align-h: flex-start;
|
|
62
75
|
}
|
|
63
76
|
|
|
64
|
-
.puzzle-stack.
|
|
65
|
-
|
|
77
|
+
.puzzle-stack.align-h-mobile-center {
|
|
78
|
+
--stack-align-h: center;
|
|
66
79
|
}
|
|
67
80
|
|
|
68
|
-
.puzzle-stack.
|
|
69
|
-
|
|
81
|
+
.puzzle-stack.align-h-mobile-end {
|
|
82
|
+
--stack-align-h: flex-end;
|
|
70
83
|
}
|
|
71
84
|
|
|
72
|
-
.puzzle-stack.
|
|
73
|
-
|
|
85
|
+
.puzzle-stack.align-h-mobile-stretch {
|
|
86
|
+
--stack-align-h: stretch;
|
|
74
87
|
}
|
|
75
88
|
|
|
76
|
-
.puzzle-stack.
|
|
77
|
-
|
|
89
|
+
.puzzle-stack.align-h-mobile-around {
|
|
90
|
+
--stack-align-h: space-around;
|
|
78
91
|
}
|
|
79
92
|
|
|
80
|
-
.puzzle-stack.
|
|
81
|
-
|
|
93
|
+
.puzzle-stack.align-h-mobile-between {
|
|
94
|
+
--stack-align-h: space-between;
|
|
82
95
|
}
|
|
83
96
|
|
|
84
|
-
.puzzle-stack.
|
|
85
|
-
|
|
97
|
+
.puzzle-stack.align-h-mobile-evenly {
|
|
98
|
+
--stack-align-h: space-evenly;
|
|
86
99
|
}
|
|
87
100
|
|
|
88
|
-
.puzzle-stack.
|
|
89
|
-
align-
|
|
101
|
+
.puzzle-stack.align-v-mobile-start {
|
|
102
|
+
--stack-align-v: flex-start;
|
|
90
103
|
}
|
|
91
104
|
|
|
92
|
-
.puzzle-stack.
|
|
93
|
-
align-
|
|
105
|
+
.puzzle-stack.align-v-mobile-center {
|
|
106
|
+
--stack-align-v: center;
|
|
94
107
|
}
|
|
95
108
|
|
|
96
|
-
.puzzle-stack.
|
|
97
|
-
align-
|
|
109
|
+
.puzzle-stack.align-v-mobile-end {
|
|
110
|
+
--stack-align-v: flex-end;
|
|
98
111
|
}
|
|
99
112
|
|
|
100
|
-
.puzzle-stack.
|
|
101
|
-
align-
|
|
113
|
+
.puzzle-stack.align-v-mobile-stretch {
|
|
114
|
+
--stack-align-v: stretch;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.puzzle-stack.align-v-mobile-around {
|
|
118
|
+
--stack-align-v: space-around;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.puzzle-stack.align-v-mobile-between {
|
|
122
|
+
--stack-align-v: space-between;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.puzzle-stack.align-v-mobile-evenly {
|
|
126
|
+
--stack-align-v: space-evenly;
|
|
102
127
|
}
|
|
103
128
|
|
|
104
129
|
@media (width >= 768px) {
|
|
105
130
|
.puzzle-stack.direction-tablet-row {
|
|
131
|
+
--stack-main-alignment: var(--stack-align-h);
|
|
132
|
+
--stack-cross-alignment: var(--stack-align-v);
|
|
106
133
|
flex-direction: row;
|
|
107
134
|
}
|
|
108
135
|
|
|
@@ -111,6 +138,8 @@
|
|
|
111
138
|
}
|
|
112
139
|
|
|
113
140
|
.puzzle-stack.direction-tablet-col {
|
|
141
|
+
--stack-main-alignment: var(--stack-align-v);
|
|
142
|
+
--stack-cross-alignment: var(--stack-align-h);
|
|
114
143
|
flex-direction: column;
|
|
115
144
|
}
|
|
116
145
|
|
|
@@ -118,58 +147,67 @@
|
|
|
118
147
|
flex-direction: column-reverse;
|
|
119
148
|
}
|
|
120
149
|
|
|
121
|
-
.puzzle-stack.
|
|
122
|
-
|
|
123
|
-
align-items: stretch;
|
|
150
|
+
.puzzle-stack.align-h-tablet-start {
|
|
151
|
+
--stack-align-h: flex-start;
|
|
124
152
|
}
|
|
125
153
|
|
|
126
|
-
.puzzle-stack.
|
|
127
|
-
|
|
154
|
+
.puzzle-stack.align-h-tablet-center {
|
|
155
|
+
--stack-align-h: center;
|
|
128
156
|
}
|
|
129
157
|
|
|
130
|
-
.puzzle-stack.
|
|
131
|
-
|
|
158
|
+
.puzzle-stack.align-h-tablet-end {
|
|
159
|
+
--stack-align-h: flex-end;
|
|
132
160
|
}
|
|
133
161
|
|
|
134
|
-
.puzzle-stack.
|
|
135
|
-
|
|
162
|
+
.puzzle-stack.align-h-tablet-stretch {
|
|
163
|
+
--stack-align-h: stretch;
|
|
136
164
|
}
|
|
137
165
|
|
|
138
|
-
.puzzle-stack.
|
|
139
|
-
|
|
166
|
+
.puzzle-stack.align-h-tablet-around {
|
|
167
|
+
--stack-align-h: space-around;
|
|
140
168
|
}
|
|
141
169
|
|
|
142
|
-
.puzzle-stack.
|
|
143
|
-
|
|
170
|
+
.puzzle-stack.align-h-tablet-between {
|
|
171
|
+
--stack-align-h: space-between;
|
|
144
172
|
}
|
|
145
173
|
|
|
146
|
-
.puzzle-stack.
|
|
147
|
-
|
|
174
|
+
.puzzle-stack.align-h-tablet-evenly {
|
|
175
|
+
--stack-align-h: space-evenly;
|
|
148
176
|
}
|
|
149
177
|
|
|
150
|
-
.puzzle-stack.
|
|
151
|
-
|
|
178
|
+
.puzzle-stack.align-v-tablet-start {
|
|
179
|
+
--stack-align-v: flex-start;
|
|
152
180
|
}
|
|
153
181
|
|
|
154
|
-
.puzzle-stack.
|
|
155
|
-
align-
|
|
182
|
+
.puzzle-stack.align-v-tablet-center {
|
|
183
|
+
--stack-align-v: center;
|
|
156
184
|
}
|
|
157
185
|
|
|
158
|
-
.puzzle-stack.
|
|
159
|
-
align-
|
|
186
|
+
.puzzle-stack.align-v-tablet-end {
|
|
187
|
+
--stack-align-v: flex-end;
|
|
160
188
|
}
|
|
161
189
|
|
|
162
|
-
.puzzle-stack.
|
|
163
|
-
align-
|
|
190
|
+
.puzzle-stack.align-v-tablet-stretch {
|
|
191
|
+
--stack-align-v: stretch;
|
|
164
192
|
}
|
|
165
193
|
|
|
166
|
-
.puzzle-stack.
|
|
167
|
-
align-
|
|
194
|
+
.puzzle-stack.align-v-tablet-around {
|
|
195
|
+
--stack-align-v: space-around;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.puzzle-stack.align-v-tablet-between {
|
|
199
|
+
--stack-align-v: space-between;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.puzzle-stack.align-v-tablet-evenly {
|
|
203
|
+
--stack-align-v: space-evenly;
|
|
168
204
|
}
|
|
169
205
|
}
|
|
170
206
|
|
|
171
207
|
@media (width >= 1024px) {
|
|
172
208
|
.puzzle-stack.direction-desktop-row {
|
|
209
|
+
--stack-main-alignment: var(--stack-align-h);
|
|
210
|
+
--stack-cross-alignment: var(--stack-align-v);
|
|
173
211
|
flex-direction: row;
|
|
174
212
|
}
|
|
175
213
|
|
|
@@ -178,6 +216,8 @@
|
|
|
178
216
|
}
|
|
179
217
|
|
|
180
218
|
.puzzle-stack.direction-desktop-col {
|
|
219
|
+
--stack-main-alignment: var(--stack-align-v);
|
|
220
|
+
--stack-cross-alignment: var(--stack-align-h);
|
|
181
221
|
flex-direction: column;
|
|
182
222
|
}
|
|
183
223
|
|
|
@@ -185,119 +225,59 @@
|
|
|
185
225
|
flex-direction: column-reverse;
|
|
186
226
|
}
|
|
187
227
|
|
|
188
|
-
.puzzle-stack.
|
|
189
|
-
|
|
190
|
-
align-items: stretch;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
.puzzle-stack.direction-desktop-row.align-h-start, .puzzle-stack.direction-desktop-col.align-v-start {
|
|
194
|
-
justify-content: flex-start;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
.puzzle-stack.direction-desktop-row.align-h-center, .puzzle-stack.direction-desktop-col.align-v-center {
|
|
198
|
-
justify-content: center;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.puzzle-stack.direction-desktop-row.align-h-end, .puzzle-stack.direction-desktop-col.align-v-end {
|
|
202
|
-
justify-content: flex-end;
|
|
228
|
+
.puzzle-stack.align-h-desktop-start {
|
|
229
|
+
--stack-align-h: flex-start;
|
|
203
230
|
}
|
|
204
231
|
|
|
205
|
-
.puzzle-stack.
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.puzzle-stack.direction-desktop-row.align-h-around, .puzzle-stack.direction-desktop-col.align-v-around {
|
|
210
|
-
justify-content: space-around;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
.puzzle-stack.direction-desktop-row.align-h-between, .puzzle-stack.direction-desktop-col.align-v-between {
|
|
214
|
-
justify-content: space-between;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
.puzzle-stack.direction-desktop-row.align-h-evenly, .puzzle-stack.direction-desktop-col.align-v-evenly {
|
|
218
|
-
justify-content: space-evenly;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
.puzzle-stack.direction-desktop-row.align-v-start, .puzzle-stack.direction-desktop-col.align-h-start {
|
|
222
|
-
align-items: flex-start;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
.puzzle-stack.direction-desktop-row.align-v-center, .puzzle-stack.direction-desktop-col.align-h-center {
|
|
226
|
-
align-items: center;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.puzzle-stack.direction-desktop-row.align-v-end, .puzzle-stack.direction-desktop-col.align-h-end {
|
|
230
|
-
align-items: flex-end;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
.puzzle-stack.direction-desktop-row.align-v-stretch, .puzzle-stack.direction-desktop-col.align-h-stretch {
|
|
234
|
-
align-items: stretch;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
@media (width >= 1440px) {
|
|
239
|
-
.puzzle-stack.direction-hd-row {
|
|
240
|
-
flex-direction: row;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
.puzzle-stack.direction-hd-row.reverse {
|
|
244
|
-
flex-direction: row-reverse;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
.puzzle-stack.direction-hd-col {
|
|
248
|
-
flex-direction: column;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
.puzzle-stack.direction-hd-col.reverse {
|
|
252
|
-
flex-direction: column-reverse;
|
|
232
|
+
.puzzle-stack.align-h-desktop-center {
|
|
233
|
+
--stack-align-h: center;
|
|
253
234
|
}
|
|
254
235
|
|
|
255
|
-
.puzzle-stack.
|
|
256
|
-
|
|
257
|
-
align-items: stretch;
|
|
236
|
+
.puzzle-stack.align-h-desktop-end {
|
|
237
|
+
--stack-align-h: flex-end;
|
|
258
238
|
}
|
|
259
239
|
|
|
260
|
-
.puzzle-stack.
|
|
261
|
-
|
|
240
|
+
.puzzle-stack.align-h-desktop-stretch {
|
|
241
|
+
--stack-align-h: stretch;
|
|
262
242
|
}
|
|
263
243
|
|
|
264
|
-
.puzzle-stack.
|
|
265
|
-
|
|
244
|
+
.puzzle-stack.align-h-desktop-around {
|
|
245
|
+
--stack-align-h: space-around;
|
|
266
246
|
}
|
|
267
247
|
|
|
268
|
-
.puzzle-stack.
|
|
269
|
-
|
|
248
|
+
.puzzle-stack.align-h-desktop-between {
|
|
249
|
+
--stack-align-h: space-between;
|
|
270
250
|
}
|
|
271
251
|
|
|
272
|
-
.puzzle-stack.
|
|
273
|
-
|
|
252
|
+
.puzzle-stack.align-h-desktop-evenly {
|
|
253
|
+
--stack-align-h: space-evenly;
|
|
274
254
|
}
|
|
275
255
|
|
|
276
|
-
.puzzle-stack.
|
|
277
|
-
|
|
256
|
+
.puzzle-stack.align-v-desktop-start {
|
|
257
|
+
--stack-align-v: flex-start;
|
|
278
258
|
}
|
|
279
259
|
|
|
280
|
-
.puzzle-stack.
|
|
281
|
-
|
|
260
|
+
.puzzle-stack.align-v-desktop-center {
|
|
261
|
+
--stack-align-v: center;
|
|
282
262
|
}
|
|
283
263
|
|
|
284
|
-
.puzzle-stack.
|
|
285
|
-
|
|
264
|
+
.puzzle-stack.align-v-desktop-end {
|
|
265
|
+
--stack-align-v: flex-end;
|
|
286
266
|
}
|
|
287
267
|
|
|
288
|
-
.puzzle-stack.
|
|
289
|
-
align-
|
|
268
|
+
.puzzle-stack.align-v-desktop-stretch {
|
|
269
|
+
--stack-align-v: stretch;
|
|
290
270
|
}
|
|
291
271
|
|
|
292
|
-
.puzzle-stack.
|
|
293
|
-
align-
|
|
272
|
+
.puzzle-stack.align-v-desktop-around {
|
|
273
|
+
--stack-align-v: space-around;
|
|
294
274
|
}
|
|
295
275
|
|
|
296
|
-
.puzzle-stack.
|
|
297
|
-
align-
|
|
276
|
+
.puzzle-stack.align-v-desktop-between {
|
|
277
|
+
--stack-align-v: space-between;
|
|
298
278
|
}
|
|
299
279
|
|
|
300
|
-
.puzzle-stack.
|
|
301
|
-
align-
|
|
280
|
+
.puzzle-stack.align-v-desktop-evenly {
|
|
281
|
+
--stack-align-v: space-evenly;
|
|
302
282
|
}
|
|
303
283
|
}
|
|
@@ -157,7 +157,10 @@ const Carousel = ({ renderItem, getItemKey, panelsPerView, itemWidth, gap = 0, c
|
|
|
157
157
|
}, [
|
|
158
158
|
items.length,
|
|
159
159
|
itemOrderSignature,
|
|
160
|
-
measureLayout
|
|
160
|
+
measureLayout,
|
|
161
|
+
gaps.mobile,
|
|
162
|
+
gaps.tablet,
|
|
163
|
+
gaps.desktop
|
|
161
164
|
]);
|
|
162
165
|
/**
|
|
163
166
|
* currentPanel is always an item index.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["cloneElement","useCarouselContext","useRef","useState","resolveResponsiveValue","useCallback","useMemo","cn"],"sources":["../../../../src/components/navigation/carousel/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn, resolveResponsiveValue } from \"@puzzle-ui/core\";\nimport {\n cloneElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type Key,\n type MouseEvent as ReactMouseEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport { useCarouselContext } from \"./controller\";\nimport \"./carousel.css\";\nimport type { ResponsiveValue } from \"@puzzle-ui/core\";\n\ntype CarouselAlignment = \"left\" | \"center\" | \"right\";\n\ntype CarouselButtonAlignment = \"aside\" | \"over\";\n\ntype CarouselPagerAlignment = \"under\" | \"over\";\n\ntype CarouselAlignmentConfig = ResponsiveValue<CarouselButtonAlignment>;\n\ntype PagerAlignmentConfig = ResponsiveValue<CarouselPagerAlignment>;\n\ntype CarouselLayout = {\n itemsPerPage: number;\n numberOfPages: number;\n maxStartIndex: number;\n maxOffset: number;\n itemOffsets: number[];\n};\n\ntype DragSample = {\n x: number;\n time: number;\n};\n\ntype DragState = {\n pointerId: number;\n startX: number;\n startOffset: number;\n currentOffset: number;\n renderedOffset: number;\n hasMoved: boolean;\n interruptedAnimation: boolean;\n samples: DragSample[];\n};\n\ntype CarouselProps<T> = {\n renderItem: (item: T, index: number) => ReactNode;\n\n /** Returns a stable React key when items may be inserted, removed, or reordered. */\n getItemKey?: (item: T, index: number) => Key;\n\n panelsPerView?: ResponsiveValue<number>;\n itemWidth?: ResponsiveValue<CSSProperties[\"width\"]>;\n gap?: ResponsiveValue<CSSProperties[\"gap\"]>;\n\n className?: string;\n viewportClassName?: string;\n viewportStyle?: CSSProperties;\n ariaLabel?: string;\n\n singlePageAlignment?: CarouselAlignment;\n\n backButton?: ReactElement;\n nextButton?: ReactElement;\n\n buttonAlignment?: CarouselAlignmentConfig;\n pagerAlignment?: PagerAlignmentConfig;\n renderPager?: (currentPage: number, numberOfPages: number) => ReactNode;\n};\n\nconst defaultLayout: CarouselLayout = {\n itemsPerPage: 1,\n numberOfPages: 0,\n maxStartIndex: 0,\n maxOffset: 0,\n itemOffsets: [],\n};\n\nconst rubberBandDistance = (distance: number, dimension: number): number => {\n const size = Math.max(1, dimension);\n const resistance = 0.55;\n\n return (distance * resistance * size) / (size + resistance * distance);\n};\n\nconst rubberBandOffset = (\n offset: number,\n maxOffset: number,\n viewportWidth: number,\n): number => {\n if (offset < 0) {\n return -rubberBandDistance(-offset, viewportWidth);\n }\n\n if (offset > maxOffset) {\n return maxOffset + rubberBandDistance(offset - maxOffset, viewportWidth);\n }\n\n return offset;\n};\n\nconst readRenderedOffset = (element: HTMLElement, fallback: number): number => {\n const ownerWindow = element.ownerDocument.defaultView ?? window;\n const transform = ownerWindow.getComputedStyle(element).transform;\n\n if (!transform || transform === \"none\") {\n return fallback;\n }\n\n const isMatrix3d = transform.startsWith(\"matrix3d(\");\n const values = transform\n .slice(isMatrix3d ? 9 : 7, -1)\n .split(\",\")\n .map(Number);\n\n const translateX = values[isMatrix3d ? 12 : 4] ?? Number.NaN;\n\n return Number.isFinite(translateX) ? -translateX : fallback;\n};\n\nconst estimatePointerVelocity = (samples: DragSample[]): number => {\n if (samples.length < 2) {\n return 0;\n }\n\n const end = samples[samples.length - 1]!;\n const cutoff = end.time - 100;\n\n let start = samples[0]!;\n\n for (const sample of samples) {\n if (sample.time <= cutoff) {\n start = sample;\n } else {\n break;\n }\n }\n\n const elapsedSeconds = (end.time - start.time) / 1000;\n\n if (elapsedSeconds <= 0) {\n return 0;\n }\n\n // Convert pointer movement to content movement.\n return -(end.x - start.x) / elapsedSeconds;\n};\n\nconst toCssLength = (\n value: CSSProperties[\"width\"] | CSSProperties[\"gap\"] | undefined,\n): string => {\n if (typeof value === \"number\") {\n return `${value}px`;\n }\n\n return value ?? \"0px\";\n};\n\nconst getItemBasis = (itemsPerPage: number, gap: string): string => {\n const count = Math.max(1, Math.floor(itemsPerPage || 1));\n\n if (count === 1) {\n return \"100%\";\n }\n\n if (gap === \"\" || gap === \"0px\" || gap === \"0\") {\n return `calc((100% / ${count}) - (1px / ${count}))`;\n }\n\n const gapTerms = Array.from({ length: count - 1 }, () => `(${gap})`).join(\n \" + \",\n );\n\n return `calc((100% - (${gapTerms})) / ${count})`;\n};\n\nconst getPagerDataAttribute = (alignment: CarouselPagerAlignment) =>\n alignment === \"under\" ? \"under\" : \"over\";\n\nconst cloneNavigationButton = (\n button: ReactElement | undefined,\n disabled: boolean,\n onNavigate: () => void,\n): ReactNode => {\n if (!button) {\n return null;\n }\n\n const originalProps = button.props as {\n disabled?: boolean;\n onClick?: (event: ReactMouseEvent<HTMLElement>) => void;\n };\n\n const isDisabled = disabled || originalProps.disabled === true;\n\n return cloneElement(button as ReactElement<Record<string, unknown>>, {\n disabled: isDisabled,\n \"aria-disabled\": isDisabled,\n onClick: (event: ReactMouseEvent<HTMLElement>) => {\n if (isDisabled) {\n event.preventDefault();\n return;\n }\n\n originalProps.onClick?.(event);\n onNavigate();\n },\n });\n};\n\nconst Carousel = <T,>({\n renderItem,\n getItemKey,\n panelsPerView,\n itemWidth,\n gap = 0,\n className,\n viewportClassName,\n viewportStyle,\n ariaLabel = \"Carousel\",\n singlePageAlignment = \"left\",\n backButton,\n nextButton,\n buttonAlignment,\n pagerAlignment,\n renderPager,\n}: CarouselProps<T>) => {\n const { items, currentPanel, setPanel } = useCarouselContext<T>();\n\n const viewportRef = useRef<HTMLDivElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const itemRefs = useRef<Array<HTMLDivElement | null>>([]);\n\n const dragRef = useRef<DragState | null>(null);\n const pointerCleanupRef = useRef<(() => void) | null>(null);\n const animationFrameRef = useRef<number | null>(null);\n const visualOffsetRef = useRef(0);\n const suppressClickRef = useRef(false);\n\n const [isDragging, setIsDragging] = useState(false);\n const [isAnimating, setIsAnimating] = useState(false);\n\n const [layout, setLayout] = useState<CarouselLayout>(defaultLayout);\n\n const sizingMode = itemWidth !== undefined ? \"item-width\" : \"panels\";\n\n const panelCounts = resolveResponsiveValue(panelsPerView, 1);\n const itemWidths = resolveResponsiveValue(itemWidth, \"100%\");\n const gaps = resolveResponsiveValue(gap, 0);\n\n const buttonAlignments = resolveResponsiveValue<CarouselButtonAlignment>(\n buttonAlignment,\n \"over\",\n );\n\n const pagerAlignments = resolveResponsiveValue<CarouselPagerAlignment>(\n pagerAlignment,\n \"under\",\n );\n\n const cssVariables = {\n \"--puzzle-carousel-gap-mobile\": toCssLength(gaps.mobile),\n \"--puzzle-carousel-gap-tablet\": toCssLength(gaps.tablet),\n \"--puzzle-carousel-gap-desktop\": toCssLength(gaps.desktop),\n \"--puzzle-carousel-basis-mobile\": getItemBasis(\n panelCounts.mobile,\n toCssLength(gaps.mobile),\n ),\n \"--puzzle-carousel-basis-tablet\": getItemBasis(\n panelCounts.tablet ?? panelCounts.mobile,\n toCssLength(gaps.tablet),\n ),\n \"--puzzle-carousel-basis-desktop\": getItemBasis(\n panelCounts.desktop ?? panelCounts.tablet ?? panelCounts.mobile,\n toCssLength(gaps.desktop),\n ),\n \"--puzzle-carousel-item-width-mobile\": toCssLength(itemWidths.mobile),\n \"--puzzle-carousel-item-width-tablet\": toCssLength(itemWidths.tablet),\n \"--puzzle-carousel-item-width-desktop\": toCssLength(itemWidths.desktop),\n } as CSSProperties;\n\n /**\n * Read the actual rendered widths and positions of the items.\n * This supports both panelsPerView and itemWidth sizing.\n */\n const measureLayout = useCallback(() => {\n const viewport = viewportRef.current;\n const track = trackRef.current;\n\n if (!viewport || !track || items.length === 0) {\n setLayout(defaultLayout);\n return;\n }\n\n const viewportRect = viewport.getBoundingClientRect();\n const viewportWidth = viewportRect.width;\n const itemNodes = itemRefs.current\n .slice(0, items.length)\n .filter((item): item is HTMLDivElement => item !== null);\n\n if (viewportWidth <= 0 || itemNodes.length === 0) {\n return;\n }\n\n // Relative positions preserve fractional CSS pixels and cancel the\n // track's current translate transform.\n const trackRect = track.getBoundingClientRect();\n const itemRects = itemNodes.map((item) => item.getBoundingClientRect());\n\n const itemOffsets = itemRects.map((rect) => rect.left - trackRect.left);\n\n let itemsPerPage = 0;\n\n for (const rect of itemRects) {\n const itemEnd = rect.right - trackRect.left;\n\n if (itemEnd <= viewportWidth + 0.01) {\n itemsPerPage += 1;\n } else {\n break;\n }\n }\n\n itemsPerPage = Math.max(1, itemsPerPage);\n\n const numberOfPages = Math.ceil(items.length / itemsPerPage);\n const maxStartIndex = Math.max(0, items.length - itemsPerPage);\n const lastItemEnd = itemRects[itemRects.length - 1]!.right - trackRect.left;\n const maxOffset = Math.max(0, lastItemEnd - viewportWidth);\n\n setLayout((previous) => {\n const unchanged =\n previous.itemsPerPage === itemsPerPage &&\n previous.numberOfPages === numberOfPages &&\n previous.maxStartIndex === maxStartIndex &&\n previous.maxOffset === maxOffset &&\n previous.itemOffsets.length === itemOffsets.length &&\n previous.itemOffsets.every(\n (offset, index) => offset === itemOffsets[index],\n );\n\n if (unchanged) {\n return previous;\n }\n\n return {\n itemsPerPage,\n numberOfPages,\n maxStartIndex,\n maxOffset,\n itemOffsets,\n };\n });\n }, [items.length]);\n\n const itemOrderSignature = items\n .map((item, index) => String(getItemKey ? getItemKey(item, index) : index))\n .join(\"\\u0000\");\n\n useEffect(() => {\n const viewport = viewportRef.current;\n const track = trackRef.current;\n\n if (!viewport || !track) {\n return;\n }\n\n const ownerWindow = viewport.ownerDocument.defaultView ?? window;\n\n measureLayout();\n\n if (typeof ResizeObserver === \"undefined\") {\n ownerWindow.addEventListener(\"resize\", measureLayout);\n\n return () => {\n ownerWindow.removeEventListener(\"resize\", measureLayout);\n };\n }\n\n const observer = new ResizeObserver(measureLayout);\n\n observer.observe(viewport);\n observer.observe(track);\n\n itemRefs.current.slice(0, items.length).forEach((item) => {\n if (item) {\n observer.observe(item);\n }\n });\n\n return () => observer.disconnect();\n }, [items.length, itemOrderSignature, measureLayout]);\n\n /**\n * currentPanel is always an item index.\n *\n * Restrict it to the last position from which the viewport can be\n * completely filled without scrolling beyond the end of the track.\n */\n const activePanel = Math.min(\n Math.max(0, Math.floor(currentPanel)),\n layout.maxStartIndex,\n );\n\n /**\n * Logical page starts can overlap at the end.\n *\n * Example: 5 items with 3 visible per page:\n * [0, 2], not [0, 3].\n *\n * Example: 8 items with 3 visible per page:\n * [0, 3, 5].\n */\n const pageStartIndices = useMemo(\n () =>\n Array.from({ length: layout.numberOfPages }, (_, pageIndex) => {\n if (pageIndex === layout.numberOfPages - 1) {\n return layout.maxStartIndex;\n }\n\n return Math.min(pageIndex * layout.itemsPerPage, layout.maxStartIndex);\n }),\n [layout.itemsPerPage, layout.maxStartIndex, layout.numberOfPages],\n );\n\n /**\n * Map the active item to the nearest logical page.\n * This lets swipe-to-panel and page-based navigation coexist.\n */\n const activePageIndex = useMemo(() => {\n if (pageStartIndices.length === 0) {\n return 0;\n }\n\n return pageStartIndices.reduce((closestIndex, pageStart, index) => {\n const closestStart = pageStartIndices[closestIndex]!;\n\n return Math.abs(pageStart - activePanel) <\n Math.abs(closestStart - activePanel)\n ? index\n : closestIndex;\n }, 0);\n }, [activePanel, pageStartIndices]);\n\n const clampOffset = useCallback(\n (offset: number) => Math.min(layout.maxOffset, Math.max(0, offset)),\n [layout.maxOffset],\n );\n\n const activeOffset = clampOffset(layout.itemOffsets[activePanel] ?? 0);\n\n useEffect(() => {\n if (dragRef.current || animationFrameRef.current !== null) {\n return;\n }\n\n visualOffsetRef.current = activeOffset;\n }, [activeOffset]);\n\n useEffect(\n () => () => {\n pointerCleanupRef.current?.();\n\n if (animationFrameRef.current !== null) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n },\n [],\n );\n\n /**\n * Only correct the controller after layout measurement has completed.\n * This avoids forcing currentPanel to 0 during the initial render.\n */\n useEffect(() => {\n if (layout.numberOfPages > 0 && currentPanel !== activePanel) {\n setPanel(activePanel);\n }\n }, [activePanel, currentPanel, layout.numberOfPages, setPanel]);\n\n const goToPage = useCallback(\n (pageIndex: number) => {\n const targetPage = Math.max(\n 0,\n Math.min(pageIndex, pageStartIndices.length - 1),\n );\n\n const targetPanel = pageStartIndices[targetPage];\n\n if (targetPanel !== undefined) {\n setPanel(targetPanel);\n }\n },\n [pageStartIndices, setPanel],\n );\n\n const goToPreviousPage = useCallback(() => {\n goToPage(activePageIndex - 1);\n }, [activePageIndex, goToPage]);\n\n const goToNextPage = useCallback(() => {\n goToPage(activePageIndex + 1);\n }, [activePageIndex, goToPage]);\n\n /**\n * Start tracking a swipe or mouse drag.\n *\n * Capture on the original element rather than always on the viewport,\n * so a normal click on an interactive child can still work.\n */\n\n const writeTrackOffset = useCallback((offset: number) => {\n visualOffsetRef.current = offset;\n\n if (trackRef.current) {\n trackRef.current.style.transform = `translate3d(${-offset}px, 0, 0)`;\n }\n }, []);\n\n const getNearestPanelIndex = useCallback(\n (offset: number) => {\n let nearestIndex = 0;\n let nearestDistance = Number.POSITIVE_INFINITY;\n\n for (let index = 0; index <= layout.maxStartIndex; index += 1) {\n const candidateOffset = clampOffset(layout.itemOffsets[index] ?? 0);\n\n const distance = Math.abs(candidateOffset - offset);\n\n if (distance < nearestDistance) {\n nearestDistance = distance;\n nearestIndex = index;\n }\n }\n\n return nearestIndex;\n },\n [clampOffset, layout.itemOffsets, layout.maxStartIndex],\n );\n\n /**\n * Animate to a panel using a damped spring.\n *\n * A little underdamping gives the motion a natural overshoot.\n * The target remains a real, reachable item offset.\n */\n const animateToPanel = useCallback(\n (fromOffset: number, targetPanel: number, initialVelocity: number) => {\n if (animationFrameRef.current !== null) {\n cancelAnimationFrame(animationFrameRef.current);\n animationFrameRef.current = null;\n }\n\n const track = trackRef.current;\n const ownerWindow =\n viewportRef.current?.ownerDocument.defaultView ?? window;\n const targetOffset = clampOffset(layout.itemOffsets[targetPanel] ?? 0);\n\n if (\n !track ||\n ownerWindow.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n ) {\n writeTrackOffset(targetOffset);\n track?.style.removeProperty(\"transition\");\n setPanel(targetPanel);\n setIsDragging(false);\n setIsAnimating(false);\n return;\n }\n\n track.style.transition = \"none\";\n\n setIsDragging(false);\n setIsAnimating(true);\n\n let position = fromOffset;\n\n // Preserve some release momentum without allowing extreme fling speeds.\n let velocity = Math.max(-1800, Math.min(1800, initialVelocity * 0.4));\n\n let previousTime = performance.now();\n\n const stiffness = 230;\n const damping = 24;\n\n const animate = (now: number) => {\n const deltaSeconds = Math.min((now - previousTime) / 1000, 1 / 30);\n\n previousTime = now;\n\n const springAcceleration = (targetOffset - position) * stiffness;\n\n const dampingAcceleration = velocity * damping;\n\n velocity += (springAcceleration - dampingAcceleration) * deltaSeconds;\n\n position += velocity * deltaSeconds;\n\n const viewportWidth = viewportRef.current?.clientWidth ?? 1;\n\n writeTrackOffset(\n rubberBandOffset(position, layout.maxOffset, viewportWidth),\n );\n\n const positionSettled = Math.abs(targetOffset - position) < 0.5;\n\n const velocitySettled = Math.abs(velocity) < 10;\n\n if (positionSettled && velocitySettled) {\n animationFrameRef.current = null;\n\n writeTrackOffset(targetOffset);\n track.style.removeProperty(\"transition\");\n\n setPanel(targetPanel);\n setIsAnimating(false);\n\n return;\n }\n\n animationFrameRef.current = requestAnimationFrame(animate);\n };\n\n animationFrameRef.current = requestAnimationFrame(animate);\n },\n [\n clampOffset,\n layout.itemOffsets,\n layout.maxOffset,\n setPanel,\n writeTrackOffset,\n ],\n );\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!event.isPrimary || dragRef.current) {\n return;\n }\n\n if (event.pointerType === \"mouse\" && event.button !== 0) {\n return;\n }\n\n if (layout.maxOffset <= 0) {\n return;\n }\n\n const track = trackRef.current;\n const viewport = viewportRef.current;\n const ownerWindow = viewport?.ownerDocument.defaultView ?? window;\n\n if (!track || !viewport || !ownerWindow) {\n return;\n }\n\n const interruptedAnimation = animationFrameRef.current !== null;\n\n if (animationFrameRef.current !== null) {\n cancelAnimationFrame(animationFrameRef.current);\n animationFrameRef.current = null;\n }\n\n /*\n * Read the currently displayed offset before disabling the CSS\n * transition. This also handles starting a drag during an animation.\n */\n const startOffset = readRenderedOffset(track, visualOffsetRef.current);\n\n track.style.transition = \"none\";\n writeTrackOffset(startOffset);\n\n setIsAnimating(false);\n setIsDragging(true);\n\n const startTime = performance.now();\n\n const drag: DragState = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startOffset,\n currentOffset: startOffset,\n renderedOffset: startOffset,\n hasMoved: false,\n interruptedAnimation,\n samples: [\n {\n x: event.clientX,\n time: startTime,\n },\n ],\n };\n\n dragRef.current = drag;\n\n const updatePointerPosition = (pointerEvent: PointerEvent) => {\n const deltaX = pointerEvent.clientX - drag.startX;\n\n if (!drag.hasMoved && Math.abs(deltaX) <= 4) {\n return;\n }\n\n drag.hasMoved = true;\n\n // Positive offset means the content moves to the left.\n drag.currentOffset = drag.startOffset - deltaX;\n\n drag.renderedOffset = rubberBandOffset(\n drag.currentOffset,\n layout.maxOffset,\n viewport.clientWidth,\n );\n\n const now = performance.now();\n\n drag.samples.push({\n x: pointerEvent.clientX,\n time: now,\n });\n\n // Retain a short history for release-velocity estimation.\n while (drag.samples.length > 2 && now - drag.samples[1]!.time > 120) {\n drag.samples.shift();\n }\n\n writeTrackOffset(drag.renderedOffset);\n\n if (pointerEvent.cancelable) {\n pointerEvent.preventDefault();\n }\n };\n\n const cleanup = () => {\n ownerWindow.removeEventListener(\"pointermove\", handleWindowPointerMove);\n ownerWindow.removeEventListener(\"pointerup\", handleWindowPointerUp);\n ownerWindow.removeEventListener(\n \"pointercancel\",\n handleWindowPointerCancel,\n );\n ownerWindow.removeEventListener(\"blur\", handleWindowBlur);\n\n if (pointerCleanupRef.current === cleanup) {\n pointerCleanupRef.current = null;\n }\n };\n\n const settleCancelledDrag = () => {\n if (dragRef.current !== drag) {\n return;\n }\n\n cleanup();\n dragRef.current = null;\n setIsDragging(false);\n\n const targetPanel = getNearestPanelIndex(\n clampOffset(drag.currentOffset),\n );\n\n animateToPanel(drag.renderedOffset, targetPanel, 0);\n };\n\n const handleWindowPointerMove = (pointerEvent: PointerEvent) => {\n if (pointerEvent.pointerId !== drag.pointerId) {\n return;\n }\n\n updatePointerPosition(pointerEvent);\n };\n\n const handleWindowPointerUp = (pointerEvent: PointerEvent) => {\n if (pointerEvent.pointerId !== drag.pointerId) {\n return;\n }\n\n // Include the final pointer position, even if no final move fired.\n updatePointerPosition(pointerEvent);\n\n cleanup();\n dragRef.current = null;\n setIsDragging(false);\n\n if (!drag.hasMoved) {\n if (drag.interruptedAnimation) {\n const targetPanel = getNearestPanelIndex(\n clampOffset(drag.startOffset),\n );\n\n animateToPanel(drag.startOffset, targetPanel, 0);\n } else {\n track.style.removeProperty(\"transition\");\n writeTrackOffset(drag.startOffset);\n }\n\n return;\n }\n\n suppressClickRef.current = true;\n\n ownerWindow.setTimeout(() => {\n suppressClickRef.current = false;\n }, 0);\n\n const velocity = estimatePointerVelocity(drag.samples);\n\n /*\n * Project the release position forward. A fast swipe can skip\n * multiple items, while a slow drag generally snaps nearby.\n */\n const projectedOffset = clampOffset(\n clampOffset(drag.currentOffset) + velocity * 0.18,\n );\n\n const targetPanel = getNearestPanelIndex(projectedOffset);\n\n animateToPanel(drag.renderedOffset, targetPanel, velocity);\n };\n\n const handleWindowPointerCancel = (pointerEvent: PointerEvent) => {\n if (pointerEvent.pointerId === drag.pointerId) {\n settleCancelledDrag();\n }\n };\n\n const handleWindowBlur = () => {\n settleCancelledDrag();\n };\n\n pointerCleanupRef.current = cleanup;\n\n /*\n * Listen on window instead of relying on events staying inside the\n * viewport. Releasing outside the carousel still completes the drag.\n */\n ownerWindow.addEventListener(\"pointermove\", handleWindowPointerMove);\n ownerWindow.addEventListener(\"pointerup\", handleWindowPointerUp);\n ownerWindow.addEventListener(\"pointercancel\", handleWindowPointerCancel);\n ownerWindow.addEventListener(\"blur\", handleWindowBlur);\n },\n [\n animateToPanel,\n clampOffset,\n getNearestPanelIndex,\n layout.maxOffset,\n setIsAnimating,\n writeTrackOffset,\n ],\n );\n\n const handleClickCapture = useCallback(\n (event: ReactMouseEvent<HTMLDivElement>) => {\n if (!suppressClickRef.current) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n suppressClickRef.current = false;\n },\n [],\n );\n\n const isFirstPage = activePageIndex === 0;\n const isLastPage =\n layout.numberOfPages <= 1 || activePageIndex >= layout.numberOfPages - 1;\n\n const currentPage = layout.numberOfPages > 0 ? activePageIndex : 0;\n\n return (\n <div\n className={cn(\"puzzle-carousel\", className)}\n style={cssVariables}\n data-sizing={sizingMode}\n data-dragging={isDragging ? \"true\" : \"false\"}\n data-animating={isAnimating ? \"true\" : \"false\"}\n data-single-page={layout.numberOfPages <= 1 ? \"true\" : \"false\"}\n data-single-page-alignment={singlePageAlignment}\n data-button-mobile={buttonAlignments.mobile}\n data-button-tablet={buttonAlignments.tablet}\n data-button-desktop={buttonAlignments.desktop}\n data-pager-mobile={getPagerDataAttribute(pagerAlignments.mobile)}\n data-pager-tablet={getPagerDataAttribute(\n pagerAlignments.tablet ?? pagerAlignments.mobile,\n )}\n data-pager-desktop={getPagerDataAttribute(\n pagerAlignments.desktop ??\n pagerAlignments.tablet ??\n pagerAlignments.mobile,\n )}\n >\n <div className=\"puzzle-carousel__stage\">\n <div className=\"puzzle-carousel__navigation puzzle-carousel__navigation--previous\">\n {cloneNavigationButton(backButton, isFirstPage, goToPreviousPage)}\n </div>\n\n <div\n ref={viewportRef}\n className={cn(\"puzzle-carousel__viewport\", viewportClassName)}\n style={viewportStyle}\n role=\"group\"\n aria-roledescription=\"carousel\"\n aria-label={ariaLabel}\n onPointerDown={handlePointerDown}\n onClickCapture={handleClickCapture}\n onDragStart={(event) => event.preventDefault()}\n >\n <div\n ref={trackRef}\n className=\"puzzle-carousel__track\"\n style={{\n transform: `translate3d(${-activeOffset}px, 0, 0)`,\n }}\n >\n {items.map((item, index) => (\n <div\n key={getItemKey ? getItemKey(item, index) : index}\n ref={(node) => {\n itemRefs.current[index] = node;\n }}\n className=\"puzzle-carousel__item\"\n role=\"group\"\n aria-roledescription=\"slide\"\n aria-label={`${index + 1} of ${items.length}`}\n >\n {renderItem(item, index)}\n </div>\n ))}\n </div>\n </div>\n\n <div className=\"puzzle-carousel__navigation puzzle-carousel__navigation--next\">\n {cloneNavigationButton(nextButton, isLastPage, goToNextPage)}\n </div>\n </div>\n\n {renderPager && layout.numberOfPages > 0 && (\n <div className=\"puzzle-carousel__pager\">\n {renderPager(currentPage, layout.numberOfPages)}\n </div>\n )}\n </div>\n );\n};\n\nexport {\n Carousel,\n type CarouselProps,\n type CarouselAlignment,\n type CarouselButtonAlignment,\n type CarouselPagerAlignment,\n type CarouselAlignmentConfig,\n type PagerAlignmentConfig,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["cloneElement","useCarouselContext","useRef","useState","resolveResponsiveValue","useCallback","useMemo","cn"],"sources":["../../../../src/components/navigation/carousel/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn, resolveResponsiveValue } from \"@puzzle-ui/core\";\nimport {\n cloneElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type Key,\n type MouseEvent as ReactMouseEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport { useCarouselContext } from \"./controller\";\nimport \"./carousel.css\";\nimport type { ResponsiveValue } from \"@puzzle-ui/core\";\n\ntype CarouselAlignment = \"left\" | \"center\" | \"right\";\n\ntype CarouselButtonAlignment = \"aside\" | \"over\";\n\ntype CarouselPagerAlignment = \"under\" | \"over\";\n\ntype CarouselAlignmentConfig = ResponsiveValue<CarouselButtonAlignment>;\n\ntype PagerAlignmentConfig = ResponsiveValue<CarouselPagerAlignment>;\n\ntype CarouselLayout = {\n itemsPerPage: number;\n numberOfPages: number;\n maxStartIndex: number;\n maxOffset: number;\n itemOffsets: number[];\n};\n\ntype DragSample = {\n x: number;\n time: number;\n};\n\ntype DragState = {\n pointerId: number;\n startX: number;\n startOffset: number;\n currentOffset: number;\n renderedOffset: number;\n hasMoved: boolean;\n interruptedAnimation: boolean;\n samples: DragSample[];\n};\n\ntype CarouselProps<T> = {\n renderItem: (item: T, index: number) => ReactNode;\n\n /** Returns a stable React key when items may be inserted, removed, or reordered. */\n getItemKey?: (item: T, index: number) => Key;\n\n panelsPerView?: ResponsiveValue<number>;\n itemWidth?: ResponsiveValue<CSSProperties[\"width\"]>;\n gap?: ResponsiveValue<CSSProperties[\"gap\"]>;\n\n className?: string;\n viewportClassName?: string;\n viewportStyle?: CSSProperties;\n ariaLabel?: string;\n\n singlePageAlignment?: CarouselAlignment;\n\n backButton?: ReactElement;\n nextButton?: ReactElement;\n\n buttonAlignment?: CarouselAlignmentConfig;\n pagerAlignment?: PagerAlignmentConfig;\n renderPager?: (currentPage: number, numberOfPages: number) => ReactNode;\n};\n\nconst defaultLayout: CarouselLayout = {\n itemsPerPage: 1,\n numberOfPages: 0,\n maxStartIndex: 0,\n maxOffset: 0,\n itemOffsets: [],\n};\n\nconst rubberBandDistance = (distance: number, dimension: number): number => {\n const size = Math.max(1, dimension);\n const resistance = 0.55;\n\n return (distance * resistance * size) / (size + resistance * distance);\n};\n\nconst rubberBandOffset = (\n offset: number,\n maxOffset: number,\n viewportWidth: number,\n): number => {\n if (offset < 0) {\n return -rubberBandDistance(-offset, viewportWidth);\n }\n\n if (offset > maxOffset) {\n return maxOffset + rubberBandDistance(offset - maxOffset, viewportWidth);\n }\n\n return offset;\n};\n\nconst readRenderedOffset = (element: HTMLElement, fallback: number): number => {\n const ownerWindow = element.ownerDocument.defaultView ?? window;\n const transform = ownerWindow.getComputedStyle(element).transform;\n\n if (!transform || transform === \"none\") {\n return fallback;\n }\n\n const isMatrix3d = transform.startsWith(\"matrix3d(\");\n const values = transform\n .slice(isMatrix3d ? 9 : 7, -1)\n .split(\",\")\n .map(Number);\n\n const translateX = values[isMatrix3d ? 12 : 4] ?? Number.NaN;\n\n return Number.isFinite(translateX) ? -translateX : fallback;\n};\n\nconst estimatePointerVelocity = (samples: DragSample[]): number => {\n if (samples.length < 2) {\n return 0;\n }\n\n const end = samples[samples.length - 1]!;\n const cutoff = end.time - 100;\n\n let start = samples[0]!;\n\n for (const sample of samples) {\n if (sample.time <= cutoff) {\n start = sample;\n } else {\n break;\n }\n }\n\n const elapsedSeconds = (end.time - start.time) / 1000;\n\n if (elapsedSeconds <= 0) {\n return 0;\n }\n\n // Convert pointer movement to content movement.\n return -(end.x - start.x) / elapsedSeconds;\n};\n\nconst toCssLength = (\n value: CSSProperties[\"width\"] | CSSProperties[\"gap\"] | undefined,\n): string => {\n if (typeof value === \"number\") {\n return `${value}px`;\n }\n\n return value ?? \"0px\";\n};\n\nconst getItemBasis = (itemsPerPage: number, gap: string): string => {\n const count = Math.max(1, Math.floor(itemsPerPage || 1));\n\n if (count === 1) {\n return \"100%\";\n }\n\n if (gap === \"\" || gap === \"0px\" || gap === \"0\") {\n return `calc((100% / ${count}) - (1px / ${count}))`;\n }\n\n const gapTerms = Array.from({ length: count - 1 }, () => `(${gap})`).join(\n \" + \",\n );\n\n return `calc((100% - (${gapTerms})) / ${count})`;\n};\n\nconst getPagerDataAttribute = (alignment: CarouselPagerAlignment) =>\n alignment === \"under\" ? \"under\" : \"over\";\n\nconst cloneNavigationButton = (\n button: ReactElement | undefined,\n disabled: boolean,\n onNavigate: () => void,\n): ReactNode => {\n if (!button) {\n return null;\n }\n\n const originalProps = button.props as {\n disabled?: boolean;\n onClick?: (event: ReactMouseEvent<HTMLElement>) => void;\n };\n\n const isDisabled = disabled || originalProps.disabled === true;\n\n return cloneElement(button as ReactElement<Record<string, unknown>>, {\n disabled: isDisabled,\n \"aria-disabled\": isDisabled,\n onClick: (event: ReactMouseEvent<HTMLElement>) => {\n if (isDisabled) {\n event.preventDefault();\n return;\n }\n\n originalProps.onClick?.(event);\n onNavigate();\n },\n });\n};\n\nconst Carousel = <T,>({\n renderItem,\n getItemKey,\n panelsPerView,\n itemWidth,\n gap = 0,\n className,\n viewportClassName,\n viewportStyle,\n ariaLabel = \"Carousel\",\n singlePageAlignment = \"left\",\n backButton,\n nextButton,\n buttonAlignment,\n pagerAlignment,\n renderPager,\n}: CarouselProps<T>) => {\n const { items, currentPanel, setPanel } = useCarouselContext<T>();\n\n const viewportRef = useRef<HTMLDivElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const itemRefs = useRef<Array<HTMLDivElement | null>>([]);\n\n const dragRef = useRef<DragState | null>(null);\n const pointerCleanupRef = useRef<(() => void) | null>(null);\n const animationFrameRef = useRef<number | null>(null);\n const visualOffsetRef = useRef(0);\n const suppressClickRef = useRef(false);\n\n const [isDragging, setIsDragging] = useState(false);\n const [isAnimating, setIsAnimating] = useState(false);\n\n const [layout, setLayout] = useState<CarouselLayout>(defaultLayout);\n\n const sizingMode = itemWidth !== undefined ? \"item-width\" : \"panels\";\n\n const panelCounts = resolveResponsiveValue(panelsPerView, 1);\n const itemWidths = resolveResponsiveValue(itemWidth, \"100%\");\n const gaps = resolveResponsiveValue(gap, 0);\n\n const buttonAlignments = resolveResponsiveValue<CarouselButtonAlignment>(\n buttonAlignment,\n \"over\",\n );\n\n const pagerAlignments = resolveResponsiveValue<CarouselPagerAlignment>(\n pagerAlignment,\n \"under\",\n );\n\n const cssVariables = {\n \"--puzzle-carousel-gap-mobile\": toCssLength(gaps.mobile),\n \"--puzzle-carousel-gap-tablet\": toCssLength(gaps.tablet),\n \"--puzzle-carousel-gap-desktop\": toCssLength(gaps.desktop),\n \"--puzzle-carousel-basis-mobile\": getItemBasis(\n panelCounts.mobile,\n toCssLength(gaps.mobile),\n ),\n \"--puzzle-carousel-basis-tablet\": getItemBasis(\n panelCounts.tablet ?? panelCounts.mobile,\n toCssLength(gaps.tablet),\n ),\n \"--puzzle-carousel-basis-desktop\": getItemBasis(\n panelCounts.desktop ?? panelCounts.tablet ?? panelCounts.mobile,\n toCssLength(gaps.desktop),\n ),\n \"--puzzle-carousel-item-width-mobile\": toCssLength(itemWidths.mobile),\n \"--puzzle-carousel-item-width-tablet\": toCssLength(itemWidths.tablet),\n \"--puzzle-carousel-item-width-desktop\": toCssLength(itemWidths.desktop),\n } as CSSProperties;\n\n /**\n * Read the actual rendered widths and positions of the items.\n * This supports both panelsPerView and itemWidth sizing.\n */\n const measureLayout = useCallback(() => {\n const viewport = viewportRef.current;\n const track = trackRef.current;\n\n if (!viewport || !track || items.length === 0) {\n setLayout(defaultLayout);\n return;\n }\n\n const viewportRect = viewport.getBoundingClientRect();\n const viewportWidth = viewportRect.width;\n const itemNodes = itemRefs.current\n .slice(0, items.length)\n .filter((item): item is HTMLDivElement => item !== null);\n\n if (viewportWidth <= 0 || itemNodes.length === 0) {\n return;\n }\n\n // Relative positions preserve fractional CSS pixels and cancel the\n // track's current translate transform.\n const trackRect = track.getBoundingClientRect();\n const itemRects = itemNodes.map((item) => item.getBoundingClientRect());\n\n const itemOffsets = itemRects.map((rect) => rect.left - trackRect.left);\n\n let itemsPerPage = 0;\n\n for (const rect of itemRects) {\n const itemEnd = rect.right - trackRect.left;\n\n if (itemEnd <= viewportWidth + 0.01) {\n itemsPerPage += 1;\n } else {\n break;\n }\n }\n\n itemsPerPage = Math.max(1, itemsPerPage);\n\n const numberOfPages = Math.ceil(items.length / itemsPerPage);\n const maxStartIndex = Math.max(0, items.length - itemsPerPage);\n const lastItemEnd = itemRects[itemRects.length - 1]!.right - trackRect.left;\n const maxOffset = Math.max(0, lastItemEnd - viewportWidth);\n\n setLayout((previous) => {\n const unchanged =\n previous.itemsPerPage === itemsPerPage &&\n previous.numberOfPages === numberOfPages &&\n previous.maxStartIndex === maxStartIndex &&\n previous.maxOffset === maxOffset &&\n previous.itemOffsets.length === itemOffsets.length &&\n previous.itemOffsets.every(\n (offset, index) => offset === itemOffsets[index],\n );\n\n if (unchanged) {\n return previous;\n }\n\n return {\n itemsPerPage,\n numberOfPages,\n maxStartIndex,\n maxOffset,\n itemOffsets,\n };\n });\n }, [items.length]);\n\n const itemOrderSignature = items\n .map((item, index) => String(getItemKey ? getItemKey(item, index) : index))\n .join(\"\\u0000\");\n\n useEffect(() => {\n const viewport = viewportRef.current;\n const track = trackRef.current;\n\n if (!viewport || !track) {\n return;\n }\n\n const ownerWindow = viewport.ownerDocument.defaultView ?? window;\n\n measureLayout();\n\n if (typeof ResizeObserver === \"undefined\") {\n ownerWindow.addEventListener(\"resize\", measureLayout);\n\n return () => {\n ownerWindow.removeEventListener(\"resize\", measureLayout);\n };\n }\n\n const observer = new ResizeObserver(measureLayout);\n\n observer.observe(viewport);\n observer.observe(track);\n\n itemRefs.current.slice(0, items.length).forEach((item) => {\n if (item) {\n observer.observe(item);\n }\n });\n\n return () => observer.disconnect();\n }, [\n items.length,\n itemOrderSignature,\n measureLayout,\n gaps.mobile,\n gaps.tablet,\n gaps.desktop,\n ]);\n\n /**\n * currentPanel is always an item index.\n *\n * Restrict it to the last position from which the viewport can be\n * completely filled without scrolling beyond the end of the track.\n */\n const activePanel = Math.min(\n Math.max(0, Math.floor(currentPanel)),\n layout.maxStartIndex,\n );\n\n /**\n * Logical page starts can overlap at the end.\n *\n * Example: 5 items with 3 visible per page:\n * [0, 2], not [0, 3].\n *\n * Example: 8 items with 3 visible per page:\n * [0, 3, 5].\n */\n const pageStartIndices = useMemo(\n () =>\n Array.from({ length: layout.numberOfPages }, (_, pageIndex) => {\n if (pageIndex === layout.numberOfPages - 1) {\n return layout.maxStartIndex;\n }\n\n return Math.min(pageIndex * layout.itemsPerPage, layout.maxStartIndex);\n }),\n [layout.itemsPerPage, layout.maxStartIndex, layout.numberOfPages],\n );\n\n /**\n * Map the active item to the nearest logical page.\n * This lets swipe-to-panel and page-based navigation coexist.\n */\n const activePageIndex = useMemo(() => {\n if (pageStartIndices.length === 0) {\n return 0;\n }\n\n return pageStartIndices.reduce((closestIndex, pageStart, index) => {\n const closestStart = pageStartIndices[closestIndex]!;\n\n return Math.abs(pageStart - activePanel) <\n Math.abs(closestStart - activePanel)\n ? index\n : closestIndex;\n }, 0);\n }, [activePanel, pageStartIndices]);\n\n const clampOffset = useCallback(\n (offset: number) => Math.min(layout.maxOffset, Math.max(0, offset)),\n [layout.maxOffset],\n );\n\n const activeOffset = clampOffset(layout.itemOffsets[activePanel] ?? 0);\n\n useEffect(() => {\n if (dragRef.current || animationFrameRef.current !== null) {\n return;\n }\n\n visualOffsetRef.current = activeOffset;\n }, [activeOffset]);\n\n useEffect(\n () => () => {\n pointerCleanupRef.current?.();\n\n if (animationFrameRef.current !== null) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n },\n [],\n );\n\n /**\n * Only correct the controller after layout measurement has completed.\n * This avoids forcing currentPanel to 0 during the initial render.\n */\n useEffect(() => {\n if (layout.numberOfPages > 0 && currentPanel !== activePanel) {\n setPanel(activePanel);\n }\n }, [activePanel, currentPanel, layout.numberOfPages, setPanel]);\n\n const goToPage = useCallback(\n (pageIndex: number) => {\n const targetPage = Math.max(\n 0,\n Math.min(pageIndex, pageStartIndices.length - 1),\n );\n\n const targetPanel = pageStartIndices[targetPage];\n\n if (targetPanel !== undefined) {\n setPanel(targetPanel);\n }\n },\n [pageStartIndices, setPanel],\n );\n\n const goToPreviousPage = useCallback(() => {\n goToPage(activePageIndex - 1);\n }, [activePageIndex, goToPage]);\n\n const goToNextPage = useCallback(() => {\n goToPage(activePageIndex + 1);\n }, [activePageIndex, goToPage]);\n\n /**\n * Start tracking a swipe or mouse drag.\n *\n * Capture on the original element rather than always on the viewport,\n * so a normal click on an interactive child can still work.\n */\n\n const writeTrackOffset = useCallback((offset: number) => {\n visualOffsetRef.current = offset;\n\n if (trackRef.current) {\n trackRef.current.style.transform = `translate3d(${-offset}px, 0, 0)`;\n }\n }, []);\n\n const getNearestPanelIndex = useCallback(\n (offset: number) => {\n let nearestIndex = 0;\n let nearestDistance = Number.POSITIVE_INFINITY;\n\n for (let index = 0; index <= layout.maxStartIndex; index += 1) {\n const candidateOffset = clampOffset(layout.itemOffsets[index] ?? 0);\n\n const distance = Math.abs(candidateOffset - offset);\n\n if (distance < nearestDistance) {\n nearestDistance = distance;\n nearestIndex = index;\n }\n }\n\n return nearestIndex;\n },\n [clampOffset, layout.itemOffsets, layout.maxStartIndex],\n );\n\n /**\n * Animate to a panel using a damped spring.\n *\n * A little underdamping gives the motion a natural overshoot.\n * The target remains a real, reachable item offset.\n */\n const animateToPanel = useCallback(\n (fromOffset: number, targetPanel: number, initialVelocity: number) => {\n if (animationFrameRef.current !== null) {\n cancelAnimationFrame(animationFrameRef.current);\n animationFrameRef.current = null;\n }\n\n const track = trackRef.current;\n const ownerWindow =\n viewportRef.current?.ownerDocument.defaultView ?? window;\n const targetOffset = clampOffset(layout.itemOffsets[targetPanel] ?? 0);\n\n if (\n !track ||\n ownerWindow.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n ) {\n writeTrackOffset(targetOffset);\n track?.style.removeProperty(\"transition\");\n setPanel(targetPanel);\n setIsDragging(false);\n setIsAnimating(false);\n return;\n }\n\n track.style.transition = \"none\";\n\n setIsDragging(false);\n setIsAnimating(true);\n\n let position = fromOffset;\n\n // Preserve some release momentum without allowing extreme fling speeds.\n let velocity = Math.max(-1800, Math.min(1800, initialVelocity * 0.4));\n\n let previousTime = performance.now();\n\n const stiffness = 230;\n const damping = 24;\n\n const animate = (now: number) => {\n const deltaSeconds = Math.min((now - previousTime) / 1000, 1 / 30);\n\n previousTime = now;\n\n const springAcceleration = (targetOffset - position) * stiffness;\n\n const dampingAcceleration = velocity * damping;\n\n velocity += (springAcceleration - dampingAcceleration) * deltaSeconds;\n\n position += velocity * deltaSeconds;\n\n const viewportWidth = viewportRef.current?.clientWidth ?? 1;\n\n writeTrackOffset(\n rubberBandOffset(position, layout.maxOffset, viewportWidth),\n );\n\n const positionSettled = Math.abs(targetOffset - position) < 0.5;\n\n const velocitySettled = Math.abs(velocity) < 10;\n\n if (positionSettled && velocitySettled) {\n animationFrameRef.current = null;\n\n writeTrackOffset(targetOffset);\n track.style.removeProperty(\"transition\");\n\n setPanel(targetPanel);\n setIsAnimating(false);\n\n return;\n }\n\n animationFrameRef.current = requestAnimationFrame(animate);\n };\n\n animationFrameRef.current = requestAnimationFrame(animate);\n },\n [\n clampOffset,\n layout.itemOffsets,\n layout.maxOffset,\n setPanel,\n writeTrackOffset,\n ],\n );\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!event.isPrimary || dragRef.current) {\n return;\n }\n\n if (event.pointerType === \"mouse\" && event.button !== 0) {\n return;\n }\n\n if (layout.maxOffset <= 0) {\n return;\n }\n\n const track = trackRef.current;\n const viewport = viewportRef.current;\n const ownerWindow = viewport?.ownerDocument.defaultView ?? window;\n\n if (!track || !viewport || !ownerWindow) {\n return;\n }\n\n const interruptedAnimation = animationFrameRef.current !== null;\n\n if (animationFrameRef.current !== null) {\n cancelAnimationFrame(animationFrameRef.current);\n animationFrameRef.current = null;\n }\n\n /*\n * Read the currently displayed offset before disabling the CSS\n * transition. This also handles starting a drag during an animation.\n */\n const startOffset = readRenderedOffset(track, visualOffsetRef.current);\n\n track.style.transition = \"none\";\n writeTrackOffset(startOffset);\n\n setIsAnimating(false);\n setIsDragging(true);\n\n const startTime = performance.now();\n\n const drag: DragState = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startOffset,\n currentOffset: startOffset,\n renderedOffset: startOffset,\n hasMoved: false,\n interruptedAnimation,\n samples: [\n {\n x: event.clientX,\n time: startTime,\n },\n ],\n };\n\n dragRef.current = drag;\n\n const updatePointerPosition = (pointerEvent: PointerEvent) => {\n const deltaX = pointerEvent.clientX - drag.startX;\n\n if (!drag.hasMoved && Math.abs(deltaX) <= 4) {\n return;\n }\n\n drag.hasMoved = true;\n\n // Positive offset means the content moves to the left.\n drag.currentOffset = drag.startOffset - deltaX;\n\n drag.renderedOffset = rubberBandOffset(\n drag.currentOffset,\n layout.maxOffset,\n viewport.clientWidth,\n );\n\n const now = performance.now();\n\n drag.samples.push({\n x: pointerEvent.clientX,\n time: now,\n });\n\n // Retain a short history for release-velocity estimation.\n while (drag.samples.length > 2 && now - drag.samples[1]!.time > 120) {\n drag.samples.shift();\n }\n\n writeTrackOffset(drag.renderedOffset);\n\n if (pointerEvent.cancelable) {\n pointerEvent.preventDefault();\n }\n };\n\n const cleanup = () => {\n ownerWindow.removeEventListener(\"pointermove\", handleWindowPointerMove);\n ownerWindow.removeEventListener(\"pointerup\", handleWindowPointerUp);\n ownerWindow.removeEventListener(\n \"pointercancel\",\n handleWindowPointerCancel,\n );\n ownerWindow.removeEventListener(\"blur\", handleWindowBlur);\n\n if (pointerCleanupRef.current === cleanup) {\n pointerCleanupRef.current = null;\n }\n };\n\n const settleCancelledDrag = () => {\n if (dragRef.current !== drag) {\n return;\n }\n\n cleanup();\n dragRef.current = null;\n setIsDragging(false);\n\n const targetPanel = getNearestPanelIndex(\n clampOffset(drag.currentOffset),\n );\n\n animateToPanel(drag.renderedOffset, targetPanel, 0);\n };\n\n const handleWindowPointerMove = (pointerEvent: PointerEvent) => {\n if (pointerEvent.pointerId !== drag.pointerId) {\n return;\n }\n\n updatePointerPosition(pointerEvent);\n };\n\n const handleWindowPointerUp = (pointerEvent: PointerEvent) => {\n if (pointerEvent.pointerId !== drag.pointerId) {\n return;\n }\n\n // Include the final pointer position, even if no final move fired.\n updatePointerPosition(pointerEvent);\n\n cleanup();\n dragRef.current = null;\n setIsDragging(false);\n\n if (!drag.hasMoved) {\n if (drag.interruptedAnimation) {\n const targetPanel = getNearestPanelIndex(\n clampOffset(drag.startOffset),\n );\n\n animateToPanel(drag.startOffset, targetPanel, 0);\n } else {\n track.style.removeProperty(\"transition\");\n writeTrackOffset(drag.startOffset);\n }\n\n return;\n }\n\n suppressClickRef.current = true;\n\n ownerWindow.setTimeout(() => {\n suppressClickRef.current = false;\n }, 0);\n\n const velocity = estimatePointerVelocity(drag.samples);\n\n /*\n * Project the release position forward. A fast swipe can skip\n * multiple items, while a slow drag generally snaps nearby.\n */\n const projectedOffset = clampOffset(\n clampOffset(drag.currentOffset) + velocity * 0.18,\n );\n\n const targetPanel = getNearestPanelIndex(projectedOffset);\n\n animateToPanel(drag.renderedOffset, targetPanel, velocity);\n };\n\n const handleWindowPointerCancel = (pointerEvent: PointerEvent) => {\n if (pointerEvent.pointerId === drag.pointerId) {\n settleCancelledDrag();\n }\n };\n\n const handleWindowBlur = () => {\n settleCancelledDrag();\n };\n\n pointerCleanupRef.current = cleanup;\n\n /*\n * Listen on window instead of relying on events staying inside the\n * viewport. Releasing outside the carousel still completes the drag.\n */\n ownerWindow.addEventListener(\"pointermove\", handleWindowPointerMove);\n ownerWindow.addEventListener(\"pointerup\", handleWindowPointerUp);\n ownerWindow.addEventListener(\"pointercancel\", handleWindowPointerCancel);\n ownerWindow.addEventListener(\"blur\", handleWindowBlur);\n },\n [\n animateToPanel,\n clampOffset,\n getNearestPanelIndex,\n layout.maxOffset,\n setIsAnimating,\n writeTrackOffset,\n ],\n );\n\n const handleClickCapture = useCallback(\n (event: ReactMouseEvent<HTMLDivElement>) => {\n if (!suppressClickRef.current) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n suppressClickRef.current = false;\n },\n [],\n );\n\n const isFirstPage = activePageIndex === 0;\n const isLastPage =\n layout.numberOfPages <= 1 || activePageIndex >= layout.numberOfPages - 1;\n\n const currentPage = layout.numberOfPages > 0 ? activePageIndex : 0;\n\n return (\n <div\n className={cn(\"puzzle-carousel\", className)}\n style={cssVariables}\n data-sizing={sizingMode}\n data-dragging={isDragging ? \"true\" : \"false\"}\n data-animating={isAnimating ? \"true\" : \"false\"}\n data-single-page={layout.numberOfPages <= 1 ? \"true\" : \"false\"}\n data-single-page-alignment={singlePageAlignment}\n data-button-mobile={buttonAlignments.mobile}\n data-button-tablet={buttonAlignments.tablet}\n data-button-desktop={buttonAlignments.desktop}\n data-pager-mobile={getPagerDataAttribute(pagerAlignments.mobile)}\n data-pager-tablet={getPagerDataAttribute(\n pagerAlignments.tablet ?? pagerAlignments.mobile,\n )}\n data-pager-desktop={getPagerDataAttribute(\n pagerAlignments.desktop ??\n pagerAlignments.tablet ??\n pagerAlignments.mobile,\n )}\n >\n <div className=\"puzzle-carousel__stage\">\n <div className=\"puzzle-carousel__navigation puzzle-carousel__navigation--previous\">\n {cloneNavigationButton(backButton, isFirstPage, goToPreviousPage)}\n </div>\n\n <div\n ref={viewportRef}\n className={cn(\"puzzle-carousel__viewport\", viewportClassName)}\n style={viewportStyle}\n role=\"group\"\n aria-roledescription=\"carousel\"\n aria-label={ariaLabel}\n onPointerDown={handlePointerDown}\n onClickCapture={handleClickCapture}\n onDragStart={(event) => event.preventDefault()}\n >\n <div\n ref={trackRef}\n className=\"puzzle-carousel__track\"\n style={{\n transform: `translate3d(${-activeOffset}px, 0, 0)`,\n }}\n >\n {items.map((item, index) => (\n <div\n key={getItemKey ? getItemKey(item, index) : index}\n ref={(node) => {\n itemRefs.current[index] = node;\n }}\n className=\"puzzle-carousel__item\"\n role=\"group\"\n aria-roledescription=\"slide\"\n aria-label={`${index + 1} of ${items.length}`}\n >\n {renderItem(item, index)}\n </div>\n ))}\n </div>\n </div>\n\n <div className=\"puzzle-carousel__navigation puzzle-carousel__navigation--next\">\n {cloneNavigationButton(nextButton, isLastPage, goToNextPage)}\n </div>\n </div>\n\n {renderPager && layout.numberOfPages > 0 && (\n <div className=\"puzzle-carousel__pager\">\n {renderPager(currentPage, layout.numberOfPages)}\n </div>\n )}\n </div>\n );\n};\n\nexport {\n Carousel,\n type CarouselProps,\n type CarouselAlignment,\n type CarouselButtonAlignment,\n type CarouselPagerAlignment,\n type CarouselAlignmentConfig,\n type PagerAlignmentConfig,\n};\n"],"mappings":"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"}
|
|
@@ -157,7 +157,10 @@ const Carousel = ({ renderItem, getItemKey, panelsPerView, itemWidth, gap = 0, c
|
|
|
157
157
|
}, [
|
|
158
158
|
items.length,
|
|
159
159
|
itemOrderSignature,
|
|
160
|
-
measureLayout
|
|
160
|
+
measureLayout,
|
|
161
|
+
gaps.mobile,
|
|
162
|
+
gaps.tablet,
|
|
163
|
+
gaps.desktop
|
|
161
164
|
]);
|
|
162
165
|
/**
|
|
163
166
|
* currentPanel is always an item index.
|