@alto-avios/alto-ui 3.4.0-alpha.4 → 3.4.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -73,6 +73,14 @@ We need to create static storybook files for our public domain site to use. Run
73
73
 
74
74
  `npm run build:storybook`
75
75
 
76
+ ## Run Chromatic (Dev)
77
+
78
+ Run the following command to analyze our code and send to chromatic
79
+
80
+ `npx chromatic --project-token <YOUR_PROJECT_TOKEN>`
81
+
82
+ Project Token can be found in the chromatic dashboard
83
+
76
84
  ## For Application using our package
77
85
 
78
86
  ### Install Package in Applications
@@ -1 +1 @@
1
- ._carouselWrapper_mtbhv_1{max-width:100%;overflow:hidden;position:relative;width:100%}._showPartialItems_mtbhv_9,._showPartialItems_mtbhv_9 ._carousel_mtbhv_1{overflow:visible}._carousel_mtbhv_1{overflow:hidden;position:relative;width:100%}._scroller_mtbhv_23{display:flex;overflow-x:hidden;scroll-behavior:smooth;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;transition:all .3s ease}[data-dragging=true] ._scroller_mtbhv_23{cursor:grabbing;scroll-behavior:auto}._scroller_mtbhv_23:hover{cursor:grab}._item_mtbhv_43{box-sizing:border-box;flex:0 0 100%;scroll-snap-align:start;scroll-snap-stop:always}div[style*=--items-per-page] ._item_mtbhv_43{flex:0 0 auto;flex-basis:calc(100%/var(--items-per-page))}div[style*=--space-between-items] ._item_mtbhv_43{margin-right:var(--space-between-items)}div[style*=--space-between-items] ._item_mtbhv_43:last-child{margin-right:0}div[style*=--scroll-padding] ._scroller_mtbhv_23{padding-left:var(--scroll-padding);padding-right:var(--scroll-padding);scroll-padding-left:var(--scroll-padding);scroll-padding-right:var(--scroll-padding)}._slideLeft_mtbhv_73{animation:_slideLeftAnimation_mtbhv_1 .4s ease-out}._slideRight_mtbhv_77{animation:_slideRightAnimation_mtbhv_1 .4s ease-out}@keyframes _slideLeftAnimation_mtbhv_1{0%{transform:translate(5%)}to{transform:translate(0)}}@keyframes _slideRightAnimation_mtbhv_1{0%{transform:translate(-5%)}to{transform:translate(0)}}._controls_mtbhv_100{bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:1}._dotsContainerWrapper_mtbhv_111{pointer-events:auto;z-index:2}._dotsContainer_mtbhv_111{position:relative}@media (max-width:768px){._dotsContainerWrapper_mtbhv_111{cursor:pointer}._dotsContainerWrapper_mtbhv_111:active{opacity:.8}}._hiddenTabs_mtbhv_133{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}._tapEnabled_mtbhv_146{cursor:pointer;touch-action:manipulation}._autoplayControlWrapper_mtbhv_161{align-items:center;display:flex;justify-content:center;pointer-events:auto;position:absolute;right:16px;top:16px;z-index:10}
1
+ ._carouselWrapper_1hn3p_2{max-width:100%;overflow:hidden;position:relative;width:100%}._showPartialItems_1hn3p_10,._showPartialItems_1hn3p_10 ._carousel_1hn3p_2{overflow:visible}._hasScrollPadding_1hn3p_19,._hasScrollPadding_1hn3p_19 ._carousel_1hn3p_2{overflow:visible!important}._carousel_1hn3p_2{overflow:hidden;position:relative;width:100%}._scroller_1hn3p_33{display:flex;overflow-x:hidden;scroll-behavior:smooth;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;border-radius:var(--alto-sem-radius-md);height:auto;transition:all .3s ease}._scroller_1hn3p_33:focus{outline-offset:-2px;outline-width:2px}[data-dragging=true] ._scroller_1hn3p_33{cursor:grabbing;scroll-behavior:auto}._scroller_1hn3p_33:hover{cursor:grab}._item_1hn3p_60{box-sizing:border-box;flex:0 0 100%;scroll-snap-align:start;scroll-snap-stop:always}div[style*=--items-per-page] ._item_1hn3p_60{flex:0 0 auto;width:calc(100%/var(--items-per-page))}div[style*=--space-between-items] ._item_1hn3p_60{margin-right:var(--space-between-items)}div[style*=--space-between-items] ._item_1hn3p_60:last-child{margin-right:0}[data-scroll-padding=true],[data-scroll-padding=true] ._carousel_1hn3p_2,[data-scroll-padding=true] ._scroller_1hn3p_33{overflow:visible!important}[data-scroll-padding=true] ._item_1hn3p_60{scroll-snap-align:start}._slideLeft_1hn3p_99{animation:_slideLeftAnimation_1hn3p_1 1s cubic-bezier(.25,0,.85,.1)}._slideRight_1hn3p_103{animation:_slideRightAnimation_1hn3p_1 1s cubic-bezier(.25,0,.85,.1)}@keyframes _slideLeftAnimation_1hn3p_1{0%{transform:translate(0)}to{transform:translate(0)}}@keyframes _slideRightAnimation_1hn3p_1{0%{transform:translate(0)}to{transform:translate(0)}}._controls_1hn3p_126{bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:1}._showOnHover_1hn3p_137 ._arrowContainer_1hn3p_137{opacity:0;transition:opacity .3s ease}[data-arrows-visible=true] ._showOnHover_1hn3p_137 ._arrowContainer_1hn3p_137{opacity:1}._hidden_1hn3p_147{opacity:0;transition:opacity .3s ease,visibility .3s ease;visibility:hidden}._dotsContainerWrapper_1hn3p_156{pointer-events:auto;z-index:2}._dotsContainer_1hn3p_156{position:relative}@media (max-width:768px){._dotsContainerWrapper_1hn3p_156{cursor:pointer}._dotsContainerWrapper_1hn3p_156:active{opacity:.8}}._hiddenTabs_1hn3p_178{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}._tapEnabled_1hn3p_191{cursor:pointer;touch-action:manipulation}._autoplayControlWrapper_1hn3p_206{align-items:center;display:flex;justify-content:center;pointer-events:auto;position:absolute;right:16px;top:16px;z-index:10}._carouselDefault_1hn3p_220{height:100%;overflow-x:hidden;width:361px}._carouselDefault_1hn3p_220 ._prevButton_1hn3p_225{left:10px;position:absolute;top:50%;transform:translateY(-50%);z-index:5}._carouselDefault_1hn3p_220 ._nextButton_1hn3p_232{position:absolute;right:10px;top:50%;transform:translateY(-50%);z-index:5}._carouselDefault_1hn3p_220 ._dotsContainer_1hn3p_156{bottom:12px;display:flex;justify-content:center;left:0;position:absolute;right:0;z-index:5}._carouselWithAutoPlay_1hn3p_250{position:relative;width:100%}._carouselWithAutoPlay_1hn3p_250 ._prevButton_1hn3p_225{left:10px;position:absolute;top:50%;transform:translateY(-50%);z-index:5}._carouselWithAutoPlay_1hn3p_250 ._nextButton_1hn3p_232{position:absolute;right:10px;top:50%;transform:translateY(-50%);z-index:5}._carouselWithAutoPlay_1hn3p_250 ._dotsContainer_1hn3p_156{bottom:12px;display:flex;justify-content:center;left:0;position:absolute;right:0;z-index:5}._carouselWithAutoPlay_1hn3p_250 ._autoplayControl_1hn3p_206{pointer-events:auto!important;position:absolute!important;right:16px!important;top:16px!important;z-index:20!important}._carouselWithScrollPeek_1hn3p_286{overflow:visible!important;position:relative}._carouselWithScrollPeek_1hn3p_286 ._carousel_1hn3p_2{overflow:visible!important}._carouselWithScrollPeek_1hn3p_286 ._prevButton_1hn3p_225{left:16px;position:absolute;top:50%;transform:translateY(-50%);z-index:10}._carouselWithScrollPeek_1hn3p_286 ._nextButton_1hn3p_232{position:absolute;right:16px;top:50%;transform:translateY(-50%);z-index:10}._carouselWithScrollPeek_1hn3p_286 ._dotsContainer_1hn3p_156{bottom:20px;display:flex;justify-content:center;left:0;position:absolute;right:0;z-index:5}._carouselWithFractionalItems_1hn3p_318{overflow:visible!important;position:relative}._carouselWithFractionalItems_1hn3p_318 ._carousel_1hn3p_2{overflow:visible!important}._carouselWithFractionalItems_1hn3p_318 ._prevButton_1hn3p_225{left:16px;position:absolute;top:50%;transform:translateY(-50%);z-index:10}._carouselWithFractionalItems_1hn3p_318 ._nextButton_1hn3p_232{position:absolute;right:16px;top:50%;transform:translateY(-50%);z-index:10}._carouselWithFractionalItems_1hn3p_318 ._dotsContainer_1hn3p_156{bottom:20px;display:flex;justify-content:center;left:0;position:absolute;right:0;z-index:5}._paginationDotsDefault_1hn3p_350{position:relative;width:100%}._paginationDotsDefault_1hn3p_350 ._prevButton_1hn3p_225{left:10px;position:absolute;top:50%;transform:translateY(-50%);z-index:5}._paginationDotsDefault_1hn3p_350 ._nextButton_1hn3p_232{position:absolute;right:10px;top:50%;transform:translateY(-50%);z-index:5}._paginationDotsDefault_1hn3p_350 ._dotsContainer_1hn3p_156{bottom:12px;display:flex;justify-content:center;left:0;position:absolute;right:0;z-index:5}._hoverArrowsDefault_1hn3p_379{height:100%;overflow-x:hidden;width:361px}._hoverArrowsDefault_1hn3p_379 ._prevButton_1hn3p_225{left:10px;opacity:0;position:absolute;top:50%;transform:translateY(-50%);transition:opacity .3s ease;z-index:5}._hoverArrowsDefault_1hn3p_379 ._nextButton_1hn3p_232{opacity:0;position:absolute;right:10px;top:50%;transform:translateY(-50%);transition:opacity .3s ease;z-index:5}._hoverArrowsDefault_1hn3p_379:focus-within ._nextButton_1hn3p_232,._hoverArrowsDefault_1hn3p_379:focus-within ._prevButton_1hn3p_225,._hoverArrowsDefault_1hn3p_379:hover ._nextButton_1hn3p_232,._hoverArrowsDefault_1hn3p_379:hover ._prevButton_1hn3p_225{opacity:1}._hoverArrowsDefault_1hn3p_379 ._dotsContainer_1hn3p_156{bottom:12px;display:flex;justify-content:center;left:0;position:absolute;right:0;z-index:5}
@@ -1 +1 @@
1
- ._arrowContainer_ny9r1_1{background:none;border:none;padding:0;pointer-events:auto;position:relative;z-index:2}._iconButton_ny9r1_10{align-items:center;display:flex;justify-content:center}._hideWhenDisabled_ny9r1_16[aria-disabled=true]{display:none}._neutral_ny9r1_22 ._iconButton_ny9r1_10[data-focused=true],._neutral_ny9r1_22 ._iconButton_ny9r1_10[data-parent-hovered=true]{background-color:var(--alto-sem-color-overlay-state-darken-invert-hover)}:not([aria-disabled]) ._neutral_ny9r1_22 ._iconButton_ny9r1_10[data-parent-pressed=true]{background-color:var(--alto-sem-color-overlay-state-darken-invert-active)}._white_ny9r1_32 ._iconButton_ny9r1_10{background-color:transparent;border:none;border-radius:0}._white_ny9r1_32:not([aria-disabled]) ._iconButton_ny9r1_10[data-focused=true],._white_ny9r1_32:not([aria-disabled]) ._iconButton_ny9r1_10[data-parent-hovered=true]{background-color:var(--alto-sem-color-overlay-state-lighten-hover)}._white_ny9r1_32:not([aria-disabled]) ._iconButton_ny9r1_10[data-parent-pressed=true]{background-color:var(--alto-sem-color-overlay-state-lighten-active)}._shapeFlat_ny9r1_48:not([aria-disabled]) ._iconButton_ny9r1_10{background-color:var(--alto-sem-color-bg-white-vibrant-default)}._shapeFlat_ny9r1_48:not([aria-disabled]) ._iconButton_ny9r1_10[data-focused=true],._shapeFlat_ny9r1_48:not([aria-disabled]) ._iconButton_ny9r1_10[data-parent-hovered=true]{background-color:var(--alto-sem-color-bg-white-vibrant-hover)}._shapeFlat_ny9r1_48:not([aria-disabled]) ._iconButton_ny9r1_10[data-parent-pressed=true]{background-color:var(--alto-sem-color-bg-white-vibrant-active)}._shapeElevated_ny9r1_62:not([aria-disabled]) ._iconButton_ny9r1_10{background-color:var(--alto-sem-color-bg-white-vibrant-default);box-shadow:0 11.4px 9.12px #2f2a850d,0 2.59px 4.4px #2f2a850d,0 6.99px 18.18px #2f2a8514}._shapeElevated_ny9r1_62:not([aria-disabled]) ._iconButton_ny9r1_10[data-focused=true],._shapeElevated_ny9r1_62:not([aria-disabled]) ._iconButton_ny9r1_10[data-parent-hovered=true]{background-color:var(--alto-sem-color-bg-white-vibrant-hover)}._shapeElevated_ny9r1_62:not([aria-disabled]) ._iconButton_ny9r1_10[data-parent-pressed=true]{background-color:var(--alto-sem-color-bg-white-vibrant-active)}._gradient_ny9r1_80:not([aria-disabled]) ._iconButton_ny9r1_10{background:linear-gradient(90deg,#fefefe 50%,#fff0);border:none;border-radius:0}._gradient_ny9r1_80._next_ny9r1_86:not([aria-disabled]) ._iconButton_ny9r1_10{background:linear-gradient(90deg,#fff0,#fefefe 50%)}._gradient_ny9r1_80:not([aria-disabled]) ._iconButton_ny9r1_10[data-focused=true],._gradient_ny9r1_80:not([aria-disabled]) ._iconButton_ny9r1_10[data-parent-hovered=true]{background:linear-gradient(90deg,#fefefe 50%,#fff0);color:var(--alto-sem-color-fg-accent-primary)}._gradient_ny9r1_80._next_ny9r1_86:not([aria-disabled]) ._iconButton_ny9r1_10[data-focused=true],._gradient_ny9r1_80._next_ny9r1_86:not([aria-disabled]) ._iconButton_ny9r1_10[data-parent-hovered=true]{background:linear-gradient(90deg,#fff0,#fefefe 50%);color:var(--alto-sem-color-fg-accent-primary)}._gradient_ny9r1_80:not([aria-disabled]) ._iconButton_ny9r1_10[data-parent-pressed=true]{background-color:var(--alto-sem-color-overlay-state-lighten-active)}._gradient_ny9r1_80:not([aria-disabled]) ._iconButton_ny9r1_10[data-focused],._white_ny9r1_32:not([aria-disabled]) ._iconButton_ny9r1_10{outline-offset:var(--alto-sem-border-width-none)}[aria-disabled] ._iconButton_ny9r1_10{background-color:var(--alto-sem-color-fg-disabled-primary);cursor:not-allowed;opacity:var(--alto-sem-opacity-30)}
1
+ ._arrowContainer_v9ex2_1{background:none;border:none;padding:0;pointer-events:auto;position:relative;z-index:2}._iconButton_v9ex2_10{align-items:center;display:flex;justify-content:center}._hideWhenDisabled_v9ex2_16[aria-disabled=true]{display:none}._neutral_v9ex2_22 ._iconButton_v9ex2_10[data-focused=true],._neutral_v9ex2_22 ._iconButton_v9ex2_10[data-parent-hovered=true]{background-color:var(--alto-sem-color-overlay-state-darken-invert-hover)}:not([aria-disabled]) ._neutral_v9ex2_22 ._iconButton_v9ex2_10[data-parent-pressed=true]{background-color:var(--alto-sem-color-overlay-state-darken-invert-active)}._white_v9ex2_32 ._iconButton_v9ex2_10{background-color:transparent;border:none;border-radius:0}._white_v9ex2_32:not([aria-disabled]) ._iconButton_v9ex2_10[data-focused=true],._white_v9ex2_32:not([aria-disabled]) ._iconButton_v9ex2_10[data-parent-hovered=true]{background-color:var(--alto-sem-color-overlay-state-lighten-hover)}._white_v9ex2_32:not([aria-disabled]) ._iconButton_v9ex2_10[data-parent-pressed=true]{background-color:var(--alto-sem-color-overlay-state-lighten-active)}._shapeFlat_v9ex2_48:not([aria-disabled]) ._iconButton_v9ex2_10{background-color:var(--alto-sem-color-bg-white-vibrant-default)}._shapeFlat_v9ex2_48:not([aria-disabled]) ._iconButton_v9ex2_10[data-parent-pressed=true]{background-color:var(--alto-sem-color-bg-white-vibrant-active)}._shapeElevated_v9ex2_57:not([aria-disabled]) ._iconButton_v9ex2_10{background-color:var(--alto-sem-color-bg-white-vibrant-default);box-shadow:0 11.4px 9.12px #2f2a850d,0 2.59px 4.4px #2f2a850d,0 6.99px 18.18px #2f2a8514}._shapeElevated_v9ex2_57:not([aria-disabled]) ._iconButton_v9ex2_10[data-focused=true],._shapeElevated_v9ex2_57:not([aria-disabled]) ._iconButton_v9ex2_10[data-parent-hovered=true]{background-color:var(--alto-sem-color-bg-white-vibrant-hover)}._shapeElevated_v9ex2_57:not([aria-disabled]) ._iconButton_v9ex2_10[data-parent-pressed=true]{background-color:var(--alto-sem-color-bg-white-vibrant-active)}._gradient_v9ex2_75:not([aria-disabled]) ._iconButton_v9ex2_10{background:linear-gradient(90deg,#fefefe 50%,#fff0);border:none;border-radius:0}._gradient_v9ex2_75._next_v9ex2_81:not([aria-disabled]) ._iconButton_v9ex2_10{background:linear-gradient(90deg,#fff0,#fefefe 50%)}._gradient_v9ex2_75:not([aria-disabled]) ._iconButton_v9ex2_10[data-focused=true],._gradient_v9ex2_75:not([aria-disabled]) ._iconButton_v9ex2_10[data-parent-hovered=true]{background:linear-gradient(90deg,#fefefe 50%,#fff0);color:var(--alto-sem-color-fg-accent-primary)}._gradient_v9ex2_75._next_v9ex2_81:not([aria-disabled]) ._iconButton_v9ex2_10[data-focused=true],._gradient_v9ex2_75._next_v9ex2_81:not([aria-disabled]) ._iconButton_v9ex2_10[data-parent-hovered=true]{background:linear-gradient(90deg,#fff0,#fefefe 50%);color:var(--alto-sem-color-fg-accent-primary)}._gradient_v9ex2_75:not([aria-disabled]) ._iconButton_v9ex2_10[data-parent-pressed=true]{background-color:var(--alto-sem-color-overlay-state-lighten-active)}._gradient_v9ex2_75:not([aria-disabled]) ._iconButton_v9ex2_10[data-focused],._white_v9ex2_32:not([aria-disabled]) ._iconButton_v9ex2_10{outline-offset:var(--alto-sem-border-width-none)}[aria-disabled] ._iconButton_v9ex2_10{background-color:var(--alto-sem-color-fg-disabled-primary);cursor:not-allowed;opacity:var(--alto-sem-opacity-30)}._fullHeight_v9ex2_114{align-items:center;bottom:0;cursor:pointer;display:flex;height:100%;top:0;transform:none}._fullHeight_v9ex2_114._prev_v9ex2_124{justify-content:flex-start;left:0}._fullHeight_v9ex2_114._next_v9ex2_81{justify-content:flex-end;right:0}._fullHeight_v9ex2_114 ._iconButton_v9ex2_10{box-shadow:none!important;outline:none!important;position:relative;z-index:2}._fullHeight_v9ex2_114 ._iconButton_v9ex2_10:focus,._fullHeight_v9ex2_114 ._iconButton_v9ex2_10:focus-visible,._fullHeight_v9ex2_114 ._iconButton_v9ex2_10[data-focused=true]{border:none!important;box-shadow:none!important;outline:none!important}
@@ -1 +1 @@
1
- ._tabsContainer_1yet6_1{margin:0 auto;min-height:30px;width:240px}._tabsContainer_1yet6_1,._tabs_1yet6_1{align-items:center;display:flex;justify-content:center;overflow:hidden;position:relative}._tabs_1yet6_1{background-color:var(--alto-sem-color-bg-white-vibrant-default);border-radius:var(--alto-sem-radius-circle);padding:var(--alto-sem-space-2xs) var(--alto-sem-space-xs)}._tabs_1yet6_1[data-focused=true]{outline:2px solid var(--alto-sem-color-border-accent);outline-offset:1px}._tabs_1yet6_1._transparent_1yet6_28{background-color:transparent}._dotsScroller_1yet6_32{align-items:center;display:flex;gap:var(--alto-sem-space-2xs);justify-content:center;position:relative;white-space:nowrap;will-change:transform}._tab_1yet6_1{background-color:#0000004d;border:none;border-radius:var(--alto-sem-radius-circle);cursor:pointer;display:block;flex-shrink:0;margin:0;padding:0;transition:background-color .6s ease,width .6s ease,height .6s ease,opacity .6s ease}._tab_1yet6_1:hover,._tab_1yet6_1[data-hovered=true]{transform:scale(1.1)}._tab_1yet6_1._activeTab_1yet6_65{background-color:var(--alto-sem-color-fg-primary)}._tabs_1yet6_1[data-focused=true] ._tab_1yet6_1._activeTab_1yet6_65{background-color:var(--alto-sem-color-border-accent)}._tabMd_1yet6_74{height:8px;width:8px}._tabLg_1yet6_79{height:12px;width:12px}._tabSizeMedium_1yet6_85{height:6px;opacity:.8;width:6px}._tabSizeSmall_1yet6_92{height:4px;opacity:.6;width:4px}[data-dot-size=lg] ._tabSizeMedium_1yet6_85{height:9px;width:9px}[data-dot-size=lg] ._tabSizeSmall_1yet6_92{height:6px;width:6px}
1
+ ._tabsContainer_1rprd_1{align-items:center;display:flex;justify-content:center;margin:0 auto;min-height:30px;position:relative;width:auto}._tabsContainer_1rprd_1:focus{border:2px solid green}._tabs_1rprd_1{align-items:center;background-color:var(--alto-sem-color-bg-white-vibrant-default);border-radius:var(--alto-sem-radius-circle);display:flex;justify-content:center;padding:var(--alto-sem-space-2xs) var(--alto-sem-space-xs);position:relative}._tabs_1rprd_1._transparent_1rprd_25{background-color:transparent}._dotsScroller_1rprd_29{align-items:center;display:flex;flex-wrap:wrap;gap:var(--alto-sem-space-2xs);justify-content:center;position:relative;white-space:nowrap}._tab_1rprd_1{background-color:#0000004d;border:none;border-radius:var(--alto-sem-radius-circle);cursor:pointer;display:block;flex-shrink:0;margin:0;padding:0}._tab_1rprd_1:hover,._tab_1rprd_1[data-hovered=true]{transform:scale(1.1)}._tab_1rprd_1._activeTab_1rprd_56{background-color:var(--alto-sem-color-fg-primary)}._tabs_1rprd_1[data-focused=true] ._tab_1rprd_1._activeTab_1rprd_56{background-color:var(--alto-sem-color-border-accent)}[data-transitioning=true] ._tab_1rprd_1{pointer-events:none;transition:none!important}[data-transitioning=true] ._dotsScroller_1rprd_29{transition:none!important}._tabMd_1rprd_75{height:8px;width:8px}._tabLg_1rprd_80{height:12px;width:12px}
@@ -19,17 +19,26 @@ export interface CarouselProps {
19
19
  * @min 1
20
20
  */
21
21
  itemsPerPage?: number;
22
+ /**
23
+ * Number of items to scroll when navigating
24
+ * If not specified, will default to itemsPerPage
25
+ * @default undefined
26
+ * @min 1
27
+ */
28
+ scrollByCount?: number;
22
29
  /**
23
30
  * Space between carousel items in pixels
24
31
  * @default 0
25
32
  */
26
33
  spaceBetweenItems?: number;
27
34
  /**
28
- * Whether to show a peek of the next/previous slides when in
29
- * overflow mode
30
- * @default false
35
+ * Amount of padding added to the scroll container to create a "peek" effect.
36
+ * This shows a portion of the adjacent items.
37
+ * Accepts any valid CSS dimension (px, rem, em, %) - e.g., "15%", "20px", "2rem"
38
+ * @example "15%" or "20px" or "2rem"
39
+ * @default undefined
31
40
  */
32
- hasScrollPeek?: boolean;
41
+ scrollPadding?: string;
33
42
  /**
34
43
  * Additional CSS class for the carousel container
35
44
  */
@@ -54,6 +63,11 @@ export interface CarouselProps {
54
63
  * @default false
55
64
  */
56
65
  hideWhenDisabled?: boolean;
66
+ /**
67
+ * Whether to show arrows only when hovering over the carousel or when it has focus
68
+ * @default false
69
+ */
70
+ showArrowsOnHover?: boolean;
57
71
  /**
58
72
  * Focus style for interactive elements
59
73
  * @default 'default'
@@ -145,6 +159,11 @@ export interface CarouselProps {
145
159
  * Class name for the active dot
146
160
  */
147
161
  activeDotClassName?: string;
162
+ /**
163
+ * Whether the navigation buttons should be full height of the carousel
164
+ * @default false
165
+ */
166
+ fullHeightButtons?: boolean;
148
167
  }
149
- export declare const Carousel: ({ children, looping, className, itemsPerPage, spaceBetweenItems, hasScrollPeek, iconType, carouselArrow, buttonSize, hideWhenDisabled, focusStyle, dotSize, dotsVariant, hideDots, enableTapCycling, isPaused, autoPlayInterval, autoPlayControlVariant, autoPlayControlSize, mouseDragging, carouselWrapperClassName, controlsClassName, prevButtonClassName, nextButtonClassName, autoplayControlClassName, dotsContainerClassName, dotsWrapperClassName, dotClassName, activeDotClassName, }: CarouselProps) => import("react/jsx-runtime").JSX.Element;
168
+ export declare const Carousel: ({ children, looping, className, itemsPerPage, scrollByCount, spaceBetweenItems, scrollPadding, iconType, carouselArrow, buttonSize, hideWhenDisabled, showArrowsOnHover, focusStyle, fullHeightButtons, dotSize, dotsVariant, hideDots, enableTapCycling, isPaused, autoPlayInterval, autoPlayControlVariant, autoPlayControlSize, mouseDragging, carouselWrapperClassName, controlsClassName, prevButtonClassName, nextButtonClassName, autoplayControlClassName, dotsContainerClassName, dotsWrapperClassName, dotClassName, activeDotClassName, }: CarouselProps) => import("react/jsx-runtime").JSX.Element;
150
169
  export default Carousel;
@@ -5,27 +5,43 @@ import { C as Carousel$1, a as CarouselScroller, b as CarouselItem, c as Carouse
5
5
  import { CarouselButton } from "./CarouselButton/CarouselButton.js";
6
6
  import { CarouselDots } from "./CarouselDots/CarouselDots.js";
7
7
  import { AutoplayControl } from "./AutoplayControl/AutoplayControl.js";
8
- import '../../assets/Carousel.css';const carouselWrapper = "_carouselWrapper_mtbhv_1";
9
- const showPartialItems = "_showPartialItems_mtbhv_9";
10
- const carousel$1 = "_carousel_mtbhv_1";
11
- const scroller = "_scroller_mtbhv_23";
12
- const item = "_item_mtbhv_43";
13
- const slideLeft = "_slideLeft_mtbhv_73";
14
- const slideLeftAnimation = "_slideLeftAnimation_mtbhv_1";
15
- const slideRight = "_slideRight_mtbhv_77";
16
- const slideRightAnimation = "_slideRightAnimation_mtbhv_1";
17
- const controls = "_controls_mtbhv_100";
18
- const dotsContainerWrapper = "_dotsContainerWrapper_mtbhv_111";
19
- const dotsContainer = "_dotsContainer_mtbhv_111";
20
- const hiddenTabs = "_hiddenTabs_mtbhv_133";
21
- const tapEnabled = "_tapEnabled_mtbhv_146";
22
- const infinite = "_infinite_mtbhv_152";
23
- const native = "_native_mtbhv_157";
24
- const autoplayControlWrapper = "_autoplayControlWrapper_mtbhv_161";
8
+ import { focusStyleVariants } from "../../utils/focus/focusStyles.js";
9
+ import { useFocusRing } from "@react-aria/focus";
10
+ import '../../assets/Carousel.css';const carouselWrapper = "_carouselWrapper_1hn3p_2";
11
+ const showPartialItems = "_showPartialItems_1hn3p_10";
12
+ const carousel$1 = "_carousel_1hn3p_2";
13
+ const hasScrollPadding = "_hasScrollPadding_1hn3p_19";
14
+ const scroller = "_scroller_1hn3p_33";
15
+ const item = "_item_1hn3p_60";
16
+ const slideLeft = "_slideLeft_1hn3p_99";
17
+ const slideLeftAnimation = "_slideLeftAnimation_1hn3p_1";
18
+ const slideRight = "_slideRight_1hn3p_103";
19
+ const slideRightAnimation = "_slideRightAnimation_1hn3p_1";
20
+ const controls = "_controls_1hn3p_126";
21
+ const showOnHover = "_showOnHover_1hn3p_137";
22
+ const arrowContainer = "_arrowContainer_1hn3p_137";
23
+ const hidden = "_hidden_1hn3p_147";
24
+ const dotsContainerWrapper = "_dotsContainerWrapper_1hn3p_156";
25
+ const dotsContainer = "_dotsContainer_1hn3p_156";
26
+ const hiddenTabs = "_hiddenTabs_1hn3p_178";
27
+ const tapEnabled = "_tapEnabled_1hn3p_191";
28
+ const infinite = "_infinite_1hn3p_197";
29
+ const native = "_native_1hn3p_202";
30
+ const autoplayControlWrapper = "_autoplayControlWrapper_1hn3p_206";
31
+ const carouselDefault = "_carouselDefault_1hn3p_220";
32
+ const prevButton = "_prevButton_1hn3p_225";
33
+ const nextButton = "_nextButton_1hn3p_232";
34
+ const carouselWithAutoPlay = "_carouselWithAutoPlay_1hn3p_250";
35
+ const autoplayControl = "_autoplayControl_1hn3p_206";
36
+ const carouselWithScrollPeek = "_carouselWithScrollPeek_1hn3p_286";
37
+ const carouselWithFractionalItems = "_carouselWithFractionalItems_1hn3p_318";
38
+ const paginationDotsDefault = "_paginationDotsDefault_1hn3p_350";
39
+ const hoverArrowsDefault = "_hoverArrowsDefault_1hn3p_379";
25
40
  const styles = {
26
41
  carouselWrapper,
27
42
  showPartialItems,
28
43
  carousel: carousel$1,
44
+ hasScrollPadding,
29
45
  scroller,
30
46
  item,
31
47
  slideLeft,
@@ -33,13 +49,25 @@ const styles = {
33
49
  slideRight,
34
50
  slideRightAnimation,
35
51
  controls,
52
+ showOnHover,
53
+ arrowContainer,
54
+ hidden,
36
55
  dotsContainerWrapper,
37
56
  dotsContainer,
38
57
  hiddenTabs,
39
58
  tapEnabled,
40
59
  infinite,
41
60
  native,
42
- autoplayControlWrapper
61
+ autoplayControlWrapper,
62
+ carouselDefault,
63
+ prevButton,
64
+ nextButton,
65
+ carouselWithAutoPlay,
66
+ autoplayControl,
67
+ carouselWithScrollPeek,
68
+ carouselWithFractionalItems,
69
+ paginationDotsDefault,
70
+ hoverArrowsDefault
43
71
  };
44
72
  const carousel = cva(styles.carousel, {
45
73
  variants: {
@@ -55,14 +83,17 @@ const Carousel = ({
55
83
  looping = "off",
56
84
  className = "",
57
85
  itemsPerPage = 1,
86
+ scrollByCount,
58
87
  spaceBetweenItems = 0,
59
- hasScrollPeek = false,
88
+ scrollPadding,
60
89
  // Button and Controls Props
61
90
  iconType = "chevron",
62
91
  carouselArrow = "neutral",
63
92
  buttonSize = "md",
64
93
  hideWhenDisabled = false,
94
+ showArrowsOnHover = false,
65
95
  focusStyle = "default",
96
+ fullHeightButtons = false,
66
97
  // Dots/Tabs Props
67
98
  dotSize = "md",
68
99
  dotsVariant = "standard",
@@ -102,11 +133,20 @@ const Carousel = ({
102
133
  const [currentPage, setCurrentPage] = useState(0);
103
134
  const [prevPage, setPrevPage] = useState(0);
104
135
  const [isDragging, setIsDragging] = useState(false);
136
+ const [isHovered, setIsHovered] = useState(false);
137
+ const [isFocused, setIsFocused] = useState(false);
138
+ const [isTransitioning, setIsTransitioning] = useState(false);
139
+ const [dragStartPosition, setDragStartPosition] = useState(null);
140
+ const dragThreshold = 5;
141
+ const effectiveScrollByCount = scrollByCount !== void 0 ? Math.max(1, scrollByCount) : safeItemsPerPage;
105
142
  const getCarouselWrapperClasses = () => {
106
143
  const classes = [styles.carouselWrapper];
107
144
  if (!Number.isInteger(safeItemsPerPage)) {
108
145
  classes.push(styles.showPartialItems);
109
146
  }
147
+ if (scrollPadding) {
148
+ classes.push(styles.hasScrollPadding);
149
+ }
110
150
  if (carouselWrapperClassName) {
111
151
  classes.push(carouselWrapperClassName);
112
152
  }
@@ -120,22 +160,103 @@ const Carousel = ({
120
160
  if (spaceBetweenItems > 0) {
121
161
  cssVars2["--space-between-items"] = `${spaceBetweenItems}px`;
122
162
  }
123
- if (hasScrollPeek) {
124
- cssVars2["--scroll-padding"] = "16px";
125
- }
126
163
  return Object.keys(cssVars2).length > 0 ? cssVars2 : void 0;
127
164
  };
128
165
  const navigateToSlide = (index) => {
129
- if (index === currentPage) return;
166
+ if (index === currentPage || isTransitioning) return;
167
+ let nativeTab = null;
168
+ if (carouselRef.current) {
169
+ nativeTab = carouselRef.current.querySelector(`[data-index="${index}"]`);
170
+ }
171
+ setIsTransitioning(true);
130
172
  setPrevPage(currentPage);
131
173
  setCurrentPage(index);
132
- if (carouselRef.current) {
133
- const nativeTab = carouselRef.current.querySelector(`[data-index="${index}"]`);
134
- if (nativeTab && nativeTab instanceof HTMLElement) {
174
+ setTimeout(() => {
175
+ if (nativeTab) {
135
176
  nativeTab.click();
136
177
  }
178
+ setTimeout(() => {
179
+ setIsTransitioning(false);
180
+ }, 600);
181
+ }, 0);
182
+ };
183
+ const navigateByScrollCount = (direction) => {
184
+ if (!carouselRef.current || isTransitioning) return;
185
+ const totalVisiblePages = Math.ceil(totalItems / safeItemsPerPage);
186
+ let targetPage;
187
+ if (direction === "next") {
188
+ targetPage = currentPage + effectiveScrollByCount;
189
+ if (targetPage >= totalVisiblePages) {
190
+ if (looping === "infinite") {
191
+ targetPage = targetPage % totalVisiblePages;
192
+ } else if (looping === "backToStart") {
193
+ targetPage = 0;
194
+ } else {
195
+ targetPage = totalVisiblePages - 1;
196
+ }
197
+ }
198
+ } else {
199
+ targetPage = currentPage - effectiveScrollByCount;
200
+ if (targetPage < 0) {
201
+ if (looping === "infinite") {
202
+ targetPage = totalVisiblePages + targetPage % totalVisiblePages;
203
+ } else if (looping === "backToStart") {
204
+ targetPage = totalVisiblePages - 1;
205
+ } else {
206
+ targetPage = 0;
207
+ }
208
+ }
137
209
  }
210
+ navigateToSlide(targetPage);
138
211
  };
212
+ useEffect(() => {
213
+ if (!carouselRef.current || !mouseDragging) return;
214
+ const preventLinkActivation = (e) => {
215
+ if (isDragging) {
216
+ e.preventDefault();
217
+ e.stopPropagation();
218
+ setTimeout(() => {
219
+ setIsDragging(false);
220
+ }, 0);
221
+ }
222
+ };
223
+ const handleMouseDown = (e) => {
224
+ setDragStartPosition({
225
+ x: e.clientX,
226
+ y: e.clientY
227
+ });
228
+ };
229
+ const handleMouseMove = (e) => {
230
+ if (dragStartPosition === null) return;
231
+ const dx = Math.abs(e.clientX - dragStartPosition.x);
232
+ const dy = Math.abs(e.clientY - dragStartPosition.y);
233
+ const distance = Math.sqrt(dx * dx + dy * dy);
234
+ if (distance > dragThreshold) {
235
+ setIsDragging(true);
236
+ }
237
+ };
238
+ const handleMouseUp = () => {
239
+ if (!isDragging) {
240
+ setDragStartPosition(null);
241
+ return;
242
+ }
243
+ setTimeout(() => {
244
+ setIsDragging(false);
245
+ setDragStartPosition(null);
246
+ }, 50);
247
+ };
248
+ const carouselElement = carouselRef.current;
249
+ carouselElement.addEventListener("mousedown", handleMouseDown, true);
250
+ carouselElement.addEventListener("mousemove", handleMouseMove, true);
251
+ carouselElement.addEventListener("mouseup", handleMouseUp, true);
252
+ carouselElement.addEventListener("click", preventLinkActivation, true);
253
+ return () => {
254
+ carouselElement.removeEventListener("mousedown", handleMouseDown, true);
255
+ carouselElement.removeEventListener("mousemove", handleMouseMove, true);
256
+ carouselElement.removeEventListener("mouseup", handleMouseUp, true);
257
+ carouselElement.removeEventListener("click", preventLinkActivation, true);
258
+ };
259
+ }, [mouseDragging, isDragging, dragStartPosition, dragThreshold]);
139
260
  useEffect(() => {
140
261
  if (carouselRef.current) {
141
262
  const scroller2 = carouselRef.current.querySelector(`.${styles.scroller}`);
@@ -172,13 +293,13 @@ const Carousel = ({
172
293
  }
173
294
  }
174
295
  };
175
- const prevButton = carouselRef.current.querySelector('[dir="prev"]');
176
- const nextButton = carouselRef.current.querySelector('[dir="next"]');
296
+ const prevButton2 = carouselRef.current.querySelector('[dir="prev"]');
297
+ const nextButton2 = carouselRef.current.querySelector('[dir="next"]');
177
298
  const handleButtonClick = () => {
178
299
  setTimeout(updateCurrentPage, 50);
179
300
  };
180
- prevButton == null ? void 0 : prevButton.addEventListener("click", handleButtonClick);
181
- nextButton == null ? void 0 : nextButton.addEventListener("click", handleButtonClick);
301
+ prevButton2 == null ? void 0 : prevButton2.addEventListener("click", handleButtonClick);
302
+ nextButton2 == null ? void 0 : nextButton2.addEventListener("click", handleButtonClick);
182
303
  const observer = new MutationObserver((mutations) => {
183
304
  for (const mutation of mutations) {
184
305
  if (mutation.type === "attributes" && (mutation.attributeName === "aria-selected" || mutation.attributeName === "aria-current")) {
@@ -200,6 +321,7 @@ const Carousel = ({
200
321
  }
201
322
  const handleSlideTransition = () => {
202
323
  updateCurrentPage();
324
+ setIsTransitioning(false);
203
325
  };
204
326
  const scrollerElement = carouselRef.current.querySelector(`.${styles.scroller}`);
205
327
  if (scrollerElement) {
@@ -209,34 +331,55 @@ const Carousel = ({
209
331
  const checkInterval = setInterval(updateCurrentPage, 300);
210
332
  return () => {
211
333
  observer.disconnect();
212
- prevButton == null ? void 0 : prevButton.removeEventListener("click", handleButtonClick);
213
- nextButton == null ? void 0 : nextButton.removeEventListener("click", handleButtonClick);
334
+ prevButton2 == null ? void 0 : prevButton2.removeEventListener("click", handleButtonClick);
335
+ nextButton2 == null ? void 0 : nextButton2.removeEventListener("click", handleButtonClick);
214
336
  if (scrollerElement) {
215
337
  scrollerElement.removeEventListener("transitionend", handleSlideTransition);
216
338
  }
217
339
  clearInterval(checkInterval);
218
340
  };
219
341
  }, [currentPage]);
342
+ const interactionHandlers = showArrowsOnHover ? {
343
+ onMouseEnter: () => setIsHovered(true),
344
+ onMouseLeave: () => setIsHovered(false),
345
+ onFocus: () => setIsFocused(true),
346
+ onBlur: (e) => {
347
+ if (!e.currentTarget.contains(e.relatedTarget)) {
348
+ setIsFocused(false);
349
+ }
350
+ }
351
+ } : {};
352
+ const arrowsVisible = !showArrowsOnHover || isHovered || isFocused;
220
353
  const cssVars = getCssVariables();
221
- return /* @__PURE__ */ jsx("div", { className: getCarouselWrapperClasses(), ref: carouselRef, style: cssVars, "data-dots-size": dotSize, children: /* @__PURE__ */ jsxs(Carousel$1, { className: `${carousel({
354
+ const {
355
+ focusProps,
356
+ isFocusVisible
357
+ } = useFocusRing();
358
+ return /* @__PURE__ */ jsx("div", { className: getCarouselWrapperClasses(), ref: carouselRef, style: cssVars, "data-dots-size": dotSize, ...interactionHandlers, "data-arrows-visible": arrowsVisible ? "true" : "false", "data-transitioning": isTransitioning ? "true" : void 0, "data-scroll-padding": scrollPadding, children: /* @__PURE__ */ jsxs(Carousel$1, { className: `${carousel({
222
359
  looping
223
- })} ${className}`, loop: getLoopValue(), ref: ariaCarouselRef, autoplay: isPaused, autoplayInterval: autoPlayInterval, mouseDragging, onDragStart: () => setIsDragging(true), onDragEnd: () => setIsDragging(false), "data-dragging": isDragging ? "true" : "false", itemsPerPage: safeItemsPerPage, spaceBetweenItems: spaceBetweenItems > 0 ? `${spaceBetweenItems}px` : void 0, scrollPadding: hasScrollPeek ? "16px" : void 0, "data-has-scroll-peek": hasScrollPeek ? "true" : void 0, "data-has-space-between": spaceBetweenItems > 0 ? "true" : void 0, "data-items-per-page": itemsPerPage !== 1 ? safeItemsPerPage.toString() : void 0, children: [
360
+ })} ${className}`, loop: getLoopValue(), ref: ariaCarouselRef, autoplay: isPaused, autoplayInterval: autoPlayInterval, mouseDragging: mouseDragging && !isTransitioning, onDragStart: (e) => {
361
+ setIsDragging(true);
362
+ if (e && e.nativeEvent) {
363
+ setDragStartPosition({
364
+ x: e.nativeEvent.clientX,
365
+ y: e.nativeEvent.clientY
366
+ });
367
+ }
368
+ }, onDragEnd: () => {
369
+ setTimeout(() => {
370
+ setIsDragging(false);
371
+ }, 50);
372
+ }, "data-dragging": isDragging ? "true" : "false", itemsPerPage: safeItemsPerPage, spaceBetweenItems: spaceBetweenItems > 0 ? `${spaceBetweenItems}px` : void 0, scrollPadding, "data-has-space-between": spaceBetweenItems > 0 ? "true" : void 0, "data-items-per-page": itemsPerPage !== 1 ? safeItemsPerPage.toString() : void 0, "data-scroll-by-count": scrollByCount !== void 0 ? effectiveScrollByCount.toString() : void 0, children: [
224
373
  isPaused && /* @__PURE__ */ jsx("div", { className: `${styles.autoplayControlWrapper} ${autoplayControlClassName || ""}`, children: /* @__PURE__ */ jsx(AutoplayControl, { variant: autoPlayControlVariant, size: autoPlayControlSize, className: "" }) }),
225
- /* @__PURE__ */ jsx(CarouselScroller, { className: styles.scroller, children: items.map((child, index) => /* @__PURE__ */ jsx(CarouselItem, { className: styles.item, children: child }, index)) }),
226
- /* @__PURE__ */ jsxs("div", { className: `${styles.controls} ${controlsClassName}`, children: [
227
- /* @__PURE__ */ jsx(CarouselButton, { dir: "prev", variant: carouselArrow, size: buttonSize, focusStyle, iconType, hideWhenDisabled, className: prevButtonClassName }),
228
- /* @__PURE__ */ jsx(CarouselButton, { dir: "next", variant: carouselArrow, size: buttonSize, focusStyle, iconType, hideWhenDisabled, className: nextButtonClassName })
374
+ /* @__PURE__ */ jsxs("div", { className: `${styles.controls} ${controlsClassName} ${showArrowsOnHover ? styles.showOnHover : ""}`, children: [
375
+ /* @__PURE__ */ jsx(CarouselButton, { dir: "prev", variant: carouselArrow, size: buttonSize, focusStyle, iconType, hideWhenDisabled, className: `${prevButtonClassName} ${!arrowsVisible ? styles.hidden : ""}`, fullHeight: fullHeightButtons, onClick: scrollByCount !== void 0 && !isTransitioning ? () => navigateByScrollCount("prev") : void 0 }),
376
+ /* @__PURE__ */ jsx(CarouselButton, { dir: "next", variant: carouselArrow, size: buttonSize, focusStyle, iconType, hideWhenDisabled, className: `${nextButtonClassName} ${!arrowsVisible ? styles.hidden : ""}`, fullHeight: fullHeightButtons, onClick: scrollByCount !== void 0 && !isTransitioning ? () => navigateByScrollCount("next") : void 0 })
229
377
  ] }),
230
- /* @__PURE__ */ jsx("div", { className: styles.hiddenTabs, children: /* @__PURE__ */ jsx(CarouselTabs, { children: (page) => /* @__PURE__ */ jsx(CarouselTab, { index: page.index, "data-index": page.index, "data-slide-tab": "true" }, page.index) }) }),
231
- !hideDots && /* @__PURE__ */ jsx(CarouselDots, { totalItems: totalPages, currentPage, onDotClick: (index) => {
232
- const isMobileDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
233
- if (isMobileDevice && enableTapCycling) {
234
- const nextPage = (currentPage + 1) % totalPages;
235
- navigateToSlide(nextPage);
236
- } else {
237
- navigateToSlide(index);
238
- }
239
- }, focusStyle, dotSize, variant: dotsVariant, className: `${dotsContainerClassName} ${enableTapCycling ? styles.tapEnabled : ""}`, dotsWrapperClassName, dotClassName, activeDotClassName })
378
+ /* @__PURE__ */ jsx(CarouselScroller, { className: `${styles.scroller} ${focusStyleVariants({
379
+ focusStyle
380
+ })}`, ...focusProps, "data-focused": isFocusVisible ? true : void 0, "data-transitioning": isTransitioning ? "true" : void 0, children: items.map((child, index) => /* @__PURE__ */ jsx(CarouselItem, { className: styles.item, children: child }, index)) }),
381
+ /* @__PURE__ */ jsx("div", { className: styles.hiddenTabs, children: /* @__PURE__ */ jsx(CarouselTabs, { children: (page) => /* @__PURE__ */ jsx(CarouselTab, { index: page.index, "data-index": page.index, "data-slide-tab": "true", tabIndex: -1 }, page.index) }) }),
382
+ !hideDots && /* @__PURE__ */ jsx(CarouselDots, { totalItems: totalPages, currentPage, onDotClick: (index) => navigateToSlide(index), focusStyle, dotSize, variant: dotsVariant, className: `${dotsContainerClassName} ${enableTapCycling ? styles.tapEnabled : ""}`, dotsWrapperClassName, dotClassName, activeDotClassName, isTransitioning })
240
383
  ] }) });
241
384
  };
242
385
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"Carousel.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Carousel.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -31,10 +31,19 @@ export interface CarouselButtonProps {
31
31
  * Additional CSS class name for the button content
32
32
  */
33
33
  buttonClassName?: string;
34
+ /**
35
+ * Whether the button should be full height of the container
36
+ * @default false
37
+ */
38
+ fullHeight?: boolean;
39
+ /**
40
+ * Custom click handler for implementing custom navigation behavior
41
+ */
42
+ onClick?: () => void;
34
43
  /**
35
44
  * @private
36
45
  */
37
46
  iconType?: 'chevron';
38
47
  }
39
- export declare const CarouselButton: ({ dir, variant, size, focusStyle, hideWhenDisabled, iconType, className, buttonClassName, }: CarouselButtonProps) => import("react/jsx-runtime").JSX.Element;
48
+ export declare const CarouselButton: ({ dir, variant, size, focusStyle, hideWhenDisabled, iconType, className, buttonClassName, fullHeight, onClick, }: CarouselButtonProps) => import("react/jsx-runtime").JSX.Element;
40
49
  export default CarouselButton;
@@ -5,15 +5,17 @@ import { useFocusRing } from "@react-aria/focus";
5
5
  import { i as iconButtonStyles } from "../../../IconButton.module-DcfPVyUX.js";
6
6
  import { focusStyleVariants } from "../../../utils/focus/focusStyles.js";
7
7
  import { Icon } from "../../Icon/Icon.js";
8
- import '../../../assets/CarouselButton.css';const arrowContainer = "_arrowContainer_ny9r1_1";
9
- const iconButton = "_iconButton_ny9r1_10";
10
- const hideWhenDisabled = "_hideWhenDisabled_ny9r1_16";
11
- const neutral = "_neutral_ny9r1_22";
12
- const white = "_white_ny9r1_32";
13
- const shapeFlat = "_shapeFlat_ny9r1_48";
14
- const shapeElevated = "_shapeElevated_ny9r1_62";
15
- const gradient = "_gradient_ny9r1_80";
16
- const next = "_next_ny9r1_86";
8
+ import '../../../assets/CarouselButton.css';const arrowContainer = "_arrowContainer_v9ex2_1";
9
+ const iconButton = "_iconButton_v9ex2_10";
10
+ const hideWhenDisabled = "_hideWhenDisabled_v9ex2_16";
11
+ const neutral = "_neutral_v9ex2_22";
12
+ const white = "_white_v9ex2_32";
13
+ const shapeFlat = "_shapeFlat_v9ex2_48";
14
+ const shapeElevated = "_shapeElevated_v9ex2_57";
15
+ const gradient = "_gradient_v9ex2_75";
16
+ const next = "_next_v9ex2_81";
17
+ const fullHeight = "_fullHeight_v9ex2_114";
18
+ const prev = "_prev_v9ex2_124";
17
19
  const styles = {
18
20
  arrowContainer,
19
21
  iconButton,
@@ -23,7 +25,9 @@ const styles = {
23
25
  shapeFlat,
24
26
  shapeElevated,
25
27
  gradient,
26
- next
28
+ next,
29
+ fullHeight,
30
+ prev
27
31
  };
28
32
  const CarouselButton = ({
29
33
  dir,
@@ -33,7 +37,9 @@ const CarouselButton = ({
33
37
  hideWhenDisabled: hideWhenDisabled2 = false,
34
38
  iconType = "chevron",
35
39
  className = "",
36
- buttonClassName = ""
40
+ buttonClassName = "",
41
+ fullHeight: fullHeight2 = false,
42
+ onClick
37
43
  }) => {
38
44
  const {
39
45
  isFocusVisible,
@@ -85,6 +91,9 @@ const CarouselButton = ({
85
91
  return "whiteOnVibrant";
86
92
  }
87
93
  };
94
+ const containerFocusClass = fullHeight2 && isFocusVisible ? focusStyleVariants({
95
+ focusStyle
96
+ }) : "";
88
97
  const getButtonClasses = () => {
89
98
  let styleVariant = "neutral";
90
99
  let emphasis = "quaternary";
@@ -96,9 +105,9 @@ const CarouselButton = ({
96
105
  const sizeClass = iconButtonStyles[size] || "";
97
106
  const emphasisClassKey = `${styleVariant}${emphasis.charAt(0).toUpperCase() + emphasis.slice(1)}`;
98
107
  const emphasisClass = iconButtonStyles[emphasisClassKey] || "";
99
- const focusClass = focusStyleVariants({
108
+ const focusClass = !fullHeight2 ? focusStyleVariants({
100
109
  focusStyle
101
- });
110
+ }) : "";
102
111
  return `${baseClass} ${sizeClass} ${emphasisClass} ${focusClass} ${buttonClassName || ""}`;
103
112
  };
104
113
  const mouseEventHandlers = isDisabled ? {} : {
@@ -107,7 +116,12 @@ const CarouselButton = ({
107
116
  onMouseDown: () => setIsPressed(true),
108
117
  onMouseUp: () => setIsPressed(false)
109
118
  };
110
- return /* @__PURE__ */ jsx(CarouselButton$1, { dir, className: `${styles.arrowContainer} ${directionClass} ${hideWhenDisabled2 ? styles.hideWhenDisabled : ""} ${variantStyleClass || ""} ${className || ""}`, ...focusProps, ...mouseEventHandlers, "data-hovered": !isDisabled && isHovered ? true : void 0, "data-pressed": !isDisabled && isPressed ? true : void 0, "data-disabled": isDisabled ? true : void 0, ref: buttonRef, children: /* @__PURE__ */ jsx("div", { className: `${getButtonClasses()} ${styles.iconButton}`, "data-focused": !isDisabled && isFocusVisible ? true : void 0, "data-parent-hovered": !isDisabled && isHovered ? true : void 0, "data-parent-pressed": !isDisabled && isPressed ? true : void 0, "data-parent-disabled": isDisabled ? true : void 0, children: /* @__PURE__ */ jsx(Icon, { iconName: `${iconType}-${dir === "prev" ? "left" : "right"}`, color: getIconColor(), iconSize: getIconSize(), "aria-hidden": "true" }) }) });
119
+ const handleClick = () => {
120
+ if (!isDisabled && onClick) {
121
+ onClick();
122
+ }
123
+ };
124
+ return /* @__PURE__ */ jsx(CarouselButton$1, { dir, className: `${styles.arrowContainer} ${directionClass} ${hideWhenDisabled2 ? styles.hideWhenDisabled : ""} ${variantStyleClass || ""} ${fullHeight2 ? styles.fullHeight : ""} ${containerFocusClass} ${className || ""}`, ...focusProps, ...mouseEventHandlers, "data-hovered": !isDisabled && isHovered ? true : void 0, "data-pressed": !isDisabled && isPressed ? true : void 0, "data-disabled": isDisabled ? true : void 0, "data-focused": fullHeight2 && !isDisabled && isFocusVisible ? true : void 0, ref: buttonRef, tabIndex: isDisabled ? -1 : void 0, onClick: handleClick, children: /* @__PURE__ */ jsx("div", { className: `${getButtonClasses()} ${styles.iconButton}`, "data-focused": !fullHeight2 && !isDisabled && isFocusVisible ? true : void 0, "data-parent-hovered": !isDisabled && isHovered ? true : void 0, "data-parent-pressed": !isDisabled && isPressed ? true : void 0, "data-parent-disabled": isDisabled ? true : void 0, children: /* @__PURE__ */ jsx(Icon, { iconName: `${iconType}-${dir === "prev" ? "left" : "right"}`, color: getIconColor(), iconSize: getIconSize(), "aria-hidden": "true" }) }) });
111
125
  };
112
126
  export {
113
127
  CarouselButton,
@@ -1 +1 @@
1
- {"version":3,"file":"CarouselButton.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"CarouselButton.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -4,12 +4,14 @@ export interface CarouselDotsProps {
4
4
  currentPage: number;
5
5
  onDotClick: (index: number) => void;
6
6
  dotSize?: 'md' | 'lg';
7
- focusStyle?: 'default' | 'white';
7
+ tabSize?: 'md' | 'lg';
8
8
  variant?: 'standard' | 'transparent';
9
+ focusStyle?: 'default' | 'white';
9
10
  className?: string;
10
11
  dotsWrapperClassName?: string;
11
12
  dotClassName?: string;
12
13
  activeDotClassName?: string;
14
+ isTransitioning?: boolean;
13
15
  }
14
16
  export declare const CarouselDots: React.FC<CarouselDotsProps>;
15
17
  export default CarouselDots;
@@ -1,18 +1,16 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { useRef, useState, useEffect, useCallback } from "react";
2
+ import { useRef } from "react";
3
3
  import { useFocusRing } from "@react-aria/focus";
4
4
  import { useHover } from "@react-aria/interactions";
5
5
  import { focusStyleVariants } from "../../../utils/focus/focusStyles.js";
6
- import '../../../assets/CarouselDots.css';const tabsContainer = "_tabsContainer_1yet6_1";
7
- const tabs = "_tabs_1yet6_1";
8
- const transparent = "_transparent_1yet6_28";
9
- const dotsScroller = "_dotsScroller_1yet6_32";
10
- const tab = "_tab_1yet6_1";
11
- const activeTab = "_activeTab_1yet6_65";
12
- const tabMd = "_tabMd_1yet6_74";
13
- const tabLg = "_tabLg_1yet6_79";
14
- const tabSizeMedium = "_tabSizeMedium_1yet6_85";
15
- const tabSizeSmall = "_tabSizeSmall_1yet6_92";
6
+ import '../../../assets/CarouselDots.css';const tabsContainer = "_tabsContainer_1rprd_1";
7
+ const tabs = "_tabs_1rprd_1";
8
+ const transparent = "_transparent_1rprd_25";
9
+ const dotsScroller = "_dotsScroller_1rprd_29";
10
+ const tab = "_tab_1rprd_1";
11
+ const activeTab = "_activeTab_1rprd_56";
12
+ const tabMd = "_tabMd_1rprd_75";
13
+ const tabLg = "_tabLg_1rprd_80";
16
14
  const styles = {
17
15
  tabsContainer,
18
16
  tabs,
@@ -21,25 +19,26 @@ const styles = {
21
19
  tab,
22
20
  activeTab,
23
21
  tabMd,
24
- tabLg,
25
- tabSizeMedium,
26
- tabSizeSmall
22
+ tabLg
27
23
  };
28
24
  const CarouselDots = ({
29
25
  totalItems,
30
26
  currentPage,
31
27
  onDotClick,
32
28
  dotSize = "md",
29
+ tabSize,
30
+ // For backward compatibility
33
31
  variant = "standard",
34
32
  focusStyle = "default",
35
33
  className = "",
36
34
  dotsWrapperClassName = "",
37
35
  dotClassName = "",
38
- activeDotClassName = ""
36
+ activeDotClassName = "",
37
+ isTransitioning = false
39
38
  }) => {
40
39
  const tabsRef = useRef(null);
41
40
  const wrapperRef = useRef(null);
42
- const effectiveDotSize = dotSize || "md";
41
+ const effectiveDotSize = dotSize || tabSize || "md";
43
42
  const {
44
43
  isFocusVisible,
45
44
  focusProps
@@ -48,21 +47,16 @@ const CarouselDots = ({
48
47
  isHovered,
49
48
  hoverProps
50
49
  } = useHover({});
51
- const [isAnimating, setIsAnimating] = useState(false);
52
- const [prevPage, setPrevPage] = useState(currentPage);
53
- const [offsetPercentage, setOffsetPercentage] = useState(0);
54
- const focusClass = focusStyleVariants({
55
- focusStyle
56
- });
57
50
  const handleKeyDown = (e) => {
51
+ if (isTransitioning) return;
58
52
  if (e.key === "ArrowRight" || e.key === "ArrowDown") {
59
53
  e.preventDefault();
60
54
  const nextPage = (currentPage + 1) % totalItems;
61
55
  onDotClick(nextPage);
62
56
  } else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
63
57
  e.preventDefault();
64
- const prevPage2 = (currentPage - 1 + totalItems) % totalItems;
65
- onDotClick(prevPage2);
58
+ const prevPage = (currentPage - 1 + totalItems) % totalItems;
59
+ onDotClick(prevPage);
66
60
  } else if (e.key === "Home") {
67
61
  e.preventDefault();
68
62
  onDotClick(0);
@@ -71,123 +65,44 @@ const CarouselDots = ({
71
65
  onDotClick(totalItems - 1);
72
66
  }
73
67
  };
74
- useEffect(() => {
75
- if (currentPage !== prevPage) {
76
- setIsAnimating(true);
77
- const direction = currentPage > prevPage ? -20 : 20;
78
- setOffsetPercentage(direction);
79
- requestAnimationFrame(() => {
80
- requestAnimationFrame(() => {
81
- setOffsetPercentage(0);
82
- });
83
- });
84
- setPrevPage(currentPage);
85
- const timer = setTimeout(() => {
86
- setIsAnimating(false);
87
- }, 600);
88
- return () => clearTimeout(timer);
89
- }
90
- }, [currentPage, prevPage]);
91
68
  const getContainerClasses = () => {
92
69
  const classes = [styles.tabsContainer];
93
70
  if (className) classes.push(className);
71
+ if (isTransitioning) classes.push(styles.transitioning);
94
72
  return classes.join(" ");
95
73
  };
96
74
  const getDotsWrapperClasses = () => {
97
75
  const classes = [styles.tabs];
98
76
  if (variant === "transparent") classes.push(styles.transparent);
99
- classes.push(focusClass);
77
+ classes.push(focusStyleVariants({
78
+ focusStyle
79
+ }));
100
80
  if (dotsWrapperClassName) classes.push(dotsWrapperClassName);
101
81
  return classes.join(" ");
102
82
  };
103
- const getDotsInfo = useCallback(() => {
104
- const VISIBLE_NORMAL_DOTS = 5;
105
- if (totalItems <= VISIBLE_NORMAL_DOTS) {
106
- return Array.from({
107
- length: totalItems
108
- }, (_, i) => ({
109
- index: i,
110
- state: "normal"
111
- }));
112
- }
113
- const dotsOnEachSide = Math.floor(VISIBLE_NORMAL_DOTS / 2);
114
- let startNormal = Math.max(0, currentPage - dotsOnEachSide);
115
- let endNormal = Math.min(totalItems - 1, startNormal + VISIBLE_NORMAL_DOTS - 1);
116
- if (endNormal >= totalItems - 1) {
117
- endNormal = totalItems - 1;
118
- startNormal = Math.max(0, endNormal - (VISIBLE_NORMAL_DOTS - 1));
119
- }
120
- const dots2 = [];
121
- if (startNormal > 1) {
122
- dots2.push({
123
- index: startNormal - 2,
124
- state: "small"
125
- });
126
- }
127
- if (startNormal > 0) {
128
- dots2.push({
129
- index: startNormal - 1,
130
- state: "medium"
131
- });
132
- }
133
- for (let i = startNormal; i <= endNormal; i++) {
134
- dots2.push({
135
- index: i,
136
- state: "normal"
137
- });
83
+ const handleDotClick = (index) => {
84
+ if (!isTransitioning) {
85
+ onDotClick(index);
138
86
  }
139
- if (endNormal < totalItems - 1) {
140
- dots2.push({
141
- index: endNormal + 1,
142
- state: "medium"
143
- });
144
- }
145
- if (endNormal < totalItems - 2) {
146
- dots2.push({
147
- index: endNormal + 2,
148
- state: "small"
149
- });
150
- }
151
- return dots2;
152
- }, [totalItems, currentPage]);
153
- const getDotClasses = (index, state) => {
154
- const classes = [styles.tab];
155
- const tabSizeClass = styles[`tab${effectiveDotSize.charAt(0).toUpperCase() + effectiveDotSize.slice(1)}`];
156
- if (tabSizeClass) classes.push(tabSizeClass);
157
- if (state === "medium") {
158
- classes.push(styles.tabSizeMedium);
159
- } else if (state === "small") {
160
- classes.push(styles.tabSizeSmall);
161
- }
162
- if (index === currentPage) {
163
- classes.push(styles.activeTab);
164
- if (activeDotClassName) classes.push(activeDotClassName);
165
- }
166
- if (dotClassName) classes.push(dotClassName);
167
- return classes.join(" ");
168
87
  };
169
- const dots = getDotsInfo();
170
- return /* @__PURE__ */ jsx("div", { className: getContainerClasses(), ref: wrapperRef, "data-animating": isAnimating ? "true" : "false", "data-direction": currentPage > prevPage ? "next" : "prev", "data-dot-size": effectiveDotSize, children: /* @__PURE__ */ jsx("div", { className: getDotsWrapperClasses(), ref: tabsRef, tabIndex: 0, role: "tablist", "aria-label": "Slide pagination", onKeyDown: handleKeyDown, "data-focused": isFocusVisible ? true : void 0, "data-hovered": isHovered ? true : void 0, ...focusProps, ...hoverProps, children: /* @__PURE__ */ jsx("div", { className: styles.dotsScroller, style: {
171
- transform: `translateX(${offsetPercentage}%)`,
172
- transition: isAnimating ? "transform 0.6s cubic-bezier(0.25, 0.1, 0.25, 1)" : "none"
173
- }, children: dots.map(({
174
- index,
175
- state
176
- }) => /* @__PURE__ */ jsx(
177
- "button",
178
- {
179
- type: "button",
180
- className: getDotClasses(index, state),
181
- onClick: () => onDotClick(index),
182
- "aria-label": `Go to slide ${index + 1}`,
183
- "aria-selected": index === currentPage,
184
- role: "tab",
185
- "data-tab-index": index,
186
- tabIndex: -1,
187
- "aria-current": index === currentPage ? "true" : "false"
188
- },
189
- index
190
- )) }) }) });
88
+ return /* @__PURE__ */ jsx("div", { className: getContainerClasses(), ref: wrapperRef, "data-dot-size": effectiveDotSize, "data-transitioning": isTransitioning ? "true" : void 0, children: /* @__PURE__ */ jsx("div", { className: getDotsWrapperClasses(), ref: tabsRef, tabIndex: 0, role: "tablist", "aria-label": "Slide pagination", onKeyDown: handleKeyDown, "data-focused": isFocusVisible ? true : void 0, "data-hovered": isHovered ? true : void 0, ...focusProps, ...hoverProps, children: /* @__PURE__ */ jsx("div", { className: styles.dotsScroller, children: Array.from({
89
+ length: totalItems
90
+ }, (_, index) => {
91
+ const baseStyle = {
92
+ width: effectiveDotSize === "lg" ? "12px" : "8px",
93
+ height: effectiveDotSize === "lg" ? "12px" : "8px",
94
+ borderRadius: "50%",
95
+ backgroundColor: index === currentPage ? "var(--alto-sem-color-fg-primary)" : "rgba(0, 0, 0, 0.3)",
96
+ border: "none",
97
+ padding: 0,
98
+ cursor: "pointer",
99
+ display: "block",
100
+ flexShrink: 0,
101
+ margin: 0,
102
+ transition: "none"
103
+ };
104
+ return /* @__PURE__ */ jsx("button", { type: "button", className: `${styles.tab} ${index === currentPage ? styles.activeTab : ""} ${dotClassName || ""} ${index === currentPage && activeDotClassName ? activeDotClassName : ""}`, onClick: () => handleDotClick(index), "aria-label": `Go to slide ${index + 1}`, "aria-selected": index === currentPage, role: "tab", "data-tab-index": index, tabIndex: -1, "aria-current": index === currentPage ? "true" : "false", disabled: isTransitioning, style: baseStyle }, index);
105
+ }) }) }) });
191
106
  };
192
107
  export {
193
108
  CarouselDots,
@@ -1 +1 @@
1
- {"version":3,"file":"CarouselDots.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"CarouselDots.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alto-avios/alto-ui",
3
- "version": "3.4.0-alpha.4",
3
+ "version": "3.4.0-alpha.6",
4
4
  "description": "A react component library for Alto Design System",
5
5
  "author": {
6
6
  "name": "Ian Caldwell IAGL",
@@ -41,7 +41,8 @@
41
41
  "react-aria-carousel": "^0.2.0",
42
42
  "react-aria-components": "^1.5.0",
43
43
  "react-number-format": "^5.4.3",
44
- "ts-node": "^10.9.2"
44
+ "ts-node": "^10.9.2",
45
+ "use-breakpoint": "^4.0.6"
45
46
  },
46
47
  "devDependencies": {
47
48
  "@chromatic-com/storybook": "^1.4.0",
@@ -72,6 +73,7 @@
72
73
  "@vitejs/plugin-react": "^4.3.1",
73
74
  "autoprefixer": "^10.4.19",
74
75
  "axe-playwright": "^2.0.3",
76
+ "chromatic": "^11.28.2",
75
77
  "commitizen": "^4.3.1",
76
78
  "cssnano": "^7.0.4",
77
79
  "eslint": "^9.14.0",
@@ -107,7 +109,7 @@
107
109
  "wait-on": "^8.0.1"
108
110
  },
109
111
  "peerDependencies": {
110
- "@alto-avios/alto-tokens": "^3.0.2",
112
+ "@alto-avios/alto-tokens": "^3.1.0",
111
113
  "react": "^18.0.0"
112
114
  },
113
115
  "main": "dist/index.js",