@snack-uikit/carousel 0.5.6 → 0.6.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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 0.6.0 (2025-07-08)
7
+
8
+
9
+ ### Features
10
+
11
+ * **FF-6899:** add controlsVisibility prop ([780bf9f](https://github.com/cloud-ru-tech/snack-uikit/commit/780bf9fab6bc0c4a3487c52d68e4f13f063ecd76))
12
+
13
+
14
+
15
+
16
+
6
17
  ## 0.5.6 (2025-07-07)
7
18
 
8
19
  ### Only dependencies have been changed
package/README.md CHANGED
@@ -25,6 +25,7 @@
25
25
  | gap | `string` | var(--dimension-2m) | Расстояние между айтемами |
26
26
  | state | `{ page: number; onChange(page: number): void; }` | - | Управление состоянием извне |
27
27
  | infiniteScroll | `boolean` | - | Цикличная прокрутка |
28
+ | controlsVisibility | "hover" \| "always" | hover | Управление видимостью стрелок: 'hover' — по ховеру, 'always' — всегда |
28
29
 
29
30
 
30
31
  [//]: DOCUMENTATION_SECTION_END
@@ -30,5 +30,7 @@ export type CarouselProps = WithSupportProps<{
30
30
  };
31
31
  /** Цикличная прокрутка @default false*/
32
32
  infiniteScroll?: boolean;
33
+ /** Управление видимостью стрелок: 'hover' — по ховеру, 'always' — всегда @default 'hover' */
34
+ controlsVisibility?: 'hover' | 'always';
33
35
  }>;
34
- export declare function Carousel({ children: items, showItems, scrollBy: scrollByProp, transition, swipe, arrows, pagination, className, gap, state, infiniteScroll, swipeActivateLength, autoSwipe, ...rest }: CarouselProps): import("react/jsx-runtime").JSX.Element;
36
+ export declare function Carousel({ children: items, showItems, scrollBy: scrollByProp, transition, swipe, arrows, pagination, className, gap, state, infiniteScroll, swipeActivateLength, autoSwipe, controlsVisibility, ...rest }: CarouselProps): import("react/jsx-runtime").JSX.Element;
@@ -42,9 +42,10 @@ function Carousel(_a) {
42
42
  state,
43
43
  infiniteScroll = false,
44
44
  swipeActivateLength = 48,
45
- autoSwipe
45
+ autoSwipe,
46
+ controlsVisibility = 'hover'
46
47
  } = _a,
47
- rest = __rest(_a, ["children", "showItems", "scrollBy", "transition", "swipe", "arrows", "pagination", "className", "gap", "state", "infiniteScroll", "swipeActivateLength", "autoSwipe"]);
48
+ rest = __rest(_a, ["children", "showItems", "scrollBy", "transition", "swipe", "arrows", "pagination", "className", "gap", "state", "infiniteScroll", "swipeActivateLength", "autoSwipe", "controlsVisibility"]);
48
49
  const timerRef = (0, react_1.useRef)();
49
50
  const scrollBy = (0, react_1.useMemo)(() => scrollByProp !== null && scrollByProp !== void 0 ? scrollByProp : Math.trunc(showItems), [showItems, scrollByProp]);
50
51
  const [page, setPage] = (0, uncontrollable_1.useUncontrolledProp)(state === null || state === void 0 ? void 0 : state.page, (_b = state === null || state === void 0 ? void 0 : state.page) !== null && _b !== void 0 ? _b : 0, newPage => {
@@ -78,7 +79,8 @@ function Carousel(_a) {
78
79
  return () => clearTimeout(timerRef.current);
79
80
  }, [autoSwipe, infiniteScroll, onRightArrowClick]);
80
81
  return (0, jsx_runtime_1.jsxs)("div", Object.assign({
81
- className: (0, classnames_1.default)(styles_module_scss_1.default.carousel, className)
82
+ className: (0, classnames_1.default)(styles_module_scss_1.default.carousel, className),
83
+ "data-controls-visibility": controlsVisibility
82
84
  }, (0, utils_1.extractSupportProps)(rest), {
83
85
  children: [(0, jsx_runtime_1.jsxs)("div", {
84
86
  className: styles_module_scss_1.default.carouselBase,
@@ -96,11 +98,13 @@ function Carousel(_a) {
96
98
  children: [(infiniteScroll || page > 0) && (0, jsx_runtime_1.jsx)(Control_1.Control, {
97
99
  onClick: onLeftArrowClick,
98
100
  variant: 'prev',
99
- "data-test-id": testIds_1.TEST_IDS.arrowPrev
101
+ "data-test-id": testIds_1.TEST_IDS.arrowPrev,
102
+ className: styles_module_scss_1.default.control
100
103
  }), (infiniteScroll || page + 1 < total) && (0, jsx_runtime_1.jsx)(Control_1.Control, {
101
104
  onClick: onRightArrowClick,
102
105
  variant: 'next',
103
- "data-test-id": testIds_1.TEST_IDS.arrowNext
106
+ "data-test-id": testIds_1.TEST_IDS.arrowNext,
107
+ className: styles_module_scss_1.default.control
104
108
  })]
105
109
  })]
106
110
  }), pagination && (0, jsx_runtime_1.jsx)("div", {
@@ -6,12 +6,22 @@
6
6
  outline:none;
7
7
  }
8
8
 
9
+ .control{
10
+ pointer-events:none;
11
+ opacity:0;
12
+ transition:opacity 0.2s;
13
+ }
14
+
9
15
  .carousel{
10
16
  display:flex;
11
17
  flex-direction:column;
12
18
  align-items:center;
13
19
  box-sizing:border-box;
14
20
  }
21
+ .carousel[data-controls-visibility=always] .control, .carousel[data-controls-visibility=hover]:hover .control{
22
+ pointer-events:auto;
23
+ opacity:1;
24
+ }
15
25
 
16
26
  .pagination{
17
27
  padding-top:var(--space-carousel-sliders-wrap-padding-top, 8px);
@@ -3,4 +3,5 @@ export declare const Control: import("react").ForwardRefExoticComponent<{
3
3
  } & import("react").AriaAttributes & {
4
4
  onClick?(): void;
5
5
  variant: "prev" | "next";
6
+ className?: string;
6
7
  } & import("react").RefAttributes<HTMLButtonElement>>;
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", {
18
18
  });
19
19
  exports.Control = void 0;
20
20
  const jsx_runtime_1 = require("react/jsx-runtime");
21
+ const classnames_1 = __importDefault(require("classnames"));
21
22
  const react_1 = require("react");
22
23
  const icons_1 = require("@snack-uikit/icons");
23
24
  const utils_1 = require("@snack-uikit/utils");
@@ -25,12 +26,13 @@ const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
25
26
  exports.Control = (0, react_1.forwardRef)((_a, ref) => {
26
27
  var {
27
28
  onClick,
28
- variant
29
+ variant,
30
+ className
29
31
  } = _a,
30
- rest = __rest(_a, ["onClick", "variant"]);
32
+ rest = __rest(_a, ["onClick", "variant", "className"]);
31
33
  return (0, jsx_runtime_1.jsx)("button", Object.assign({
32
34
  ref: ref,
33
- className: styles_module_scss_1.default.control,
35
+ className: (0, classnames_1.default)(styles_module_scss_1.default.control, className),
34
36
  onClick: onClick,
35
37
  type: 'button',
36
38
  "data-variant": variant
@@ -30,5 +30,7 @@ export type CarouselProps = WithSupportProps<{
30
30
  };
31
31
  /** Цикличная прокрутка @default false*/
32
32
  infiniteScroll?: boolean;
33
+ /** Управление видимостью стрелок: 'hover' — по ховеру, 'always' — всегда @default 'hover' */
34
+ controlsVisibility?: 'hover' | 'always';
33
35
  }>;
34
- export declare function Carousel({ children: items, showItems, scrollBy: scrollByProp, transition, swipe, arrows, pagination, className, gap, state, infiniteScroll, swipeActivateLength, autoSwipe, ...rest }: CarouselProps): import("react/jsx-runtime").JSX.Element;
36
+ export declare function Carousel({ children: items, showItems, scrollBy: scrollByProp, transition, swipe, arrows, pagination, className, gap, state, infiniteScroll, swipeActivateLength, autoSwipe, controlsVisibility, ...rest }: CarouselProps): import("react/jsx-runtime").JSX.Element;
@@ -21,7 +21,7 @@ import { ItemProvider } from '../ItemProvider';
21
21
  import styles from './styles.module.css';
22
22
  export function Carousel(_a) {
23
23
  var _b;
24
- var { children: items, showItems = 1, scrollBy: scrollByProp, transition = 0.4, swipe = true, arrows = true, pagination = true, className, gap, state, infiniteScroll = false, swipeActivateLength = 48, autoSwipe } = _a, rest = __rest(_a, ["children", "showItems", "scrollBy", "transition", "swipe", "arrows", "pagination", "className", "gap", "state", "infiniteScroll", "swipeActivateLength", "autoSwipe"]);
24
+ var { children: items, showItems = 1, scrollBy: scrollByProp, transition = 0.4, swipe = true, arrows = true, pagination = true, className, gap, state, infiniteScroll = false, swipeActivateLength = 48, autoSwipe, controlsVisibility = 'hover' } = _a, rest = __rest(_a, ["children", "showItems", "scrollBy", "transition", "swipe", "arrows", "pagination", "className", "gap", "state", "infiniteScroll", "swipeActivateLength", "autoSwipe", "controlsVisibility"]);
25
25
  const timerRef = useRef();
26
26
  const scrollBy = useMemo(() => scrollByProp !== null && scrollByProp !== void 0 ? scrollByProp : Math.trunc(showItems), [showItems, scrollByProp]);
27
27
  const [page, setPage] = useUncontrolledProp(state === null || state === void 0 ? void 0 : state.page, (_b = state === null || state === void 0 ? void 0 : state.page) !== null && _b !== void 0 ? _b : 0, newPage => {
@@ -54,7 +54,7 @@ export function Carousel(_a) {
54
54
  timerRef.current = setTimeout(() => onRightArrowClick(), autoSwipe * 1000);
55
55
  return () => clearTimeout(timerRef.current);
56
56
  }, [autoSwipe, infiniteScroll, onRightArrowClick]);
57
- return (_jsxs("div", Object.assign({ className: cn(styles.carousel, className) }, extractSupportProps(rest), { children: [_jsxs("div", { className: styles.carouselBase, children: [_jsx(ItemProvider, { showItems: showItems, scrollBy: scrollBy, swipe: swipe, transition: transition, items: items, slideCallback: slideCallback, page: page, gap: gap, swipeActivateLength: swipeActivateLength }), arrows && (_jsxs(_Fragment, { children: [(infiniteScroll || page > 0) && (_jsx(Control, { onClick: onLeftArrowClick, variant: 'prev', "data-test-id": TEST_IDS.arrowPrev })), (infiniteScroll || page + 1 < total) && (_jsx(Control, { onClick: onRightArrowClick, variant: 'next', "data-test-id": TEST_IDS.arrowNext }))] }))] }), pagination && (_jsx("div", { className: styles.pagination, children: _jsx(PaginationSlider, { "data-test-id": TEST_IDS.pagination, page: page + 1, onChange: (page) => {
57
+ return (_jsxs("div", Object.assign({ className: cn(styles.carousel, className), "data-controls-visibility": controlsVisibility }, extractSupportProps(rest), { children: [_jsxs("div", { className: styles.carouselBase, children: [_jsx(ItemProvider, { showItems: showItems, scrollBy: scrollBy, swipe: swipe, transition: transition, items: items, slideCallback: slideCallback, page: page, gap: gap, swipeActivateLength: swipeActivateLength }), arrows && (_jsxs(_Fragment, { children: [(infiniteScroll || page > 0) && (_jsx(Control, { onClick: onLeftArrowClick, variant: 'prev', "data-test-id": TEST_IDS.arrowPrev, className: styles.control })), (infiniteScroll || page + 1 < total) && (_jsx(Control, { onClick: onRightArrowClick, variant: 'next', "data-test-id": TEST_IDS.arrowNext, className: styles.control }))] }))] }), pagination && (_jsx("div", { className: styles.pagination, children: _jsx(PaginationSlider, { "data-test-id": TEST_IDS.pagination, page: page + 1, onChange: (page) => {
58
58
  setPage(page - 1);
59
59
  }, total: total }) }))] })));
60
60
  }
@@ -6,12 +6,22 @@
6
6
  outline:none;
7
7
  }
8
8
 
9
+ .control{
10
+ pointer-events:none;
11
+ opacity:0;
12
+ transition:opacity 0.2s;
13
+ }
14
+
9
15
  .carousel{
10
16
  display:flex;
11
17
  flex-direction:column;
12
18
  align-items:center;
13
19
  box-sizing:border-box;
14
20
  }
21
+ .carousel[data-controls-visibility=always] .control, .carousel[data-controls-visibility=hover]:hover .control{
22
+ pointer-events:auto;
23
+ opacity:1;
24
+ }
15
25
 
16
26
  .pagination{
17
27
  padding-top:var(--space-carousel-sliders-wrap-padding-top, 8px);
@@ -3,4 +3,5 @@ export declare const Control: import("react").ForwardRefExoticComponent<{
3
3
  } & import("react").AriaAttributes & {
4
4
  onClick?(): void;
5
5
  variant: "prev" | "next";
6
+ className?: string;
6
7
  } & import("react").RefAttributes<HTMLButtonElement>>;
@@ -10,11 +10,12 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
+ import cn from 'classnames';
13
14
  import { forwardRef } from 'react';
14
15
  import { ChevronLeftSVG } from '@snack-uikit/icons';
15
16
  import { extractSupportProps } from '@snack-uikit/utils';
16
17
  import styles from './styles.module.css';
17
18
  export const Control = forwardRef((_a, ref) => {
18
- var { onClick, variant } = _a, rest = __rest(_a, ["onClick", "variant"]);
19
- return (_jsx("button", Object.assign({ ref: ref, className: styles.control, onClick: onClick, type: 'button', "data-variant": variant }, extractSupportProps(rest), { children: _jsx(ChevronLeftSVG, { size: 24, className: styles.icon }) })));
19
+ var { onClick, variant, className } = _a, rest = __rest(_a, ["onClick", "variant", "className"]);
20
+ return (_jsx("button", Object.assign({ ref: ref, className: cn(styles.control, className), onClick: onClick, type: 'button', "data-variant": variant }, extractSupportProps(rest), { children: _jsx(ChevronLeftSVG, { size: 24, className: styles.icon }) })));
20
21
  });
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.5.6",
7
+ "version": "0.6.0",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -44,5 +44,5 @@
44
44
  "merge-refs": "1.3.0",
45
45
  "uncontrollable": "8.0.4"
46
46
  },
47
- "gitHead": "9e08a5c61a90e739f44ba128242a95d866452dc0"
47
+ "gitHead": "fd6c80ece2583c94b7686214acf00c70b3a8f55a"
48
48
  }
@@ -40,6 +40,8 @@ export type CarouselProps = WithSupportProps<{
40
40
  };
41
41
  /** Цикличная прокрутка @default false*/
42
42
  infiniteScroll?: boolean;
43
+ /** Управление видимостью стрелок: 'hover' — по ховеру, 'always' — всегда @default 'hover' */
44
+ controlsVisibility?: 'hover' | 'always';
43
45
  }>;
44
46
 
45
47
  export function Carousel({
@@ -56,6 +58,7 @@ export function Carousel({
56
58
  infiniteScroll = false,
57
59
  swipeActivateLength = 48,
58
60
  autoSwipe,
61
+ controlsVisibility = 'hover',
59
62
  ...rest
60
63
  }: CarouselProps) {
61
64
  const timerRef = useRef<NodeJS.Timeout>();
@@ -105,7 +108,11 @@ export function Carousel({
105
108
  }, [autoSwipe, infiniteScroll, onRightArrowClick]);
106
109
 
107
110
  return (
108
- <div className={cn(styles.carousel, className)} {...extractSupportProps(rest)}>
111
+ <div
112
+ className={cn(styles.carousel, className)}
113
+ data-controls-visibility={controlsVisibility}
114
+ {...extractSupportProps(rest)}
115
+ >
109
116
  <div className={styles.carouselBase}>
110
117
  <ItemProvider
111
118
  showItems={showItems}
@@ -122,10 +129,20 @@ export function Carousel({
122
129
  {arrows && (
123
130
  <>
124
131
  {(infiniteScroll || page > 0) && (
125
- <Control onClick={onLeftArrowClick} variant='prev' data-test-id={TEST_IDS.arrowPrev} />
132
+ <Control
133
+ onClick={onLeftArrowClick}
134
+ variant='prev'
135
+ data-test-id={TEST_IDS.arrowPrev}
136
+ className={styles.control}
137
+ />
126
138
  )}
127
139
  {(infiniteScroll || page + 1 < total) && (
128
- <Control onClick={onRightArrowClick} variant='next' data-test-id={TEST_IDS.arrowNext} />
140
+ <Control
141
+ onClick={onRightArrowClick}
142
+ variant='next'
143
+ data-test-id={TEST_IDS.arrowNext}
144
+ className={styles.control}
145
+ />
129
146
  )}
130
147
  </>
131
148
  )}
@@ -11,11 +11,25 @@
11
11
  outline: none;
12
12
  }
13
13
 
14
+ .control {
15
+ pointer-events: none;
16
+ opacity: 0;
17
+ transition: opacity 0.2s;
18
+ }
19
+
14
20
  .carousel {
15
21
  display: flex;
16
22
  flex-direction: column;
17
23
  align-items: center;
18
24
  box-sizing: border-box;
25
+
26
+ &[data-controls-visibility=always],
27
+ &[data-controls-visibility=hover]:hover {
28
+ & .control {
29
+ pointer-events: auto;
30
+ opacity: 1;
31
+ }
32
+ }
19
33
  }
20
34
 
21
35
  .pagination {
@@ -1,3 +1,4 @@
1
+ import cn from 'classnames';
1
2
  import { forwardRef } from 'react';
2
3
 
3
4
  import { ChevronLeftSVG } from '@snack-uikit/icons';
@@ -8,13 +9,14 @@ import styles from './styles.module.scss';
8
9
  type ControlProps = WithSupportProps<{
9
10
  onClick?(): void;
10
11
  variant: 'prev' | 'next';
12
+ className?: string;
11
13
  }>;
12
14
 
13
15
  export const Control = forwardRef<HTMLButtonElement, ControlProps>(
14
- ({ onClick, variant, ...rest }: ControlProps, ref) => (
16
+ ({ onClick, variant, className, ...rest }: ControlProps, ref) => (
15
17
  <button
16
18
  ref={ref}
17
- className={styles.control}
19
+ className={cn(styles.control, className)}
18
20
  onClick={onClick}
19
21
  type='button'
20
22
  data-variant={variant}