@snack-uikit/carousel 0.6.13 → 0.6.14-preview-4e8bfebd.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.
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/slicedToArray"));
3
5
  var __rest = void 0 && (void 0).__rest || function (s, e) {
4
6
  var t = {};
5
7
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
@@ -29,29 +31,38 @@ const ItemProvider_1 = require("../ItemProvider");
29
31
  const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
30
32
  function Carousel(_a) {
31
33
  var _b;
32
- var {
33
- children: items,
34
- showItems = 1,
35
- scrollBy: scrollByProp,
36
- transition = 0.4,
37
- swipe = true,
38
- arrows = true,
39
- pagination = true,
40
- className,
41
- gap,
42
- state,
43
- infiniteScroll = false,
44
- swipeActivateLength = 48,
45
- autoSwipe,
46
- controlsVisibility = 'hover'
47
- } = _a,
34
+ var items = _a.children,
35
+ _a$showItems = _a.showItems,
36
+ showItems = _a$showItems === void 0 ? 1 : _a$showItems,
37
+ scrollByProp = _a.scrollBy,
38
+ _a$transition = _a.transition,
39
+ transition = _a$transition === void 0 ? 0.4 : _a$transition,
40
+ _a$swipe = _a.swipe,
41
+ swipe = _a$swipe === void 0 ? true : _a$swipe,
42
+ _a$arrows = _a.arrows,
43
+ arrows = _a$arrows === void 0 ? true : _a$arrows,
44
+ _a$pagination = _a.pagination,
45
+ pagination = _a$pagination === void 0 ? true : _a$pagination,
46
+ className = _a.className,
47
+ gap = _a.gap,
48
+ state = _a.state,
49
+ _a$infiniteScroll = _a.infiniteScroll,
50
+ infiniteScroll = _a$infiniteScroll === void 0 ? false : _a$infiniteScroll,
51
+ _a$swipeActivateLengt = _a.swipeActivateLength,
52
+ swipeActivateLength = _a$swipeActivateLengt === void 0 ? 48 : _a$swipeActivateLengt,
53
+ autoSwipe = _a.autoSwipe,
54
+ _a$controlsVisibility = _a.controlsVisibility,
55
+ controlsVisibility = _a$controlsVisibility === void 0 ? 'hover' : _a$controlsVisibility,
48
56
  rest = __rest(_a, ["children", "showItems", "scrollBy", "transition", "swipe", "arrows", "pagination", "className", "gap", "state", "infiniteScroll", "swipeActivateLength", "autoSwipe", "controlsVisibility"]);
49
57
  const timerRef = (0, react_1.useRef)();
50
58
  const scrollBy = (0, react_1.useMemo)(() => scrollByProp !== null && scrollByProp !== void 0 ? scrollByProp : Math.trunc(showItems), [showItems, scrollByProp]);
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 => {
52
- const result = typeof newPage === 'function' ? newPage(page) : newPage;
53
- state === null || state === void 0 ? void 0 : state.onChange(result);
54
- });
59
+ const _ref = (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 => {
60
+ const result = typeof newPage === 'function' ? newPage(page) : newPage;
61
+ state === null || state === void 0 ? void 0 : state.onChange(result);
62
+ }),
63
+ _ref2 = (0, _slicedToArray2.default)(_ref, 2),
64
+ page = _ref2[0],
65
+ setPage = _ref2[1];
55
66
  const total = (0, react_1.useMemo)(() => {
56
67
  if (items.length <= showItems) {
57
68
  return 1;
@@ -24,11 +24,9 @@ const icons_1 = require("@snack-uikit/icons");
24
24
  const utils_1 = require("@snack-uikit/utils");
25
25
  const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
26
26
  exports.Control = (0, react_1.forwardRef)((_a, ref) => {
27
- var {
28
- onClick,
29
- variant,
30
- className
31
- } = _a,
27
+ var onClick = _a.onClick,
28
+ variant = _a.variant,
29
+ className = _a.className,
32
30
  rest = __rest(_a, ["onClick", "variant", "className"]);
33
31
  return (0, jsx_runtime_1.jsx)("button", Object.assign({
34
32
  ref: ref,
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/slicedToArray"));
3
5
  var __rest = void 0 && (void 0).__rest || function (s, e) {
4
6
  var t = {};
5
7
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
@@ -18,58 +20,67 @@ Object.defineProperty(exports, "__esModule", {
18
20
  });
19
21
  exports.ItemProvider = ItemProvider;
20
22
  const jsx_runtime_1 = require("react/jsx-runtime");
21
- const lodash_debounce_1 = __importDefault(require("lodash.debounce"));
23
+ const lodash_1 = require("lodash");
22
24
  const merge_refs_1 = __importDefault(require("merge-refs"));
23
25
  const react_1 = require("react");
24
26
  const utils_1 = require("@snack-uikit/utils");
25
27
  const testIds_1 = require("../../testIds");
26
28
  const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
29
+ function parseCssLength(value) {
30
+ const parsed = Number.parseFloat(value);
31
+ return Number.isFinite(parsed) ? parsed : 0;
32
+ }
27
33
  function ItemProvider(_ref) {
28
- let {
29
- items,
30
- showItems,
31
- scrollBy,
32
- slideCallback,
33
- transition,
34
- swipe,
35
- swipeActivateLength,
36
- page,
37
- gap
38
- } = _ref;
34
+ let items = _ref.items,
35
+ showItems = _ref.showItems,
36
+ scrollBy = _ref.scrollBy,
37
+ slideCallback = _ref.slideCallback,
38
+ transition = _ref.transition,
39
+ swipe = _ref.swipe,
40
+ swipeActivateLength = _ref.swipeActivateLength,
41
+ page = _ref.page,
42
+ gap = _ref.gap;
39
43
  const containerRef = (0, react_1.useRef)(null);
40
- const [computedValues, setComputedValues] = (0, react_1.useState)({
41
- itemWidth: 0,
42
- gap: 0
43
- });
44
+ const itemsTrackerRef = (0, react_1.useRef)(null);
45
+ const _ref2 = (0, react_1.useState)({
46
+ itemWidth: 0,
47
+ gap: 0
48
+ }),
49
+ _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
50
+ computedValues = _ref3[0],
51
+ setComputedValues = _ref3[1];
44
52
  const recalculateItemsSize = (0, react_1.useCallback)(() => {
45
53
  const containerElement = containerRef.current;
46
- if (!containerElement) {
54
+ const trackerElement = itemsTrackerRef.current;
55
+ if (!containerElement || !trackerElement) {
47
56
  return;
48
57
  }
49
- const styles = getComputedStyle(containerElement);
50
- const gap = Number.parseFloat(styles.getPropertyValue('--gap'));
51
- const paddingLeft = Number.parseFloat(styles.getPropertyValue('padding-left'));
52
- const paddingRight = Number.parseFloat(styles.getPropertyValue('padding-right'));
53
- const itemWidth = (containerElement.getBoundingClientRect().width - (Math.trunc(showItems) - 1) * gap - paddingLeft - paddingRight) / showItems;
58
+ const containerStyles = getComputedStyle(containerElement);
59
+ const trackerStyles = getComputedStyle(trackerElement);
60
+ const gapValue = gap ? parseCssLength(gap) : parseCssLength(trackerStyles.columnGap || trackerStyles.gap);
61
+ const paddingLeft = parseCssLength(containerStyles.paddingLeft);
62
+ const paddingRight = parseCssLength(containerStyles.paddingRight);
63
+ const gapsCount = Math.max(Math.trunc(showItems) - 1, 0);
64
+ const contentWidth = containerElement.getBoundingClientRect().width - paddingLeft - paddingRight;
65
+ const itemWidth = (contentWidth - gapsCount * gapValue) / showItems;
54
66
  setComputedValues({
55
67
  itemWidth,
56
- gap
68
+ gap: gapValue
57
69
  });
58
- }, [showItems]);
59
- (0, react_1.useEffect)(() => {
70
+ }, [showItems, gap]);
71
+ (0, utils_1.useLayoutEffect)(() => {
60
72
  const node = containerRef.current;
61
73
  if (!node) {
62
74
  return;
63
75
  }
64
76
  recalculateItemsSize();
65
- const observer = new ResizeObserver((0, lodash_debounce_1.default)(recalculateItemsSize, 100));
77
+ const observer = new ResizeObserver((0, lodash_1.debounce)(recalculateItemsSize, 100));
66
78
  observer.observe(node);
67
79
  return () => observer.disconnect();
68
80
  }, [recalculateItemsSize]);
69
- const itemsTrackerRef = (0, react_1.useRef)(null);
70
81
  const hideNonVisibleItems = () => {
71
82
  var _a;
72
- (_a = itemsTrackerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`[data-test-id=${testIds_1.TEST_IDS.trackItem}]`).forEach(slide => {
83
+ (_a = itemsTrackerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll("[data-test-id=".concat(testIds_1.TEST_IDS.trackItem, "]")).forEach(slide => {
73
84
  slide.setAttribute('aria-hidden', '0');
74
85
  slide.querySelectorAll('a, button, select, input, textarea, [tabindex="0"]').forEach(focusableElement => {
75
86
  focusableElement.setAttribute('tabindex', '-5');
@@ -79,7 +90,7 @@ function ItemProvider(_ref) {
79
90
  };
80
91
  const showVisibleItems = (slide, page, show) => {
81
92
  var _a;
82
- (_a = itemsTrackerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`[data-test-id=${testIds_1.TEST_IDS.trackItem}]`).forEach((item, i) => {
93
+ (_a = itemsTrackerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll("[data-test-id=".concat(testIds_1.TEST_IDS.trackItem, "]")).forEach((item, i) => {
83
94
  if (i >= page * slide && i < page * slide + Math.trunc(show)) {
84
95
  item.removeAttribute('aria-hidden');
85
96
  item.querySelectorAll('a, button, select, input, textarea, [tabindex="-5"]').forEach(focusableElement => {
@@ -113,12 +124,15 @@ function ItemProvider(_ref) {
113
124
  return computedValues.itemWidth;
114
125
  }
115
126
  const fallbackWidth = Math.floor(100 / showItems);
116
- return `${fallbackWidth}%`;
127
+ return "".concat(fallbackWidth, "%");
117
128
  }, [computedValues.itemWidth, showItems]);
118
- const [drag, setDrag] = (0, react_1.useState)({
119
- drag: 0,
120
- pointers: true
121
- });
129
+ const _ref4 = (0, react_1.useState)({
130
+ drag: 0,
131
+ pointers: true
132
+ }),
133
+ _ref5 = (0, _slicedToArray2.default)(_ref4, 2),
134
+ drag = _ref5[0],
135
+ setDrag = _ref5[1];
122
136
  const handleSwiping = eventData => {
123
137
  setDrag({
124
138
  drag: eventData.deltaX,
@@ -146,9 +160,7 @@ function ItemProvider(_ref) {
146
160
  enabled: swipe,
147
161
  availableDirections: ['Left', 'Right']
148
162
  }),
149
- {
150
- ref
151
- } = _a,
163
+ ref = _a.ref,
152
164
  swipeProps = __rest(_a, ["ref"]);
153
165
  return (0, jsx_runtime_1.jsx)("div", {
154
166
  ref: containerRef,
@@ -163,8 +175,8 @@ function ItemProvider(_ref) {
163
175
  className: styles_module_scss_1.default.itemTracker,
164
176
  "data-test-id": testIds_1.TEST_IDS.trackLine,
165
177
  style: {
166
- transform: `translateX(${transform + drag.drag}px)`,
167
- transition: `transform ${transition}s ease 0s`
178
+ transform: "translateX(".concat(transform + drag.drag, "px)"),
179
+ transition: "transform ".concat(transition, "s ease 0s")
168
180
  },
169
181
  ref: (0, merge_refs_1.default)(ref, itemsTrackerRef),
170
182
  children: items.map((item, i) =>
@@ -1,12 +1,9 @@
1
1
  .itemProvider{
2
2
  --gap:var(--dimension-2m, 16px);
3
- padding-top:var(--space-carousel-content-layout-padding, 4px);
4
- padding-bottom:var(--space-carousel-content-layout-padding, 4px);
5
- padding-left:var(--space-carousel-content-layout-padding, 4px);
6
- padding-right:var(--space-carousel-content-layout-padding, 4px);
7
3
  overflow-x:hidden;
8
4
  width:100%;
9
- margin:calc(0px - var(--space-carousel-content-layout-padding, 4px));
5
+ margin-block:calc(0px - var(--space-carousel-content-layout-padding, 4px));
6
+ padding-block:var(--space-carousel-content-layout-padding, 4px);
10
7
  }
11
8
  .itemProvider[data-swipe]{
12
9
  cursor:grab;
@@ -22,6 +19,7 @@
22
19
  .itemContainer{
23
20
  flex-shrink:0;
24
21
  box-sizing:border-box;
22
+ padding:var(--border-width-card-container, 1px);
25
23
  }
26
24
 
27
25
  .itemTracker{
@@ -10,35 +10,40 @@ 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 debounce from 'lodash.debounce';
13
+ import { debounce } from 'lodash';
14
14
  import mergeRefs from 'merge-refs';
15
15
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
16
- import { useSwipeable } from '@snack-uikit/utils';
16
+ import { useLayoutEffect, useSwipeable } from '@snack-uikit/utils';
17
17
  import { TEST_IDS } from '../../testIds';
18
18
  import styles from './styles.module.css';
19
+ function parseCssLength(value) {
20
+ const parsed = Number.parseFloat(value);
21
+ return Number.isFinite(parsed) ? parsed : 0;
22
+ }
19
23
  export function ItemProvider({ items, showItems, scrollBy, slideCallback, transition, swipe, swipeActivateLength, page, gap, }) {
20
24
  const containerRef = useRef(null);
25
+ const itemsTrackerRef = useRef(null);
21
26
  const [computedValues, setComputedValues] = useState({
22
27
  itemWidth: 0,
23
28
  gap: 0,
24
29
  });
25
30
  const recalculateItemsSize = useCallback(() => {
26
31
  const containerElement = containerRef.current;
27
- if (!containerElement) {
32
+ const trackerElement = itemsTrackerRef.current;
33
+ if (!containerElement || !trackerElement) {
28
34
  return;
29
35
  }
30
- const styles = getComputedStyle(containerElement);
31
- const gap = Number.parseFloat(styles.getPropertyValue('--gap'));
32
- const paddingLeft = Number.parseFloat(styles.getPropertyValue('padding-left'));
33
- const paddingRight = Number.parseFloat(styles.getPropertyValue('padding-right'));
34
- const itemWidth = (containerElement.getBoundingClientRect().width -
35
- (Math.trunc(showItems) - 1) * gap -
36
- paddingLeft -
37
- paddingRight) /
38
- showItems;
39
- setComputedValues({ itemWidth, gap });
40
- }, [showItems]);
41
- useEffect(() => {
36
+ const containerStyles = getComputedStyle(containerElement);
37
+ const trackerStyles = getComputedStyle(trackerElement);
38
+ const gapValue = gap ? parseCssLength(gap) : parseCssLength(trackerStyles.columnGap || trackerStyles.gap);
39
+ const paddingLeft = parseCssLength(containerStyles.paddingLeft);
40
+ const paddingRight = parseCssLength(containerStyles.paddingRight);
41
+ const gapsCount = Math.max(Math.trunc(showItems) - 1, 0);
42
+ const contentWidth = containerElement.getBoundingClientRect().width - paddingLeft - paddingRight;
43
+ const itemWidth = (contentWidth - gapsCount * gapValue) / showItems;
44
+ setComputedValues({ itemWidth, gap: gapValue });
45
+ }, [showItems, gap]);
46
+ useLayoutEffect(() => {
42
47
  const node = containerRef.current;
43
48
  if (!node) {
44
49
  return;
@@ -48,7 +53,6 @@ export function ItemProvider({ items, showItems, scrollBy, slideCallback, transi
48
53
  observer.observe(node);
49
54
  return () => observer.disconnect();
50
55
  }, [recalculateItemsSize]);
51
- const itemsTrackerRef = useRef(null);
52
56
  const hideNonVisibleItems = () => {
53
57
  var _a;
54
58
  (_a = itemsTrackerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`[data-test-id=${TEST_IDS.trackItem}]`).forEach(slide => {
@@ -1,12 +1,9 @@
1
1
  .itemProvider{
2
2
  --gap:var(--dimension-2m, 16px);
3
- padding-top:var(--space-carousel-content-layout-padding, 4px);
4
- padding-bottom:var(--space-carousel-content-layout-padding, 4px);
5
- padding-left:var(--space-carousel-content-layout-padding, 4px);
6
- padding-right:var(--space-carousel-content-layout-padding, 4px);
7
3
  overflow-x:hidden;
8
4
  width:100%;
9
- margin:calc(0px - var(--space-carousel-content-layout-padding, 4px));
5
+ margin-block:calc(0px - var(--space-carousel-content-layout-padding, 4px));
6
+ padding-block:var(--space-carousel-content-layout-padding, 4px);
10
7
  }
11
8
  .itemProvider[data-swipe]{
12
9
  cursor:grab;
@@ -22,6 +19,7 @@
22
19
  .itemContainer{
23
20
  flex-shrink:0;
24
21
  box-sizing:border-box;
22
+ padding:var(--border-width-card-container, 1px);
25
23
  }
26
24
 
27
25
  .itemTracker{
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.6.13",
7
+ "version": "0.6.14-preview-4e8bfebd.0",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -36,13 +36,13 @@
36
36
  "license": "Apache-2.0",
37
37
  "scripts": {},
38
38
  "dependencies": {
39
- "@snack-uikit/icons": "0.27.7",
40
- "@snack-uikit/pagination": "0.10.26",
39
+ "@snack-uikit/icons": "0.27.8-preview-4e8bfebd.0",
40
+ "@snack-uikit/pagination": "0.10.27-preview-4e8bfebd.0",
41
41
  "@snack-uikit/utils": "4.0.2",
42
42
  "classnames": "2.5.1",
43
- "lodash.debounce": "4.0.8",
43
+ "lodash": "4.18.1",
44
44
  "merge-refs": "1.3.0",
45
45
  "uncontrollable": "8.0.4"
46
46
  },
47
- "gitHead": "dfbff14ac89d87d7a86abd70d307e92bf11906cb"
47
+ "gitHead": "d52534cac02c3b621615686607bfba56762150ac"
48
48
  }
@@ -1,8 +1,8 @@
1
- import debounce from 'lodash.debounce';
1
+ import { debounce } from 'lodash';
2
2
  import mergeRefs from 'merge-refs';
3
3
  import { MouseEventHandler, ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
 
5
- import { SwipeCallback, useSwipeable } from '@snack-uikit/utils';
5
+ import { SwipeCallback, useLayoutEffect, useSwipeable } from '@snack-uikit/utils';
6
6
 
7
7
  import { TEST_IDS } from '../../testIds';
8
8
  import styles from './styles.module.scss';
@@ -19,6 +19,12 @@ export type ItemProviderProps = {
19
19
  gap?: string;
20
20
  };
21
21
 
22
+ function parseCssLength(value: string): number {
23
+ const parsed = Number.parseFloat(value);
24
+
25
+ return Number.isFinite(parsed) ? parsed : 0;
26
+ }
27
+
22
28
  export function ItemProvider({
23
29
  items,
24
30
  showItems,
@@ -31,6 +37,7 @@ export function ItemProvider({
31
37
  gap,
32
38
  }: ItemProviderProps) {
33
39
  const containerRef = useRef<HTMLDivElement>(null);
40
+ const itemsTrackerRef = useRef<HTMLDivElement>(null);
34
41
 
35
42
  const [computedValues, setComputedValues] = useState({
36
43
  itemWidth: 0,
@@ -39,27 +46,27 @@ export function ItemProvider({
39
46
 
40
47
  const recalculateItemsSize = useCallback(() => {
41
48
  const containerElement = containerRef.current;
49
+ const trackerElement = itemsTrackerRef.current;
42
50
 
43
- if (!containerElement) {
51
+ if (!containerElement || !trackerElement) {
44
52
  return;
45
53
  }
46
54
 
47
- const styles = getComputedStyle(containerElement);
55
+ const containerStyles = getComputedStyle(containerElement);
56
+ const trackerStyles = getComputedStyle(trackerElement);
48
57
 
49
- const gap = Number.parseFloat(styles.getPropertyValue('--gap'));
50
- const paddingLeft = Number.parseFloat(styles.getPropertyValue('padding-left'));
51
- const paddingRight = Number.parseFloat(styles.getPropertyValue('padding-right'));
58
+ const gapValue = gap ? parseCssLength(gap) : parseCssLength(trackerStyles.columnGap || trackerStyles.gap);
59
+ const paddingLeft = parseCssLength(containerStyles.paddingLeft);
60
+ const paddingRight = parseCssLength(containerStyles.paddingRight);
52
61
 
53
- const itemWidth =
54
- (containerElement.getBoundingClientRect().width -
55
- (Math.trunc(showItems) - 1) * gap -
56
- paddingLeft -
57
- paddingRight) /
58
- showItems;
59
- setComputedValues({ itemWidth, gap });
60
- }, [showItems]);
62
+ const gapsCount = Math.max(Math.trunc(showItems) - 1, 0);
63
+ const contentWidth = containerElement.getBoundingClientRect().width - paddingLeft - paddingRight;
64
+ const itemWidth = (contentWidth - gapsCount * gapValue) / showItems;
61
65
 
62
- useEffect(() => {
66
+ setComputedValues({ itemWidth, gap: gapValue });
67
+ }, [showItems, gap]);
68
+
69
+ useLayoutEffect(() => {
63
70
  const node = containerRef.current;
64
71
 
65
72
  if (!node) {
@@ -73,8 +80,6 @@ export function ItemProvider({
73
80
  return () => observer.disconnect();
74
81
  }, [recalculateItemsSize]);
75
82
 
76
- const itemsTrackerRef = useRef<HTMLDivElement>(null);
77
-
78
83
  const hideNonVisibleItems = () => {
79
84
  itemsTrackerRef.current?.querySelectorAll(`[data-test-id=${TEST_IDS.trackItem}]`).forEach(slide => {
80
85
  slide.setAttribute('aria-hidden', '0');
@@ -3,11 +3,14 @@
3
3
  .itemProvider {
4
4
  --gap: #{styles-tokens-carousel.$dimension-2m};
5
5
 
6
- @include styles-tokens-carousel.composite-var(styles-tokens-carousel.$carousel-content-layout);
7
-
8
6
  overflow-x: hidden;
9
7
  width: 100%;
10
- margin: calc(0px - styles-tokens-carousel.$space-carousel-content-layout-padding);
8
+ margin-block: calc(0px - #{styles-tokens-carousel.$space-carousel-content-layout-padding});
9
+
10
+ // Only block padding: inline padding created a gutter where the next item
11
+ // (and its outline) painted through when gap < padding. Card outline is
12
+ // contained by .itemContainer padding instead.
13
+ padding-block: styles-tokens-carousel.$space-carousel-content-layout-padding;
11
14
 
12
15
  &[data-swipe] {
13
16
  cursor: grab;
@@ -24,6 +27,9 @@
24
27
  .itemContainer {
25
28
  flex-shrink: 0;
26
29
  box-sizing: border-box;
30
+ // Reserve space inside the slide for card outline/border so it is not clipped
31
+ // by overflow and does not paint into a shared gutter with the next slide.
32
+ padding: styles-tokens-carousel.$border-width-card-container;
27
33
  }
28
34
 
29
35
  .itemTracker {