@azmr/mui-carousel-react 2.0.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/LICENSE.txt +21 -0
- package/README.md +419 -0
- package/dist/esm/components/Carousel.d.ts +4 -0
- package/dist/esm/components/Carousel.js +165 -0
- package/dist/esm/components/CarouselItem.d.ts +19 -0
- package/dist/esm/components/CarouselItem.js +141 -0
- package/dist/esm/components/Indicators.d.ts +12 -0
- package/dist/esm/components/Indicators.js +61 -0
- package/dist/esm/components/Styled.d.ts +17 -0
- package/dist/esm/components/Styled.js +81 -0
- package/dist/esm/components/types.d.ts +86 -0
- package/dist/esm/components/types.js +1 -0
- package/dist/esm/components/util.d.ts +51 -0
- package/dist/esm/components/util.js +86 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/package.json +83 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Ioannis Maliaras
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
# React Material UI Carousel [](https://www.npmjs.com/package/mui-carousel-react)
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
A Generic, extendible Carousel UI component for React using [Material UI](https://material-ui.com/)
|
|
6
|
+
It switches between given children using a smooth animation.
|
|
7
|
+
Provides next and previous buttons.
|
|
8
|
+
Also provides interactible bullet indicators.
|
|
9
|
+
|
|
10
|
+
## Live Demo
|
|
11
|
+
|
|
12
|
+
Take a look at this interactible [Live Demo](https://coderchef26.dev/mui-carousel)
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```shell
|
|
17
|
+
npm install mui-carousel-react --save
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Note:**
|
|
21
|
+
|
|
22
|
+
You will need to have Material UI installed, in order to use this library/component
|
|
23
|
+
|
|
24
|
+
```shell
|
|
25
|
+
npm install @mui/material
|
|
26
|
+
npm install @mui/icons-material
|
|
27
|
+
npm install @mui/styles
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage Example
|
|
31
|
+
|
|
32
|
+
```jsx
|
|
33
|
+
import React from "react";
|
|
34
|
+
import Carousel from "mui-carousel-react";
|
|
35
|
+
import { Paper, Button } from "@mui/material";
|
|
36
|
+
|
|
37
|
+
function Example(props) {
|
|
38
|
+
var items = [
|
|
39
|
+
{
|
|
40
|
+
name: "Random Name #1",
|
|
41
|
+
description: "Probably the most random thing you have ever seen!",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "Random Name #2",
|
|
45
|
+
description: "Hello World!",
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Carousel>
|
|
51
|
+
{items.map((item, i) => (
|
|
52
|
+
<Item key={i} item={item} />
|
|
53
|
+
))}
|
|
54
|
+
</Carousel>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function Item(props) {
|
|
59
|
+
return (
|
|
60
|
+
<Paper>
|
|
61
|
+
<h2>{props.item.name}</h2>
|
|
62
|
+
<p>{props.item.description}</p>
|
|
63
|
+
|
|
64
|
+
<Button className="CheckButton">Check it out!</Button>
|
|
65
|
+
</Paper>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Next & Prev Usage
|
|
71
|
+
|
|
72
|
+
```jsx
|
|
73
|
+
<Carousel
|
|
74
|
+
next={ (next, active) => console.log(`we left ${active}, and are now at ${next}`); }
|
|
75
|
+
prev={ (prev, active) => console.log(`we left ${active}, and are now at ${prev}`); }
|
|
76
|
+
>
|
|
77
|
+
{...}
|
|
78
|
+
</Carousel>
|
|
79
|
+
|
|
80
|
+
// OR
|
|
81
|
+
|
|
82
|
+
<Carousel
|
|
83
|
+
next={ () => {/* Do stuff */} }
|
|
84
|
+
prev={ () => {/* Do other stuff */} }
|
|
85
|
+
>
|
|
86
|
+
{...}
|
|
87
|
+
</Carousel>
|
|
88
|
+
|
|
89
|
+
// And so on...
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Note: `onChange` works in a similar fashion. See [Props](#props) below.
|
|
93
|
+
|
|
94
|
+
## Customizing Navigation
|
|
95
|
+
|
|
96
|
+
### Navigation Buttons - Customizing the default solution
|
|
97
|
+
|
|
98
|
+
These are the props that are used to directly customize the Carousel's default buttons:
|
|
99
|
+
|
|
100
|
+
- NextIcon
|
|
101
|
+
- PrevIcon
|
|
102
|
+
- navButtonsProps
|
|
103
|
+
- navButtonsWrapperProps
|
|
104
|
+
- fullHeightHover
|
|
105
|
+
|
|
106
|
+
#### Example #1
|
|
107
|
+
|
|
108
|
+
Say we don't like the default icons used for the next and prev buttons
|
|
109
|
+
and want to change them to be an MUI Icon or an image of our own.
|
|
110
|
+
|
|
111
|
+
```jsx
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
import RandomIcon from '@@mui/icons-material/Random'; // Note: this doesn't exist
|
|
115
|
+
|
|
116
|
+
<Carousel
|
|
117
|
+
NextIcon={<RandomIcon/>}
|
|
118
|
+
PrevIcon={<RandomIcon/>}
|
|
119
|
+
// OR
|
|
120
|
+
NextIcon={<img src="http://random.com/next"/>}
|
|
121
|
+
PrevIcon={<img src="http://random.com/prev"/>}
|
|
122
|
+
>
|
|
123
|
+
{...}
|
|
124
|
+
</Carousel>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The `NextIcon` and `PrevIcon` is of type `ReactNode`, meaning it can be any JSX element or a string. _Note: Extra styling may be needed when using those props_.
|
|
128
|
+
|
|
129
|
+
#### Example #2
|
|
130
|
+
|
|
131
|
+
Let's now say we don't like the default graphite background of the buttons, nor do we like the fact that it is round.
|
|
132
|
+
We also want to place them under the main Carousel, and finally remove the arrows and have "next" and "prev" accordingly to each button.
|
|
133
|
+
|
|
134
|
+
A very important note here, is that any styles specified by the user **DO NOT OVERRIDE THE EXISTING STYLES**. They work in tandem with them. That means, that if you want to change, or get rid of a CSS attribute you will have to override it or unset it. The [Default styles](#default-styles) are given at the end of this section, and are part of the code.
|
|
135
|
+
|
|
136
|
+
```jsx
|
|
137
|
+
<Carousel
|
|
138
|
+
fullHeightHover={false} // We want the nav buttons wrapper to only be as big as the button element is
|
|
139
|
+
navButtonsProps={{ // Change the colors and radius of the actual buttons. THIS STYLES BOTH BUTTONS
|
|
140
|
+
style: {
|
|
141
|
+
backgroundColor: 'cornflowerblue',
|
|
142
|
+
borderRadius: 0
|
|
143
|
+
}
|
|
144
|
+
}}
|
|
145
|
+
navButtonsWrapperProps={{ // Move the buttons to the bottom. Unsetting top here to override default style.
|
|
146
|
+
style: {
|
|
147
|
+
bottom: '0',
|
|
148
|
+
top: 'unset'
|
|
149
|
+
}
|
|
150
|
+
}}
|
|
151
|
+
NextIcon='next' // Change the "inside" of the next button to "next"
|
|
152
|
+
PrevIcon='prev' // Change the "inside of the prev button to "prev"
|
|
153
|
+
>
|
|
154
|
+
{...}
|
|
155
|
+
</Carousel>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Of course, extra styling to the button wrappers, or indicators might be needed to achieve exactly what we may be looking for. _Note: You can also use `className` to change the styles externally_.
|
|
159
|
+
|
|
160
|
+
### Customizing the navigation buttons directly
|
|
161
|
+
|
|
162
|
+
Do directly customize/change the navigation buttons `NavButton` prop, that allows the user to take complete control of the components rendered as the navigation buttons. It should be used like this:
|
|
163
|
+
|
|
164
|
+
#### Example
|
|
165
|
+
|
|
166
|
+
```jsx
|
|
167
|
+
import {Button} from '@mui/material';
|
|
168
|
+
|
|
169
|
+
<Carousel
|
|
170
|
+
NavButton={({onClick, className, style, next, prev}) => {
|
|
171
|
+
// Other logic
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<Button onClick={onClick} className={className} style={style}>
|
|
175
|
+
{next && "Next"}
|
|
176
|
+
{prev && "Previous"}
|
|
177
|
+
</Button>
|
|
178
|
+
)
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
{...}
|
|
182
|
+
</Carousel>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
##### Parameters Explanation
|
|
186
|
+
|
|
187
|
+
- `onClick`: The function that handles actual navigation. If you do not add this to your component, the buttons will not work.
|
|
188
|
+
- `className`: The className given by the carousel component. This is used to handle Visible/Invisible, hover, and user specified styles (e.g. from navButtonProps). Apply it to the outmost element.
|
|
189
|
+
- `style`: The style given by the carousel component. Used to give any user specified styles (e.g. from navButtonProps).
|
|
190
|
+
- `next`: Boolean value that specifies whether this is the next button.
|
|
191
|
+
- `prev`: Boolean value that specifies whether this is the prev button.
|
|
192
|
+
|
|
193
|
+
The prop value must be a function that returns a component. All parameters are optional as far as styling goes (**not functionality**), but it is advised you use them as shown above.
|
|
194
|
+
As implied, any `className`s or `style`s specified in the navButtonsProps will only be used iff you apply the given `className` and `style` parameters.
|
|
195
|
+
|
|
196
|
+
### Customizing the Indicators
|
|
197
|
+
|
|
198
|
+
There are 4 props that handle indicator customization
|
|
199
|
+
|
|
200
|
+
- IndicatorIcon
|
|
201
|
+
- activeIndicatorIconButtonProps
|
|
202
|
+
- indicatorIconButtonProps
|
|
203
|
+
- indicatorContainerProps
|
|
204
|
+
|
|
205
|
+
#### Example
|
|
206
|
+
|
|
207
|
+
Let's say we would like to change the indicator icon from a circle to a something else, for example a little house
|
|
208
|
+
|
|
209
|
+
```jsx
|
|
210
|
+
import Home from '@mui/icons-material/Home';
|
|
211
|
+
|
|
212
|
+
<Carousel
|
|
213
|
+
IndicatorIcon={<Home/>}
|
|
214
|
+
// OR
|
|
215
|
+
IndicatorIcon={<img src="http://random.com/home"/>}
|
|
216
|
+
>
|
|
217
|
+
{...}
|
|
218
|
+
</Carousel>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The `IndicatorIcon` works the same way as the `NextIcon` and `PrevIcon` prop.
|
|
222
|
+
|
|
223
|
+
#### Example #2
|
|
224
|
+
|
|
225
|
+
Let's say we would like to have an array to icons like numbers, to order the elements of my carousel numerically. Let's do this!
|
|
226
|
+
|
|
227
|
+
```jsx
|
|
228
|
+
const anArrayOfNumbers = [<img src="http://random.com/one"/>,
|
|
229
|
+
<img src="http://random.com/two"/>,
|
|
230
|
+
<img src="http://random.com/three"/>
|
|
231
|
+
];
|
|
232
|
+
|
|
233
|
+
<Carousel
|
|
234
|
+
IndicatorIcon={anArrayOfNumbers}
|
|
235
|
+
>
|
|
236
|
+
{...}
|
|
237
|
+
</Carousel>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
#### Example #3
|
|
241
|
+
|
|
242
|
+
Now we want to do more complex customizations. Specifically:
|
|
243
|
+
|
|
244
|
+
1. More distance between the indicator icons
|
|
245
|
+
2. Change the background color of the active indicator to `red`
|
|
246
|
+
3. Change the color of all indicators to `blue`
|
|
247
|
+
4. Move the indicators to the right side of the carousel
|
|
248
|
+
5. Move the indicators to be further away down from the carousel
|
|
249
|
+
|
|
250
|
+
We are going to use all props to style the indicators
|
|
251
|
+
|
|
252
|
+
```jsx
|
|
253
|
+
import Home from '@mui/icons-material/Home';
|
|
254
|
+
|
|
255
|
+
<Carousel
|
|
256
|
+
IndicatorIcon={<Home/>} // Previous Example
|
|
257
|
+
indicatorIconButtonProps={{
|
|
258
|
+
style: {
|
|
259
|
+
padding: '10px', // 1
|
|
260
|
+
color: 'blue' // 3
|
|
261
|
+
}
|
|
262
|
+
}}
|
|
263
|
+
activeIndicatorIconButtonProps={{
|
|
264
|
+
style: {
|
|
265
|
+
backgroundColor: 'red' // 2
|
|
266
|
+
}
|
|
267
|
+
}}
|
|
268
|
+
indicatorContainerProps={{
|
|
269
|
+
style: {
|
|
270
|
+
marginTop: '50px', // 5
|
|
271
|
+
textAlign: 'right' // 4
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
}}
|
|
275
|
+
>
|
|
276
|
+
{...}
|
|
277
|
+
</Carousel>
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
As before, you can use `className` to style the elements externally.
|
|
281
|
+
|
|
282
|
+
### Default Styles
|
|
283
|
+
|
|
284
|
+
Giving the default styles in pseudo-code.
|
|
285
|
+
|
|
286
|
+
#### Navigation Buttons
|
|
287
|
+
|
|
288
|
+
```js
|
|
289
|
+
{
|
|
290
|
+
buttonWrapper: {
|
|
291
|
+
position: "absolute",
|
|
292
|
+
height: "100px",
|
|
293
|
+
backgroundColor: "transparent",
|
|
294
|
+
top: "calc(50% - 70px)",
|
|
295
|
+
'&:hover': {
|
|
296
|
+
'& $button': {
|
|
297
|
+
backgroundColor: "black",
|
|
298
|
+
filter: "brightness(120%)",
|
|
299
|
+
opacity: "0.4"
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
fullHeightHoverWrapper: {
|
|
304
|
+
height: "100%",
|
|
305
|
+
top: "0"
|
|
306
|
+
},
|
|
307
|
+
buttonVisible:{
|
|
308
|
+
opacity: "1"
|
|
309
|
+
},
|
|
310
|
+
buttonHidden:{
|
|
311
|
+
opacity: "0",
|
|
312
|
+
},
|
|
313
|
+
button: {
|
|
314
|
+
margin: "0 10px",
|
|
315
|
+
position: "relative",
|
|
316
|
+
backgroundColor: "#494949",
|
|
317
|
+
top: "calc(50% - 20px) !important",
|
|
318
|
+
color: "white",
|
|
319
|
+
fontSize: "30px",
|
|
320
|
+
transition: "200ms",
|
|
321
|
+
cursor: "pointer",
|
|
322
|
+
'&:hover': {
|
|
323
|
+
opacity: "0.6 !important"
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
// Applies to the "next" button wrapper
|
|
327
|
+
next: {
|
|
328
|
+
right: 0
|
|
329
|
+
},
|
|
330
|
+
// Applies to the "prev" button wrapper
|
|
331
|
+
prev: {
|
|
332
|
+
left: 0
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
#### Indicators
|
|
338
|
+
|
|
339
|
+
```js
|
|
340
|
+
{
|
|
341
|
+
indicators: {
|
|
342
|
+
width: "100%",
|
|
343
|
+
marginTop: "10px",
|
|
344
|
+
textAlign: "center"
|
|
345
|
+
},
|
|
346
|
+
indicator: {
|
|
347
|
+
cursor: "pointer",
|
|
348
|
+
transition: "200ms",
|
|
349
|
+
padding: 0,
|
|
350
|
+
color: "#afafaf",
|
|
351
|
+
'&:hover': {
|
|
352
|
+
color: "#1f1f1f"
|
|
353
|
+
},
|
|
354
|
+
'&:active': {
|
|
355
|
+
color: "#1f1f1f"
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
indicatorIcon: {
|
|
359
|
+
fontSize: "15px",
|
|
360
|
+
},
|
|
361
|
+
// Applies to the active indicator
|
|
362
|
+
active: {
|
|
363
|
+
color: "#494949"
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Props
|
|
369
|
+
|
|
370
|
+
| Prop name | Type | Default | Description |
|
|
371
|
+
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
372
|
+
| sx | `SxProps<Theme>` | `{}` | Defines `sx` props, that will be **inserted** into the Carousel 's root element |
|
|
373
|
+
| className | `string` | "" | Defines custom class name(s), that will be **added** to Carousel element |
|
|
374
|
+
| height | `number \| string` | `undefined` | Defines the carousel's height in `px`. If this is not set, the carousel's height will be the height of its children. If it is not set, the carousel's height will be the same as the current active child. |
|
|
375
|
+
| index | `number` | `0` | Defines which child (assuming there are more than 1 children) will be displayed. Next and Previous Buttons as well as Indicators will work normally after the first render. When this prop is updated the carousel will display the chosen child. _Use this prop to programmatically set the active child_. If (index > children.length) then if (strictIndexing) index = last element. index |
|
|
376
|
+
| strictIndexing | `boolean` | `true` | Defines whether index can be bigger than children length |
|
|
377
|
+
| autoPlay | `boolean` | `true` | Defines if the component will auto scroll between children |
|
|
378
|
+
| stopAutoPlayOnHover | `boolean` | `true` | Defines if auto scrolling will continue while mousing over carousel |
|
|
379
|
+
| interval | `number` | `4000` | Defines the interval in **ms** between active child changes (autoPlay) |
|
|
380
|
+
| animation | `"fade" \| "slide"` | `"fade"` | Defines the animation style of the Carousel |
|
|
381
|
+
| duration | `number` | `500` | Defines the duration of the animations. |
|
|
382
|
+
| swipe | `boolean` | `true` | Defines if swiping left and right (in touch devices) triggers `next` and `prev` behaviour |
|
|
383
|
+
| indicators | `boolean` | `true` | Defines the existence of bullet indicators |
|
|
384
|
+
| navButtonsAlwaysVisible | `boolean` | `false` | Defines if the next/previous buttons will always be visible or not |
|
|
385
|
+
| navButtonsAlwaysInvisible | `boolean` | `false` | Defines if the next/previous buttons will always be invisible or not |
|
|
386
|
+
| cycleNavigation | `boolean` | `true` | Defines if the next button will be visible on the last slide, and the previous button on the first slide. Auto-play also stops on the last slide. Indicators continue to work normally. |
|
|
387
|
+
| fullHeightHover | `boolean` | `true` | Defines if the the next/previous button wrappers will cover the full **height** of the Item element and show buttons on full height hover |
|
|
388
|
+
| navButtonsWrapperProps | `{className: string, style: React.CSSProperties} & React.AriaAttributes` | `undefined` | Used to customize the div surrounding the nav `IconButtons`. Use this to position the buttons onto, below, outside, e.t.c. the carousel. _Tip_: Check the [default styles](#default-styles) below. |
|
|
389
|
+
| navButtonsProps | `{className: string, style: React.CSSProperties} & React.AriaAttributes` | `undefined` | Used to customize the actual nav `IconButton`s |
|
|
390
|
+
| NextIcon | `ReactNode` | `<NavigateNextIcon/>` | Defines the element inside the nav "next" `IconButton`. Refer to [MaterialUI Button Documentation](https://material-ui.com/components/buttons/) for more examples. It is advised to use Material UI Icons, but you could use any element (`<img/>`, `<div/>`, ...) you like. |
|
|
391
|
+
| PrevIcon | `ReactNode` | `<NavigateNextIcon/>` | Defines the element inside the nav "prev" `IconButton`. Refer to [MaterialUI Button Documentation](https://material-ui.com/components/buttons/) for more examples. It is advised to use Material UI Icons, but you could use any element (`<img/>`, `<div/>`, ...) you like. |
|
|
392
|
+
| NavButton | `({onClick, className, style, prev, next}: {onClick: Function, className: string, style: React.CSSProperties, next: boolean, prev: boolean}) => ReactNode` | `undefined` | Gives full control of the nav buttons. Should return a button that uses the given `onClick`. Works in tandem with all other customization options (`navButtonsProps`, `navButtonsWrapperProps`, `navButtonsAlwaysVisible`, `navButtonsAlwaysInvisible`, `fullHeightHover`, ...). Refer to the [example section](README.md#CustomizingNavigation) for more information. |
|
|
393
|
+
| indicatorIconButtonProps | `{className: string, style: React.CSSProperties} & React.AriaAttributes` | `undefined` | Used to customize **all** indicator `IconButton`s. Additive to `activeIndicatorIconButtonProps`. Any `aria-label` property used will be rendered with the indicator index next to it. e.g. `{'aria-label': 'indicator'}` --> `'indicator 1'` |
|
|
394
|
+
| activeIndicatorIconButtonProps | `{className: string, style: React.CSSProperties} & React.AriaAttributes` | `undefined` | Used to customize the **active** indicator `IconButton`. Additive to `indicatorIconButtonProps`. |
|
|
395
|
+
| indicatorContainerProps | `{className: string, style: React.CSSProperties} & React.AriaAttributes` | `undefined` | Used to customize the indicators container/wrapper. |
|
|
396
|
+
| IndicatorIcon | `ReactNode` | `<FiberManualRecordIcon size='small' className={classes.indicatorIcon}/>` | Defines the element inside the indicator `IconButton`s Refer to [MaterialUI Button Documentation](https://material-ui.com/components/buttons/) for more examples. It is advised to use Material UI Icons, but you could use any element (`<img/>`, `<div/>`, ...) you like. |
|
|
397
|
+
| onChange | `(now?: number, previous?: number) => any` | `() => {}` | Function that is called **after** internal `setActive()` method. The `setActive()` method is called when the next and previous buttons are pressed, when an indicator is pressed, or when the `index` prop changes. First argument is the child **we are going to display**, while the second argument is the child **that was previously displayed**. Will be called in conjunction with and **after** `next` and `prev` props if defined. It will not get called in first render, except if `changeOnFirstRender` is defined |
|
|
398
|
+
| changeOnFirstRender | `boolean` | `false` | Defines if `onChange` prop will be called when the carousel renders for the first time. In `componentDidMount` |
|
|
399
|
+
| next | `(now?: number, previous?: number) => any` | `() => {}` | Function that is called **after** internal `next()` method. First argument is the child **we are going to display**, while the second argument is the child **that was previously displayed** |
|
|
400
|
+
| prev | `(now?: number, previous?: number) => any` | `() => {}` | Function that is called **after** internal `prev()` method. First argument is the child **we are going to display**, while the second argument is the child **that was previously displayed** |
|
|
401
|
+
|
|
402
|
+
## License
|
|
403
|
+
|
|
404
|
+
The MIT License.
|
|
405
|
+
|
|
406
|
+
## Credits
|
|
407
|
+
|
|
408
|
+
**Original Author**: Learus (no longer actively maintaining)
|
|
409
|
+
|
|
410
|
+
**Current Maintainer**: [Azmara Technologies](https://azmara.io) ([Coder Chef](https://github.com/coderchef26))
|
|
411
|
+
|
|
412
|
+
## Support
|
|
413
|
+
|
|
414
|
+
If you find this library useful, consider supporting its development:
|
|
415
|
+
|
|
416
|
+
[](https://buymeacoffee.com/alghaazi)
|
|
417
|
+
[](https://www.paypal.me/alghaazi)
|
|
418
|
+
|
|
419
|
+
Your support helps maintain and improve this library!
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { CarouselItem } from './CarouselItem';
|
|
13
|
+
import { Indicators } from './Indicators';
|
|
14
|
+
import { sanitizeProps, useInterval } from './util';
|
|
15
|
+
import { StyledButtonWrapper, StyledIconButton, StyledItemWrapper, StyledRoot } from './Styled';
|
|
16
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
17
|
+
export var Carousel = function (props) {
|
|
18
|
+
var _a = useState({
|
|
19
|
+
active: 0,
|
|
20
|
+
prevActive: 0,
|
|
21
|
+
next: true
|
|
22
|
+
}), state = _a[0], setState = _a[1];
|
|
23
|
+
/** Used to set carousel's height. It is being set by the CarouselItems */
|
|
24
|
+
var _b = useState(), childrenHeight = _b[0], setChildrenHeight = _b[1];
|
|
25
|
+
var _c = useState(false), paused = _c[0], setPaused = _c[1];
|
|
26
|
+
var sanitizedProps = sanitizeProps(props);
|
|
27
|
+
// componentDidMount & onIndexChange
|
|
28
|
+
useEffect(function () {
|
|
29
|
+
var index = sanitizedProps.index, changeOnFirstRender = sanitizedProps.changeOnFirstRender;
|
|
30
|
+
setNext(index, true, changeOnFirstRender);
|
|
31
|
+
}, [sanitizedProps.index]);
|
|
32
|
+
useInterval(function () {
|
|
33
|
+
var autoPlay = sanitizedProps.autoPlay;
|
|
34
|
+
if (autoPlay && !paused) {
|
|
35
|
+
next(undefined);
|
|
36
|
+
}
|
|
37
|
+
}, sanitizedProps.interval);
|
|
38
|
+
// Memoized setNext function - must be defined before next/prev
|
|
39
|
+
var setNext = useCallback(function (index, isNext, runCallbacks) {
|
|
40
|
+
if (runCallbacks === void 0) { runCallbacks = true; }
|
|
41
|
+
var onChange = sanitizedProps.onChange, children = sanitizedProps.children, strictIndexing = sanitizedProps.strictIndexing;
|
|
42
|
+
if (Array.isArray(children)) {
|
|
43
|
+
if (strictIndexing && index > children.length - 1)
|
|
44
|
+
index = children.length - 1;
|
|
45
|
+
if (strictIndexing && index < 0)
|
|
46
|
+
index = 0;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
index = 0;
|
|
50
|
+
}
|
|
51
|
+
if (runCallbacks) {
|
|
52
|
+
if (isNext !== undefined)
|
|
53
|
+
isNext ? sanitizedProps.next(index, state.active) : sanitizedProps.prev(index, state.active);
|
|
54
|
+
onChange(index, state.active);
|
|
55
|
+
}
|
|
56
|
+
if (isNext === undefined) {
|
|
57
|
+
isNext = index > state.active;
|
|
58
|
+
}
|
|
59
|
+
setState({
|
|
60
|
+
active: index,
|
|
61
|
+
prevActive: state.active,
|
|
62
|
+
next: isNext
|
|
63
|
+
});
|
|
64
|
+
}, [sanitizedProps, state.active]);
|
|
65
|
+
var next = useCallback(function (event) {
|
|
66
|
+
var children = sanitizedProps.children, cycleNavigation = sanitizedProps.cycleNavigation;
|
|
67
|
+
var last = Array.isArray(children) ? children.length - 1 : 0;
|
|
68
|
+
var nextActive = state.active + 1 > last ? (cycleNavigation ? 0 : state.active) : state.active + 1;
|
|
69
|
+
setNext(nextActive, true);
|
|
70
|
+
if (event)
|
|
71
|
+
event.stopPropagation();
|
|
72
|
+
}, [sanitizedProps, state.active, setNext]);
|
|
73
|
+
var prev = useCallback(function (event) {
|
|
74
|
+
var children = sanitizedProps.children, cycleNavigation = sanitizedProps.cycleNavigation;
|
|
75
|
+
var last = Array.isArray(children) ? children.length - 1 : 0;
|
|
76
|
+
var nextActive = state.active - 1 < 0 ? (cycleNavigation ? last : state.active) : state.active - 1;
|
|
77
|
+
setNext(nextActive, false);
|
|
78
|
+
if (event)
|
|
79
|
+
event.stopPropagation();
|
|
80
|
+
}, [sanitizedProps, state.active, setNext]);
|
|
81
|
+
var children = sanitizedProps.children, sx = sanitizedProps.sx, className = sanitizedProps.className, height = sanitizedProps.height, stopAutoPlayOnHover = sanitizedProps.stopAutoPlayOnHover, animation = sanitizedProps.animation, duration = sanitizedProps.duration, swipe = sanitizedProps.swipe, navButtonsAlwaysInvisible = sanitizedProps.navButtonsAlwaysInvisible, navButtonsAlwaysVisible = sanitizedProps.navButtonsAlwaysVisible, cycleNavigation = sanitizedProps.cycleNavigation, fullHeightHover = sanitizedProps.fullHeightHover, navButtonsProps = sanitizedProps.navButtonsProps, navButtonsWrapperProps = sanitizedProps.navButtonsWrapperProps, NavButton = sanitizedProps.NavButton, NextIcon = sanitizedProps.NextIcon, PrevIcon = sanitizedProps.PrevIcon, indicators = sanitizedProps.indicators, indicatorContainerProps = sanitizedProps.indicatorContainerProps, indicatorIconButtonProps = sanitizedProps.indicatorIconButtonProps, activeIndicatorIconButtonProps = sanitizedProps.activeIndicatorIconButtonProps, IndicatorIcon = sanitizedProps.IndicatorIcon, ariaLabel = sanitizedProps.ariaLabel, keyboardNavigation = sanitizedProps.keyboardNavigation;
|
|
82
|
+
var childrenLength = Array.isArray(children) ? children.length : 1;
|
|
83
|
+
// Keyboard navigation
|
|
84
|
+
useEffect(function () {
|
|
85
|
+
if (!keyboardNavigation)
|
|
86
|
+
return;
|
|
87
|
+
var handleKeyDown = function (e) {
|
|
88
|
+
switch (e.key) {
|
|
89
|
+
case 'ArrowLeft':
|
|
90
|
+
e.preventDefault();
|
|
91
|
+
prev(undefined);
|
|
92
|
+
setPaused(true);
|
|
93
|
+
break;
|
|
94
|
+
case 'ArrowRight':
|
|
95
|
+
e.preventDefault();
|
|
96
|
+
next(undefined);
|
|
97
|
+
setPaused(true);
|
|
98
|
+
break;
|
|
99
|
+
case 'Home':
|
|
100
|
+
e.preventDefault();
|
|
101
|
+
setNext(0, false);
|
|
102
|
+
setPaused(true);
|
|
103
|
+
break;
|
|
104
|
+
case 'End':
|
|
105
|
+
e.preventDefault();
|
|
106
|
+
var last = childrenLength - 1;
|
|
107
|
+
setNext(last, true);
|
|
108
|
+
setPaused(true);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
113
|
+
return function () { return window.removeEventListener('keydown', handleKeyDown); };
|
|
114
|
+
}, [keyboardNavigation, next, prev, setNext, childrenLength]);
|
|
115
|
+
var showButton = useCallback(function (next) {
|
|
116
|
+
if (next === void 0) { next = true; }
|
|
117
|
+
if (cycleNavigation)
|
|
118
|
+
return true;
|
|
119
|
+
var last = Array.isArray(children) ? children.length - 1 : 0;
|
|
120
|
+
if (next && state.active === last)
|
|
121
|
+
return false;
|
|
122
|
+
if (!next && state.active === 0)
|
|
123
|
+
return false;
|
|
124
|
+
return true;
|
|
125
|
+
}, [cycleNavigation, children, state.active]);
|
|
126
|
+
// Memoize carousel items rendering
|
|
127
|
+
var carouselItems = useMemo(function () {
|
|
128
|
+
return Array.isArray(children) ?
|
|
129
|
+
children.map(function (child, index) {
|
|
130
|
+
return (React.createElement(CarouselItem, { key: "carousel-item".concat(index), state: state, index: index, maxIndex: children.length - 1, child: child, animation: animation, duration: duration, swipe: swipe, next: next, prev: prev, height: height, setHeight: setChildrenHeight }));
|
|
131
|
+
})
|
|
132
|
+
:
|
|
133
|
+
React.createElement(CarouselItem, { key: "carousel-item0", state: state, index: 0, maxIndex: 0, child: children, animation: animation, duration: duration, height: height, setHeight: setChildrenHeight });
|
|
134
|
+
}, [children, state, animation, duration, swipe, next, prev, height, setChildrenHeight]);
|
|
135
|
+
return (React.createElement(StyledRoot, { role: "region", "aria-roledescription": "carousel", "aria-label": ariaLabel, tabIndex: keyboardNavigation ? 0 : undefined, sx: sx, className: className, onMouseOver: function () { stopAutoPlayOnHover && setPaused(true); }, onMouseOut: function () { stopAutoPlayOnHover && setPaused(false); }, onFocus: function () { stopAutoPlayOnHover && setPaused(true); }, onBlur: function () { stopAutoPlayOnHover && setPaused(false); } },
|
|
136
|
+
React.createElement("div", { style: {
|
|
137
|
+
position: 'absolute',
|
|
138
|
+
width: '1px',
|
|
139
|
+
height: '1px',
|
|
140
|
+
padding: 0,
|
|
141
|
+
margin: '-1px',
|
|
142
|
+
overflow: 'hidden',
|
|
143
|
+
clip: 'rect(0, 0, 0, 0)',
|
|
144
|
+
whiteSpace: 'nowrap',
|
|
145
|
+
borderWidth: 0,
|
|
146
|
+
}, "aria-live": "polite", "aria-atomic": "true" },
|
|
147
|
+
"Item ",
|
|
148
|
+
state.active + 1,
|
|
149
|
+
" of ",
|
|
150
|
+
childrenLength),
|
|
151
|
+
React.createElement(StyledItemWrapper, { style: { height: height ? height : childrenHeight } }, carouselItems),
|
|
152
|
+
!navButtonsAlwaysInvisible && showButton(true) &&
|
|
153
|
+
React.createElement(StyledButtonWrapper, __assign({ "$next": true, "$prev": false, "$fullHeightHover": fullHeightHover }, navButtonsWrapperProps), NavButton !== undefined ?
|
|
154
|
+
NavButton(__assign({ onClick: next, next: true, prev: false }, navButtonsProps))
|
|
155
|
+
:
|
|
156
|
+
React.createElement(StyledIconButton, __assign({ "$alwaysVisible": navButtonsAlwaysVisible, "$fullHeightHover": fullHeightHover, onClick: next, "aria-label": "Next" }, navButtonsProps), NextIcon)),
|
|
157
|
+
!navButtonsAlwaysInvisible && showButton(false) &&
|
|
158
|
+
React.createElement(StyledButtonWrapper, __assign({ "$next": false, "$prev": true, "$fullHeightHover": fullHeightHover }, navButtonsWrapperProps), NavButton !== undefined ?
|
|
159
|
+
NavButton(__assign({ onClick: prev, next: false, prev: true }, navButtonsProps))
|
|
160
|
+
:
|
|
161
|
+
React.createElement(StyledIconButton, __assign({ "$alwaysVisible": navButtonsAlwaysVisible, "$fullHeightHover": fullHeightHover, onClick: prev, "aria-label": "Previous" }, navButtonsProps), PrevIcon)),
|
|
162
|
+
indicators ?
|
|
163
|
+
React.createElement(Indicators, { length: Array.isArray(children) ? children.length : 0, active: state.active, press: setNext, indicatorContainerProps: indicatorContainerProps, indicatorIconButtonProps: indicatorIconButtonProps, activeIndicatorIconButtonProps: activeIndicatorIconButtonProps, IndicatorIcon: IndicatorIcon }) : null));
|
|
164
|
+
};
|
|
165
|
+
export default Carousel;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
export interface CarouselItemProps {
|
|
3
|
+
animation: 'fade' | 'slide';
|
|
4
|
+
next?: (event: any) => void;
|
|
5
|
+
prev?: (event: any) => void;
|
|
6
|
+
state: {
|
|
7
|
+
active: number;
|
|
8
|
+
prevActive: number;
|
|
9
|
+
next: boolean;
|
|
10
|
+
};
|
|
11
|
+
swipe?: boolean;
|
|
12
|
+
index: number;
|
|
13
|
+
maxIndex: number;
|
|
14
|
+
duration: number;
|
|
15
|
+
child: ReactNode;
|
|
16
|
+
height?: number | string;
|
|
17
|
+
setHeight: (height: number) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare const CarouselItem: ({ animation, next, prev, swipe, state, index, maxIndex, duration, child, height, setHeight }: CarouselItemProps) => React.JSX.Element;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { AnimatePresence, motion } from 'framer-motion';
|
|
13
|
+
import React, { useEffect, useRef } from 'react';
|
|
14
|
+
import { StyledItem } from './Styled';
|
|
15
|
+
// Animation variants - extracted as constants to prevent recreation on every render
|
|
16
|
+
var SLIDE_VARIANTS = {
|
|
17
|
+
leftwardExit: {
|
|
18
|
+
x: '-100%',
|
|
19
|
+
opacity: 1,
|
|
20
|
+
zIndex: 0,
|
|
21
|
+
},
|
|
22
|
+
leftOut: {
|
|
23
|
+
x: '-100%',
|
|
24
|
+
opacity: 1,
|
|
25
|
+
display: 'none',
|
|
26
|
+
zIndex: 0,
|
|
27
|
+
},
|
|
28
|
+
rightwardExit: {
|
|
29
|
+
x: '100%',
|
|
30
|
+
opacity: 1,
|
|
31
|
+
zIndex: 0,
|
|
32
|
+
},
|
|
33
|
+
rightOut: {
|
|
34
|
+
x: '100%',
|
|
35
|
+
opacity: 1,
|
|
36
|
+
display: 'none',
|
|
37
|
+
zIndex: 0,
|
|
38
|
+
},
|
|
39
|
+
center: {
|
|
40
|
+
x: 0,
|
|
41
|
+
opacity: 1,
|
|
42
|
+
zIndex: 1,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
var FADE_VARIANTS = {
|
|
46
|
+
leftwardExit: {
|
|
47
|
+
x: 0,
|
|
48
|
+
opacity: 0,
|
|
49
|
+
zIndex: 0,
|
|
50
|
+
},
|
|
51
|
+
leftOut: {
|
|
52
|
+
x: 0,
|
|
53
|
+
opacity: 0,
|
|
54
|
+
display: 'none',
|
|
55
|
+
zIndex: 0,
|
|
56
|
+
},
|
|
57
|
+
rightwardExit: {
|
|
58
|
+
x: 0,
|
|
59
|
+
opacity: 0,
|
|
60
|
+
zIndex: 0,
|
|
61
|
+
},
|
|
62
|
+
rightOut: {
|
|
63
|
+
x: 0,
|
|
64
|
+
opacity: 0,
|
|
65
|
+
display: 'none',
|
|
66
|
+
zIndex: 0,
|
|
67
|
+
},
|
|
68
|
+
center: {
|
|
69
|
+
x: 0,
|
|
70
|
+
opacity: 1,
|
|
71
|
+
zIndex: 1,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
export var CarouselItem = function (_a) {
|
|
75
|
+
var animation = _a.animation, next = _a.next, prev = _a.prev, swipe = _a.swipe, state = _a.state, index = _a.index, maxIndex = _a.maxIndex, duration = _a.duration, child = _a.child, height = _a.height, setHeight = _a.setHeight;
|
|
76
|
+
var slide = animation === 'slide';
|
|
77
|
+
var dragProps = {
|
|
78
|
+
drag: 'x',
|
|
79
|
+
layout: true,
|
|
80
|
+
onDragEnd: function (event, info) {
|
|
81
|
+
if (!swipe)
|
|
82
|
+
return;
|
|
83
|
+
if (info.offset.x > 0)
|
|
84
|
+
prev && prev(event);
|
|
85
|
+
else if (info.offset.x < 0)
|
|
86
|
+
next && next(event);
|
|
87
|
+
event.stopPropagation();
|
|
88
|
+
},
|
|
89
|
+
dragElastic: 0,
|
|
90
|
+
dragConstraints: { left: 0, right: 0 }
|
|
91
|
+
};
|
|
92
|
+
var divRef = useRef(null);
|
|
93
|
+
// Use ResizeObserver for efficient height tracking
|
|
94
|
+
useEffect(function () {
|
|
95
|
+
if (index !== state.active || !divRef.current)
|
|
96
|
+
return;
|
|
97
|
+
var resizeObserver = new ResizeObserver(function (entries) {
|
|
98
|
+
for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
|
|
99
|
+
var entry = entries_1[_i];
|
|
100
|
+
var height_1 = entry.contentRect.height;
|
|
101
|
+
if (height_1 > 0) {
|
|
102
|
+
setHeight(height_1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
resizeObserver.observe(divRef.current);
|
|
107
|
+
return function () {
|
|
108
|
+
resizeObserver.disconnect();
|
|
109
|
+
};
|
|
110
|
+
}, [index, state.active, setHeight]);
|
|
111
|
+
// Select variant set based on animation type
|
|
112
|
+
var variants = slide ? SLIDE_VARIANTS : FADE_VARIANTS;
|
|
113
|
+
// Handle animation directions and opacity given based on active, prevActive and this item's index
|
|
114
|
+
var active = state.active, isNext = state.next, prevActive = state.prevActive;
|
|
115
|
+
var animate = 'center';
|
|
116
|
+
if (index === active)
|
|
117
|
+
animate = 'center';
|
|
118
|
+
else if (index === prevActive) {
|
|
119
|
+
animate = isNext ? 'leftwardExit' : 'rightwardExit';
|
|
120
|
+
if (active === maxIndex && index === 0)
|
|
121
|
+
animate = 'rightwardExit';
|
|
122
|
+
if (active === 0 && index === maxIndex)
|
|
123
|
+
animate = 'leftwardExit';
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
animate = index < active ? 'leftOut' : 'rightOut';
|
|
127
|
+
if (active === maxIndex && index === 0)
|
|
128
|
+
animate = 'rightOut';
|
|
129
|
+
if (active === 0 && index === maxIndex)
|
|
130
|
+
animate = 'leftOut';
|
|
131
|
+
}
|
|
132
|
+
duration = duration / 1000;
|
|
133
|
+
return (React.createElement(StyledItem, null,
|
|
134
|
+
React.createElement(AnimatePresence, { custom: isNext },
|
|
135
|
+
React.createElement(motion.div, __assign({}, (swipe && dragProps), { style: { height: '100%' } }),
|
|
136
|
+
React.createElement(motion.div, { custom: isNext, variants: variants, animate: animate, transition: {
|
|
137
|
+
x: { type: "tween", duration: duration, delay: 0 },
|
|
138
|
+
opacity: { duration: duration },
|
|
139
|
+
}, style: { position: 'relative', height: '100%' } },
|
|
140
|
+
React.createElement("div", { ref: divRef, style: { height: height } }, child))))));
|
|
141
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import { SanitizedCarouselNavProps } from "./util";
|
|
3
|
+
export interface IndicatorProps {
|
|
4
|
+
IndicatorIcon?: ReactNode;
|
|
5
|
+
length: number;
|
|
6
|
+
active: number;
|
|
7
|
+
press: (index: number, isNext?: boolean, runCallbacks?: boolean) => void;
|
|
8
|
+
indicatorContainerProps: SanitizedCarouselNavProps;
|
|
9
|
+
indicatorIconButtonProps: SanitizedCarouselNavProps;
|
|
10
|
+
activeIndicatorIconButtonProps: SanitizedCarouselNavProps;
|
|
11
|
+
}
|
|
12
|
+
export declare const Indicators: (props: IndicatorProps) => React.JSX.Element;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
13
|
+
var t = {};
|
|
14
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
15
|
+
t[p] = s[p];
|
|
16
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
17
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
18
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
19
|
+
t[p[i]] = s[p[i]];
|
|
20
|
+
}
|
|
21
|
+
return t;
|
|
22
|
+
};
|
|
23
|
+
import React, { useCallback, useMemo } from "react";
|
|
24
|
+
import { StyledFiberManualRecordIcon, StyledIndicatorIconButton, StyledIndicators } from "./Styled";
|
|
25
|
+
export var Indicators = function (props) {
|
|
26
|
+
var IndicatorIcon = useMemo(function () { return props.IndicatorIcon !== undefined ? props.IndicatorIcon : React.createElement(StyledFiberManualRecordIcon, null); }, [props.IndicatorIcon]);
|
|
27
|
+
var completeListIfRequired = useCallback(function (arrayOfIcons) {
|
|
28
|
+
while (arrayOfIcons.length < props.length) {
|
|
29
|
+
var index = 0;
|
|
30
|
+
arrayOfIcons.push(arrayOfIcons[index]);
|
|
31
|
+
index += 1;
|
|
32
|
+
}
|
|
33
|
+
}, [props.length]);
|
|
34
|
+
var _a = props.indicatorIconButtonProps, indicatorIconButtonClass = _a.className, indicatorIconButtonStyle = _a.style, indicatorIconButtonProps = __rest(_a, ["className", "style"]);
|
|
35
|
+
var _b = props.activeIndicatorIconButtonProps, activeIndicatorIconButtonClass = _b.className, activeIndicatorIconButtonStyle = _b.style, activeIndicatorIconButtonProps = __rest(_b, ["className", "style"]);
|
|
36
|
+
var indicators = [];
|
|
37
|
+
var _loop_1 = function (i) {
|
|
38
|
+
var className = i === props.active ?
|
|
39
|
+
"".concat(indicatorIconButtonClass, " ").concat(activeIndicatorIconButtonClass) :
|
|
40
|
+
"".concat(indicatorIconButtonClass);
|
|
41
|
+
var style = i === props.active ?
|
|
42
|
+
Object.assign({}, indicatorIconButtonStyle, activeIndicatorIconButtonStyle) :
|
|
43
|
+
indicatorIconButtonStyle;
|
|
44
|
+
var restProps = i === props.active ?
|
|
45
|
+
Object.assign({}, indicatorIconButtonProps, activeIndicatorIconButtonProps) :
|
|
46
|
+
indicatorIconButtonProps;
|
|
47
|
+
if (restProps['aria-label'] === undefined)
|
|
48
|
+
restProps['aria-label'] = 'carousel indicator';
|
|
49
|
+
var createIndicator = function (IndicatorIcon) {
|
|
50
|
+
return (React.createElement(StyledIndicatorIconButton, __assign({ "$active": i === props.active, key: i, className: className, style: style, onClick: function () { props.press(i); } }, restProps, { "aria-label": "".concat(restProps['aria-label'], " ").concat(i + 1) }), IndicatorIcon));
|
|
51
|
+
};
|
|
52
|
+
Array.isArray(IndicatorIcon)
|
|
53
|
+
? indicators.push(createIndicator(IndicatorIcon[i])) && completeListIfRequired(IndicatorIcon)
|
|
54
|
+
: indicators.push(createIndicator(IndicatorIcon));
|
|
55
|
+
};
|
|
56
|
+
for (var i = 0; i < props.length; i++) {
|
|
57
|
+
_loop_1(i);
|
|
58
|
+
}
|
|
59
|
+
var _c = props.indicatorContainerProps, indicatorContainerClass = _c.className, indicatorContainerStyle = _c.style, indicatorContainerProps = __rest(_c, ["className", "style"]);
|
|
60
|
+
return (React.createElement(StyledIndicators, __assign({ className: indicatorContainerClass, style: indicatorContainerStyle }, indicatorContainerProps), indicators));
|
|
61
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const StyledRoot: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
2
|
+
export declare const StyledItem: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
3
|
+
export declare const StyledItemWrapper: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
4
|
+
export declare const StyledIndicators: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
5
|
+
export declare const StyledFiberManualRecordIcon: import("@emotion/styled").StyledComponent<import("@mui/material").SvgIconOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<import("react").SVGProps<SVGSVGElement>, "style" | "color" | "fontSize" | "shapeRendering" | "className" | "classes" | "children" | "htmlColor" | "inheritViewBox" | "sx" | "titleAccess" | "viewBox"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
|
|
6
|
+
export declare const StyledIndicatorIconButton: import("@emotion/styled").StyledComponent<import("@mui/material").IconButtonOwnProps & Omit<import("@mui/material").ButtonBaseOwnProps, "classes"> & import("@mui/material/OverridableComponent").CommonProps & Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "style" | "color" | "className" | "classes" | "children" | "sx" | "tabIndex" | "action" | "centerRipple" | "disabled" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "loading" | "loadingIndicator" | "size"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & {
|
|
7
|
+
$active: boolean;
|
|
8
|
+
}, {}, {}>;
|
|
9
|
+
export declare const StyledIconButton: import("@emotion/styled").StyledComponent<import("@mui/material").IconButtonOwnProps & Omit<import("@mui/material").ButtonBaseOwnProps, "classes"> & import("@mui/material/OverridableComponent").CommonProps & Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "style" | "color" | "className" | "classes" | "children" | "sx" | "tabIndex" | "action" | "centerRipple" | "disabled" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "loading" | "loadingIndicator" | "size"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & {
|
|
10
|
+
$alwaysVisible: boolean;
|
|
11
|
+
$fullHeightHover: boolean;
|
|
12
|
+
}, {}, {}>;
|
|
13
|
+
export declare const StyledButtonWrapper: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & {
|
|
14
|
+
$next: boolean;
|
|
15
|
+
$prev: boolean;
|
|
16
|
+
$fullHeightHover: boolean;
|
|
17
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import FiberManualRecord from '@mui/icons-material/FiberManualRecord';
|
|
13
|
+
import { IconButton, styled } from '@mui/material';
|
|
14
|
+
export var StyledRoot = styled("div")({
|
|
15
|
+
position: "relative",
|
|
16
|
+
overflow: "hidden",
|
|
17
|
+
});
|
|
18
|
+
export var StyledItem = styled("div")({
|
|
19
|
+
position: "absolute",
|
|
20
|
+
height: "100%",
|
|
21
|
+
width: '100%',
|
|
22
|
+
// flexGrow: 1
|
|
23
|
+
});
|
|
24
|
+
export var StyledItemWrapper = styled("div")({
|
|
25
|
+
position: 'relative',
|
|
26
|
+
width: '100%',
|
|
27
|
+
height: '100%',
|
|
28
|
+
});
|
|
29
|
+
export var StyledIndicators = styled("div")({
|
|
30
|
+
width: "100%",
|
|
31
|
+
marginTop: "10px",
|
|
32
|
+
textAlign: "center"
|
|
33
|
+
});
|
|
34
|
+
export var StyledFiberManualRecordIcon = styled(FiberManualRecord)({
|
|
35
|
+
fontSize: "15px",
|
|
36
|
+
});
|
|
37
|
+
export var StyledIndicatorIconButton = styled(IconButton, { shouldForwardProp: function (propName) { return !propName.startsWith('$'); } })(function (_a) {
|
|
38
|
+
var $active = _a.$active;
|
|
39
|
+
return ({
|
|
40
|
+
cursor: "pointer",
|
|
41
|
+
transition: "200ms",
|
|
42
|
+
padding: 0,
|
|
43
|
+
color: $active ? "#494949" : "#afafaf",
|
|
44
|
+
'&:hover': {
|
|
45
|
+
color: $active ? "#494949" : "#1f1f1f",
|
|
46
|
+
},
|
|
47
|
+
'&:active': {
|
|
48
|
+
color: $active ? "#494949" : "#1f1f1f",
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
export var StyledIconButton = styled(IconButton, { shouldForwardProp: function (propName) { return !propName.startsWith('$'); } })(function (_a) {
|
|
53
|
+
var $alwaysVisible = _a.$alwaysVisible;
|
|
54
|
+
return ({
|
|
55
|
+
margin: "0 10px",
|
|
56
|
+
position: "relative",
|
|
57
|
+
backgroundColor: "#494949",
|
|
58
|
+
top: "calc(50% - 20px) !important",
|
|
59
|
+
color: "white",
|
|
60
|
+
fontSize: "30px",
|
|
61
|
+
transition: "200ms",
|
|
62
|
+
cursor: "pointer",
|
|
63
|
+
opacity: $alwaysVisible ? '1' : '0',
|
|
64
|
+
'&:hover': {
|
|
65
|
+
opacity: "0.6 !important",
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
export var StyledButtonWrapper = styled("div", { shouldForwardProp: function (propName) { return !propName.startsWith('$'); } })(function (_a) {
|
|
70
|
+
var $next = _a.$next, $prev = _a.$prev, $fullHeightHover = _a.$fullHeightHover;
|
|
71
|
+
return (__assign(__assign(__assign({ position: "absolute", height: "100px", backgroundColor: "transparent", zIndex: 1, top: "calc(50% - 70px)", '&:hover': {
|
|
72
|
+
'& button': {
|
|
73
|
+
backgroundColor: "black",
|
|
74
|
+
filter: "brightness(120%)",
|
|
75
|
+
opacity: "0.4"
|
|
76
|
+
}
|
|
77
|
+
} }, ($fullHeightHover ? {
|
|
78
|
+
height: "100%", // This is 100% - indicator height - indicator margin
|
|
79
|
+
top: "0"
|
|
80
|
+
} : undefined)), ($next ? { right: 0 } : undefined)), ($prev ? { left: 0 } : undefined)));
|
|
81
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React, { AriaAttributes, ReactNode } from 'react';
|
|
2
|
+
import { SxProps } from '@mui/system';
|
|
3
|
+
import { Theme } from '@mui/material/styles';
|
|
4
|
+
export interface CarouselNavProps extends AriaAttributes {
|
|
5
|
+
className?: string;
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
}
|
|
8
|
+
export interface CarouselProps {
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
/** Defines `sx` props, that will be inserted into Carousel element */
|
|
11
|
+
sx?: SxProps<Theme>;
|
|
12
|
+
/** Defines custom class name(s), that will be added to Carousel element */
|
|
13
|
+
className?: string;
|
|
14
|
+
/** Defines the carousel's height in `px`. If this is not set, the carousel's height will be the height of its children. */
|
|
15
|
+
height?: number | string;
|
|
16
|
+
/** Defines which child (assuming there are more than 1 children) will be displayed. Next and Previous Buttons as well as Indicators will work normally after the first render. When this prop is updated the carousel will display the chosen child. Use this prop to programmatically set the active child. If (index > children.length) then if (strictIndexing) index = last element. index */
|
|
17
|
+
index?: number;
|
|
18
|
+
/** Defines whether index can be bigger than children length */
|
|
19
|
+
strictIndexing?: boolean;
|
|
20
|
+
/** Defines if the component will auto scroll between children */
|
|
21
|
+
autoPlay?: boolean;
|
|
22
|
+
/** Defines if auto scrolling will continue while mousing over carousel */
|
|
23
|
+
stopAutoPlayOnHover?: boolean;
|
|
24
|
+
/** Defines the interval in ms between active child changes (autoPlay) */
|
|
25
|
+
interval?: number;
|
|
26
|
+
/** Defines the animation style of the Carousel */
|
|
27
|
+
animation?: 'fade' | 'slide';
|
|
28
|
+
/** Defines the duration of the animations. For more information refer to the [Material UI Documentation for Transitions](https://material-ui.com/components/transitions/) */
|
|
29
|
+
duration?: number;
|
|
30
|
+
/** Defines if swiping left and right (in touch devices) triggers `next` and `prev` behaviour */
|
|
31
|
+
swipe?: boolean;
|
|
32
|
+
/** Defines the existence of bullet indicators */
|
|
33
|
+
indicators?: boolean;
|
|
34
|
+
/** Defines if the next/previous buttons will always be visible or not */
|
|
35
|
+
navButtonsAlwaysVisible?: boolean;
|
|
36
|
+
/** Defines if the next/previous buttons will always be invisible or not */
|
|
37
|
+
navButtonsAlwaysInvisible?: boolean;
|
|
38
|
+
/** Defines if the next button will be visible on the last slide, and the previous button on the first slide. Auto-play also stops on the last slide. Indicators continue to work normally. */
|
|
39
|
+
cycleNavigation?: boolean;
|
|
40
|
+
/** Defines if the the next/previous button wrappers will cover the full height of the Item element and show buttons on full height hover */
|
|
41
|
+
fullHeightHover?: boolean;
|
|
42
|
+
/** Used to customize the div surrounding the nav `IconButtons`. Use this to position the buttons onto, below, outside, e.t.c. the carousel. */
|
|
43
|
+
navButtonsWrapperProps?: CarouselNavProps;
|
|
44
|
+
/** Used to customize the actual nav `IconButton`s */
|
|
45
|
+
navButtonsProps?: CarouselNavProps;
|
|
46
|
+
/** Defines the element inside the nav "next" `IconButton`. Refer to [MaterialUI Button Documentation](https://material-ui.com/components/buttons/) for more examples.
|
|
47
|
+
* It is advised to use Material UI Icons, but you could use any element (`<img/>`, `<div/>`, ...) you like. */
|
|
48
|
+
NextIcon?: ReactNode;
|
|
49
|
+
/** Defines the element inside the nav "prev" `IconButton`. Refer to [MaterialUI Button Documentation](https://material-ui.com/components/buttons/) for more examples.
|
|
50
|
+
* It is advised to use Material UI Icons, but you could use any element (`<img/>`, `<div/>`, ...) you like. */
|
|
51
|
+
PrevIcon?: ReactNode;
|
|
52
|
+
/** Gives full control of the nav buttons. Should return a button that uses the given `onClick`.
|
|
53
|
+
* Works in tandem with all other customization options (`navButtonsProps`, `navButtonsWrapperProps`, `navButtonsAlwaysVisible`, `navButtonsAlwaysInvisible`, `fullHeightHover` ...).
|
|
54
|
+
* Refer to the [example section](README.md) for more information */
|
|
55
|
+
NavButton?: ({ onClick, next, className, style, prev }: {
|
|
56
|
+
onClick: (event: React.MouseEvent) => void;
|
|
57
|
+
className: string;
|
|
58
|
+
style: React.CSSProperties;
|
|
59
|
+
next: boolean;
|
|
60
|
+
prev: boolean;
|
|
61
|
+
}) => ReactNode;
|
|
62
|
+
/** Used to customize the indicators container/wrapper.
|
|
63
|
+
* Type: `{className: string, style: React.CSSProperties}` */
|
|
64
|
+
indicatorContainerProps?: CarouselNavProps;
|
|
65
|
+
/** Used to customize the **non-active** indicator `IconButton`s.
|
|
66
|
+
* Type: `{className: string, style: React.CSSProperties}` */
|
|
67
|
+
indicatorIconButtonProps?: CarouselNavProps;
|
|
68
|
+
/** Used to customize the **active** indicator `IconButton`.
|
|
69
|
+
* Type: `{className: string, style: React.CSSProperties}` */
|
|
70
|
+
activeIndicatorIconButtonProps?: CarouselNavProps;
|
|
71
|
+
/** Function that is called **after** internal `setActive()` method. The `setActive()` method is called when the next and previous buttons are pressed, when an indicator is pressed, or when the `index` prop changes. First argument is the child **we are going to display**, while the second argument is the child **that was previously displayed**. */
|
|
72
|
+
onChange?: (now?: number, previous?: number) => void;
|
|
73
|
+
/** Defines if `onChange` prop will be called when the carousel renders for the first time. In `componentDidMount` */
|
|
74
|
+
changeOnFirstRender?: boolean;
|
|
75
|
+
/** Function that is called **after** internal `next()` method. First argument is the child **we are going to display**, while the second argument is the child **that was previously displayed** */
|
|
76
|
+
next?: (now?: number, previous?: number) => void;
|
|
77
|
+
/** Function that is called **after** internal `prev()` method. First argument is the child **we are going to display**, while the second argument is the child **that was previously displayed** */
|
|
78
|
+
prev?: (now?: number, previous?: number) => void;
|
|
79
|
+
/** Defines the element inside the indicator `IconButton`s Refer to [MaterialUI Button Documentation](https://material-ui.com/components/buttons/) for more examples.
|
|
80
|
+
* It is advised to use Material UI Icons, but you could use any element (`<img/>`, `<div/>`, ...) you like.*/
|
|
81
|
+
IndicatorIcon?: ReactNode;
|
|
82
|
+
/** Accessible label for the carousel region */
|
|
83
|
+
ariaLabel?: string;
|
|
84
|
+
/** Enable keyboard navigation (Arrow keys, Home, End). Default: true */
|
|
85
|
+
keyboardNavigation?: boolean;
|
|
86
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CarouselNavProps, CarouselProps } from './types';
|
|
2
|
+
import React, { ReactNode } from 'react';
|
|
3
|
+
import { SxProps } from '@mui/system';
|
|
4
|
+
import { Theme } from '@mui/material';
|
|
5
|
+
export interface SanitizedCarouselProps extends CarouselProps {
|
|
6
|
+
sx: SxProps<Theme>;
|
|
7
|
+
className: string;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
height: number | string | undefined;
|
|
10
|
+
index: number;
|
|
11
|
+
strictIndexing: boolean;
|
|
12
|
+
autoPlay: boolean;
|
|
13
|
+
stopAutoPlayOnHover: boolean;
|
|
14
|
+
interval: number;
|
|
15
|
+
animation: "fade" | "slide";
|
|
16
|
+
duration: number;
|
|
17
|
+
swipe: boolean;
|
|
18
|
+
navButtonsAlwaysInvisible: boolean;
|
|
19
|
+
navButtonsAlwaysVisible: boolean;
|
|
20
|
+
cycleNavigation: boolean;
|
|
21
|
+
fullHeightHover: boolean;
|
|
22
|
+
navButtonsWrapperProps: SanitizedCarouselNavProps;
|
|
23
|
+
navButtonsProps: SanitizedCarouselNavProps;
|
|
24
|
+
NavButton: (({ onClick, next, className, style, prev }: {
|
|
25
|
+
onClick: (event: React.MouseEvent) => void;
|
|
26
|
+
className: string;
|
|
27
|
+
style: React.CSSProperties;
|
|
28
|
+
next: boolean;
|
|
29
|
+
prev: boolean;
|
|
30
|
+
}) => ReactNode) | undefined;
|
|
31
|
+
NextIcon: ReactNode;
|
|
32
|
+
PrevIcon: ReactNode;
|
|
33
|
+
indicators: boolean;
|
|
34
|
+
indicatorContainerProps: SanitizedCarouselNavProps;
|
|
35
|
+
indicatorIconButtonProps: SanitizedCarouselNavProps;
|
|
36
|
+
activeIndicatorIconButtonProps: SanitizedCarouselNavProps;
|
|
37
|
+
IndicatorIcon: ReactNode;
|
|
38
|
+
onChange: (now?: number, previous?: number) => void;
|
|
39
|
+
changeOnFirstRender: boolean;
|
|
40
|
+
next: (now?: number, previous?: number) => void;
|
|
41
|
+
prev: (now?: number, previous?: number) => void;
|
|
42
|
+
ariaLabel: string;
|
|
43
|
+
keyboardNavigation: boolean;
|
|
44
|
+
}
|
|
45
|
+
export interface SanitizedCarouselNavProps extends CarouselNavProps {
|
|
46
|
+
style: React.CSSProperties;
|
|
47
|
+
className: string;
|
|
48
|
+
}
|
|
49
|
+
export declare const sanitizeNavProps: (props: CarouselNavProps | undefined) => SanitizedCarouselNavProps;
|
|
50
|
+
export declare const sanitizeProps: (props: CarouselProps) => SanitizedCarouselProps;
|
|
51
|
+
export declare const useInterval: (callback: Function, delay: number) => void;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
13
|
+
var t = {};
|
|
14
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
15
|
+
t[p] = s[p];
|
|
16
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
17
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
18
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
19
|
+
t[p[i]] = s[p[i]];
|
|
20
|
+
}
|
|
21
|
+
return t;
|
|
22
|
+
};
|
|
23
|
+
import NavigateBefore from '@mui/icons-material/NavigateBefore';
|
|
24
|
+
import NavigateNext from '@mui/icons-material/NavigateNext';
|
|
25
|
+
import React, { useEffect, useRef } from 'react';
|
|
26
|
+
;
|
|
27
|
+
export var sanitizeNavProps = function (props) {
|
|
28
|
+
var _a = props || {}, className = _a.className, style = _a.style, rest = __rest(_a, ["className", "style"]);
|
|
29
|
+
return props !== undefined ? __assign({ style: props.style !== undefined ? props.style : {}, className: props.className !== undefined ? props.className : "" }, rest) : __assign({ style: {}, className: "" }, rest);
|
|
30
|
+
};
|
|
31
|
+
export var sanitizeProps = function (props) {
|
|
32
|
+
var animation = props.animation !== undefined ? props.animation : "fade";
|
|
33
|
+
var duration = props.duration !== undefined ? props.duration : (animation === "fade" ? 500 : 200);
|
|
34
|
+
return {
|
|
35
|
+
sx: props.sx !== undefined ? props.sx : {},
|
|
36
|
+
className: props.className !== undefined ? props.className : "",
|
|
37
|
+
children: props.children ? props.children : [],
|
|
38
|
+
height: props.height,
|
|
39
|
+
index: props.index !== undefined ? props.index : 0,
|
|
40
|
+
strictIndexing: props.strictIndexing !== undefined ? props.strictIndexing : true,
|
|
41
|
+
autoPlay: props.autoPlay !== undefined ? props.autoPlay : true,
|
|
42
|
+
stopAutoPlayOnHover: props.stopAutoPlayOnHover !== undefined ? props.stopAutoPlayOnHover : true,
|
|
43
|
+
interval: props.interval !== undefined ? props.interval : 4000,
|
|
44
|
+
animation: animation,
|
|
45
|
+
duration: duration,
|
|
46
|
+
swipe: props.swipe !== undefined ? props.swipe : true,
|
|
47
|
+
navButtonsAlwaysInvisible: props.navButtonsAlwaysInvisible !== undefined ? props.navButtonsAlwaysInvisible : false,
|
|
48
|
+
navButtonsAlwaysVisible: props.navButtonsAlwaysVisible !== undefined ? props.navButtonsAlwaysVisible : false,
|
|
49
|
+
cycleNavigation: props.cycleNavigation !== undefined ? props.cycleNavigation : true,
|
|
50
|
+
fullHeightHover: props.fullHeightHover !== undefined ? props.fullHeightHover : true,
|
|
51
|
+
navButtonsWrapperProps: sanitizeNavProps(props.navButtonsWrapperProps),
|
|
52
|
+
navButtonsProps: sanitizeNavProps(props.navButtonsProps),
|
|
53
|
+
NavButton: props.NavButton,
|
|
54
|
+
NextIcon: props.NextIcon !== undefined ? props.NextIcon : React.createElement(NavigateNext, null),
|
|
55
|
+
PrevIcon: props.PrevIcon !== undefined ? props.PrevIcon : React.createElement(NavigateBefore, null),
|
|
56
|
+
indicators: props.indicators !== undefined ? props.indicators : true,
|
|
57
|
+
indicatorContainerProps: sanitizeNavProps(props.indicatorContainerProps),
|
|
58
|
+
indicatorIconButtonProps: sanitizeNavProps(props.indicatorIconButtonProps),
|
|
59
|
+
activeIndicatorIconButtonProps: sanitizeNavProps(props.activeIndicatorIconButtonProps),
|
|
60
|
+
IndicatorIcon: props.IndicatorIcon,
|
|
61
|
+
onChange: props.onChange !== undefined ? props.onChange : function () { },
|
|
62
|
+
changeOnFirstRender: props.changeOnFirstRender !== undefined ? props.changeOnFirstRender : false,
|
|
63
|
+
next: props.next !== undefined ? props.next : function () { },
|
|
64
|
+
prev: props.prev !== undefined ? props.prev : function () { },
|
|
65
|
+
ariaLabel: props.ariaLabel !== undefined ? props.ariaLabel : "Carousel",
|
|
66
|
+
keyboardNavigation: props.keyboardNavigation !== undefined ? props.keyboardNavigation : true,
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export var useInterval = function (callback, delay) {
|
|
70
|
+
var savedCallback = useRef(function () { });
|
|
71
|
+
// Remember the latest callback.
|
|
72
|
+
useEffect(function () {
|
|
73
|
+
savedCallback.current = callback;
|
|
74
|
+
}, [callback]);
|
|
75
|
+
// Set up the interval.
|
|
76
|
+
useEffect(function () {
|
|
77
|
+
function tick() {
|
|
78
|
+
savedCallback.current();
|
|
79
|
+
}
|
|
80
|
+
if (delay !== null) {
|
|
81
|
+
var id_1 = setInterval(tick, delay);
|
|
82
|
+
return function () { return clearInterval(id_1); };
|
|
83
|
+
}
|
|
84
|
+
return function () { };
|
|
85
|
+
}, [delay]);
|
|
86
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@azmr/mui-carousel-react",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "A Generic, extendible Carousel UI component for React using Material UI v7 - responsive and dynamic for any screen or surface",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"material",
|
|
8
|
+
"material ui",
|
|
9
|
+
"mui",
|
|
10
|
+
"carousel",
|
|
11
|
+
"gallery",
|
|
12
|
+
"slider",
|
|
13
|
+
"responsive",
|
|
14
|
+
"mobile",
|
|
15
|
+
"desktop"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://coderchef26.dev/mui-carousel",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/coderchef26/mui-carousel/issues"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/coderchef26/mui-carousel.git"
|
|
24
|
+
},
|
|
25
|
+
"funding": [
|
|
26
|
+
{
|
|
27
|
+
"type": "individual",
|
|
28
|
+
"url": "https://buymeacoffee.com/alghaazi"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "paypal",
|
|
32
|
+
"url": "https://www.paypal.me/alghaazi"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"author": "Azmara Technologies (Coder Chef)",
|
|
37
|
+
"type": "commonjs",
|
|
38
|
+
"exports": {
|
|
39
|
+
".": {
|
|
40
|
+
"types": "./dist/esm/index.d.ts",
|
|
41
|
+
"import": "./dist/esm/index.js",
|
|
42
|
+
"require": "./dist/esm/index.js",
|
|
43
|
+
"default": "./dist/esm/index.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"main": "dist/esm/index.js",
|
|
47
|
+
"types": "dist/esm/index.d.ts",
|
|
48
|
+
"files": [
|
|
49
|
+
"/dist"
|
|
50
|
+
],
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "rimraf dist && tsc",
|
|
53
|
+
"prepublishOnly": "npm run build",
|
|
54
|
+
"test": "echo \"No tests yet\" && exit 0"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@emotion/react": "^11.14.0",
|
|
58
|
+
"@emotion/styled": "^11.14.1",
|
|
59
|
+
"@mui/icons-material": "^7.3.7",
|
|
60
|
+
"@mui/material": "^7.3.7",
|
|
61
|
+
"@mui/system": "^7.3.7",
|
|
62
|
+
"framer-motion": "^12.29.0"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@types/react": "^19.2.9",
|
|
66
|
+
"@types/react-dom": "^19.2.3",
|
|
67
|
+
"rimraf": "^6.1.2",
|
|
68
|
+
"typescript": "^5.9.3"
|
|
69
|
+
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"@emotion/react": "^11.14.0",
|
|
72
|
+
"@emotion/styled": "^11.14.0",
|
|
73
|
+
"@mui/icons-material": "^7.0.0",
|
|
74
|
+
"@mui/material": "^7.0.0",
|
|
75
|
+
"@mui/system": "^7.0.0",
|
|
76
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
77
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
78
|
+
},
|
|
79
|
+
"engines": {
|
|
80
|
+
"node": ">=18.0.0"
|
|
81
|
+
},
|
|
82
|
+
"module": "dist/esm/index.js"
|
|
83
|
+
}
|