@alto-avios/alto-ui 5.2.0 → 5.3.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/dist/assets/BannerSectionContent.css +1 -0
- package/dist/assets/BannerSectionPlectrum.css +1 -0
- package/dist/assets/BoxLink.css +1 -0
- package/dist/assets/IntroSection.css +1 -0
- package/dist/assets/ProductTile.css +1 -0
- package/dist/components/BannerSectionContent/BannerSectionContent.d.ts +31 -0
- package/dist/components/BannerSectionContent/BannerSectionContent.js +5 -0
- package/dist/components/BannerSectionContent/BannerSectionContent.js.map +1 -0
- package/dist/components/BannerSectionContent/index.d.ts +2 -0
- package/dist/components/BannerSectionContent/index.js +2 -0
- package/dist/components/BannerSectionContent/index.js.map +1 -0
- package/dist/components/BannerSectionPlectrum/BannerSectionPlectrum.d.ts +39 -0
- package/dist/components/BannerSectionPlectrum/BannerSectionPlectrum.js +9 -0
- package/dist/components/BannerSectionPlectrum/BannerSectionPlectrum.js.map +1 -0
- package/dist/components/BannerSectionPlectrum/index.d.ts +2 -0
- package/dist/components/BannerSectionPlectrum/index.js +2 -0
- package/dist/components/BannerSectionPlectrum/index.js.map +1 -0
- package/dist/components/BoxLink/BoxLink.d.ts +52 -0
- package/dist/components/BoxLink/BoxLink.js +3 -0
- package/dist/components/BoxLink/BoxLink.js.map +1 -0
- package/dist/components/BoxLink/BoxLinkContext.d.ts +24 -0
- package/dist/components/BoxLink/BoxLinkContext.js +2 -0
- package/dist/components/BoxLink/BoxLinkContext.js.map +1 -0
- package/dist/components/BoxLink/index.d.ts +4 -0
- package/dist/components/BoxLink/index.js +2 -0
- package/dist/components/BoxLink/index.js.map +1 -0
- package/dist/components/Button/Button.d.ts +1 -1
- package/dist/components/Carousel/Carousel.d.ts +8 -1
- package/dist/components/Carousel/Carousel.js +7 -7
- package/dist/components/Carousel/Carousel.js.map +1 -1
- package/dist/components/IntroSection/IntroSection.d.ts +42 -0
- package/dist/components/IntroSection/IntroSection.js +4 -0
- package/dist/components/IntroSection/IntroSection.js.map +1 -0
- package/dist/components/IntroSection/index.d.ts +2 -0
- package/dist/components/IntroSection/index.js +2 -0
- package/dist/components/IntroSection/index.js.map +1 -0
- package/dist/components/Menu/Menu.d.ts +4 -4
- package/dist/components/ProductTile/ProductTile.d.ts +51 -0
- package/dist/components/ProductTile/ProductTile.js +7 -0
- package/dist/components/ProductTile/ProductTile.js.map +1 -0
- package/dist/components/ProductTile/index.d.ts +2 -0
- package/dist/components/ProductTile/index.js +2 -0
- package/dist/components/ProductTile/index.js.map +1 -0
- package/dist/components/index.d.ts +12 -2
- package/dist/components/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/utils/stories/DraggableContainer.js +7 -7
- package/dist/utils/stories/DraggableContainer.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._bannerSectionContent_1196e_1,._bannerSectionContent__content_1196e_7{align-items:flex-start;display:flex;flex-direction:column}._bannerSectionContent__content_1196e_7{gap:var(--alto-sem-space-2xs)}._bannerSectionContent__content_1196e_7:has(+._bannerSectionContent__end-slot_1196e_14){padding-bottom:var(--alto-grid-gutter-default)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._banner-section-plectrum_148yy_1{display:flex;justify-content:center;padding-block:var(--alto-section-padding-vertical-default);width:100%}@media(min-width:1024px){._banner-section-plectrum_148yy_1{height:568px;padding-inline:var(--alto-sem-space-lg)}}@media(min-width:1920px){._banner-section-plectrum_148yy_1{padding-inline:var(--alto-section-padding-vertical-default)}}._banner-section-plectrum__inner_148yy_22{box-sizing:border-box;display:flex;flex-direction:column;gap:var(--alto-sem-space-sm);height:100%;overflow:hidden;position:relative;width:100%}._banner-section-plectrum__inner--is-mobile-reversed_148yy_33{flex-direction:column-reverse}@media(min-width:1024px){._banner-section-plectrum__inner_148yy_22{background-color:var(--alto-sem-color-bg-layer1-default);border-radius:var(--alto-card-radius);flex-direction:row;padding-inline:var(--alto-sem-space-4xl)}._banner-section-plectrum__inner--is-mobile-reversed_148yy_33{flex-direction:row}}@media(min-width:1920px){._banner-section-plectrum__inner_148yy_22{max-width:calc(1920px - var(--alto-section-padding-vertical-default)*2)}}._banner-section-plectrum__content-wrapper_148yy_59{padding:var(--alto-sem-space-sm) var(--alto-section-padding-horizontal-default);position:relative;z-index:2}@media(min-width:1024px){._banner-section-plectrum__content-wrapper_148yy_59{display:grid;gap:var(--alto-sem-space-md);grid-template-columns:1fr 1fr;margin:auto;max-width:var(--alto-section-container-max-width);padding:0}}._banner-section-plectrum__media-wrapper_148yy_78{position:relative}@media(min-width:1024px){._banner-section-plectrum__media-wrapper_148yy_78{height:100%;left:0;position:absolute;top:0;width:100%;z-index:1}}._banner-section-plectrum-media_148yy_93{display:flex;position:relative;width:100%}@media(min-width:1024px){._banner-section-plectrum-media_148yy_93{height:100%;overflow:hidden;position:absolute;right:0;top:0;width:calc(50% - 44px);z-index:1}}._banner-section-plectrum-media__image_148yy_111{aspect-ratio:1;background-color:var(--alto-sem-color-bg-base);border:1px solid var(--alto-sem-color-bg-base);display:flex;width:100%}._banner-section-plectrum-media__image_148yy_111 img{height:100%;-o-object-fit:cover;object-fit:cover;width:100%}@media(min-width:480px){._banner-section-plectrum-media__image_148yy_111{aspect-ratio:5/4}}@media(min-width:768px){._banner-section-plectrum-media__image_148yy_111{aspect-ratio:3/2}}@media(min-width:1024px){._banner-section-plectrum-media__image_148yy_111{aspect-ratio:unset;background-color:var(--alto-sem-color-bg-layer1-default);border:1px solid var(--alto-sem-color-bg-layer1-default);height:100%}}._banner-section-plectrum-media__plectrum-overlay_148yy_145{left:-9.6%;position:absolute;top:0;width:150%}._banner-section-plectrum-media__plectrum-overlay_148yy_145 path{fill:var(--alto-sem-color-bg-base)}@media(min-width:1024px){._banner-section-plectrum-media__plectrum-overlay_148yy_145{left:0;min-width:800px;top:0;width:167%}._banner-section-plectrum-media__plectrum-overlay_148yy_145 path{fill:var(--alto-sem-color-bg-layer1-default)}._banner-section-plectrum-media__plectrum-overlay--plectrum-variant-sharkfin_148yy_168{top:0}._banner-section-plectrum-media__plectrum-overlay--plectrum-variant-sharktooth_148yy_172{bottom:-1px;top:unset}}._banner-section-plectrum-media__pictocard-wrapper_148yy_178{bottom:0;max-width:calc(100% - var(--alto-grid-gutter-default)*2);padding:var(--alto-grid-gutter-default);position:absolute;right:0;z-index:1}._banner-section-plectrum_148yy_1 [data-alto-box-link]{width:100%}@media(max-width:479px){._banner-section-plectrum_148yy_1 [data-alto-box-link]>div>div{max-width:calc(100% - var(--alto-grid-gutter-default)*2)}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._box-link_jbtzi_1,[data-alto-box-link]{--alto-boxlink-transition:.3s cubic-bezier(.5,0,.23,1);display:inline-block;text-decoration:none}._box-link--default_jbtzi_8{background-color:var(--alto-sem-color-bg-layer2-default);border:var(--alto-sem-border-width-sm) solid var(--alto-sem-color-border-secondary);border-radius:var(--alto-card-radius);outline-offset:-1px;transition:background-color var(--alto-boxlink-transition),outline-color var(--alto-boxlink-transition),transform var(--alto-boxlink-transition)}._box-link--default_jbtzi_8[data-hovered]{background-color:var(--alto-sem-color-bg-layer2-hover);outline:var(--alto-sem-border-width-md) solid var(--alto-sem-color-border-accent);transform:translateY(-1px)}._box-link--default_jbtzi_8[data-pressed]{background-color:var(--alto-sem-color-bg-layer2-active);outline:var(--alto-sem-border-width-md) solid var(--alto-sem-color-border-accent);transform:translateY(0)}._box-link--default_jbtzi_8[data-focused]{outline-offset:var(--alto-sem-border-width-md);outline-style:solid;outline-width:var(--alto-sem-border-width-md)}._box-link--default_jbtzi_8[data-focused],._box-link--default_jbtzi_8[data-selected]{background-color:var(--alto-sem-color-bg-layer2-hover);border-radius:var(--alto-sem-radius-sm);transform:translateY(-1px)}._box-link--default_jbtzi_8[data-selected]{outline:var(--alto-sem-border-width-md) solid var(--alto-sem-color-border-accent)}._box-link--underline-heading-on-hover_jbtzi_53[data-hovered] h2,._box-link--underline-heading-on-hover_jbtzi_53[data-hovered] h3,._box-link--underline-heading-on-hover_jbtzi_53[data-hovered] h4,._box-link--underline-heading-on-hover_jbtzi_53[data-hovered] h5,._box-link--underline-heading-on-hover_jbtzi_53[data-hovered] h6{-webkit-text-decoration:var(--alto-sem-text-body-link-text-decoration);text-decoration:var(--alto-sem-text-body-link-text-decoration)}._box-link--disabled_jbtzi_61,._box-link_jbtzi_1[aria-disabled=true]{opacity:.5;pointer-events:none}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._intro-section_187d3_1{--intro-section-text-align-base-current:var( --intro-section-text-align-base,start );--intro-section-text-align-current:var( --intro-section-text-align-base-current );text-align:var(--intro-section-text-align-current)}._intro-section__header_187d3_13{display:flex;flex-direction:column;width:100%}._intro-section__actions_187d3_20,._intro-section__header_187d3_13{text-align:var(--intro-section-text-align-current)}._intro-section__actions_187d3_20{--intro-section-actions-text-align-base-current:var( --intro-section-actions-text-align-base,var(--intro-section-text-align-current) );--intro-section-actions-text-align-current:var( --intro-section-actions-text-align-base-current );text-align:var(--intro-section-actions-text-align-current)}._intro-section__heading_187d3_36{margin:0 0 var(--alto-sem-space-4xs);text-align:inherit}._intro-section__subheading_187d3_41{text-align:inherit}._intro-section__heading_187d3_36>*{margin:0;text-align:inherit}._intro-section__subheading_187d3_41>*{text-align:inherit}._intro-section__start-slot_187d3_54{margin-bottom:var(--alto-sem-space-xs);order:-1}._intro-section__end-slot_187d3_61,._intro-section__start-slot_187d3_54{display:flex;justify-content:var(--intro-section-text-align-current)}._intro-section__actions_187d3_20,._intro-section__end-slot_187d3_61{margin-top:var(--alto-sem-space-xs)}@media(min-width:480px){._intro-section_187d3_1{--intro-section-text-align-sm-current:var( --intro-section-text-align-sm,var(--intro-section-text-align-base-current) );--intro-section-text-align-current:var( --intro-section-text-align-sm-current )}._intro-section__actions_187d3_20{--intro-section-actions-text-align-sm-current:var( --intro-section-actions-text-align-sm,var(--intro-section-actions-text-align-base-current) );--intro-section-actions-text-align-current:var( --intro-section-actions-text-align-sm-current )}}@media(min-width:768px){._intro-section_187d3_1{--intro-section-text-align-md-current:var( --intro-section-text-align-md,var(--intro-section-text-align-sm-current) );--intro-section-text-align-current:var( --intro-section-text-align-md-current )}._intro-section__actions_187d3_20{--intro-section-actions-text-align-md-current:var( --intro-section-actions-text-align-md,var(--intro-section-actions-text-align-sm-current) );--intro-section-actions-text-align-current:var( --intro-section-actions-text-align-md-current )}}@media(min-width:1024px){._intro-section_187d3_1{--intro-section-text-align-lg-current:var( --intro-section-text-align-lg,var(--intro-section-text-align-md-current) );--intro-section-text-align-current:var( --intro-section-text-align-lg-current )}._intro-section__actions_187d3_20{--intro-section-actions-text-align-lg-current:var( --intro-section-actions-text-align-lg,var(--intro-section-actions-text-align-md-current) );--intro-section-actions-text-align-current:var( --intro-section-actions-text-align-lg-current )}}@media(min-width:1440px){._intro-section_187d3_1{--intro-section-text-align-xl-current:var( --intro-section-text-align-xl,var(--intro-section-text-align-lg-current) );--intro-section-text-align-current:var( --intro-section-text-align-xl-current )}._intro-section__actions_187d3_20{--intro-section-actions-text-align-xl-current:var( --intro-section-actions-text-align-xl,var(--intro-section-actions-text-align-lg-current) );--intro-section-actions-text-align-current:var( --intro-section-actions-text-align-xl-current )}}@media(min-width:1920px){._intro-section_187d3_1{--intro-section-text-align-xxl-current:var( --intro-section-text-align-xxl,var(--intro-section-text-align-xl-current) );--intro-section-text-align-current:var( --intro-section-text-align-xxl-current )}._intro-section__actions_187d3_20{--intro-section-actions-text-align-xxl-current:var( --intro-section-actions-text-align-xxl,var(--intro-section-actions-text-align-xl-current) );--intro-section-actions-text-align-current:var( --intro-section-actions-text-align-xxl-current )}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._product-tile_zcaft_1{display:flex;flex-direction:column}._product-tile__media_zcaft_6{flex-shrink:0;height:64px;width:64px}._product-tile__content_zcaft_12{display:flex;flex:1;flex-direction:column;min-width:0}._product-tile__content-details_zcaft_19{align-items:flex-start;display:flex;flex-direction:column;margin-top:var(--alto-sem-space-4xs)}._product-tile__content-icon_zcaft_26{flex-shrink:0;transition:var(--alto-boxlink-transition)}[data-alto-box-link][data-focused]:has(._product-tile_zcaft_1),[data-alto-box-link][data-hovered]:has(._product-tile_zcaft_1),[data-alto-box-link][data-pressed]:has(._product-tile_zcaft_1){transform:translateY(0)}[data-alto-box-link][data-focused] ._product-tile__content-title_zcaft_38 p,[data-alto-box-link][data-hovered] ._product-tile__content-title_zcaft_38 p,[data-alto-box-link][data-pressed] ._product-tile__content-title_zcaft_38 p{-webkit-text-decoration:var(--alto-sem-text-body-link-text-decoration);text-decoration:var(--alto-sem-text-body-link-text-decoration)}[data-alto-box-link][data-focused] ._product-tile__content-icon_zcaft_26,[data-alto-box-link][data-hovered] ._product-tile__content-icon_zcaft_26,[data-alto-box-link][data-pressed] ._product-tile__content-icon_zcaft_26{transform:translate(4px)}[dir=rtl] [data-alto-box-link] ._product-tile__content-icon_zcaft_26{transform:rotate(180deg)}[dir=rtl] [data-alto-box-link][data-focused] ._product-tile__content-icon_zcaft_26,[dir=rtl] [data-alto-box-link][data-hovered] ._product-tile__content-icon_zcaft_26,[dir=rtl] [data-alto-box-link][data-pressed] ._product-tile__content-icon_zcaft_26{transform:translate(-4px) rotate(180deg)}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { default as React, HTMLAttributes } from 'react';
|
|
2
|
+
export interface BannerSectionContentProps extends Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style'> {
|
|
3
|
+
/**
|
|
4
|
+
* Text displayed in heading. Renders as an `h2`
|
|
5
|
+
*/
|
|
6
|
+
title: string;
|
|
7
|
+
/**
|
|
8
|
+
* Text displayed in subheading. Renders as an `h3`
|
|
9
|
+
*/
|
|
10
|
+
subtitle?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Content displayed below the title
|
|
13
|
+
*/
|
|
14
|
+
description?: React.ReactNode;
|
|
15
|
+
/**
|
|
16
|
+
* Changes the colour of the `title` and `description` for placement on light or dark backgrounds
|
|
17
|
+
*
|
|
18
|
+
* @default 'onLight'
|
|
19
|
+
*/
|
|
20
|
+
styleVariant?: 'onLight' | 'onDark';
|
|
21
|
+
/**
|
|
22
|
+
* Content displayed above the title
|
|
23
|
+
*/
|
|
24
|
+
startSlot?: React.ReactNode;
|
|
25
|
+
/**
|
|
26
|
+
* Content displayed below the description
|
|
27
|
+
*/
|
|
28
|
+
endSlot?: React.ReactNode;
|
|
29
|
+
}
|
|
30
|
+
export declare const BannerSectionContent: React.ForwardRefExoticComponent<BannerSectionContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
31
|
+
export default BannerSectionContent;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{jsxs as e,jsx as r}from"react/jsx-runtime";import{forwardRef as n}from"react";import{Heading as t}from"../Heading/Heading.js";import{Paragraph as o}from"../Paragraph/Paragraph.js";import{SubHeading as a}from"../SubHeading/SubHeading.js";import '../../assets/BannerSectionContent.css';const i="_bannerSectionContent_1196e_1",d="_bannerSectionContent__content_1196e_7",c="_bannerSectionContent__end-slot_1196e_14",s=n(({title:n,subtitle:s,description:l,styleVariant:m="onLight",startSlot:h,endSlot:g,..._},f)=>{const p="onLight"===m;/* @__PURE__ */
|
|
2
|
+
return e("div",{..._,className:i,"data-on-light":p||void 0,"data-on-dark":!p||void 0,ref:f,children:[
|
|
3
|
+
/* @__PURE__ */e("div",{className:d,children:[h,
|
|
4
|
+
/* @__PURE__ */r(t,{as:"h2",size:"lg",foregroundColor:p?"accentSecondary":"whitePrimary",children:n}),s&&/* @__PURE__ */r(a,{as:"h3",size:"xs",foregroundColor:p?"accentSecondary":"whitePrimary",children:s}),l&&/* @__PURE__ */r(o,{size:"lg",foregroundColor:p?"secondary":"whitePrimary",children:l})]}),g&&/* @__PURE__ */r("div",{className:c,children:g})]})});s.displayName="BannerSectionContent";export{s as BannerSectionContent,s as default};
|
|
5
|
+
//# sourceMappingURL=BannerSectionContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BannerSectionContent.js","sources":["../../../src/components/BannerSectionContent/BannerSectionContent.tsx"],"sourcesContent":["import React, { forwardRef, HTMLAttributes } from 'react';\nimport Heading from '../Heading';\nimport Paragraph from '../Paragraph';\n\nimport styles from './BannerSectionContent.module.css';\nimport SubHeading from '../SubHeading';\n\nexport interface BannerSectionContentProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style'> {\n /**\n * Text displayed in heading. Renders as an `h2`\n */\n title: string;\n /**\n * Text displayed in subheading. Renders as an `h3`\n */\n subtitle?: string;\n /**\n * Content displayed below the title\n */\n description?: React.ReactNode;\n /**\n * Changes the colour of the `title` and `description` for placement on light or dark backgrounds\n *\n * @default 'onLight'\n */\n styleVariant?: 'onLight' | 'onDark';\n /**\n * Content displayed above the title\n */\n startSlot?: React.ReactNode;\n /**\n * Content displayed below the description\n */\n endSlot?: React.ReactNode;\n}\n\nexport const BannerSectionContent = forwardRef<\n HTMLDivElement,\n BannerSectionContentProps\n>(\n (\n {\n title,\n subtitle,\n description,\n styleVariant = 'onLight',\n startSlot,\n endSlot,\n ...props\n },\n forwardedRef,\n ) => {\n const isOnLight = styleVariant === 'onLight';\n\n return (\n <div\n {...props}\n className={styles['bannerSectionContent']}\n data-on-light={isOnLight || undefined}\n data-on-dark={!isOnLight || undefined}\n ref={forwardedRef}\n >\n <div className={styles['bannerSectionContent__content']}>\n {startSlot}\n <Heading\n as=\"h2\"\n size=\"lg\"\n foregroundColor={isOnLight ? 'accentSecondary' : 'whitePrimary'}\n >\n {title}\n </Heading>\n {subtitle && (\n <SubHeading\n as=\"h3\"\n size=\"xs\"\n foregroundColor={isOnLight ? 'accentSecondary' : 'whitePrimary'}\n >\n {subtitle}\n </SubHeading>\n )}\n {description && (\n <Paragraph\n size=\"lg\"\n foregroundColor={isOnLight ? 'secondary' : 'whitePrimary'}\n >\n {description}\n </Paragraph>\n )}\n </div>\n {endSlot && (\n <div className={styles['bannerSectionContent__end-slot']}>\n {endSlot}\n </div>\n )}\n </div>\n );\n },\n);\nBannerSectionContent.displayName = 'BannerSectionContent';\n\nexport default BannerSectionContent;\n"],"names":["BannerSectionContent","forwardRef","title","subtitle","description","styleVariant","startSlot","endSlot","props","forwardedRef","isOnLight","jsxs","className","styles","ref","children","jsx","Heading","as","size","foregroundColor","SubHeading","Paragraph","displayName"],"mappings":"oXAqCaA,EAAuBC,EAIlC,EAEIC,QACAC,WACAC,cACAC,eAAe,UACfC,YACAC,aACGC,GAELC,KAEA,MAAMC,EAA6B,YAAjBL;AAElB,OACEM,EAAC,MAAA,IACKH,EACJI,UAAWC,EACX,gBAAeH,QAAa,EAC5B,gBAAeA,QAAa,EAC5BI,IAAKL,EAELM,SAAA;iBAAC,MAAA,CAAIH,UAAWC,EACbE,SAAA,CAAAT;eACDU,EAACC,EAAA,CACCC,GAAG,KACHC,KAAK,KACLC,gBAAiBV,EAAY,kBAAoB,eAEhDK,SAAAb,IAEFC,kBACCa,EAACK,EAAA,CACCH,GAAG,KACHC,KAAK,KACLC,gBAAiBV,EAAY,kBAAoB,eAEhDK,SAAAZ,IAGJC,kBACCY,EAACM,EAAA,CACCH,KAAK,KACLC,gBAAiBV,EAAY,YAAc,eAE1CK,SAAAX,OAING,kBACCS,EAAC,MAAA,CAAIJ,UAAWC,EACbE,SAAAR,SAObP,EAAqBuB,YAAc"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { default as React, HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { default as BannerSectionContent } from '../BannerSectionContent';
|
|
3
|
+
import { ResponsiveValue } from '../../utils/breakpoint/responsiveSSR';
|
|
4
|
+
export interface BannerSectionPlectrumMediaProps extends Omit<HTMLAttributes<HTMLDivElement>, 'classname' | 'styles'> {
|
|
5
|
+
/**
|
|
6
|
+
* Element positioned on top on the media in the bottom right corner
|
|
7
|
+
*/
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
/**
|
|
10
|
+
* Style of the plectrum overlay
|
|
11
|
+
* @default 'sharktooth'
|
|
12
|
+
*/
|
|
13
|
+
plectrumVariant?: 'sharktooth' | 'sharkfin';
|
|
14
|
+
/**
|
|
15
|
+
* **[Responsive]** Media source, recommended aspect ratio: 3:2.
|
|
16
|
+
* Responsive image sources are useful when art directing.
|
|
17
|
+
*/
|
|
18
|
+
src: string | ResponsiveValue<string>;
|
|
19
|
+
}
|
|
20
|
+
export declare const BannerSectionPlectrumMedia: {
|
|
21
|
+
({ children, plectrumVariant, src, ...rest }: BannerSectionPlectrumMediaProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
displayName: string;
|
|
23
|
+
};
|
|
24
|
+
export interface BannerSectionPlectrumProps extends Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style'> {
|
|
25
|
+
/**
|
|
26
|
+
* Content displayed in the banner section. Expects `BannerSectionPlectrum.Content`, `BannerSectionPlectrum.Media`
|
|
27
|
+
*/
|
|
28
|
+
children?: React.ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Reverses layout order of Media and Content on screens below lg breakpoint (1024px)
|
|
31
|
+
*/
|
|
32
|
+
isMobileReversed?: boolean;
|
|
33
|
+
}
|
|
34
|
+
interface BannerSectionPlectrumComponent extends React.ForwardRefExoticComponent<BannerSectionPlectrumProps & React.RefAttributes<HTMLElement>> {
|
|
35
|
+
Content: typeof BannerSectionContent;
|
|
36
|
+
Media: typeof BannerSectionPlectrumMedia;
|
|
37
|
+
}
|
|
38
|
+
export declare const BannerSectionPlectrum: BannerSectionPlectrumComponent;
|
|
39
|
+
export default BannerSectionPlectrum;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{jsx as e,jsxs as r}from"react/jsx-runtime";import t,{forwardRef as n,useMemo as a}from"react";import{BannerSectionContent as i}from"../BannerSectionContent/BannerSectionContent.js";import{c}from"../../index-CCUt_dAN.js";import{getBaseValueOrUndefined as s}from"../../utils/breakpoint/responsiveSSR.js";import{BREAKPOINTS as m}from"../../utils/breakpoint/theme/breakpoints.js";import '../../assets/BannerSectionPlectrum.css';const o="_banner-section-plectrum_148yy_1",l="_banner-section-plectrum__inner_148yy_22",d="_banner-section-plectrum__inner--is-mobile-reversed_148yy_33",p="_banner-section-plectrum__content-wrapper_148yy_59",_="_banner-section-plectrum__media-wrapper_148yy_78",u="_banner-section-plectrum-media_148yy_93",y="_banner-section-plectrum-media__image_148yy_111",b="_banner-section-plectrum-media__pictocard-wrapper_148yy_178",h=c("_banner-section-plectrum-media__plectrum-overlay_148yy_145",{variants:{plectrumVariant:{sharkfin:"_banner-section-plectrum-media__plectrum-overlay--plectrum-variant-sharkfin_148yy_168",sharktooth:"_banner-section-plectrum-media__plectrum-overlay--plectrum-variant-sharktooth_148yy_172"}}}),v=({children:t,plectrumVariant:n="sharkfin",src:a,...i})=>{const c=s(a);/* @__PURE__ */
|
|
2
|
+
return r("div",{className:u,...i,children:[
|
|
3
|
+
/* @__PURE__ */r("picture",{className:y,children:["object"==typeof a&&Object.entries(m).toSorted((e,r)=>r[1]-e[1]).map(r=>{const[t,n]=r;return"base"!==t&&a[t]?/* @__PURE__ */e("source",{"data-testid":`banner-section-plectrum-media-source-${t}`,media:`(min-width: ${n}px)`,srcSet:a[t]},t):null}),
|
|
4
|
+
/* @__PURE__ */e("img",{src:c,"data-testid":"banner-section-plectrum-media-image",alt:""})]}),
|
|
5
|
+
/* @__PURE__ */e("svg",{role:"img","aria-hidden":!0,"data-testid":"banner-section-plectrum-media-plectrum-overlay",viewBox:"0 0 1677 1677",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:h({plectrumVariant:n}),children:/* @__PURE__ */e("path",{d:"M1676.67 1676.67H0V0L1676.67 0V1676.67ZM353.326 1.11555C283.916 -3.42414 215.25 35.7074 187.301 95.9813C56.3545 378.22 -103.769 1008.64 126.585 1581.16C150.857 1641.51 202.026 1675.72 266.001 1675.72C273.616 1675.72 281.408 1675.24 289.351 1674.25C1078.71 1576.78 1578.79 1020.94 1649.94 872.37C1678.62 812.449 1689.71 758.544 1650.58 690.268C1597.01 596.788 1031.47 43.8853 353.326 1.11555Z"})}),t&&/* @__PURE__ */e("div",{className:b,children:t})]})},f=c(l,{variants:{isMobileReversed:{true:d,false:null}}}),C=n(({isMobileReversed:n,children:c,...s},m)=>{const l=t.Children.toArray(c),d=a(()=>l.find(e=>e.type===i),l),u=a(()=>l.find(e=>e.type===v),l);/* @__PURE__ */
|
|
6
|
+
return e("section",{className:o,ref:m,...s,children:/* @__PURE__ */r("div",{className:f({isMobileReversed:n}),children:[
|
|
7
|
+
/* @__PURE__ */e("div",{className:p,children:d}),
|
|
8
|
+
/* @__PURE__ */e("div",{className:_,children:u})]})})});C.displayName="BannerSectionPlectrum",i.displayName="BannerSectionPlectrum.Content",C.Content=i,v.displayName="BannerSectionPlectrum.Media",C.Media=v;export{C as BannerSectionPlectrum,v as BannerSectionPlectrumMedia,C as default};
|
|
9
|
+
//# sourceMappingURL=BannerSectionPlectrum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BannerSectionPlectrum.js","sources":["../../../src/components/BannerSectionPlectrum/BannerSectionPlectrum.tsx"],"sourcesContent":["import React, {\n HTMLAttributes,\n ReactElement,\n ReactNode,\n forwardRef,\n useMemo,\n} from 'react';\nimport styles from './BannerSectionPlectrum.module.css';\nimport BannerSectionContent, {\n BannerSectionContentProps,\n} from '../BannerSectionContent';\nimport { cva } from 'class-variance-authority';\nimport {\n getBaseValueOrUndefined,\n ResponsiveValue,\n} from '../../utils/breakpoint/responsiveSSR';\nimport { Breakpoint, BREAKPOINTS } from '../../utils';\n\n// Define `src` explicity with `ResponsiveValue` instead of using `WithResponsiveKeys` to fix the prop disappearing in Storybook sub-components section\nexport interface BannerSectionPlectrumMediaProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'classname' | 'styles'> {\n /**\n * Element positioned on top on the media in the bottom right corner\n */\n children?: ReactNode;\n /**\n * Style of the plectrum overlay\n * @default 'sharktooth'\n */\n plectrumVariant?: 'sharktooth' | 'sharkfin';\n /**\n * **[Responsive]** Media source, recommended aspect ratio: 3:2.\n * Responsive image sources are useful when art directing.\n */\n src: string | ResponsiveValue<string>;\n}\n\nconst plectrumOverlay = cva(\n styles['banner-section-plectrum-media__plectrum-overlay'],\n {\n variants: {\n plectrumVariant: {\n sharkfin:\n styles[\n 'banner-section-plectrum-media__plectrum-overlay--plectrum-variant-sharkfin'\n ],\n sharktooth:\n styles[\n 'banner-section-plectrum-media__plectrum-overlay--plectrum-variant-sharktooth'\n ],\n },\n },\n },\n);\n\nexport const BannerSectionPlectrumMedia = ({\n children,\n plectrumVariant = 'sharkfin',\n src,\n ...rest\n}: BannerSectionPlectrumMediaProps) => {\n const baseSrc = getBaseValueOrUndefined(src);\n\n return (\n <div className={styles['banner-section-plectrum-media']} {...rest}>\n {/* Media element */}\n <picture className={styles['banner-section-plectrum-media__image']}>\n {typeof src === 'object' &&\n Object.entries(BREAKPOINTS)\n .toSorted((a, b) => b[1] - a[1]) // `source` breakpoints need to be rendered in the correct order, largest to smallest\n .map((bp) => {\n const [breakpoint, minWidth] = bp;\n if (breakpoint === 'base' || !src[breakpoint as Breakpoint])\n return null;\n\n return (\n <source\n key={breakpoint}\n data-testid={`banner-section-plectrum-media-source-${breakpoint}`}\n media={`(min-width: ${minWidth}px)`}\n srcSet={src[breakpoint as Breakpoint]}\n />\n );\n })}\n <img\n src={baseSrc}\n data-testid=\"banner-section-plectrum-media-image\"\n alt=\"\"\n />\n </picture>\n {/* Plectrum cutout overlay element */}\n <svg\n role=\"img\" // Role for purely visual svg elements\n aria-hidden\n data-testid=\"banner-section-plectrum-media-plectrum-overlay\"\n viewBox=\"0 0 1677 1677\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={plectrumOverlay({ plectrumVariant })}\n >\n <path d=\"M1676.67 1676.67H0V0L1676.67 0V1676.67ZM353.326 1.11555C283.916 -3.42414 215.25 35.7074 187.301 95.9813C56.3545 378.22 -103.769 1008.64 126.585 1581.16C150.857 1641.51 202.026 1675.72 266.001 1675.72C273.616 1675.72 281.408 1675.24 289.351 1674.25C1078.71 1576.78 1578.79 1020.94 1649.94 872.37C1678.62 812.449 1689.71 758.544 1650.58 690.268C1597.01 596.788 1031.47 43.8853 353.326 1.11555Z\" />\n </svg>\n {children && (\n <div\n className={styles['banner-section-plectrum-media__pictocard-wrapper']}\n >\n {children}\n </div>\n )}\n </div>\n );\n};\n\nexport interface BannerSectionPlectrumProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style'> {\n /**\n * Content displayed in the banner section. Expects `BannerSectionPlectrum.Content`, `BannerSectionPlectrum.Media`\n */\n children?: React.ReactNode;\n /**\n * Reverses layout order of Media and Content on screens below lg breakpoint (1024px)\n */\n isMobileReversed?: boolean;\n}\n\ninterface BannerSectionPlectrumComponent\n extends React.ForwardRefExoticComponent<\n BannerSectionPlectrumProps & React.RefAttributes<HTMLElement>\n > {\n Content: typeof BannerSectionContent;\n Media: typeof BannerSectionPlectrumMedia;\n}\n\nconst bannerSectionPlectrumInner = cva(\n styles['banner-section-plectrum__inner'],\n {\n variants: {\n isMobileReversed: {\n true: styles['banner-section-plectrum__inner--is-mobile-reversed'],\n false: null,\n },\n },\n },\n);\n\nexport const BannerSectionPlectrum = forwardRef<\n HTMLDivElement,\n BannerSectionPlectrumProps\n>(({ isMobileReversed, children, ...rest }, forwardedRef) => {\n /**\n * Media\n */\n const childComponents = React.Children.toArray(children);\n\n const content = useMemo(() => {\n return childComponents.find(\n (child) =>\n (child as ReactElement<BannerSectionContentProps>).type ===\n BannerSectionContent,\n );\n }, childComponents);\n\n const media = useMemo(() => {\n return childComponents.find(\n (child) =>\n (child as ReactElement<BannerSectionPlectrumMediaProps>).type ===\n BannerSectionPlectrumMedia,\n );\n }, childComponents);\n\n return (\n <section\n className={styles['banner-section-plectrum']}\n ref={forwardedRef}\n {...rest}\n >\n <div className={bannerSectionPlectrumInner({ isMobileReversed })}>\n <div className={styles['banner-section-plectrum__content-wrapper']}>\n {content}\n </div>\n <div className={styles['banner-section-plectrum__media-wrapper']}>\n {media}\n </div>\n </div>\n </section>\n );\n}) as BannerSectionPlectrumComponent;\nBannerSectionPlectrum.displayName = 'BannerSectionPlectrum';\n\nBannerSectionContent.displayName = 'BannerSectionPlectrum.Content';\nBannerSectionPlectrum.Content = BannerSectionContent;\n\nBannerSectionPlectrumMedia.displayName = 'BannerSectionPlectrum.Media';\nBannerSectionPlectrum.Media = BannerSectionPlectrumMedia;\n\nexport default BannerSectionPlectrum;\n"],"names":["plectrumOverlay","cva","variants","plectrumVariant","sharkfin","sharktooth","BannerSectionPlectrumMedia","children","src","rest","baseSrc","getBaseValueOrUndefined","className","styles","Object","entries","BREAKPOINTS","toSorted","a","b","map","bp","breakpoint","minWidth","jsx","media","srcSet","alt","role","viewBox","fill","xmlns","d","bannerSectionPlectrumInner","isMobileReversed","true","false","BannerSectionPlectrum","forwardRef","forwardedRef","childComponents","React","Children","toArray","content","useMemo","find","child","type","BannerSectionContent","ref","displayName","Content","Media"],"mappings":"oyBAqCMA,EAAkBC,+DAEtB,CACEC,SAAU,CACRC,gBAAiB,CACfC,iGAIAC,yGASKC,EAA6B,EACxCC,WACAJ,kBAAkB,WAClBK,SACGC,MAEH,MAAMC,EAAUC,EAAwBH;AAExC,SACG,MAAA,CAAII,UAAWC,KAA6CJ,EAE3DF,SAAA;iBAAC,UAAA,CAAQK,UAAWC,EACjBN,SAAA,CAAe,iBAARC,GACNM,OAAOC,QAAQC,GACZC,SAAS,CAACC,EAAGC,IAAMA,EAAE,GAAKD,EAAE,IAC5BE,IAAKC,IACJ,MAAOC,EAAYC,GAAYF,EAC/B,MAAmB,SAAfC,GAA0Bd,EAAIc,kBAIhCE,EAAC,SAAA,CAEC,cAAa,wCAAwCF,IACrDG,MAAO,eAAeF,OACtBG,OAAQlB,EAAIc,IAHPA,GAJA;eAWfE,EAAC,MAAA,CACChB,IAAKE,EACL,cAAY,sCACZiB,IAAI;eAIRH,EAAC,MAAA,CACCI,KAAK,MACL,eAAW,EACX,cAAY,iDACZC,QAAQ,gBACRC,KAAK,OACLC,MAAM,6BACNnB,UAAWZ,EAAgB,CAAEG,oBAE7BI,wBAAAiB,EAAC,OAAA,CAAKQ,EAAE,8YAETzB,kBACCiB,EAAC,MAAA,CACCZ,UAAWC,EAEVN,iBA2BL0B,EAA6BhC,EACjCY,EACA,CACEX,SAAU,CACRgC,iBAAkB,CAChBC,KAAMtB,EACNuB,MAAO,SAMFC,EAAwBC,EAGnC,EAAGJ,mBAAkB3B,cAAaE,GAAQ8B,KAI1C,MAAMC,EAAkBC,EAAMC,SAASC,QAAQpC,GAEzCqC,EAAUC,EAAQ,IACfL,EAAgBM,KACpBC,GACEA,EAAkDC,OACnDC,GAEHT,GAEGf,EAAQoB,EAAQ,IACbL,EAAgBM,KACpBC,GACEA,EAAwDC,OACzD1C,GAEHkC;AAEH,OACEhB,EAAC,UAAA,CACCZ,UAAWC,EACXqC,IAAKX,KACD9B,EAEJF,0BAAC,MAAA,CAAIK,UAAWqB,EAA2B,CAAEC,qBAC3C3B,SAAA;eAAAiB,EAAC,MAAA,CAAIZ,UAAWC,EACbN,SAAAqC;iBAEF,MAAA,CAAIhC,UAAWC,EACbN,SAAAkB,WAMXY,EAAsBc,YAAc,wBAEpCF,EAAqBE,YAAc,gCACnCd,EAAsBe,QAAUH,EAEhC3C,EAA2B6C,YAAc,8BACzCd,EAAsBgB,MAAQ/C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
type OmittedAnchorProps = 'className' | 'style';
|
|
3
|
+
export interface BoxLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, OmittedAnchorProps> {
|
|
4
|
+
/**
|
|
5
|
+
* The content to render inside the BoxLink.
|
|
6
|
+
*/
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Whether the BoxLink is in a selected state.
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
isSelected?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether the BoxLink is disabled.
|
|
15
|
+
* Prevents navigation, removes href, and reflects aria-disabled.
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
isDisabled?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The focus ring style.
|
|
21
|
+
* Use 'white' when BoxLink is placed on a dark or coloured background.
|
|
22
|
+
* @default 'default'
|
|
23
|
+
*/
|
|
24
|
+
focusStyle?: 'default' | 'white';
|
|
25
|
+
/**
|
|
26
|
+
* Whether headings (h2–h6) inside the BoxLink should be underlined on hover.
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
underlineHeadingOnHover?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Controls which layer handles CSS styling for interactive states.
|
|
32
|
+
*
|
|
33
|
+
* - 'default' — BoxLink applies all styles including hover, focus, pressed and selected
|
|
34
|
+
* - 'custom' — BoxLink strips back to inline-block only, children own
|
|
35
|
+
* their own styles via the `useBoxLink` hook
|
|
36
|
+
*
|
|
37
|
+
* @default 'default'
|
|
38
|
+
*/
|
|
39
|
+
styleVariant?: 'default' | 'custom';
|
|
40
|
+
/**
|
|
41
|
+
* The target attribute for the link.
|
|
42
|
+
* @default '_self'
|
|
43
|
+
*/
|
|
44
|
+
target?: '_self' | '_blank' | '_parent' | '_top';
|
|
45
|
+
/**
|
|
46
|
+
* Specify custom screen reader text for external links.
|
|
47
|
+
* @default 'opens in a new tab'
|
|
48
|
+
*/
|
|
49
|
+
externalLinkScreenReaderText?: string;
|
|
50
|
+
}
|
|
51
|
+
export declare const BoxLink: React.ForwardRefExoticComponent<BoxLinkProps & React.RefAttributes<HTMLAnchorElement>>;
|
|
52
|
+
export default BoxLink;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{jsx as e,jsxs as i}from"react/jsx-runtime";import{forwardRef as s}from"react";import{useLink as r}from"@react-aria/link";import{useHover as o}from"@react-aria/interactions";import{useFocusRing as d}from"@react-aria/focus";import{useObjectRef as a,mergeProps as t}from"@react-aria/utils";import{focusStyleVariants as l}from"../../utils/focus/focusStyles.js";import{BoxLinkContext as n}from"./BoxLinkContext.js";import{VisuallyHidden as u}from"../VisuallyHidden/VisuallyHidden.js";import '../../assets/BoxLink.css';const c="_box-link_jbtzi_1",f="_box-link--default_jbtzi_8",v="_box-link--underline-heading-on-hover_jbtzi_53",p="_box-link--disabled_jbtzi_61",b="noopener noreferrer",m=s(function({children:s,isSelected:m=!1,isDisabled:h=!1,focusStyle:_="default",underlineHeadingOnHover:k=!1,styleVariant:H="default",target:x="_self",externalLinkScreenReaderText:S="opens in a new tab",href:j,onClick:D,rel:y,...P},g){const F=a(g),V=!!h,z="_blank"===x,C=((e,i)=>e?i?`${b} ${i}`:b:i)(z,y),O={isDisabled:V,href:j},{linkProps:B,isPressed:L}=r(O,F),{hoverProps:$,isHovered:w}=o({isDisabled:V}),{focusProps:N,isFocusVisible:R,isFocused:T}=d(),q="default"===H,A=(({isDefault:e,focusStyle:i,underlineHeadingOnHover:s,disabled:r})=>{const o=[c];return e&&(o.push(f),o.push(l({focusStyle:i})),s&&o.push(v)),r&&o.push(p),o.filter(Boolean).join(" ")})({isDefault:q,focusStyle:_,underlineHeadingOnHover:k,disabled:V}),E=(({isDefault:e,isHovered:i,isFocused:s,isPressed:r,isSelected:o})=>e?{"data-hovered":!!i||void 0,"data-focused":!!s||void 0,"data-pressed":!!r||void 0,"data-selected":!!o||void 0}:{"data-hovered":void 0,"data-focused":void 0,"data-pressed":void 0,"data-selected":void 0})({isDefault:q,isHovered:w,isFocused:T,isPressed:L,isSelected:m});/* @__PURE__ */
|
|
2
|
+
return e(n.Provider,{value:{isHovered:w,isPressed:L,isFocusVisible:R,isDisabled:V,isSelected:m},children:/* @__PURE__ */i("a",{...t(B,$,N,P),ref:F,href:V?void 0:j,target:x,rel:C,"aria-disabled":!!V||void 0,className:A,onClick:e=>{V?e.preventDefault():(B.onClick?.(e),D?.(e))},"data-alto-box-link":"",...E,children:[s,z&&/* @__PURE__ */e(u,{children:S})]})})});export{m as BoxLink,m as default};
|
|
3
|
+
//# sourceMappingURL=BoxLink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BoxLink.js","sources":["../../../src/components/BoxLink/BoxLink.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { useLink } from '@react-aria/link';\nimport { useHover } from '@react-aria/interactions';\nimport { useFocusRing } from '@react-aria/focus';\nimport { mergeProps, useObjectRef } from '@react-aria/utils';\nimport { focusStyleVariants } from '../../utils/focus/focusStyles';\nimport { BoxLinkContext } from './BoxLinkContext';\nimport VisuallyHidden from '../VisuallyHidden/VisuallyHidden';\nimport styles from './BoxLink.module.css';\nimport type React from 'react';\n\ntype OmittedAnchorProps = 'className' | 'style';\n\nconst EXTERNAL_LINK_REL_TOKENS = 'noopener noreferrer';\n\nconst getMergedRel = (\n isExternalLink: boolean,\n rel: string | undefined,\n): string | undefined => {\n if (!isExternalLink) {\n return rel;\n }\n\n return rel ? `${EXTERNAL_LINK_REL_TOKENS} ${rel}` : EXTERNAL_LINK_REL_TOKENS;\n};\n\ninterface GetClassNameParams {\n isDefault: boolean;\n focusStyle: 'default' | 'white';\n underlineHeadingOnHover: boolean;\n disabled: boolean;\n}\n\nconst getClassName = ({\n isDefault,\n focusStyle,\n underlineHeadingOnHover,\n disabled,\n}: GetClassNameParams): string => {\n const classNames = [styles['box-link']];\n\n if (isDefault) {\n classNames.push(styles['box-link--default']);\n classNames.push(focusStyleVariants({ focusStyle }));\n\n if (underlineHeadingOnHover) {\n classNames.push(styles['box-link--underline-heading-on-hover']);\n }\n }\n\n if (disabled) {\n classNames.push(styles['box-link--disabled']);\n }\n\n return classNames.filter(Boolean).join(' ');\n};\n\ninterface GetInteractionDataAttributesParams {\n isDefault: boolean;\n isHovered: boolean;\n isFocused: boolean;\n isPressed: boolean;\n isSelected: boolean;\n}\n\nconst getInteractionDataAttributes = ({\n isDefault,\n isHovered,\n isFocused,\n isPressed,\n isSelected,\n}: GetInteractionDataAttributesParams) => {\n if (!isDefault) {\n return {\n 'data-hovered': undefined,\n 'data-focused': undefined,\n 'data-pressed': undefined,\n 'data-selected': undefined,\n };\n }\n\n return {\n 'data-hovered': isHovered ? true : undefined,\n 'data-focused': isFocused ? true : undefined,\n 'data-pressed': isPressed ? true : undefined,\n 'data-selected': isSelected ? true : undefined,\n };\n};\n\nexport interface BoxLinkProps\n extends Omit<\n React.AnchorHTMLAttributes<HTMLAnchorElement>,\n OmittedAnchorProps\n > {\n /**\n * The content to render inside the BoxLink.\n */\n children: React.ReactNode;\n /**\n * Whether the BoxLink is in a selected state.\n * @default false\n */\n isSelected?: boolean;\n /**\n * Whether the BoxLink is disabled.\n * Prevents navigation, removes href, and reflects aria-disabled.\n * @default false\n */\n isDisabled?: boolean;\n /**\n * The focus ring style.\n * Use 'white' when BoxLink is placed on a dark or coloured background.\n * @default 'default'\n */\n focusStyle?: 'default' | 'white';\n /**\n * Whether headings (h2–h6) inside the BoxLink should be underlined on hover.\n * @default false\n */\n underlineHeadingOnHover?: boolean;\n /**\n * Controls which layer handles CSS styling for interactive states.\n *\n * - 'default' — BoxLink applies all styles including hover, focus, pressed and selected\n * - 'custom' — BoxLink strips back to inline-block only, children own\n * their own styles via the `useBoxLink` hook\n *\n * @default 'default'\n */\n styleVariant?: 'default' | 'custom';\n /**\n * The target attribute for the link.\n * @default '_self'\n */\n target?: '_self' | '_blank' | '_parent' | '_top';\n /**\n * Specify custom screen reader text for external links.\n * @default 'opens in a new tab'\n */\n externalLinkScreenReaderText?: string;\n}\n\nexport const BoxLink = forwardRef<HTMLAnchorElement, BoxLinkProps>(\n function BoxLink(\n {\n children,\n isSelected = false,\n isDisabled = false,\n focusStyle = 'default',\n underlineHeadingOnHover = false,\n styleVariant = 'default',\n target = '_self',\n externalLinkScreenReaderText = 'opens in a new tab',\n href,\n onClick,\n rel,\n ...restProps\n },\n forwardedRef,\n ) {\n const ref = useObjectRef(forwardedRef);\n\n const disabled = !!isDisabled;\n const isExternalLink = target === '_blank';\n const mergedRel = getMergedRel(isExternalLink, rel);\n\n const ariaLinkProps = { isDisabled: disabled, href };\n const { linkProps, isPressed } = useLink(ariaLinkProps, ref);\n const { hoverProps, isHovered } = useHover({ isDisabled: disabled });\n const { focusProps, isFocusVisible, isFocused } = useFocusRing();\n\n const isDefault = styleVariant === 'default';\n\n const className = getClassName({\n isDefault,\n focusStyle,\n underlineHeadingOnHover,\n disabled,\n });\n\n const interactionDataAttributes = getInteractionDataAttributes({\n isDefault,\n isHovered,\n isFocused,\n isPressed,\n isSelected,\n });\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n // Call React Aria's onClick handler first\n linkProps.onClick?.(e);\n // Then call consumer's onClick\n onClick?.(e);\n };\n\n return (\n <BoxLinkContext.Provider\n value={{\n isHovered,\n isPressed,\n isFocusVisible,\n isDisabled: disabled,\n isSelected,\n }}\n >\n <a\n {...mergeProps(linkProps, hoverProps, focusProps, restProps)}\n ref={ref}\n href={disabled ? undefined : href}\n target={target}\n rel={mergedRel}\n aria-disabled={disabled ? true : undefined}\n className={className}\n onClick={handleClick}\n data-alto-box-link=\"\"\n {...interactionDataAttributes}\n >\n {children}\n {isExternalLink && (\n <VisuallyHidden>{externalLinkScreenReaderText}</VisuallyHidden>\n )}\n </a>\n </BoxLinkContext.Provider>\n );\n },\n);\n\nexport default BoxLink;\n"],"names":["EXTERNAL_LINK_REL_TOKENS","BoxLink","forwardRef","children","isSelected","isDisabled","focusStyle","underlineHeadingOnHover","styleVariant","target","externalLinkScreenReaderText","href","onClick","rel","restProps","forwardedRef","ref","useObjectRef","disabled","isExternalLink","mergedRel","getMergedRel","ariaLinkProps","linkProps","isPressed","useLink","hoverProps","isHovered","useHover","focusProps","isFocusVisible","isFocused","useFocusRing","isDefault","className","classNames","styles","push","focusStyleVariants","filter","Boolean","join","getClassName","interactionDataAttributes","getInteractionDataAttributes","jsx","BoxLinkContext","Provider","value","jsxs","mergeProps","e","preventDefault","VisuallyHidden"],"mappings":"qnBAaMA,EAA2B,sBAiIpBC,EAAUC,EACrB,UACEC,SACEA,EAAAC,WACAA,GAAa,EAAAC,WACbA,GAAa,EAAAC,WACbA,EAAa,UAAAC,wBACbA,GAA0B,EAAAC,aAC1BA,EAAe,UAAAC,OACfA,EAAS,QAAAC,6BACTA,EAA+B,qBAAAC,KAC/BA,EAAAC,QACAA,EAAAC,IACAA,KACGC,GAELC,GAEA,MAAMC,EAAMC,EAAaF,GAEnBG,IAAab,EACbc,EAA4B,WAAXV,EACjBW,EArJW,EACnBD,EACAN,IAEKM,EAIEN,EAAM,GAAGb,KAA4Ba,IAAQb,EAH3Ca,EAgJWQ,CAAaF,EAAgBN,GAEzCS,EAAgB,CAAEjB,WAAYa,EAAUP,SACxCY,UAAEA,EAAAC,UAAWA,GAAcC,EAAQH,EAAeN,IAClDU,WAAEA,YAAYC,GAAcC,EAAS,CAAEvB,WAAYa,KACnDW,WAAEA,EAAAC,eAAYA,EAAAC,UAAgBA,GAAcC,IAE5CC,EAA6B,YAAjBzB,EAEZ0B,EA5IW,GACnBD,YACA3B,aACAC,0BACAW,eAEA,MAAMiB,EAAa,CAACC,GAepB,OAbIH,IACFE,EAAWE,KAAKD,GAChBD,EAAWE,KAAKC,EAAmB,CAAEhC,gBAEjCC,GACF4B,EAAWE,KAAKD,IAIhBlB,GACFiB,EAAWE,KAAKD,GAGXD,EAAWI,OAAOC,SAASC,KAAK,MAuHnBC,CAAa,CAC7BT,YACA3B,aACAC,0BACAW,aAGIyB,EAnH2B,GACnCV,YACAN,YACAI,YACAP,YACApB,gBAEK6B,EASE,CACL,iBAAgBN,QAAmB,EACnC,iBAAgBI,QAAmB,EACnC,iBAAgBP,QAAmB,EACnC,kBAAiBpB,QAAoB,GAZ9B,CACL,oBAAgB,EAChB,oBAAgB,EAChB,oBAAgB,EAChB,qBAAiB,GAuGewC,CAA6B,CAC7DX,YACAN,YACAI,YACAP,YACApB;AAcF,OACEyC,EAACC,EAAeC,SAAf,CACCC,MAAO,CACLrB,YACAH,YACAM,iBACAzB,WAAYa,EACZd,cAGFD,wBAAA8C,EAAC,IAAA,IACKC,EAAW3B,EAAWG,EAAYG,EAAYf,GAClDE,MACAL,KAAMO,OAAW,EAAYP,EAC7BF,SACAI,IAAKO,EACL,kBAAeF,QAAkB,EACjCgB,YACAtB,QA7BeuC,IACfjC,EACFiC,EAAEC,kBAIJ7B,EAAUX,UAAUuC,GAEpBvC,IAAUuC,KAsBN,qBAAmB,MACfR,EAEHxC,SAAA,CAAAA,EACAgB,kBACC0B,EAACQ,EAAA,CAAgBlD,SAAAO,QAK3B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface BoxLinkContextValue {
|
|
2
|
+
isHovered: boolean;
|
|
3
|
+
isPressed: boolean;
|
|
4
|
+
isFocusVisible: boolean;
|
|
5
|
+
isDisabled: boolean;
|
|
6
|
+
isSelected: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const BoxLinkContext: import('react').Context<BoxLinkContextValue>;
|
|
9
|
+
/**
|
|
10
|
+
* Consume the BoxLink interaction state within a child component.
|
|
11
|
+
*
|
|
12
|
+
* Returns `isHovered`, `isPressed`, `isFocusVisible`, `isDisabled` and
|
|
13
|
+
* `isSelected` from the nearest parent `BoxLink`. If no `BoxLink` parent
|
|
14
|
+
* exists, all values default to `false` so the component is safe standalone.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const { isHovered, isPressed, isDisabled } = useBoxLink();
|
|
18
|
+
*
|
|
19
|
+
* @note
|
|
20
|
+
* If using Next.js, any component calling this hook requires client-side
|
|
21
|
+
* rendering. Follow the Alto UI SSR setup guide and import via your
|
|
22
|
+
* `alto-avios.ts` wrapper file.
|
|
23
|
+
*/
|
|
24
|
+
export declare const useBoxLink: () => BoxLinkContextValue;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BoxLinkContext.js","sources":["../../../src/components/BoxLink/BoxLinkContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nexport interface BoxLinkContextValue {\n isHovered: boolean;\n isPressed: boolean;\n isFocusVisible: boolean;\n isDisabled: boolean;\n isSelected: boolean;\n}\n\nconst defaultContextValue: BoxLinkContextValue = {\n isHovered: false,\n isPressed: false,\n isFocusVisible: false,\n isDisabled: false,\n isSelected: false,\n};\n\nexport const BoxLinkContext =\n createContext<BoxLinkContextValue>(defaultContextValue);\n\n/**\n * Consume the BoxLink interaction state within a child component.\n *\n * Returns `isHovered`, `isPressed`, `isFocusVisible`, `isDisabled` and\n * `isSelected` from the nearest parent `BoxLink`. If no `BoxLink` parent\n * exists, all values default to `false` so the component is safe standalone.\n *\n * @example\n * const { isHovered, isPressed, isDisabled } = useBoxLink();\n *\n * @note\n * If using Next.js, any component calling this hook requires client-side\n * rendering. Follow the Alto UI SSR setup guide and import via your\n * `alto-avios.ts` wrapper file.\n */\nexport const useBoxLink = (): BoxLinkContextValue => useContext(BoxLinkContext);\n"],"names":["BoxLinkContext","createContext","isHovered","isPressed","isFocusVisible","isDisabled","isSelected","useBoxLink","useContext"],"mappings":"sDAUA,MAQaA,EACXC,EAT+C,CAC/CC,WAAW,EACXC,WAAW,EACXC,gBAAgB,EAChBC,YAAY,EACZC,YAAY,IAqBDC,EAAa,IAA2BC,EAAWR"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -89,7 +89,7 @@ export type ButtonProps<T extends ElementType = 'button'> = WithResponsiveProps<
|
|
|
89
89
|
export type DefaultButtonProps = ButtonProps<'button'>;
|
|
90
90
|
export declare const Button: import('react').ForwardRefExoticComponent<Omit<ButtonBaseProps<ElementType>, ResponsivePropKeys> & {
|
|
91
91
|
size?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<ButtonSize | undefined>> | undefined;
|
|
92
|
-
fullWidth?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<boolean | undefined>> | undefined;
|
|
93
92
|
textAlign?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<ButtonTextAlignement | undefined>> | undefined;
|
|
93
|
+
fullWidth?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<boolean | undefined>> | undefined;
|
|
94
94
|
} & import('react').RefAttributes<any>>;
|
|
95
95
|
export default Button;
|
|
@@ -176,8 +176,15 @@ export interface CarouselBaseProps {
|
|
|
176
176
|
* Callback fired when the autoplay button is pressed
|
|
177
177
|
*/
|
|
178
178
|
onAutoplayPress?: (state: 'play' | 'pause') => void;
|
|
179
|
+
/**
|
|
180
|
+
* Callback fired whenever the active page changes, regardless of input method
|
|
181
|
+
* (arrow buttons, trackpad scroll, touch swipe, keyboard navigation, dot press, autoplay)
|
|
182
|
+
* Use this to track all carousel navigation events, e.g. for analytics
|
|
183
|
+
* @param index - zero-based index of the new active page
|
|
184
|
+
*/
|
|
185
|
+
onPageChange?: (index: number) => void;
|
|
179
186
|
}
|
|
180
187
|
type ResponsiveKeys = 'itemsPerPage' | 'spaceBetweenItems' | 'scrollPadding' | 'showArrowsOnHover' | 'arrowSize' | 'hideDots';
|
|
181
188
|
export type CarouselProps = WithResponsive<CarouselBaseProps, ResponsiveKeys>;
|
|
182
|
-
export declare const Carousel: ({ children, "aria-label": ariaLabel, "aria-describedby": ariaDescribedby, looping, itemsPerPage, spaceBetweenItems, scrollPadding, iconType, arrowStyleVariant, arrowSize, hideDisabledArrow, showArrowsOnHover, focusStyle, dotsSize, dotsVariant, hideDots, autoPlay, autoPlayInterval, autoPlayStyleVariant, autoPlayControlSize, mouseDragging, carouselWrapperClassName, prevArrowClassName, nextArrowClassName, autoplayControlClassName, dotsContainerClassName, dotsWrapperClassName, dotClassName, activeDotClassName, itemWrapperClassName, activeItemClassName, onArrowPress, onDotPress, onAutoplayPress, }: CarouselProps) => import("react/jsx-runtime").JSX.Element;
|
|
189
|
+
export declare const Carousel: ({ children, "aria-label": ariaLabel, "aria-describedby": ariaDescribedby, looping, itemsPerPage, spaceBetweenItems, scrollPadding, iconType, arrowStyleVariant, arrowSize, hideDisabledArrow, showArrowsOnHover, focusStyle, dotsSize, dotsVariant, hideDots, autoPlay, autoPlayInterval, autoPlayStyleVariant, autoPlayControlSize, mouseDragging, carouselWrapperClassName, prevArrowClassName, nextArrowClassName, autoplayControlClassName, dotsContainerClassName, dotsWrapperClassName, dotClassName, activeDotClassName, itemWrapperClassName, activeItemClassName, onArrowPress, onDotPress, onAutoplayPress, onPageChange, }: CarouselProps) => import("react/jsx-runtime").JSX.Element;
|
|
183
190
|
export default Carousel;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t}from"react/jsx-runtime";import a,{useRef as r,useState as s,useEffect as o}from"react";import{c as
|
|
2
|
-
return e("div",{className:(()=>{const e=[y.carouselWrapper];return Number.isInteger(
|
|
3
|
-
/* @__PURE__ */e(l,{className:`${y.scroller} ${v({focusStyle:k})}`,...
|
|
4
|
-
return e(d,{className:s,"data-is-active":r?"true":void 0,"data-item-index":a,"aria-label":`Slide ${a+1} of ${
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import a,{useRef as r,useState as s,useEffect as o}from"react";import{c as n}from"../../index-CCUt_dAN.js";import{C as i,a as l,b as d,c as u,d as c}from"../../IconButton.module-C7YCy-MU.js";import{CarouselButton as m}from"./CarouselButton/CarouselButton.js";import{CarouselDots as p}from"./CarouselDots/CarouselDots.js";import{AutoplayControl as f}from"./AutoplayControl/AutoplayControl.js";import{focusStyleVariants as v}from"../../utils/focus/focusStyles.js";import{useFocusRing as g}from"@react-aria/focus";import{resolveResponsiveProp as h}from"../../utils/breakpoint/responsive.js";import{useBreakpoint as _}from"../../utils/breakpoint/hooks/useBreakpoint.js";import '../../assets/Carousel.css';const y={carouselWrapper:"_carouselWrapper_gzlsx_2",showPartialItems:"_showPartialItems_gzlsx_14",carousel:"_carousel_gzlsx_2",hasScrollPadding:"_hasScrollPadding_gzlsx_25",scroller:"_scroller_gzlsx_43",item:"_item_gzlsx_84",slideLeft:"_slideLeft_gzlsx_122",slideRight:"_slideRight_gzlsx_126",controls:"_controls_gzlsx_149",defaultPrevButton:"_defaultPrevButton_gzlsx_160",defaultNextButton:"_defaultNextButton_gzlsx_168",defaultDotsContainer:"_defaultDotsContainer_gzlsx_177",defaultCarouselWrapper:"_defaultCarouselWrapper_gzlsx_188",defaultAutoplayControl:"_defaultAutoplayControl_gzlsx_195",showOnHover:"_showOnHover_gzlsx_204",hidden:"_hidden_gzlsx_214",hiddenTabs:"_hiddenTabs_gzlsx_245",infinite:"_infinite_gzlsx_264",native:"_native_gzlsx_269",autoplayControlWrapper:"_autoplayControlWrapper_gzlsx_273"},x=n(y.carousel,{variants:{looping:{infinite:y.infinite,backToStart:y.native,off:void 0}}}),b=({children:n=[],"aria-label":b,"aria-describedby":C,looping:N="off",itemsPerPage:P=1,spaceBetweenItems:w=0,scrollPadding:z,iconType:S="chevron",arrowStyleVariant:D="neutral",arrowSize:$="md",hideDisabledArrow:A=!1,showArrowsOnHover:L=!1,focusStyle:k="default",dotsSize:E="md",dotsVariant:I="standard",hideDots:T=!1,autoPlay:B=!1,autoPlayInterval:W=2e3,autoPlayStyleVariant:j="neutralVibrant",autoPlayControlSize:M="md",mouseDragging:q=!0,carouselWrapperClassName:H="",prevArrowClassName:O="",nextArrowClassName:R="",autoplayControlClassName:V="",dotsContainerClassName:F="",dotsWrapperClassName:X="",dotClassName:Y="",activeDotClassName:K="",itemWrapperClassName:G="",activeItemClassName:J="",onArrowPress:Q,onDotPress:U,onAutoplayPress:Z,onPageChange:ee})=>{const te=a.Children.toArray(n),ae=te.length,re=_(),se=h(P,re)??1,oe=h(w,re)??0,ne=h(z,re)??void 0,ie=h($,re)??"md",le=h(T,re)??!1,de=Math.max(1,se),ue=Math.ceil(ae/de),ce=!le&&ue>1,me=r(null),pe=r(null),[fe,ve]=s(0),[ge,he]=s(0),[_e,ye]=s(!1),[xe,be]=s(!1),[Ce,Ne]=s(!1),[Pe]=s(!1),[we,ze]=s(null),Se=(e,t)=>e||t,De=e=>{if(!(e===fe||e<0||e>=ue)&&me.current){const t=me.current.querySelector(`[data-slide-tab="true"][data-index="${e}"]`);t&&t.click()}};o(()=>{if(!me.current||!q)return;const e=e=>{_e&&(e.preventDefault(),e.stopPropagation(),setTimeout(()=>{ye(!1)},0))},t=e=>{ze({x:e.clientX,y:e.clientY})},a=e=>{if(null===we)return;const t=Math.abs(e.clientX-we.x),a=Math.abs(e.clientY-we.y);Math.sqrt(t*t+a*a)>5&&ye(!0)},r=()=>{_e?setTimeout(()=>{ye(!1),ze(null)},50):ze(null)},s=me.current;return s.addEventListener("mousedown",t,!0),s.addEventListener("mousemove",a,!0),s.addEventListener("mouseup",r,!0),s.addEventListener("click",e,!0),()=>{s.removeEventListener("mousedown",t,!0),s.removeEventListener("mousemove",a,!0),s.removeEventListener("mouseup",r,!0),s.removeEventListener("click",e,!0)}},[q,_e,we,5]),o(()=>{if(me.current){const e=me.current.querySelector(`.${y.scroller}`);e&&e instanceof HTMLElement&&(ge<fe?(e.classList.remove(y.slideLeft),e.classList.add(y.slideRight)):ge>fe&&(e.classList.remove(y.slideRight),e.classList.add(y.slideLeft)))}},[fe,ge]),o(()=>{if(!me.current)return;const e=()=>{if(!me.current)return;const e=me.current.querySelector('[data-slide-tab="true"][aria-selected="true"]');if(e){const t=e.dataset.index;if("string"==typeof t&&t.length>0){const e=parseInt(t,10);!isNaN(e)&&e!==fe&&e>=0&&e<ue&&(he(fe),ve(e))}}},t=new MutationObserver(t=>{let a=!1;t.forEach(e=>{"attributes"===e.type&&"aria-selected"===e.attributeName&&(a=!0)}),a&&setTimeout(e,10)});me.current.querySelectorAll('[data-slide-tab="true"]').forEach(e=>{t.observe(e,{attributes:!0,attributeFilter:["aria-selected"]})}),e();const a=setInterval(e,500);return()=>{t.disconnect(),clearInterval(a)}},[fe,ue]);const $e=L?{onMouseEnter:()=>be(!0),onMouseLeave:()=>be(!1),onFocus:()=>Ne(!0),onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||Ne(!1)}}:{},Ae=ue>1&&(!L||xe||Ce),Le=(()=>{const e={};return 1!==se&&(e["--items-per-page"]=String(de)),oe>0&&(e["--space-between-items"]=`${oe}px`),ne&&(e["--scroll-padding"]=ne),Object.keys(e).length>0?e:void 0})(),{focusProps:ke,isFocusVisible:Ee}=g(),Ie=(()=>{const e=fe*Math.floor(de),t=Math.min(e+Math.ceil(de),ae),a=[];for(let r=e;r<t;r++)a.push(r);return a})();/* @__PURE__ */
|
|
2
|
+
return e("div",{className:(()=>{const e=[y.carouselWrapper];return Number.isInteger(de)||e.push(y.showPartialItems),ne&&e.push(y.hasScrollPadding),H&&H.trim()?e.push(H):e.push(y.defaultCarouselWrapper),e.join(" ")})(),ref:me,style:Le,"data-dots-size":E,...$e,"data-arrows-visible":Ae?"true":"false","data-transitioning":Pe?"true":void 0,"data-scroll-padding":ne,role:"region","aria-label":(()=>{if(b)return b;return`Carousel with ${ae} items, currently showing slide ${fe+1} of ${ue}${B?", autoplay enabled":""}`})(),"aria-describedby":C,"aria-roledescription":"carousel",children:/* @__PURE__ */t(i,{className:`${x({looping:N})}`,loop:"infinite"===N?"infinite":"backToStart"===N?"native":"off"!==N?N:void 0,ref:pe,autoplay:B,autoplayInterval:W,mouseDragging:q&&!Pe,onDragStart:e=>{ye(!0),e&&e.nativeEvent&&ze({x:e.nativeEvent.clientX,y:e.nativeEvent.clientY})},onDragEnd:()=>{setTimeout(()=>{ye(!1)},50)},"data-dragging":_e?"true":"false",itemsPerPage:de,scrollPadding:ne,"data-has-space-between":oe>0?"true":void 0,"data-items-per-page":1!==se?de.toString():void 0,onActivePageIndexChange:ee?({index:e})=>ee(e):void 0,children:[
|
|
3
|
+
/* @__PURE__ */e(l,{className:`${y.scroller} ${v({focusStyle:k})}`,...ke,"data-focused":!!Ee||void 0,"data-focus-visible":!!Ee||void 0,"data-transitioning":Pe?"true":void 0,style:(()=>{const e={};if(oe>=0&&(e.gap=`${oe}px`),se>1&&oe>0){const t=oe*(de-1)/de;e.gridAutoColumns=`calc(${100/de}% - ${t}px)`}else se>1&&(e.gridAutoColumns=100/de+"%");return e})(),tabIndex:0,role:"region","aria-label":"Carousel content",onKeyDown:e=>{if("ArrowLeft"===e.key){e.preventDefault();const t=me.current?.querySelector('[dir="prev"]');t&&!t.disabled&&t.click()}else if("ArrowRight"===e.key){e.preventDefault();const t=me.current?.querySelector('[dir="next"]');t&&!t.disabled&&t.click()}else"Home"===e.key?(e.preventDefault(),De(0)):"End"===e.key&&(e.preventDefault(),De(ue-1))},children:te.map((t,a)=>{const r=Ie.includes(a),s=[G||"",y.item,r&&J?J:""].filter(Boolean).join(" ");/* @__PURE__ */
|
|
4
|
+
return e(d,{className:s,"data-is-active":r?"true":void 0,"data-item-index":a,"aria-label":`Slide ${a+1} of ${ae}`,children:t},a)})}),
|
|
5
5
|
/* @__PURE__ */t("div",{className:`${y.controls} ${L?y.showOnHover:""}`,children:[
|
|
6
|
-
/* @__PURE__ */e(m,{dir:"prev",variant:D,size:ie,focusStyle:k,iconType:S,hideDisabledArrow:A,onPress:()=>Q?.("prev"),className:`${
|
|
7
|
-
/* @__PURE__ */e(m,{dir:"next",variant:D,size:ie,focusStyle:k,iconType:S,hideDisabledArrow:A,onPress:()=>Q?.("next"),className:`${
|
|
8
|
-
/* @__PURE__ */e("div",{className:y.hiddenTabs,children:/* @__PURE__ */e(u,{children:t=>/* @__PURE__ */e(c,{index:t.index,"data-index":t.index,"data-slide-tab":"true",tabIndex:-1},t.index)})}),B&&/* @__PURE__ */e("div",{className:`${y.autoplayControlWrapper} ${
|
|
6
|
+
/* @__PURE__ */e(m,{dir:"prev",variant:D,size:ie,focusStyle:k,iconType:S,hideDisabledArrow:A,onPress:()=>Q?.("prev"),className:`${Se(O,y.defaultPrevButton)} ${Ae?"":y.hidden}`}),
|
|
7
|
+
/* @__PURE__ */e(m,{dir:"next",variant:D,size:ie,focusStyle:k,iconType:S,hideDisabledArrow:A,onPress:()=>Q?.("next"),className:`${Se(R,y.defaultNextButton)} ${Ae?"":y.hidden}`})]}),
|
|
8
|
+
/* @__PURE__ */e("div",{className:y.hiddenTabs,children:/* @__PURE__ */e(u,{children:t=>/* @__PURE__ */e(c,{index:t.index,"data-index":t.index,"data-slide-tab":"true",tabIndex:-1},t.index)})}),B&&/* @__PURE__ */e("div",{className:`${y.autoplayControlWrapper} ${Se(V,y.defaultAutoplayControl)}`,children:/* @__PURE__ */e(f,{variant:j,size:M,className:"",onPress:Z})}),ce&&/* @__PURE__ */e(p,{totalItems:ue,currentPage:fe,onDotClick:e=>De(e),onPress:U,focusStyle:k,dotsSize:E,variant:I,className:Se(F,y.defaultDotsContainer),dotsWrapperClassName:X,dotClassName:Y,activeDotClassName:K,isTransitioning:Pe})]})})};export{b as Carousel,b as default};
|
|
9
9
|
//# sourceMappingURL=Carousel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Carousel.js","sources":["../../../src/components/Carousel/Carousel.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { cva } from 'class-variance-authority';\nimport {\n Carousel as AriaCarousel,\n CarouselScroller as AriaCarouselScroller,\n CarouselItem as AriaCarouselItem,\n CarouselTabs as AriaCarouselTabs,\n CarouselTab as AriaCarouselTab,\n} from 'react-aria-carousel';\nimport styles from './Carousel.module.css';\nimport { CarouselButton } from './CarouselButton/CarouselButton';\nimport { CarouselDots } from './CarouselDots/CarouselDots';\nimport { AutoplayControl } from './AutoplayControl/AutoplayControl';\nimport { focusStyleVariants } from '../../utils/focus/focusStyles';\nimport { useFocusRing } from '@react-aria/focus';\n\nimport {\n WithResponsive,\n resolveResponsiveProp,\n} from '../../utils/breakpoint/responsive';\nimport { useBreakpoint } from '../../utils/breakpoint/hooks/useBreakpoint';\n\nconst carousel = cva(styles.carousel, {\n variants: {\n looping: {\n infinite: styles.infinite,\n backToStart: styles.native,\n off: undefined,\n },\n },\n});\n\nexport interface CarouselBaseProps {\n /**\n * Content to be displayed in the carousel\n */\n children?: React.ReactNode | React.ReactNode[];\n\n /**\n * Accessible name for the carousel\n * Describes the purpose or content of the carousel for screen readers\n * @example \"Featured products\" or \"Customer testimonials\"\n */\n 'aria-label'?: string;\n\n /**\n * ID of an element that provides additional description for the carousel\n * Can reference an element that gives more context about the carousel's content\n * @example \"carousel-description\"\n */\n 'aria-describedby'?: string;\n\n /**\n * Looping behavior\n * - 'infinite': Carousel loops continuously\n * - 'backToStart': Carousel loops back to start after reaching end\n * - 'off': Looping is disabled\n * @default 'off'\n */\n looping?: 'infinite' | 'backToStart' | 'off';\n\n /**\n * Number of items to display per page (minimum: 1)\n * Decimal values (e.g., 2.25) can be used to show partial items\n * @default 1\n * @min 1\n */\n itemsPerPage?: number;\n\n /**\n * Space between carousel items in pixels\n * @default 0\n */\n spaceBetweenItems?: number;\n\n /**\n * Amount of padding added to the scroll container to create a \"peek\" effect.\n * This shows a portion of the adjacent items.\n * Accepts any valid CSS dimension (px, rem, em, %) - e.g., \"15%\", \"20px\", \"2rem\"\n * @example \"15%\" or \"20px\" or \"2rem\"\n * @default undefined\n */\n scrollPadding?: string;\n\n /* Button and Controls Props */\n /**\n * Icon type for navigation buttons\n * @default 'chevron'\n */\n iconType?: 'chevron';\n\n /**\n * Style of carousel arrow buttons\n * @default 'neutral'\n */\n arrowStyleVariant?:\n | 'neutral'\n | 'white'\n | 'shapeFlat'\n | 'shapeElevated'\n | 'gradient';\n\n /**\n * Size of navigation buttons\n * @default 'md'\n */\n arrowSize?: 'sm' | 'md' | 'lg';\n\n /**\n * Whether to hide navigation buttons when disabled\n * Note: Navigation buttons are automatically hidden when all items fit on one page\n * @default false\n */\n hideDisabledArrow?: boolean;\n\n /**\n * Whether to show arrows only when hovering over the carousel or when it has focus\n * @default false\n */\n showArrowsOnHover?: boolean;\n\n /**\n * Focus style for interactive elements\n * @default 'default'\n */\n focusStyle?: 'default' | 'white';\n\n /* Dots/Tabs Props */\n /**\n * Size of pagination dots\n * @default 'md'\n */\n dotsSize?: 'md' | 'lg';\n\n /**\n * Visual style of pagination dots\n * @default 'standard'\n */\n dotsVariant?: 'standard' | 'transparent';\n\n /**\n * Whether to hide pagination dots\n * Note: Dots are automatically hidden when there's only one page\n * @default false\n */\n hideDots?: boolean;\n\n /* Autoplay Props */\n /**\n * Whether the autoplay is enabled\n * @default false\n */\n autoPlay?: boolean;\n\n /**\n * Interval in milliseconds between slides during autoplay\n * @default 2000\n */\n autoPlayInterval?: number;\n\n /**\n * Style variant for autoplay control button\n * @default 'neutralVibrant'\n */\n autoPlayStyleVariant?:\n | 'neutralVibrant'\n | 'neutralSubtle'\n | 'whiteVibrant'\n | 'whiteSubtle';\n\n /**\n * Size of autoplay control button\n * @default 'md'\n */\n autoPlayControlSize?: 'sm' | 'md';\n\n /**\n * Whether to enable mouse dragging for the carousel\n * @default true\n */\n mouseDragging?: boolean;\n\n /* Custom Class Names for Positioning and Styling */\n /**\n * Class name for the outermost wrapper of the carousel\n */\n carouselWrapperClassName?: string;\n\n /**\n * Class name for the previous button\n * Use this to position the previous button\n */\n prevArrowClassName?: string;\n\n /**\n * Class name for the next button\n * Use this to position the next button\n */\n nextArrowClassName?: string;\n\n /**\n * Class name for the autoplay control\n * Use this to position the autoplay button\n */\n autoplayControlClassName?: string;\n\n /**\n * Class name for the dots container\n * Use this to position the pagination dots\n */\n dotsContainerClassName?: string;\n\n /**\n * Class name for the dots wrapper\n * Use this to style the dots wrapper\n */\n dotsWrapperClassName?: string;\n\n /**\n * Class name for individual dots\n */\n dotClassName?: string;\n\n /**\n * Class name for the active dot\n */\n activeDotClassName?: string;\n\n /**\n * Class name for individual carousel item wrappers\n * Use this to style the wrapper div around each carousel item\n */\n itemWrapperClassName?: string;\n\n /**\n * Class name for the currently active/visible carousel item\n * This class is applied to the item that corresponds to the current page\n */\n activeItemClassName?: string;\n\n /**\n * Callback fired when a carousel navigation button (prev/next) is pressed\n */\n onArrowPress?: (direction: 'prev' | 'next') => void;\n\n /**\n * Callback fired when a dot is pressed\n */\n onDotPress?: (index: number) => void;\n\n /**\n * Callback fired when the autoplay button is pressed\n */\n onAutoplayPress?: (state: 'play' | 'pause') => void;\n}\n\ntype ResponsiveKeys =\n | 'itemsPerPage'\n | 'spaceBetweenItems'\n | 'scrollPadding'\n | 'showArrowsOnHover'\n | 'arrowSize'\n | 'hideDots';\n\nexport type CarouselProps = WithResponsive<CarouselBaseProps, ResponsiveKeys>;\n\nexport const Carousel = ({\n children = [],\n 'aria-label': ariaLabel,\n 'aria-describedby': ariaDescribedby,\n looping = 'off',\n itemsPerPage = 1,\n spaceBetweenItems = 0,\n scrollPadding,\n\n // Button and Controls Props\n iconType = 'chevron',\n arrowStyleVariant = 'neutral',\n arrowSize = 'md',\n hideDisabledArrow = false,\n showArrowsOnHover = false,\n focusStyle = 'default',\n\n // Dots/Tabs Props\n dotsSize = 'md',\n dotsVariant = 'standard',\n hideDots = false,\n\n // Autoplay Props\n autoPlay = false,\n autoPlayInterval = 2000,\n autoPlayStyleVariant = 'neutralVibrant',\n autoPlayControlSize = 'md',\n\n // Mouse Dragging\n mouseDragging = true,\n\n // Custom Class Names\n carouselWrapperClassName = '',\n prevArrowClassName = '',\n nextArrowClassName = '',\n autoplayControlClassName = '',\n dotsContainerClassName = '',\n dotsWrapperClassName = '',\n dotClassName = '',\n activeDotClassName = '',\n itemWrapperClassName = '',\n activeItemClassName = '',\n\n // Event Callbacks\n onArrowPress,\n onDotPress,\n onAutoplayPress,\n}: CarouselProps) => {\n // Map looping values to expected loop values for AriaCarousel\n const getLoopValue = () => {\n if (looping === 'infinite') return 'infinite';\n if (looping === 'backToStart') return 'native';\n if (looping === 'off') return undefined;\n return looping; // other values pass through\n };\n\n const items = React.Children.toArray(children);\n const totalItems = items.length;\n\n const breakpoint = useBreakpoint();\n const resolvedItemsPerPage =\n resolveResponsiveProp(itemsPerPage, breakpoint) ?? 1;\n const resolvedSpaceBetweenItems =\n resolveResponsiveProp(spaceBetweenItems, breakpoint) ?? 0;\n const resolvedScrollPadding =\n resolveResponsiveProp(scrollPadding, breakpoint) ?? undefined;\n const resolvedArrowSize =\n resolveResponsiveProp(arrowSize, breakpoint) ?? 'md';\n const resolvedHideDots = resolveResponsiveProp(hideDots, breakpoint) ?? false;\n\n // Ensure itemsPerPage is at least 1\n // We allow decimal values for showing partial items\n const safeItemsPerPage = Math.max(1, resolvedItemsPerPage);\n\n // Calculate total pages based on items per page\n const totalPages = Math.ceil(totalItems / safeItemsPerPage);\n\n // Determine if dots should be shown\n // Hide dots if:\n // 1. resolvedHideDots prop is true (responsive), OR\n // 2. There's only one page (totalPages <= 1)\n const shouldShowDots = !resolvedHideDots && totalPages > 1;\n\n const carouselRef = useRef<HTMLDivElement>(null);\n const ariaCarouselRef = useRef<HTMLDivElement>(null);\n\n const [currentPage, setCurrentPage] = useState(0);\n const [prevPage, setPrevPage] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [isTransitioning] = useState(false);\n\n // Add state variables for drag/link handling\n const [dragStartPosition, setDragStartPosition] = useState<{\n x: number;\n y: number;\n } | null>(null);\n const dragThreshold = 5; // Pixels of movement needed to consider as a drag\n\n // Helper function to get class names with defaults\n const getClassNameWithDefault = (\n customClassName: string,\n defaultClassName: string,\n ): string => {\n return customClassName || defaultClassName;\n };\n\n // Get CSS classes based on showing partial items\n const getCarouselWrapperClasses = () => {\n const classes = [styles.carouselWrapper];\n\n if (!Number.isInteger(safeItemsPerPage)) {\n classes.push(styles.showPartialItems);\n }\n\n if (resolvedScrollPadding) {\n classes.push(styles.hasScrollPadding);\n }\n\n // Apply default wrapper class if no custom wrapper class is provided\n if (carouselWrapperClassName && carouselWrapperClassName.trim()) {\n classes.push(carouselWrapperClassName);\n } else {\n classes.push(styles.defaultCarouselWrapper);\n }\n\n return classes.join(' ');\n };\n\n // Determine if we need to set CSS variables and return only what's needed\n const getCssVariables = () => {\n const cssVars: Record<string, string> = {};\n\n // Only set these if they differ from defaults\n if (resolvedItemsPerPage !== 1) {\n cssVars['--items-per-page'] = String(safeItemsPerPage);\n }\n\n if (resolvedSpaceBetweenItems > 0) {\n cssVars['--space-between-items'] = `${resolvedSpaceBetweenItems}px`;\n }\n\n if (resolvedScrollPadding) {\n cssVars['--scroll-padding'] = resolvedScrollPadding;\n }\n\n return Object.keys(cssVars).length > 0 ? cssVars : undefined;\n };\n\n // Helper function to determine which items are currently active/visible\n const getActiveItemIndices = () => {\n const startIndex = currentPage * Math.floor(safeItemsPerPage);\n const endIndex = Math.min(\n startIndex + Math.ceil(safeItemsPerPage),\n totalItems,\n );\n\n const activeIndices: number[] = [];\n for (let i = startIndex; i < endIndex; i++) {\n activeIndices.push(i);\n }\n\n return activeIndices;\n };\n\n const navigateToSlide = (index: number) => {\n if (index === currentPage || index < 0 || index >= totalPages) {\n return;\n }\n\n // Find and click the corresponding hidden tab\n if (carouselRef.current) {\n const targetTab = carouselRef.current.querySelector(\n `[data-slide-tab=\"true\"][data-index=\"${index}\"]`,\n ) as HTMLElement;\n\n if (targetTab) {\n targetTab.click();\n }\n }\n };\n\n // Add effect to handle link click prevention during drag\n useEffect(() => {\n if (!carouselRef.current || !mouseDragging) return;\n\n // Function to prevent click events on links during/after drag\n const preventLinkActivation = (e: MouseEvent) => {\n // If we are currently dragging, or just finished dragging, prevent link clicks\n if (isDragging) {\n e.preventDefault();\n e.stopPropagation();\n\n // Reset isDragging after the current event cycle completes\n setTimeout(() => {\n setIsDragging(false);\n }, 0);\n }\n };\n\n // Function to handle mouse down events\n const handleMouseDown = (e: MouseEvent) => {\n setDragStartPosition({ x: e.clientX, y: e.clientY });\n };\n\n // Function to handle mouse move events\n const handleMouseMove = (e: MouseEvent) => {\n if (dragStartPosition === null) return;\n\n // Calculate the distance moved\n const dx = Math.abs(e.clientX - dragStartPosition.x);\n const dy = Math.abs(e.clientY - dragStartPosition.y);\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // If the user has moved more than the threshold, consider it a drag\n if (distance > dragThreshold) {\n setIsDragging(true);\n }\n };\n\n // Function to handle mouse up events\n const handleMouseUp = () => {\n // If this wasn't a drag, don't interfere with normal clicks\n if (!isDragging) {\n setDragStartPosition(null);\n return;\n }\n\n // Add a brief delay for the click prevention to work\n setTimeout(() => {\n setIsDragging(false);\n setDragStartPosition(null);\n }, 50);\n };\n\n // Add event listeners for the carousel container\n const carouselElement = carouselRef.current;\n\n // Capture phase is important to catch events before they reach the links\n carouselElement.addEventListener('mousedown', handleMouseDown, true);\n carouselElement.addEventListener('mousemove', handleMouseMove, true);\n carouselElement.addEventListener('mouseup', handleMouseUp, true);\n\n // This is the key event listener that prevents link activation\n carouselElement.addEventListener('click', preventLinkActivation, true);\n\n return () => {\n // Clean up event listeners\n carouselElement.removeEventListener('mousedown', handleMouseDown, true);\n carouselElement.removeEventListener('mousemove', handleMouseMove, true);\n carouselElement.removeEventListener('mouseup', handleMouseUp, true);\n carouselElement.removeEventListener('click', preventLinkActivation, true);\n };\n }, [mouseDragging, isDragging, dragStartPosition, dragThreshold]);\n\n // Handle transition direction\n useEffect(() => {\n if (carouselRef.current) {\n const scroller = carouselRef.current.querySelector(`.${styles.scroller}`);\n if (scroller && scroller instanceof HTMLElement) {\n if (prevPage < currentPage) {\n scroller.classList.remove(styles.slideLeft);\n scroller.classList.add(styles.slideRight);\n } else if (prevPage > currentPage) {\n scroller.classList.remove(styles.slideRight);\n scroller.classList.add(styles.slideLeft);\n }\n }\n }\n }, [currentPage, prevPage]);\n\n // Track selected tab changes\n useEffect(() => {\n if (!carouselRef.current) return;\n\n const checkCurrentPage = () => {\n if (!carouselRef.current) return;\n\n // Find the currently selected tab\n const selectedTab = carouselRef.current.querySelector(\n '[data-slide-tab=\"true\"][aria-selected=\"true\"]',\n );\n if (selectedTab) {\n const indexStr = (selectedTab as HTMLElement).dataset.index;\n if (typeof indexStr === 'string' && indexStr.length > 0) {\n const newIndex = parseInt(indexStr, 10);\n if (\n !isNaN(newIndex) &&\n newIndex !== currentPage &&\n newIndex >= 0 &&\n newIndex < totalPages\n ) {\n setPrevPage(currentPage);\n setCurrentPage(newIndex);\n }\n }\n }\n };\n\n // Set up mutation observer to watch for aria-selected changes\n const observer = new MutationObserver((mutations) => {\n let shouldCheck = false;\n mutations.forEach((mutation) => {\n if (\n mutation.type === 'attributes' &&\n mutation.attributeName === 'aria-selected'\n ) {\n shouldCheck = true;\n }\n });\n\n if (shouldCheck) {\n // Small delay to ensure DOM is updated\n setTimeout(checkCurrentPage, 10);\n }\n });\n\n // Observe all hidden tabs\n const hiddenTabs = carouselRef.current.querySelectorAll(\n '[data-slide-tab=\"true\"]',\n );\n hiddenTabs.forEach((tab) => {\n observer.observe(tab, {\n attributes: true,\n attributeFilter: ['aria-selected'],\n });\n });\n\n // Initial check\n checkCurrentPage();\n\n // Also check periodically as backup\n const interval = setInterval(checkCurrentPage, 500);\n\n return () => {\n observer.disconnect();\n clearInterval(interval);\n };\n }, [currentPage, totalPages]);\n\n // Interaction handlers for hover and focus\n const interactionHandlers = showArrowsOnHover\n ? {\n onMouseEnter: () => setIsHovered(true),\n onMouseLeave: () => setIsHovered(false),\n onFocus: () => setIsFocused(true),\n onBlur: (e: React.FocusEvent) => {\n // Only blur if focus is moving outside the carousel\n if (!e.currentTarget.contains(e.relatedTarget as Node)) {\n setIsFocused(false);\n }\n },\n }\n : {};\n\n // Determine whether arrows should be visible\n // Hide arrows if:\n // 1. There's only one page (all items fit on screen), OR\n // 2. showArrowsOnHover is true and carousel is not hovered/focused\n const shouldShowArrows = totalPages > 1;\n const arrowsVisible =\n shouldShowArrows && (!showArrowsOnHover || isHovered || isFocused);\n\n // Get style object only if we have variables to set\n const cssVars = getCssVariables();\n\n const { focusProps, isFocusVisible } = useFocusRing();\n\n // Custom styles for grid-auto-columns calculation\n const getScrollerStyles = () => {\n const styles: React.CSSProperties = {};\n\n // ALWAYS apply gap if spaceBetweenItems is set, regardless of itemsPerPage\n if (resolvedSpaceBetweenItems >= 0) {\n styles.gap = `${resolvedSpaceBetweenItems}px`;\n }\n\n // Only calculate grid-auto-columns if we have multiple items per page AND spacing\n if (resolvedItemsPerPage > 1 && resolvedSpaceBetweenItems > 0) {\n // Advanced calculation for grid layout to account for gap spacing\n const gapSpacePerItem =\n (resolvedSpaceBetweenItems * (safeItemsPerPage - 1)) / safeItemsPerPage;\n\n styles.gridAutoColumns = `calc(${100 / safeItemsPerPage}% - ${gapSpacePerItem}px)`;\n } else if (resolvedItemsPerPage > 1) {\n // No gap, just divide width evenly\n styles.gridAutoColumns = `${100 / safeItemsPerPage}%`;\n }\n\n return styles;\n };\n\n // Get active item indices for the current page\n const activeItemIndices = getActiveItemIndices();\n\n // Handle carousel keyboard navigation\n const handleCarouselKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n // Navigate to previous slide\n const prevButton = carouselRef.current?.querySelector(\n '[dir=\"prev\"]',\n ) as HTMLButtonElement;\n if (prevButton && !prevButton.disabled) {\n prevButton.click();\n }\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n // Navigate to next slide\n const nextButton = carouselRef.current?.querySelector(\n '[dir=\"next\"]',\n ) as HTMLButtonElement;\n if (nextButton && !nextButton.disabled) {\n nextButton.click();\n }\n } else if (e.key === 'Home') {\n e.preventDefault();\n // Go to first slide\n navigateToSlide(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n // Go to last slide\n navigateToSlide(totalPages - 1);\n }\n };\n\n // Generate a meaningful default aria-label if none provided\n const getDefaultAriaLabel = () => {\n if (ariaLabel) return ariaLabel;\n\n const currentSlideNumber = currentPage + 1;\n const autoplayStatus = autoPlay ? ', autoplay enabled' : '';\n\n return `Carousel with ${totalItems} items, currently showing slide ${currentSlideNumber} of ${totalPages}${autoplayStatus}`;\n };\n\n return (\n <div\n className={getCarouselWrapperClasses()}\n ref={carouselRef}\n style={cssVars as React.CSSProperties}\n data-dots-size={dotsSize}\n {...interactionHandlers}\n data-arrows-visible={arrowsVisible ? 'true' : 'false'}\n data-transitioning={isTransitioning ? 'true' : undefined}\n data-scroll-padding={resolvedScrollPadding}\n role=\"region\"\n aria-label={getDefaultAriaLabel()}\n aria-describedby={ariaDescribedby}\n aria-roledescription=\"carousel\"\n >\n <AriaCarousel\n className={`${carousel({ looping })}`}\n loop={getLoopValue()}\n ref={ariaCarouselRef}\n autoplay={autoPlay}\n autoplayInterval={autoPlayInterval}\n mouseDragging={mouseDragging && !isTransitioning}\n onDragStart={(e) => {\n setIsDragging(true);\n if (e && e.nativeEvent) {\n setDragStartPosition({\n x: e.nativeEvent.clientX,\n y: e.nativeEvent.clientY,\n });\n }\n }}\n onDragEnd={() => {\n // We keep isDragging true for a short time after drag ends\n // This helps ensure click events don't fire immediately after dragging\n setTimeout(() => {\n setIsDragging(false);\n }, 50);\n }}\n data-dragging={isDragging ? 'true' : 'false'}\n itemsPerPage={safeItemsPerPage}\n scrollPadding={resolvedScrollPadding}\n data-has-space-between={\n resolvedSpaceBetweenItems > 0 ? 'true' : undefined\n }\n data-items-per-page={\n resolvedItemsPerPage !== 1 ? safeItemsPerPage.toString() : undefined\n }\n >\n <AriaCarouselScroller\n className={`${styles.scroller} ${focusStyleVariants({ focusStyle })}`}\n {...focusProps}\n data-focused={isFocusVisible ? true : undefined}\n data-focus-visible={isFocusVisible ? true : undefined}\n data-transitioning={isTransitioning ? 'true' : undefined}\n style={getScrollerStyles()}\n tabIndex={0}\n role=\"region\"\n aria-label=\"Carousel content\"\n onKeyDown={handleCarouselKeyDown}\n >\n {items.map((child, index) => {\n const isActiveItem = activeItemIndices.includes(index);\n const itemClasses = [\n itemWrapperClassName || '',\n styles.item,\n isActiveItem && activeItemClassName ? activeItemClassName : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <AriaCarouselItem\n key={index}\n className={itemClasses}\n data-is-active={isActiveItem ? 'true' : undefined}\n data-item-index={index}\n aria-label={`Slide ${index + 1} of ${totalItems}`}\n >\n {child}\n </AriaCarouselItem>\n );\n })}\n </AriaCarouselScroller>\n\n <div\n className={`${styles.controls} ${showArrowsOnHover ? styles.showOnHover : ''}`}\n >\n <CarouselButton\n dir=\"prev\"\n variant={arrowStyleVariant}\n size={resolvedArrowSize}\n focusStyle={focusStyle}\n iconType={iconType}\n hideDisabledArrow={hideDisabledArrow}\n onPress={() => onArrowPress?.('prev')}\n className={`${getClassNameWithDefault(prevArrowClassName, styles.defaultPrevButton)} ${!arrowsVisible ? styles.hidden : ''}`}\n />\n\n <CarouselButton\n dir=\"next\"\n variant={arrowStyleVariant}\n size={resolvedArrowSize}\n focusStyle={focusStyle}\n iconType={iconType}\n hideDisabledArrow={hideDisabledArrow}\n onPress={() => onArrowPress?.('next')}\n className={`${getClassNameWithDefault(nextArrowClassName, styles.defaultNextButton)} ${!arrowsVisible ? styles.hidden : ''}`}\n />\n </div>\n\n <div className={styles.hiddenTabs}>\n <AriaCarouselTabs>\n {(page) => (\n <AriaCarouselTab\n key={page.index}\n index={page.index}\n data-index={page.index}\n data-slide-tab=\"true\"\n tabIndex={-1}\n />\n )}\n </AriaCarouselTabs>\n </div>\n\n {autoPlay && (\n <div\n className={`${styles.autoplayControlWrapper} ${getClassNameWithDefault(autoplayControlClassName, styles.defaultAutoplayControl)}`}\n >\n <AutoplayControl\n variant={autoPlayStyleVariant}\n size={autoPlayControlSize}\n className=\"\"\n onPress={onAutoplayPress}\n />\n </div>\n )}\n\n {shouldShowDots && (\n <CarouselDots\n totalItems={totalPages}\n currentPage={currentPage}\n onDotClick={(index) => navigateToSlide(index)}\n onPress={onDotPress}\n focusStyle={focusStyle}\n dotsSize={dotsSize}\n variant={dotsVariant}\n className={getClassNameWithDefault(\n dotsContainerClassName,\n styles.defaultDotsContainer,\n )}\n dotsWrapperClassName={dotsWrapperClassName}\n dotClassName={dotClassName}\n activeDotClassName={activeDotClassName}\n isTransitioning={isTransitioning}\n />\n )}\n </AriaCarousel>\n </div>\n );\n};\n\nexport default Carousel;\n"],"names":["carousel","cva","styles","variants","looping","infinite","backToStart","native","off","Carousel","children","ariaLabel","ariaDescribedby","itemsPerPage","spaceBetweenItems","scrollPadding","iconType","arrowStyleVariant","arrowSize","hideDisabledArrow","showArrowsOnHover","focusStyle","dotsSize","dotsVariant","hideDots","autoPlay","autoPlayInterval","autoPlayStyleVariant","autoPlayControlSize","mouseDragging","carouselWrapperClassName","prevArrowClassName","nextArrowClassName","autoplayControlClassName","dotsContainerClassName","dotsWrapperClassName","dotClassName","activeDotClassName","itemWrapperClassName","activeItemClassName","onArrowPress","onDotPress","onAutoplayPress","items","React","Children","toArray","totalItems","length","breakpoint","useBreakpoint","resolvedItemsPerPage","resolveResponsiveProp","resolvedSpaceBetweenItems","resolvedScrollPadding","resolvedArrowSize","resolvedHideDots","safeItemsPerPage","Math","max","totalPages","ceil","shouldShowDots","carouselRef","useRef","ariaCarouselRef","currentPage","setCurrentPage","useState","prevPage","setPrevPage","isDragging","setIsDragging","isHovered","setIsHovered","isFocused","setIsFocused","isTransitioning","dragStartPosition","setDragStartPosition","getClassNameWithDefault","customClassName","defaultClassName","navigateToSlide","index","current","targetTab","querySelector","click","useEffect","preventLinkActivation","e","preventDefault","stopPropagation","setTimeout","handleMouseDown","x","clientX","y","clientY","handleMouseMove","dx","abs","dy","sqrt","handleMouseUp","carouselElement","addEventListener","removeEventListener","scroller","HTMLElement","classList","remove","slideLeft","add","slideRight","checkCurrentPage","selectedTab","indexStr","dataset","newIndex","parseInt","isNaN","observer","MutationObserver","mutations","shouldCheck","forEach","mutation","type","attributeName","querySelectorAll","tab","observe","attributes","attributeFilter","interval","setInterval","disconnect","clearInterval","interactionHandlers","onMouseEnter","onMouseLeave","onFocus","onBlur","currentTarget","contains","relatedTarget","arrowsVisible","cssVars","String","Object","keys","getCssVariables","focusProps","isFocusVisible","useFocusRing","activeItemIndices","startIndex","floor","endIndex","min","activeIndices","i","push","getActiveItemIndices","jsx","className","classes","carouselWrapper","Number","isInteger","showPartialItems","hasScrollPadding","trim","defaultCarouselWrapper","join","getCarouselWrapperClasses","ref","style","role","getDefaultAriaLabel","jsxs","AriaCarousel","loop","autoplay","autoplayInterval","onDragStart","nativeEvent","onDragEnd","toString","AriaCarouselScroller","focusStyleVariants","gap","gapSpacePerItem","gridAutoColumns","getScrollerStyles","tabIndex","onKeyDown","key","prevButton","disabled","nextButton","map","child","isActiveItem","includes","itemClasses","item","filter","Boolean","AriaCarouselItem","controls","showOnHover","CarouselButton","dir","variant","size","onPress","defaultPrevButton","hidden","defaultNextButton","hiddenTabs","AriaCarouselTabs","page","AriaCarouselTab","autoplayControlWrapper","defaultAutoplayControl","AutoplayControl","CarouselDots","onDotClick","defaultDotsContainer"],"mappings":"w/CAsBMA,EAAWC,EAAIC,EAAOF,SAAU,CACpCG,SAAU,CACRC,QAAS,CACPC,SAAUH,EAAOG,SACjBC,YAAaJ,EAAOK,OACpBC,SAAK,MA+OEC,EAAW,EACtBC,WAAW,GACX,aAAcC,EACd,mBAAoBC,EACpBR,UAAU,MACVS,eAAe,EACfC,oBAAoB,EACpBC,gBAGAC,WAAW,UACXC,oBAAoB,UACpBC,YAAY,KACZC,qBAAoB,EACpBC,qBAAoB,EACpBC,aAAa,UAGbC,WAAW,KACXC,cAAc,WACdC,YAAW,EAGXC,YAAW,EACXC,mBAAmB,IACnBC,uBAAuB,iBACvBC,sBAAsB,KAGtBC,iBAAgB,EAGhBC,2BAA2B,GAC3BC,qBAAqB,GACrBC,qBAAqB,GACrBC,2BAA2B,GAC3BC,yBAAyB,GACzBC,uBAAuB,GACvBC,eAAe,GACfC,qBAAqB,GACrBC,uBAAuB,GACvBC,sBAAsB,GAGtBC,eACAC,aACAC,sBAGA,MAOMC,GAAQC,EAAMC,SAASC,QAAQpC,GAC/BqC,GAAaJ,GAAMK,OAEnBC,GAAaC,IACbC,GACJC,EAAsBvC,EAAcoC,KAAe,EAC/CI,GACJD,EAAsBtC,EAAmBmC,KAAe,EACpDK,GACJF,EAAsBrC,EAAekC,UAAe,EAChDM,GACJH,EAAsBlC,EAAW+B,KAAe,KAC5CO,GAAmBJ,EAAsB5B,EAAUyB,MAAe,EAIlEQ,GAAmBC,KAAKC,IAAI,EAAGR,IAG/BS,GAAaF,KAAKG,KAAKd,GAAaU,IAMpCK,IAAkBN,IAAoBI,GAAa,EAEnDG,GAAcC,EAAuB,MACrCC,GAAkBD,EAAuB,OAExCE,GAAaC,IAAkBC,EAAS,IACxCC,GAAUC,IAAeF,EAAS,IAClCG,GAAYC,IAAiBJ,GAAS,IACtCK,GAAWC,IAAgBN,GAAS,IACpCO,GAAWC,IAAgBR,GAAS,IACpCS,IAAmBT,GAAS,IAG5BU,GAAmBC,IAAwBX,EAGxC,MAIJY,GAA0B,CAC9BC,EACAC,IAEOD,GAAmBC,EA6DtBC,GAAmBC,IACvB,KAAIA,IAAUlB,IAAekB,EAAQ,GAAKA,GAASxB,KAK/CG,GAAYsB,QAAS,CACvB,MAAMC,EAAYvB,GAAYsB,QAAQE,cACpC,uCAAuCH,OAGrCE,GACFA,EAAUE,OAEd,GAIFC,EAAU,KACR,IAAK1B,GAAYsB,UAAYxD,EAAe,OAG5C,MAAM6D,EAAyBC,IAEzBpB,KACFoB,EAAEC,iBACFD,EAAEE,kBAGFC,WAAW,KACTtB,IAAc,IACb,KAKDuB,EAAmBJ,IACvBZ,GAAqB,CAAEiB,EAAGL,EAAEM,QAASC,EAAGP,EAAEQ,WAItCC,EAAmBT,IACvB,GAA0B,OAAtBb,GAA4B,OAGhC,MAAMuB,EAAK3C,KAAK4C,IAAIX,EAAEM,QAAUnB,GAAkBkB,GAC5CO,EAAK7C,KAAK4C,IAAIX,EAAEQ,QAAUrB,GAAkBoB,GACjCxC,KAAK8C,KAAKH,EAAKA,EAAKE,EAAKA,GAnHxB,GAuHhB/B,IAAc,IAKZiC,EAAgB,KAEflC,GAMLuB,WAAW,KACTtB,IAAc,GACdO,GAAqB,OACpB,IARDA,GAAqB,OAYnB2B,EAAkB3C,GAAYsB,QAUpC,OAPAqB,EAAgBC,iBAAiB,YAAaZ,GAAiB,GAC/DW,EAAgBC,iBAAiB,YAAaP,GAAiB,GAC/DM,EAAgBC,iBAAiB,UAAWF,GAAe,GAG3DC,EAAgBC,iBAAiB,QAASjB,GAAuB,GAE1D,KAELgB,EAAgBE,oBAAoB,YAAab,GAAiB,GAClEW,EAAgBE,oBAAoB,YAAaR,GAAiB,GAClEM,EAAgBE,oBAAoB,UAAWH,GAAe,GAC9DC,EAAgBE,oBAAoB,QAASlB,GAAuB,KAErE,CAAC7D,EAAe0C,GAAYO,GA5JT,IA+JtBW,EAAU,KACR,GAAI1B,GAAYsB,QAAS,CACvB,MAAMwB,EAAW9C,GAAYsB,QAAQE,cAAc,IAAIrF,EAAO2G,YAC1DA,GAAYA,aAAoBC,cAC9BzC,GAAWH,IACb2C,EAASE,UAAUC,OAAO9G,EAAO+G,WACjCJ,EAASE,UAAUG,IAAIhH,EAAOiH,aACrB9C,GAAWH,KACpB2C,EAASE,UAAUC,OAAO9G,EAAOiH,YACjCN,EAASE,UAAUG,IAAIhH,EAAO+G,YAGpC,GACC,CAAC/C,GAAaG,KAGjBoB,EAAU,KACR,IAAK1B,GAAYsB,QAAS,OAE1B,MAAM+B,EAAmB,KACvB,IAAKrD,GAAYsB,QAAS,OAG1B,MAAMgC,EAActD,GAAYsB,QAAQE,cACtC,iDAEF,GAAI8B,EAAa,CACf,MAAMC,EAAYD,EAA4BE,QAAQnC,MACtD,GAAwB,iBAAbkC,GAAyBA,EAAStE,OAAS,EAAG,CACvD,MAAMwE,EAAWC,SAASH,EAAU,KAEjCI,MAAMF,IACPA,IAAatD,IACbsD,GAAY,GACZA,EAAW5D,KAEXU,GAAYJ,IACZC,GAAeqD,GAEnB,CACF,GAIIG,EAAW,IAAIC,iBAAkBC,IACrC,IAAIC,GAAc,EAClBD,EAAUE,QAASC,IAEG,eAAlBA,EAASC,MACkB,kBAA3BD,EAASE,gBAETJ,GAAc,KAIdA,GAEFhC,WAAWsB,EAAkB,MAKdrD,GAAYsB,QAAQ8C,iBACrC,2BAESJ,QAASK,IAClBT,EAASU,QAAQD,EAAK,CACpBE,YAAY,EACZC,gBAAiB,CAAC,qBAKtBnB,IAGA,MAAMoB,EAAWC,YAAYrB,EAAkB,KAE/C,MAAO,KACLO,EAASe,aACTC,cAAcH,KAEf,CAACtE,GAAaN,KAGjB,MAAMgF,GAAsBxH,EACxB,CACEyH,aAAc,IAAMnE,IAAa,GACjCoE,aAAc,IAAMpE,IAAa,GACjCqE,QAAS,IAAMnE,IAAa,GAC5BoE,OAASrD,IAEFA,EAAEsD,cAAcC,SAASvD,EAAEwD,gBAC9BvE,IAAa,KAInB,CAAA,EAOEwE,GADmBxF,GAAa,KAEdxC,GAAqBqD,IAAaE,IAGpD0E,GA1OkB,MACtB,MAAMA,EAAkC,CAAA,EAexC,OAZ6B,IAAzBlG,KACFkG,EAAQ,oBAAsBC,OAAO7F,KAGnCJ,GAA4B,IAC9BgG,EAAQ,yBAA2B,GAAGhG,QAGpCC,KACF+F,EAAQ,oBAAsB/F,IAGzBiG,OAAOC,KAAKH,GAASrG,OAAS,EAAIqG,OAAU,GA0NrCI,IAEVC,WAAEA,GAAAC,eAAYA,IAAmBC,IA2BjCC,GAnPuB,MAC3B,MAAMC,EAAa5F,GAAcR,KAAKqG,MAAMtG,IACtCuG,EAAWtG,KAAKuG,IACpBH,EAAapG,KAAKG,KAAKJ,IACvBV,IAGImH,EAA0B,GAChC,IAAA,IAASC,EAAIL,EAAYK,EAAIH,EAAUG,IACrCD,EAAcE,KAAKD,GAGrB,OAAOD,GAuOiBG;AA2C1B,OACEC,EAAC,MAAA,CACCC,UA1U8B,MAChC,MAAMC,EAAU,CAACtK,EAAOuK,iBAiBxB,OAfKC,OAAOC,UAAUlH,KACpB+G,EAAQJ,KAAKlK,EAAO0K,kBAGlBtH,IACFkH,EAAQJ,KAAKlK,EAAO2K,kBAIlB/I,GAA4BA,EAAyBgJ,OACvDN,EAAQJ,KAAKtI,GAEb0I,EAAQJ,KAAKlK,EAAO6K,wBAGfP,EAAQQ,KAAK,MAwTPC,GACXC,IAAKnH,GACLoH,MAAO9B,GACP,iBAAgB/H,KACZsH,GACJ,sBAAqBQ,GAAgB,OAAS,QAC9C,qBAAoBvE,GAAkB,YAAS,EAC/C,sBAAqBvB,GACrB8H,KAAK,SACL,aApBwB,MAC1B,GAAIzK,EAAW,OAAOA,EAKtB,MAAO,iBAAiBoC,qCAHGmB,GAAc,QAGqDN,KAFvEnC,EAAW,qBAAuB,MAgB3C4J,GACZ,mBAAkBzK,EAClB,uBAAqB,WAErBF,wBAAA4K,EAACC,EAAA,CACChB,UAAW,GAAGvK,EAAS,CAAEI,cACzBoL,KApZY,aAAZpL,EAA+B,WACnB,gBAAZA,EAAkC,SACtB,QAAZA,EACGA,OADP,EAmZI8K,IAAKjH,GACLwH,SAAUhK,EACViK,iBAAkBhK,EAClBG,cAAeA,IAAkBgD,GACjC8G,YAAchG,IACZnB,IAAc,GACVmB,GAAKA,EAAEiG,aACT7G,GAAqB,CACnBiB,EAAGL,EAAEiG,YAAY3F,QACjBC,EAAGP,EAAEiG,YAAYzF,WAIvB0F,UAAW,KAGT/F,WAAW,KACTtB,IAAc,IACb,KAEL,gBAAeD,GAAa,OAAS,QACrC1D,aAAc4C,GACd1C,cAAeuC,GACf,yBACED,GAA4B,EAAI,YAAS,EAE3C,sBAC2B,IAAzBF,GAA6BM,GAAiBqI,gBAAa,EAG7DpL,SAAA;eAAA4J,EAACyB,EAAA,CACCxB,UAAW,GAAGrK,EAAO2G,YAAYmF,EAAmB,CAAE3K,oBAClDqI,GACJ,iBAAcC,SAAwB,EACtC,uBAAoBA,SAAwB,EAC5C,qBAAoB9E,GAAkB,YAAS,EAC/CsG,MAzHkB,MACxB,MAAMjL,EAA8B,CAAA,EAQpC,GALImD,IAA6B,IAC/BnD,EAAO+L,IAAM,GAAG5I,QAIdF,GAAuB,GAAKE,GAA4B,EAAG,CAE7D,MAAM6I,EACH7I,IAA6BI,GAAmB,GAAMA,GAEzDvD,EAAOiM,gBAAkB,QAAQ,IAAM1I,SAAuByI,MAChE,MAAW/I,GAAuB,IAEhCjD,EAAOiM,gBAAqB,IAAM1I,GAAT,KAG3B,OAAOvD,GAqGMkM,GACPC,SAAU,EACVjB,KAAK,SACL,aAAW,mBACXkB,UAlGuB3G,IAC7B,GAAc,cAAVA,EAAE4G,IAAqB,CACzB5G,EAAEC,iBAEF,MAAM4G,EAAazI,GAAYsB,SAASE,cACtC,gBAEEiH,IAAeA,EAAWC,UAC5BD,EAAWhH,OAEf,MAAA,GAAqB,eAAVG,EAAE4G,IAAsB,CACjC5G,EAAEC,iBAEF,MAAM8G,EAAa3I,GAAYsB,SAASE,cACtC,gBAEEmH,IAAeA,EAAWD,UAC5BC,EAAWlH,OAEf,KAAqB,SAAVG,EAAE4G,KACX5G,EAAEC,iBAEFT,GAAgB,IACG,QAAVQ,EAAE4G,MACX5G,EAAEC,iBAEFT,GAAgBvB,GAAa,KA0ExBlD,SAAAiC,GAAMgK,IAAI,CAACC,EAAOxH,KACjB,MAAMyH,EAAehD,GAAkBiD,SAAS1H,GAC1C2H,EAAc,CAClBzK,GAAwB,GACxBpC,EAAO8M,KACPH,GAAgBtK,EAAsBA,EAAsB,IAE3D0K,OAAOC,SACPlC,KAAK;AAER,OACEV,EAAC6C,EAAA,CAEC5C,UAAWwC,EACX,iBAAgBF,EAAe,YAAS,EACxC,kBAAiBzH,EACjB,aAAY,SAASA,EAAQ,QAAQrC,KAEpCrC,SAAAkM,GANIxH;eAYbkG,EAAC,MAAA,CACCf,UAAW,GAAGrK,EAAOkN,YAAYhM,EAAoBlB,EAAOmN,YAAc,KAE1E3M,SAAA;eAAA4J,EAACgD,EAAA,CACCC,IAAI,OACJC,QAASvM,EACTwM,KAAMlK,GACNlC,aACAL,WACAG,oBACAuM,QAAS,IAAMlL,IAAe,QAC9B+H,UAAW,GAAGvF,GAAwBjD,EAAoB7B,EAAOyN,sBAAuBvE,GAAgC,GAAhBlJ,EAAO0N;eAGjHtD,EAACgD,EAAA,CACCC,IAAI,OACJC,QAASvM,EACTwM,KAAMlK,GACNlC,aACAL,WACAG,oBACAuM,QAAS,IAAMlL,IAAe,QAC9B+H,UAAW,GAAGvF,GAAwBhD,EAAoB9B,EAAO2N,sBAAuBzE,GAAgC,GAAhBlJ,EAAO0N;eAInHtD,EAAC,OAAIC,UAAWrK,EAAO4N,WACrBpN,wBAAA4J,EAACyD,EAAA,CACErN,SAACsN,kBACA1D,EAAC2D,EAAA,CAEC7I,MAAO4I,EAAK5I,MACZ,aAAY4I,EAAK5I,MACjB,iBAAe,OACfiH,UAAU,GAJL2B,EAAK5I,WAUjB3D,kBACC6I,EAAC,MAAA,CACCC,UAAW,GAAGrK,EAAOgO,0BAA0BlJ,GAAwB/C,EAA0B/B,EAAOiO,0BAExGzN,wBAAA4J,EAAC8D,EAAA,CACCZ,QAAS7L,EACT8L,KAAM7L,EACN2I,UAAU,GACVmD,QAAShL,MAKdoB,mBACCwG,EAAC+D,EAAA,CACCtL,WAAYa,GACZM,eACAoK,WAAalJ,GAAUD,GAAgBC,GACvCsI,QAASjL,EACTpB,aACAC,WACAkM,QAASjM,EACTgJ,UAAWvF,GACT9C,EACAhC,EAAOqO,sBAETpM,uBACAC,eACAC,qBACAwC"}
|
|
1
|
+
{"version":3,"file":"Carousel.js","sources":["../../../src/components/Carousel/Carousel.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { cva } from 'class-variance-authority';\nimport {\n Carousel as AriaCarousel,\n CarouselScroller as AriaCarouselScroller,\n CarouselItem as AriaCarouselItem,\n CarouselTabs as AriaCarouselTabs,\n CarouselTab as AriaCarouselTab,\n} from 'react-aria-carousel';\nimport styles from './Carousel.module.css';\nimport { CarouselButton } from './CarouselButton/CarouselButton';\nimport { CarouselDots } from './CarouselDots/CarouselDots';\nimport { AutoplayControl } from './AutoplayControl/AutoplayControl';\nimport { focusStyleVariants } from '../../utils/focus/focusStyles';\nimport { useFocusRing } from '@react-aria/focus';\n\nimport {\n WithResponsive,\n resolveResponsiveProp,\n} from '../../utils/breakpoint/responsive';\nimport { useBreakpoint } from '../../utils/breakpoint/hooks/useBreakpoint';\n\nconst carousel = cva(styles.carousel, {\n variants: {\n looping: {\n infinite: styles.infinite,\n backToStart: styles.native,\n off: undefined,\n },\n },\n});\n\nexport interface CarouselBaseProps {\n /**\n * Content to be displayed in the carousel\n */\n children?: React.ReactNode | React.ReactNode[];\n\n /**\n * Accessible name for the carousel\n * Describes the purpose or content of the carousel for screen readers\n * @example \"Featured products\" or \"Customer testimonials\"\n */\n 'aria-label'?: string;\n\n /**\n * ID of an element that provides additional description for the carousel\n * Can reference an element that gives more context about the carousel's content\n * @example \"carousel-description\"\n */\n 'aria-describedby'?: string;\n\n /**\n * Looping behavior\n * - 'infinite': Carousel loops continuously\n * - 'backToStart': Carousel loops back to start after reaching end\n * - 'off': Looping is disabled\n * @default 'off'\n */\n looping?: 'infinite' | 'backToStart' | 'off';\n\n /**\n * Number of items to display per page (minimum: 1)\n * Decimal values (e.g., 2.25) can be used to show partial items\n * @default 1\n * @min 1\n */\n itemsPerPage?: number;\n\n /**\n * Space between carousel items in pixels\n * @default 0\n */\n spaceBetweenItems?: number;\n\n /**\n * Amount of padding added to the scroll container to create a \"peek\" effect.\n * This shows a portion of the adjacent items.\n * Accepts any valid CSS dimension (px, rem, em, %) - e.g., \"15%\", \"20px\", \"2rem\"\n * @example \"15%\" or \"20px\" or \"2rem\"\n * @default undefined\n */\n scrollPadding?: string;\n\n /* Button and Controls Props */\n /**\n * Icon type for navigation buttons\n * @default 'chevron'\n */\n iconType?: 'chevron';\n\n /**\n * Style of carousel arrow buttons\n * @default 'neutral'\n */\n arrowStyleVariant?:\n | 'neutral'\n | 'white'\n | 'shapeFlat'\n | 'shapeElevated'\n | 'gradient';\n\n /**\n * Size of navigation buttons\n * @default 'md'\n */\n arrowSize?: 'sm' | 'md' | 'lg';\n\n /**\n * Whether to hide navigation buttons when disabled\n * Note: Navigation buttons are automatically hidden when all items fit on one page\n * @default false\n */\n hideDisabledArrow?: boolean;\n\n /**\n * Whether to show arrows only when hovering over the carousel or when it has focus\n * @default false\n */\n showArrowsOnHover?: boolean;\n\n /**\n * Focus style for interactive elements\n * @default 'default'\n */\n focusStyle?: 'default' | 'white';\n\n /* Dots/Tabs Props */\n /**\n * Size of pagination dots\n * @default 'md'\n */\n dotsSize?: 'md' | 'lg';\n\n /**\n * Visual style of pagination dots\n * @default 'standard'\n */\n dotsVariant?: 'standard' | 'transparent';\n\n /**\n * Whether to hide pagination dots\n * Note: Dots are automatically hidden when there's only one page\n * @default false\n */\n hideDots?: boolean;\n\n /* Autoplay Props */\n /**\n * Whether the autoplay is enabled\n * @default false\n */\n autoPlay?: boolean;\n\n /**\n * Interval in milliseconds between slides during autoplay\n * @default 2000\n */\n autoPlayInterval?: number;\n\n /**\n * Style variant for autoplay control button\n * @default 'neutralVibrant'\n */\n autoPlayStyleVariant?:\n | 'neutralVibrant'\n | 'neutralSubtle'\n | 'whiteVibrant'\n | 'whiteSubtle';\n\n /**\n * Size of autoplay control button\n * @default 'md'\n */\n autoPlayControlSize?: 'sm' | 'md';\n\n /**\n * Whether to enable mouse dragging for the carousel\n * @default true\n */\n mouseDragging?: boolean;\n\n /* Custom Class Names for Positioning and Styling */\n /**\n * Class name for the outermost wrapper of the carousel\n */\n carouselWrapperClassName?: string;\n\n /**\n * Class name for the previous button\n * Use this to position the previous button\n */\n prevArrowClassName?: string;\n\n /**\n * Class name for the next button\n * Use this to position the next button\n */\n nextArrowClassName?: string;\n\n /**\n * Class name for the autoplay control\n * Use this to position the autoplay button\n */\n autoplayControlClassName?: string;\n\n /**\n * Class name for the dots container\n * Use this to position the pagination dots\n */\n dotsContainerClassName?: string;\n\n /**\n * Class name for the dots wrapper\n * Use this to style the dots wrapper\n */\n dotsWrapperClassName?: string;\n\n /**\n * Class name for individual dots\n */\n dotClassName?: string;\n\n /**\n * Class name for the active dot\n */\n activeDotClassName?: string;\n\n /**\n * Class name for individual carousel item wrappers\n * Use this to style the wrapper div around each carousel item\n */\n itemWrapperClassName?: string;\n\n /**\n * Class name for the currently active/visible carousel item\n * This class is applied to the item that corresponds to the current page\n */\n activeItemClassName?: string;\n\n /**\n * Callback fired when a carousel navigation button (prev/next) is pressed\n */\n onArrowPress?: (direction: 'prev' | 'next') => void;\n\n /**\n * Callback fired when a dot is pressed\n */\n onDotPress?: (index: number) => void;\n\n /**\n * Callback fired when the autoplay button is pressed\n */\n onAutoplayPress?: (state: 'play' | 'pause') => void;\n\n /**\n * Callback fired whenever the active page changes, regardless of input method\n * (arrow buttons, trackpad scroll, touch swipe, keyboard navigation, dot press, autoplay)\n * Use this to track all carousel navigation events, e.g. for analytics\n * @param index - zero-based index of the new active page\n */\n onPageChange?: (index: number) => void;\n}\n\ntype ResponsiveKeys =\n | 'itemsPerPage'\n | 'spaceBetweenItems'\n | 'scrollPadding'\n | 'showArrowsOnHover'\n | 'arrowSize'\n | 'hideDots';\n\nexport type CarouselProps = WithResponsive<CarouselBaseProps, ResponsiveKeys>;\n\nexport const Carousel = ({\n children = [],\n 'aria-label': ariaLabel,\n 'aria-describedby': ariaDescribedby,\n looping = 'off',\n itemsPerPage = 1,\n spaceBetweenItems = 0,\n scrollPadding,\n\n // Button and Controls Props\n iconType = 'chevron',\n arrowStyleVariant = 'neutral',\n arrowSize = 'md',\n hideDisabledArrow = false,\n showArrowsOnHover = false,\n focusStyle = 'default',\n\n // Dots/Tabs Props\n dotsSize = 'md',\n dotsVariant = 'standard',\n hideDots = false,\n\n // Autoplay Props\n autoPlay = false,\n autoPlayInterval = 2000,\n autoPlayStyleVariant = 'neutralVibrant',\n autoPlayControlSize = 'md',\n\n // Mouse Dragging\n mouseDragging = true,\n\n // Custom Class Names\n carouselWrapperClassName = '',\n prevArrowClassName = '',\n nextArrowClassName = '',\n autoplayControlClassName = '',\n dotsContainerClassName = '',\n dotsWrapperClassName = '',\n dotClassName = '',\n activeDotClassName = '',\n itemWrapperClassName = '',\n activeItemClassName = '',\n\n // Event Callbacks\n onArrowPress,\n onDotPress,\n onAutoplayPress,\n onPageChange,\n}: CarouselProps) => {\n // Map looping values to expected loop values for AriaCarousel\n const getLoopValue = () => {\n if (looping === 'infinite') return 'infinite';\n if (looping === 'backToStart') return 'native';\n if (looping === 'off') return undefined;\n return looping; // other values pass through\n };\n\n const items = React.Children.toArray(children);\n const totalItems = items.length;\n\n const breakpoint = useBreakpoint();\n const resolvedItemsPerPage =\n resolveResponsiveProp(itemsPerPage, breakpoint) ?? 1;\n const resolvedSpaceBetweenItems =\n resolveResponsiveProp(spaceBetweenItems, breakpoint) ?? 0;\n const resolvedScrollPadding =\n resolveResponsiveProp(scrollPadding, breakpoint) ?? undefined;\n const resolvedArrowSize =\n resolveResponsiveProp(arrowSize, breakpoint) ?? 'md';\n const resolvedHideDots = resolveResponsiveProp(hideDots, breakpoint) ?? false;\n\n // Ensure itemsPerPage is at least 1\n // We allow decimal values for showing partial items\n const safeItemsPerPage = Math.max(1, resolvedItemsPerPage);\n\n // Calculate total pages based on items per page\n const totalPages = Math.ceil(totalItems / safeItemsPerPage);\n\n // Determine if dots should be shown\n // Hide dots if:\n // 1. resolvedHideDots prop is true (responsive), OR\n // 2. There's only one page (totalPages <= 1)\n const shouldShowDots = !resolvedHideDots && totalPages > 1;\n\n const carouselRef = useRef<HTMLDivElement>(null);\n const ariaCarouselRef = useRef<HTMLDivElement>(null);\n\n const [currentPage, setCurrentPage] = useState(0);\n const [prevPage, setPrevPage] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [isTransitioning] = useState(false);\n\n // Add state variables for drag/link handling\n const [dragStartPosition, setDragStartPosition] = useState<{\n x: number;\n y: number;\n } | null>(null);\n const dragThreshold = 5; // Pixels of movement needed to consider as a drag\n\n // Helper function to get class names with defaults\n const getClassNameWithDefault = (\n customClassName: string,\n defaultClassName: string,\n ): string => {\n return customClassName || defaultClassName;\n };\n\n // Get CSS classes based on showing partial items\n const getCarouselWrapperClasses = () => {\n const classes = [styles.carouselWrapper];\n\n if (!Number.isInteger(safeItemsPerPage)) {\n classes.push(styles.showPartialItems);\n }\n\n if (resolvedScrollPadding) {\n classes.push(styles.hasScrollPadding);\n }\n\n // Apply default wrapper class if no custom wrapper class is provided\n if (carouselWrapperClassName && carouselWrapperClassName.trim()) {\n classes.push(carouselWrapperClassName);\n } else {\n classes.push(styles.defaultCarouselWrapper);\n }\n\n return classes.join(' ');\n };\n\n // Determine if we need to set CSS variables and return only what's needed\n const getCssVariables = () => {\n const cssVars: Record<string, string> = {};\n\n // Only set these if they differ from defaults\n if (resolvedItemsPerPage !== 1) {\n cssVars['--items-per-page'] = String(safeItemsPerPage);\n }\n\n if (resolvedSpaceBetweenItems > 0) {\n cssVars['--space-between-items'] = `${resolvedSpaceBetweenItems}px`;\n }\n\n if (resolvedScrollPadding) {\n cssVars['--scroll-padding'] = resolvedScrollPadding;\n }\n\n return Object.keys(cssVars).length > 0 ? cssVars : undefined;\n };\n\n // Helper function to determine which items are currently active/visible\n const getActiveItemIndices = () => {\n const startIndex = currentPage * Math.floor(safeItemsPerPage);\n const endIndex = Math.min(\n startIndex + Math.ceil(safeItemsPerPage),\n totalItems,\n );\n\n const activeIndices: number[] = [];\n for (let i = startIndex; i < endIndex; i++) {\n activeIndices.push(i);\n }\n\n return activeIndices;\n };\n\n const navigateToSlide = (index: number) => {\n if (index === currentPage || index < 0 || index >= totalPages) {\n return;\n }\n\n // Find and click the corresponding hidden tab\n if (carouselRef.current) {\n const targetTab = carouselRef.current.querySelector(\n `[data-slide-tab=\"true\"][data-index=\"${index}\"]`,\n ) as HTMLElement;\n\n if (targetTab) {\n targetTab.click();\n }\n }\n };\n\n // Add effect to handle link click prevention during drag\n useEffect(() => {\n if (!carouselRef.current || !mouseDragging) return;\n\n // Function to prevent click events on links during/after drag\n const preventLinkActivation = (e: MouseEvent) => {\n // If we are currently dragging, or just finished dragging, prevent link clicks\n if (isDragging) {\n e.preventDefault();\n e.stopPropagation();\n\n // Reset isDragging after the current event cycle completes\n setTimeout(() => {\n setIsDragging(false);\n }, 0);\n }\n };\n\n // Function to handle mouse down events\n const handleMouseDown = (e: MouseEvent) => {\n setDragStartPosition({ x: e.clientX, y: e.clientY });\n };\n\n // Function to handle mouse move events\n const handleMouseMove = (e: MouseEvent) => {\n if (dragStartPosition === null) return;\n\n // Calculate the distance moved\n const dx = Math.abs(e.clientX - dragStartPosition.x);\n const dy = Math.abs(e.clientY - dragStartPosition.y);\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // If the user has moved more than the threshold, consider it a drag\n if (distance > dragThreshold) {\n setIsDragging(true);\n }\n };\n\n // Function to handle mouse up events\n const handleMouseUp = () => {\n // If this wasn't a drag, don't interfere with normal clicks\n if (!isDragging) {\n setDragStartPosition(null);\n return;\n }\n\n // Add a brief delay for the click prevention to work\n setTimeout(() => {\n setIsDragging(false);\n setDragStartPosition(null);\n }, 50);\n };\n\n // Add event listeners for the carousel container\n const carouselElement = carouselRef.current;\n\n // Capture phase is important to catch events before they reach the links\n carouselElement.addEventListener('mousedown', handleMouseDown, true);\n carouselElement.addEventListener('mousemove', handleMouseMove, true);\n carouselElement.addEventListener('mouseup', handleMouseUp, true);\n\n // This is the key event listener that prevents link activation\n carouselElement.addEventListener('click', preventLinkActivation, true);\n\n return () => {\n // Clean up event listeners\n carouselElement.removeEventListener('mousedown', handleMouseDown, true);\n carouselElement.removeEventListener('mousemove', handleMouseMove, true);\n carouselElement.removeEventListener('mouseup', handleMouseUp, true);\n carouselElement.removeEventListener('click', preventLinkActivation, true);\n };\n }, [mouseDragging, isDragging, dragStartPosition, dragThreshold]);\n\n // Handle transition direction\n useEffect(() => {\n if (carouselRef.current) {\n const scroller = carouselRef.current.querySelector(`.${styles.scroller}`);\n if (scroller && scroller instanceof HTMLElement) {\n if (prevPage < currentPage) {\n scroller.classList.remove(styles.slideLeft);\n scroller.classList.add(styles.slideRight);\n } else if (prevPage > currentPage) {\n scroller.classList.remove(styles.slideRight);\n scroller.classList.add(styles.slideLeft);\n }\n }\n }\n }, [currentPage, prevPage]);\n\n // Track selected tab changes\n useEffect(() => {\n if (!carouselRef.current) return;\n\n const checkCurrentPage = () => {\n if (!carouselRef.current) return;\n\n // Find the currently selected tab\n const selectedTab = carouselRef.current.querySelector(\n '[data-slide-tab=\"true\"][aria-selected=\"true\"]',\n );\n if (selectedTab) {\n const indexStr = (selectedTab as HTMLElement).dataset.index;\n if (typeof indexStr === 'string' && indexStr.length > 0) {\n const newIndex = parseInt(indexStr, 10);\n if (\n !isNaN(newIndex) &&\n newIndex !== currentPage &&\n newIndex >= 0 &&\n newIndex < totalPages\n ) {\n setPrevPage(currentPage);\n setCurrentPage(newIndex);\n }\n }\n }\n };\n\n // Set up mutation observer to watch for aria-selected changes\n const observer = new MutationObserver((mutations) => {\n let shouldCheck = false;\n mutations.forEach((mutation) => {\n if (\n mutation.type === 'attributes' &&\n mutation.attributeName === 'aria-selected'\n ) {\n shouldCheck = true;\n }\n });\n\n if (shouldCheck) {\n // Small delay to ensure DOM is updated\n setTimeout(checkCurrentPage, 10);\n }\n });\n\n // Observe all hidden tabs\n const hiddenTabs = carouselRef.current.querySelectorAll(\n '[data-slide-tab=\"true\"]',\n );\n hiddenTabs.forEach((tab) => {\n observer.observe(tab, {\n attributes: true,\n attributeFilter: ['aria-selected'],\n });\n });\n\n // Initial check\n checkCurrentPage();\n\n // Also check periodically as backup\n const interval = setInterval(checkCurrentPage, 500);\n\n return () => {\n observer.disconnect();\n clearInterval(interval);\n };\n }, [currentPage, totalPages]);\n\n // Interaction handlers for hover and focus\n const interactionHandlers = showArrowsOnHover\n ? {\n onMouseEnter: () => setIsHovered(true),\n onMouseLeave: () => setIsHovered(false),\n onFocus: () => setIsFocused(true),\n onBlur: (e: React.FocusEvent) => {\n // Only blur if focus is moving outside the carousel\n if (!e.currentTarget.contains(e.relatedTarget as Node)) {\n setIsFocused(false);\n }\n },\n }\n : {};\n\n // Determine whether arrows should be visible\n // Hide arrows if:\n // 1. There's only one page (all items fit on screen), OR\n // 2. showArrowsOnHover is true and carousel is not hovered/focused\n const shouldShowArrows = totalPages > 1;\n const arrowsVisible =\n shouldShowArrows && (!showArrowsOnHover || isHovered || isFocused);\n\n // Get style object only if we have variables to set\n const cssVars = getCssVariables();\n\n const { focusProps, isFocusVisible } = useFocusRing();\n\n // Custom styles for grid-auto-columns calculation\n const getScrollerStyles = () => {\n const styles: React.CSSProperties = {};\n\n // ALWAYS apply gap if spaceBetweenItems is set, regardless of itemsPerPage\n if (resolvedSpaceBetweenItems >= 0) {\n styles.gap = `${resolvedSpaceBetweenItems}px`;\n }\n\n // Only calculate grid-auto-columns if we have multiple items per page AND spacing\n if (resolvedItemsPerPage > 1 && resolvedSpaceBetweenItems > 0) {\n // Advanced calculation for grid layout to account for gap spacing\n const gapSpacePerItem =\n (resolvedSpaceBetweenItems * (safeItemsPerPage - 1)) / safeItemsPerPage;\n\n styles.gridAutoColumns = `calc(${100 / safeItemsPerPage}% - ${gapSpacePerItem}px)`;\n } else if (resolvedItemsPerPage > 1) {\n // No gap, just divide width evenly\n styles.gridAutoColumns = `${100 / safeItemsPerPage}%`;\n }\n\n return styles;\n };\n\n // Get active item indices for the current page\n const activeItemIndices = getActiveItemIndices();\n\n // Handle carousel keyboard navigation\n const handleCarouselKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n // Navigate to previous slide\n const prevButton = carouselRef.current?.querySelector(\n '[dir=\"prev\"]',\n ) as HTMLButtonElement;\n if (prevButton && !prevButton.disabled) {\n prevButton.click();\n }\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n // Navigate to next slide\n const nextButton = carouselRef.current?.querySelector(\n '[dir=\"next\"]',\n ) as HTMLButtonElement;\n if (nextButton && !nextButton.disabled) {\n nextButton.click();\n }\n } else if (e.key === 'Home') {\n e.preventDefault();\n // Go to first slide\n navigateToSlide(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n // Go to last slide\n navigateToSlide(totalPages - 1);\n }\n };\n\n // Generate a meaningful default aria-label if none provided\n const getDefaultAriaLabel = () => {\n if (ariaLabel) return ariaLabel;\n\n const currentSlideNumber = currentPage + 1;\n const autoplayStatus = autoPlay ? ', autoplay enabled' : '';\n\n return `Carousel with ${totalItems} items, currently showing slide ${currentSlideNumber} of ${totalPages}${autoplayStatus}`;\n };\n\n return (\n <div\n className={getCarouselWrapperClasses()}\n ref={carouselRef}\n style={cssVars as React.CSSProperties}\n data-dots-size={dotsSize}\n {...interactionHandlers}\n data-arrows-visible={arrowsVisible ? 'true' : 'false'}\n data-transitioning={isTransitioning ? 'true' : undefined}\n data-scroll-padding={resolvedScrollPadding}\n role=\"region\"\n aria-label={getDefaultAriaLabel()}\n aria-describedby={ariaDescribedby}\n aria-roledescription=\"carousel\"\n >\n <AriaCarousel\n className={`${carousel({ looping })}`}\n loop={getLoopValue()}\n ref={ariaCarouselRef}\n autoplay={autoPlay}\n autoplayInterval={autoPlayInterval}\n mouseDragging={mouseDragging && !isTransitioning}\n onDragStart={(e) => {\n setIsDragging(true);\n if (e && e.nativeEvent) {\n setDragStartPosition({\n x: e.nativeEvent.clientX,\n y: e.nativeEvent.clientY,\n });\n }\n }}\n onDragEnd={() => {\n // We keep isDragging true for a short time after drag ends\n // This helps ensure click events don't fire immediately after dragging\n setTimeout(() => {\n setIsDragging(false);\n }, 50);\n }}\n data-dragging={isDragging ? 'true' : 'false'}\n itemsPerPage={safeItemsPerPage}\n scrollPadding={resolvedScrollPadding}\n data-has-space-between={\n resolvedSpaceBetweenItems > 0 ? 'true' : undefined\n }\n data-items-per-page={\n resolvedItemsPerPage !== 1 ? safeItemsPerPage.toString() : undefined\n }\n onActivePageIndexChange={onPageChange ? ({ index }) => onPageChange(index) : undefined}\n >\n <AriaCarouselScroller\n className={`${styles.scroller} ${focusStyleVariants({ focusStyle })}`}\n {...focusProps}\n data-focused={isFocusVisible ? true : undefined}\n data-focus-visible={isFocusVisible ? true : undefined}\n data-transitioning={isTransitioning ? 'true' : undefined}\n style={getScrollerStyles()}\n tabIndex={0}\n role=\"region\"\n aria-label=\"Carousel content\"\n onKeyDown={handleCarouselKeyDown}\n >\n {items.map((child, index) => {\n const isActiveItem = activeItemIndices.includes(index);\n const itemClasses = [\n itemWrapperClassName || '',\n styles.item,\n isActiveItem && activeItemClassName ? activeItemClassName : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <AriaCarouselItem\n key={index}\n className={itemClasses}\n data-is-active={isActiveItem ? 'true' : undefined}\n data-item-index={index}\n aria-label={`Slide ${index + 1} of ${totalItems}`}\n >\n {child}\n </AriaCarouselItem>\n );\n })}\n </AriaCarouselScroller>\n\n <div\n className={`${styles.controls} ${showArrowsOnHover ? styles.showOnHover : ''}`}\n >\n <CarouselButton\n dir=\"prev\"\n variant={arrowStyleVariant}\n size={resolvedArrowSize}\n focusStyle={focusStyle}\n iconType={iconType}\n hideDisabledArrow={hideDisabledArrow}\n onPress={() => onArrowPress?.('prev')}\n className={`${getClassNameWithDefault(prevArrowClassName, styles.defaultPrevButton)} ${!arrowsVisible ? styles.hidden : ''}`}\n />\n\n <CarouselButton\n dir=\"next\"\n variant={arrowStyleVariant}\n size={resolvedArrowSize}\n focusStyle={focusStyle}\n iconType={iconType}\n hideDisabledArrow={hideDisabledArrow}\n onPress={() => onArrowPress?.('next')}\n className={`${getClassNameWithDefault(nextArrowClassName, styles.defaultNextButton)} ${!arrowsVisible ? styles.hidden : ''}`}\n />\n </div>\n\n <div className={styles.hiddenTabs}>\n <AriaCarouselTabs>\n {(page) => (\n <AriaCarouselTab\n key={page.index}\n index={page.index}\n data-index={page.index}\n data-slide-tab=\"true\"\n tabIndex={-1}\n />\n )}\n </AriaCarouselTabs>\n </div>\n\n {autoPlay && (\n <div\n className={`${styles.autoplayControlWrapper} ${getClassNameWithDefault(autoplayControlClassName, styles.defaultAutoplayControl)}`}\n >\n <AutoplayControl\n variant={autoPlayStyleVariant}\n size={autoPlayControlSize}\n className=\"\"\n onPress={onAutoplayPress}\n />\n </div>\n )}\n\n {shouldShowDots && (\n <CarouselDots\n totalItems={totalPages}\n currentPage={currentPage}\n onDotClick={(index) => navigateToSlide(index)}\n onPress={onDotPress}\n focusStyle={focusStyle}\n dotsSize={dotsSize}\n variant={dotsVariant}\n className={getClassNameWithDefault(\n dotsContainerClassName,\n styles.defaultDotsContainer,\n )}\n dotsWrapperClassName={dotsWrapperClassName}\n dotClassName={dotClassName}\n activeDotClassName={activeDotClassName}\n isTransitioning={isTransitioning}\n />\n )}\n </AriaCarousel>\n </div>\n );\n};\n\nexport default Carousel;\n"],"names":["carousel","cva","styles","variants","looping","infinite","backToStart","native","off","Carousel","children","ariaLabel","ariaDescribedby","itemsPerPage","spaceBetweenItems","scrollPadding","iconType","arrowStyleVariant","arrowSize","hideDisabledArrow","showArrowsOnHover","focusStyle","dotsSize","dotsVariant","hideDots","autoPlay","autoPlayInterval","autoPlayStyleVariant","autoPlayControlSize","mouseDragging","carouselWrapperClassName","prevArrowClassName","nextArrowClassName","autoplayControlClassName","dotsContainerClassName","dotsWrapperClassName","dotClassName","activeDotClassName","itemWrapperClassName","activeItemClassName","onArrowPress","onDotPress","onAutoplayPress","onPageChange","items","React","Children","toArray","totalItems","length","breakpoint","useBreakpoint","resolvedItemsPerPage","resolveResponsiveProp","resolvedSpaceBetweenItems","resolvedScrollPadding","resolvedArrowSize","resolvedHideDots","safeItemsPerPage","Math","max","totalPages","ceil","shouldShowDots","carouselRef","useRef","ariaCarouselRef","currentPage","setCurrentPage","useState","prevPage","setPrevPage","isDragging","setIsDragging","isHovered","setIsHovered","isFocused","setIsFocused","isTransitioning","dragStartPosition","setDragStartPosition","getClassNameWithDefault","customClassName","defaultClassName","navigateToSlide","index","current","targetTab","querySelector","click","useEffect","preventLinkActivation","e","preventDefault","stopPropagation","setTimeout","handleMouseDown","x","clientX","y","clientY","handleMouseMove","dx","abs","dy","sqrt","handleMouseUp","carouselElement","addEventListener","removeEventListener","scroller","HTMLElement","classList","remove","slideLeft","add","slideRight","checkCurrentPage","selectedTab","indexStr","dataset","newIndex","parseInt","isNaN","observer","MutationObserver","mutations","shouldCheck","forEach","mutation","type","attributeName","querySelectorAll","tab","observe","attributes","attributeFilter","interval","setInterval","disconnect","clearInterval","interactionHandlers","onMouseEnter","onMouseLeave","onFocus","onBlur","currentTarget","contains","relatedTarget","arrowsVisible","cssVars","String","Object","keys","getCssVariables","focusProps","isFocusVisible","useFocusRing","activeItemIndices","startIndex","floor","endIndex","min","activeIndices","i","push","getActiveItemIndices","jsx","className","classes","carouselWrapper","Number","isInteger","showPartialItems","hasScrollPadding","trim","defaultCarouselWrapper","join","getCarouselWrapperClasses","ref","style","role","getDefaultAriaLabel","jsxs","AriaCarousel","loop","autoplay","autoplayInterval","onDragStart","nativeEvent","onDragEnd","toString","onActivePageIndexChange","AriaCarouselScroller","focusStyleVariants","gap","gapSpacePerItem","gridAutoColumns","getScrollerStyles","tabIndex","onKeyDown","key","prevButton","disabled","nextButton","map","child","isActiveItem","includes","itemClasses","item","filter","Boolean","AriaCarouselItem","controls","showOnHover","CarouselButton","dir","variant","size","onPress","defaultPrevButton","hidden","defaultNextButton","hiddenTabs","AriaCarouselTabs","page","AriaCarouselTab","autoplayControlWrapper","defaultAutoplayControl","AutoplayControl","CarouselDots","onDotClick","defaultDotsContainer"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { SectionProps } from '../Section';
|
|
3
|
+
import { ResponsiveValue, WithResponsiveProps } from '../../utils/breakpoint/responsiveSSR';
|
|
4
|
+
type IntroSectionAlignContent = 'start' | 'center';
|
|
5
|
+
interface IntroSectionBaseProps {
|
|
6
|
+
children?: React.ReactNode;
|
|
7
|
+
alignContent?: IntroSectionAlignContent;
|
|
8
|
+
paddingTop?: SectionProps['paddingTop'];
|
|
9
|
+
paddingBottom?: SectionProps['paddingBottom'];
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
export type IntroSectionProps = WithResponsiveProps<IntroSectionBaseProps, 'alignContent' | 'paddingTop' | 'paddingBottom'>;
|
|
13
|
+
export interface IntroSectionHeaderProps {
|
|
14
|
+
/** Primary heading text rendered inside an `<h1>`. */
|
|
15
|
+
title?: string;
|
|
16
|
+
/** Secondary subtitle text rendered below the title. */
|
|
17
|
+
subtitle?: string;
|
|
18
|
+
/** Slot subcomponents to render within the header (e.g. `IntroSection.StartSlot`, `IntroSection.EndSlot`). */
|
|
19
|
+
children?: React.ReactNode;
|
|
20
|
+
/** Additional CSS class names applied to the `<header>` element. */
|
|
21
|
+
className?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface IntroSectionActionsProps {
|
|
24
|
+
actions?: React.ReactNode;
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
alignContent?: ResponsiveValue<IntroSectionAlignContent>;
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface IntroSectionSlotProps {
|
|
30
|
+
/** Content to render inside the slot. */
|
|
31
|
+
children: React.ReactNode;
|
|
32
|
+
/** Additional CSS class names applied to the slot wrapper. */
|
|
33
|
+
className?: string;
|
|
34
|
+
}
|
|
35
|
+
interface IntroSectionComponent extends React.FC<IntroSectionProps> {
|
|
36
|
+
Header: React.FC<IntroSectionHeaderProps>;
|
|
37
|
+
Actions: React.FC<IntroSectionActionsProps>;
|
|
38
|
+
StartSlot: React.FC<IntroSectionSlotProps>;
|
|
39
|
+
EndSlot: React.FC<IntroSectionSlotProps>;
|
|
40
|
+
}
|
|
41
|
+
export declare const IntroSection: IntroSectionComponent;
|
|
42
|
+
export default IntroSection;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{jsxs as t,jsx as e}from"react/jsx-runtime";import n from"../Section/Section.js";import{Heading as o}from"../Heading/Heading.js";import{SubHeading as i}from"../SubHeading/SubHeading.js";import{getBaseValueOrUndefined as r,generateResponsiveClasses as s}from"../../utils/breakpoint/responsiveSSR.js";import{responsiveToCssVars as a}from"../../utils/breakpoint/responsiveToCssVars.js";import{a as l}from"../../flex-BJOhaXnU.js";import{a as c}from"../../padding-nClUzhWp.js";import '../../assets/IntroSection.css';const d={"intro-section":"_intro-section_187d3_1","intro-section__header":"_intro-section__header_187d3_13","intro-section__actions":"_intro-section__actions_187d3_20","intro-section__heading":"_intro-section__heading_187d3_36","intro-section__subheading":"_intro-section__subheading_187d3_41","intro-section__start-slot":"_intro-section__start-slot_187d3_54","intro-section__end-slot":"_intro-section__end-slot_187d3_61"},_=s(l),m=s(c),p=t=>"center"===t?"center":"flexStart",f=(t,e="default")=>null==t?e:"object"==typeof t?null!=t.base?t:{base:e,...t}:t,g=({title:n,subtitle:r,children:s,className:a})=>{const l=(n??"").trim().length>0,c=(r??"").trim().length>0;return l||c||s?/* @__PURE__ */t("header",{className:[d["intro-section__header"],a].filter(Boolean).join(" "),children:[l?/* @__PURE__ */e("div",{className:d["intro-section__heading"],children:/* @__PURE__ */e(o,{as:"h1",foregroundColor:"accentSecondary",children:n})}):null,c?/* @__PURE__ */e("div",{className:d["intro-section__subheading"],children:/* @__PURE__ */e(i,{as:"span",size:"xs",foregroundColor:"secondary",children:r})}):null,s]}):null},u=({actions:t,children:n,alignContent:o,className:i})=>{const r=a(o??null,{varPrefix:"--intro-section-actions-text-align",normalise:t=>"center"===t?"center":"start"});/* @__PURE__ */
|
|
2
|
+
return e("div",{style:r,className:[d["intro-section__actions"],i].filter(Boolean).join(" "),children:t??n})},h=({children:t,className:n})=>/* @__PURE__ */e("div",{className:[d["intro-section__start-slot"],n].filter(Boolean).join(" "),children:t}),S=({children:t,className:n})=>/* @__PURE__ */e("div",{className:[d["intro-section__end-slot"],n].filter(Boolean).join(" "),children:t}),b=({children:t,alignContent:o,paddingTop:i,paddingBottom:s,className:l})=>{const c=f(i),g=f(s,"sm"),u="object"==typeof o?Object.fromEntries(Object.entries(o).filter(([,t])=>null!=t).map(([t,e])=>[t,p(e)])):null,h="object"==typeof o?p(r(o)??"start"):null!=o?p(o):"flexStart",S=_(u,"flex-align-items"),b=r(c)??"default",j=r(g)??"sm",N=m(c,"padding-top"),x=m(g,"padding-bottom"),y=a(o??null,{varPrefix:"--intro-section-text-align",normalise:t=>"center"===t?"center":"start"});/* @__PURE__ */
|
|
3
|
+
return e(n,{containerMaxWidth:"page",backgroundColor:"base",paddingX:"default",paddingTop:b,paddingBottom:j,style:y,className:[d["intro-section"],l,...N,...x].filter(Boolean).join(" "),children:/* @__PURE__ */e(n.Container,{flexDirection:"column",alignItems:h,className:S.join(" "),children:t})})};b.Header=g,b.Actions=u,b.StartSlot=h,b.EndSlot=S,g.displayName="IntroSection.Header",u.displayName="IntroSection.Actions",h.displayName="IntroSection.StartSlot",S.displayName="IntroSection.EndSlot",b.displayName="IntroSection";export{b as IntroSection,b as default};
|
|
4
|
+
//# sourceMappingURL=IntroSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IntroSection.js","sources":["../../../src/components/IntroSection/IntroSection.tsx"],"sourcesContent":["import React from 'react';\nimport Section from '../Section';\nimport type { SectionProps } from '../Section';\nimport Heading from '../Heading';\nimport SubHeading from '../SubHeading';\nimport {\n generateResponsiveClasses,\n getBaseValueOrUndefined,\n type ResponsiveValue,\n type WithResponsiveProps,\n} from '../../utils/breakpoint/responsiveSSR';\nimport { responsiveToCssVars } from '../../utils/breakpoint/responsiveToCssVars';\nimport flexStyles from '../../utils/flex/flex.module.css';\nimport paddingStyles from '../../utils/padding/padding.module.css';\nimport styles from './IntroSection.module.css';\n\ntype IntroSectionAlignContent = 'start' | 'center';\ntype AlignItemsValue = 'flexStart' | 'center';\n\nconst getFlexResponsiveClasses = generateResponsiveClasses(flexStyles);\nconst getPaddingResponsiveClasses = generateResponsiveClasses(paddingStyles);\n\nconst toAlignItems = (v: IntroSectionAlignContent): AlignItemsValue =>\n v === 'center' ? 'center' : 'flexStart';\n\nconst withDefaultPadding = (\n value: SectionProps['paddingTop'],\n defaultValue: Extract<\n NonNullable<SectionProps['paddingTop']>,\n string\n > = 'default',\n): SectionProps['paddingTop'] => {\n if (value == null) {\n return defaultValue;\n }\n\n if (typeof value === 'object') {\n return value.base != null ? value : { base: defaultValue, ...value };\n }\n\n return value;\n};\n\ninterface IntroSectionBaseProps {\n children?: React.ReactNode;\n alignContent?: IntroSectionAlignContent;\n paddingTop?: SectionProps['paddingTop'];\n paddingBottom?: SectionProps['paddingBottom'];\n className?: string;\n}\n\nexport type IntroSectionProps = WithResponsiveProps<\n IntroSectionBaseProps,\n 'alignContent' | 'paddingTop' | 'paddingBottom'\n>;\n\nexport interface IntroSectionHeaderProps {\n /** Primary heading text rendered inside an `<h1>`. */\n title?: string;\n /** Secondary subtitle text rendered below the title. */\n subtitle?: string;\n /** Slot subcomponents to render within the header (e.g. `IntroSection.StartSlot`, `IntroSection.EndSlot`). */\n children?: React.ReactNode;\n /** Additional CSS class names applied to the `<header>` element. */\n className?: string;\n}\n\nconst IntroSectionHeader = ({\n title,\n subtitle,\n children,\n className,\n}: IntroSectionHeaderProps) => {\n const hasTitle = (title ?? '').trim().length > 0;\n const hasSubtitle = (subtitle ?? '').trim().length > 0;\n\n if (!hasTitle && !hasSubtitle && !children) {\n return null;\n }\n\n return (\n <header\n className={[styles['intro-section__header'], className]\n .filter(Boolean)\n .join(' ')}\n >\n {hasTitle ? (\n <div className={styles['intro-section__heading']}>\n <Heading as=\"h1\" foregroundColor=\"accentSecondary\">\n {title}\n </Heading>\n </div>\n ) : null}\n\n {hasSubtitle ? (\n <div className={styles['intro-section__subheading']}>\n <SubHeading as=\"span\" size=\"xs\" foregroundColor=\"secondary\">\n {subtitle}\n </SubHeading>\n </div>\n ) : null}\n\n {children}\n </header>\n );\n};\n\nexport interface IntroSectionActionsProps {\n actions?: React.ReactNode;\n children?: React.ReactNode;\n alignContent?: ResponsiveValue<IntroSectionAlignContent>;\n className?: string;\n}\n\nconst Actions = ({\n actions,\n children,\n alignContent,\n className,\n}: IntroSectionActionsProps) => {\n const actionsTextAlignVars = responsiveToCssVars(alignContent ?? null, {\n varPrefix: '--intro-section-actions-text-align',\n normalise: (value) => (value === 'center' ? 'center' : 'start'),\n });\n\n return (\n <div\n style={actionsTextAlignVars}\n className={[styles['intro-section__actions'], className]\n .filter(Boolean)\n .join(' ')}\n >\n {actions ?? children}\n </div>\n );\n};\n\nexport interface IntroSectionSlotProps {\n /** Content to render inside the slot. */\n children: React.ReactNode;\n /** Additional CSS class names applied to the slot wrapper. */\n className?: string;\n}\n\nconst StartSlot = ({ children, className }: IntroSectionSlotProps) => (\n <div\n className={[styles['intro-section__start-slot'], className]\n .filter(Boolean)\n .join(' ')}\n >\n {children}\n </div>\n);\n\nconst EndSlot = ({ children, className }: IntroSectionSlotProps) => (\n <div\n className={[styles['intro-section__end-slot'], className]\n .filter(Boolean)\n .join(' ')}\n >\n {children}\n </div>\n);\n\ninterface IntroSectionComponent extends React.FC<IntroSectionProps> {\n Header: React.FC<IntroSectionHeaderProps>;\n Actions: React.FC<IntroSectionActionsProps>;\n StartSlot: React.FC<IntroSectionSlotProps>;\n EndSlot: React.FC<IntroSectionSlotProps>;\n}\n\nexport const IntroSection = (({\n children,\n alignContent,\n paddingTop,\n paddingBottom,\n className,\n}: IntroSectionProps) => {\n const resolvedPaddingTop = withDefaultPadding(paddingTop);\n const resolvedPaddingBottom = withDefaultPadding(paddingBottom, 'sm');\n\n // Map the responsive alignContent object to Section's alignItems values\n const mappedResponsive =\n typeof alignContent === 'object'\n ? (Object.fromEntries(\n Object.entries(alignContent)\n .filter(([, v]) => v != null)\n .map(([bp, v]) => [\n bp,\n toAlignItems(v as IntroSectionAlignContent),\n ]),\n ) as Record<string, AlignItemsValue>)\n : null;\n\n // Resolve the base (non-responsive) alignItems value\n const baseAlignItems: AlignItemsValue =\n typeof alignContent === 'object'\n ? toAlignItems(\n (getBaseValueOrUndefined(alignContent) as IntroSectionAlignContent) ??\n 'start',\n )\n : alignContent != null\n ? toAlignItems(alignContent as IntroSectionAlignContent)\n : 'flexStart';\n\n // Generate responsive breakpoint classes with the correct CSS prefix\n const responsiveAlignClasses = getFlexResponsiveClasses(\n mappedResponsive,\n 'flex-align-items',\n );\n\n const basePaddingTop =\n getBaseValueOrUndefined(resolvedPaddingTop) ?? 'default';\n const basePaddingBottom =\n getBaseValueOrUndefined(resolvedPaddingBottom) ?? 'sm';\n\n const responsivePaddingTopClasses = getPaddingResponsiveClasses(\n resolvedPaddingTop,\n 'padding-top',\n );\n const responsivePaddingBottomClasses = getPaddingResponsiveClasses(\n resolvedPaddingBottom,\n 'padding-bottom',\n );\n\n const textAlignVars = responsiveToCssVars(alignContent ?? null, {\n varPrefix: '--intro-section-text-align',\n normalise: (value) => (value === 'center' ? 'center' : 'start'),\n });\n\n return (\n <Section\n containerMaxWidth=\"page\"\n backgroundColor=\"base\"\n paddingX=\"default\"\n paddingTop={basePaddingTop}\n paddingBottom={basePaddingBottom}\n style={textAlignVars}\n className={[\n styles['intro-section'],\n className,\n ...responsivePaddingTopClasses,\n ...responsivePaddingBottomClasses,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <Section.Container\n flexDirection=\"column\"\n alignItems={baseAlignItems}\n className={responsiveAlignClasses.join(' ')}\n >\n {children}\n </Section.Container>\n </Section>\n );\n}) as IntroSectionComponent;\n\nIntroSection.Header = IntroSectionHeader;\nIntroSection.Actions = Actions;\nIntroSection.StartSlot = StartSlot;\nIntroSection.EndSlot = EndSlot;\n\nIntroSectionHeader.displayName = 'IntroSection.Header';\nActions.displayName = 'IntroSection.Actions';\nStartSlot.displayName = 'IntroSection.StartSlot';\nEndSlot.displayName = 'IntroSection.EndSlot';\nIntroSection.displayName = 'IntroSection';\n\nexport default IntroSection;\n"],"names":["getFlexResponsiveClasses","generateResponsiveClasses","flexStyles","getPaddingResponsiveClasses","paddingStyles","toAlignItems","v","withDefaultPadding","value","defaultValue","base","IntroSectionHeader","title","subtitle","children","className","hasTitle","trim","length","hasSubtitle","jsxs","styles","filter","Boolean","join","jsx","Heading","as","foregroundColor","SubHeading","size","Actions","actions","alignContent","actionsTextAlignVars","responsiveToCssVars","varPrefix","normalise","style","StartSlot","EndSlot","IntroSection","paddingTop","paddingBottom","resolvedPaddingTop","resolvedPaddingBottom","mappedResponsive","Object","fromEntries","entries","map","bp","baseAlignItems","getBaseValueOrUndefined","responsiveAlignClasses","basePaddingTop","basePaddingBottom","responsivePaddingTopClasses","responsivePaddingBottomClasses","textAlignVars","Section","containerMaxWidth","backgroundColor","paddingX","Container","flexDirection","alignItems","Header","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -84,17 +84,17 @@ export interface MenuProps {
|
|
|
84
84
|
/**
|
|
85
85
|
* Component to replace default Button with another button-like component/element
|
|
86
86
|
*/
|
|
87
|
-
export declare const Trigger: React.ForwardRefExoticComponent<Omit<import('../Button/Button').ButtonBaseProps<"button">, "size" | "
|
|
87
|
+
export declare const Trigger: React.ForwardRefExoticComponent<Omit<import('../Button/Button').ButtonBaseProps<"button">, "size" | "textAlign" | "fullWidth"> & {
|
|
88
88
|
size?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<("lg" | "sm" | "md") | undefined>> | undefined;
|
|
89
|
-
fullWidth?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<boolean | undefined>> | undefined;
|
|
90
89
|
textAlign?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<("left" | "right" | "center") | undefined>> | undefined;
|
|
90
|
+
fullWidth?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<boolean | undefined>> | undefined;
|
|
91
91
|
} & React.RefAttributes<HTMLButtonElement>>;
|
|
92
92
|
export declare const Menu: {
|
|
93
93
|
({ label, "aria-label": ariaLabel, isDisabled, placement, buttonEmphasis, buttonStyleVariant, buttonOpenVariant, alignToElementId, shouldFlip, openOnHoverAndFocus, allowTabOut, closeOnHover, children, iconStartProps, iconEndProps, onOpenChange, }: MenuProps): import("react/jsx-runtime").JSX.Element;
|
|
94
|
-
Trigger: React.ForwardRefExoticComponent<Omit<import('../Button/Button').ButtonBaseProps<"button">, "size" | "
|
|
94
|
+
Trigger: React.ForwardRefExoticComponent<Omit<import('../Button/Button').ButtonBaseProps<"button">, "size" | "textAlign" | "fullWidth"> & {
|
|
95
95
|
size?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<("lg" | "sm" | "md") | undefined>> | undefined;
|
|
96
|
-
fullWidth?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<boolean | undefined>> | undefined;
|
|
97
96
|
textAlign?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<("left" | "right" | "center") | undefined>> | undefined;
|
|
97
|
+
fullWidth?: import('../../utils/breakpoint/responsiveSSR').ResponsiveValue<NonNullable<boolean | undefined>> | undefined;
|
|
98
98
|
} & React.RefAttributes<HTMLButtonElement>>;
|
|
99
99
|
};
|
|
100
100
|
export default Menu;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { BoxLinkProps } from '../BoxLink';
|
|
3
|
+
import { BoxProps } from '../Box';
|
|
4
|
+
export interface ProductTileProps {
|
|
5
|
+
/**
|
|
6
|
+
* Destination URL for the tile.
|
|
7
|
+
*/
|
|
8
|
+
href: NonNullable<BoxLinkProps['href']>;
|
|
9
|
+
/**
|
|
10
|
+
* The target attribute for the link.
|
|
11
|
+
* @default '_self'
|
|
12
|
+
*/
|
|
13
|
+
target?: BoxLinkProps['target'];
|
|
14
|
+
/**
|
|
15
|
+
* Leading media content.
|
|
16
|
+
*/
|
|
17
|
+
media: React.ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Main title content.
|
|
20
|
+
*/
|
|
21
|
+
title: string;
|
|
22
|
+
/**
|
|
23
|
+
* The width of the Box.
|
|
24
|
+
* Accepts any valid CSS unit or "full"
|
|
25
|
+
* @default '390px'
|
|
26
|
+
*/
|
|
27
|
+
width?: BoxProps['width'];
|
|
28
|
+
/**
|
|
29
|
+
* **[Responsive]** The maximum width of the Box.
|
|
30
|
+
* Accepts any valid CSS unit or "pageWidth" to use the `section-container-max-width` token.
|
|
31
|
+
* @default '390px'
|
|
32
|
+
*/
|
|
33
|
+
maxWidth?: BoxProps['maxWidth'];
|
|
34
|
+
/**
|
|
35
|
+
* Optional supporting text.
|
|
36
|
+
*/
|
|
37
|
+
description?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Optional details subcomponent content, such as `ProductTile.Details`.
|
|
40
|
+
*/
|
|
41
|
+
children?: React.ReactNode;
|
|
42
|
+
}
|
|
43
|
+
export interface ProductTileDetailsProps {
|
|
44
|
+
/** Content rendered inside the ProductTile details area. */
|
|
45
|
+
children: React.ReactNode;
|
|
46
|
+
}
|
|
47
|
+
interface ProductTileComponent extends React.ForwardRefExoticComponent<ProductTileProps & React.RefAttributes<HTMLAnchorElement>> {
|
|
48
|
+
Details: React.FC<ProductTileDetailsProps>;
|
|
49
|
+
}
|
|
50
|
+
export declare const ProductTile: ProductTileComponent;
|
|
51
|
+
export default ProductTile;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{jsx as t,jsxs as e}from"react/jsx-runtime";import{forwardRef as i}from"react";import{Box as o}from"../Box/Box.js";import{BoxLink as r}from"../BoxLink/BoxLink.js";import"../BoxLink/BoxLinkContext.js";import{Paragraph as c}from"../Paragraph/Paragraph.js";import{Icon as n}from"../Icon/Icon.js";import '../../assets/ProductTile.css';const d={"product-tile":"_product-tile_zcaft_1","product-tile__media":"_product-tile__media_zcaft_6","product-tile__content":"_product-tile__content_zcaft_12","product-tile__content-details":"_product-tile__content-details_zcaft_19","product-tile__content-icon":"_product-tile__content-icon_zcaft_26","product-tile__content-title":"_product-tile__content-title_zcaft_38"},a=({children:e})=>/* @__PURE__ */t("div",{className:d["product-tile__content-details"],children:e}),l=i(function({href:i,target:a,media:l,title:_,width:s="390px",maxWidth:p="390px",description:m,children:u},h){/* @__PURE__ */
|
|
2
|
+
return t(r,{href:i,target:a,styleVariant:"default",ref:h,children:/* @__PURE__ */t("div",{className:d["product-tile"],children:/* @__PURE__ */e(o,{paddingTop:"xs",paddingBottom:"xs",paddingLeft:"xs",paddingRight:"sm",backgroundColor:"layer2",borderRadius:"sm",display:"flex",flexDirection:"row",gap:"xs",width:s,maxWidth:p,alignItems:"center",justifyContent:"spaceBetween",children:[
|
|
3
|
+
/* @__PURE__ */t("div",{className:d["product-tile__media"],children:l}),
|
|
4
|
+
/* @__PURE__ */e("div",{className:d["product-tile__content"],children:[
|
|
5
|
+
/* @__PURE__ */t("div",{className:d["product-tile__content-title"],children:/* @__PURE__ */t(c,{foregroundColor:"accentSecondary",size:"md",children:/* @__PURE__ */t("strong",{children:_})})}),m&&/* @__PURE__ */t("div",{className:d["product-tile__content-description"],children:/* @__PURE__ */t(c,{foregroundColor:"secondary",size:"sm",children:m})}),u]}),
|
|
6
|
+
/* @__PURE__ */t("div",{className:d["product-tile__content-icon"],children:/* @__PURE__ */t(n,{iconName:"circle-arrow-right",iconSize:"1.5x",padding:"none",color:"accentSecondary",pull:"right"})})]})})})});l.Details=a,a.displayName="ProductTile.Details";export{l as ProductTile,l as default};
|
|
7
|
+
//# sourceMappingURL=ProductTile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProductTile.js","sources":["../../../src/components/ProductTile/ProductTile.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport styles from './ProductTile.module.css';\nimport Box from '../Box';\nimport BoxLink from '../BoxLink';\nimport type { BoxLinkProps } from '../BoxLink';\nimport type { BoxProps } from '../Box';\nimport Paragraph from '../Paragraph';\nimport Icon from '../Icon';\n\nexport interface ProductTileProps {\n /**\n * Destination URL for the tile.\n */\n href: NonNullable<BoxLinkProps['href']>;\n /**\n * The target attribute for the link.\n * @default '_self'\n */\n target?: BoxLinkProps['target'];\n /**\n * Leading media content.\n */\n media: React.ReactNode;\n /**\n * Main title content.\n */\n title: string;\n /**\n * The width of the Box.\n * Accepts any valid CSS unit or \"full\"\n * @default '390px'\n */\n width?: BoxProps['width'];\n /**\n * **[Responsive]** The maximum width of the Box.\n * Accepts any valid CSS unit or \"pageWidth\" to use the `section-container-max-width` token.\n * @default '390px'\n */\n maxWidth?: BoxProps['maxWidth'];\n /**\n * Optional supporting text.\n */\n description?: string;\n /**\n * Optional details subcomponent content, such as `ProductTile.Details`.\n */\n children?: React.ReactNode;\n}\n\nexport interface ProductTileDetailsProps {\n /** Content rendered inside the ProductTile details area. */\n children: React.ReactNode;\n}\n\ninterface ProductTileComponent\n extends React.ForwardRefExoticComponent<\n ProductTileProps & React.RefAttributes<HTMLAnchorElement>\n > {\n Details: React.FC<ProductTileDetailsProps>;\n}\n\nconst Details = ({ children }: ProductTileDetailsProps) => (\n <div className={styles['product-tile__content-details']}>{children}</div>\n);\n\nexport const ProductTile = forwardRef<HTMLAnchorElement, ProductTileProps>(\n function ProductTile(\n {\n href,\n target,\n media,\n title,\n width = '390px',\n maxWidth = '390px',\n description,\n children,\n },\n ref,\n ) {\n return (\n <BoxLink href={href} target={target} styleVariant=\"default\" ref={ref}>\n <div className={styles['product-tile']}>\n <Box\n paddingTop=\"xs\"\n paddingBottom=\"xs\"\n paddingLeft=\"xs\"\n paddingRight=\"sm\"\n backgroundColor=\"layer2\"\n borderRadius=\"sm\"\n display=\"flex\"\n flexDirection=\"row\"\n gap=\"xs\"\n width={width}\n maxWidth={maxWidth}\n alignItems=\"center\"\n justifyContent=\"spaceBetween\"\n >\n <div className={styles['product-tile__media']}>{media}</div>\n <div className={styles['product-tile__content']}>\n <div className={styles['product-tile__content-title']}>\n <Paragraph foregroundColor=\"accentSecondary\" size=\"md\">\n <strong>{title}</strong>\n </Paragraph>\n </div>\n {description && (\n <div className={styles['product-tile__content-description']}>\n <Paragraph foregroundColor=\"secondary\" size=\"sm\">\n {description}\n </Paragraph>\n </div>\n )}\n {children}\n </div>\n <div className={styles['product-tile__content-icon']}>\n <Icon\n iconName=\"circle-arrow-right\"\n iconSize=\"1.5x\"\n padding=\"none\"\n color=\"accentSecondary\"\n pull=\"right\"\n />\n </div>\n </Box>\n </div>\n </BoxLink>\n );\n },\n) as ProductTileComponent;\n\nProductTile.Details = Details;\nDetails.displayName = 'ProductTile.Details';\n\nexport default ProductTile;\n"],"names":["Details","children","jsx","className","styles","ProductTile","forwardRef","href","target","media","title","width","maxWidth","description","ref","BoxLink","styleVariant","jsxs","Box","paddingTop","paddingBottom","paddingLeft","paddingRight","backgroundColor","borderRadius","display","flexDirection","gap","alignItems","justifyContent","Paragraph","foregroundColor","size","Icon","iconName","iconSize","padding","color","pull","displayName"],"mappings":"+pBA6DMA,EAAU,EAAGC,6BACjBC,EAAC,MAAA,CAAIC,UAAWC,EAAO,iCAAmCH,aAG/CI,EAAcC,EACzB,UACEC,KACEA,EAAAC,OACAA,EAAAC,MACAA,EAAAC,MACAA,EAAAC,MACAA,EAAQ,QAAAC,SACRA,EAAW,QAAAC,YACXA,EAAAZ,SACAA,GAEFa;AAEA,SACGC,EAAA,CAAQR,OAAYC,SAAgBQ,aAAa,UAAUF,MAC1Db,wBAAAC,EAAC,MAAA,CAAIC,UAAWC,EAAO,gBACrBH,wBAAAgB,EAACC,EAAA,CACCC,WAAW,KACXC,cAAc,KACdC,YAAY,KACZC,aAAa,KACbC,gBAAgB,SAChBC,aAAa,KACbC,QAAQ,OACRC,cAAc,MACdC,IAAI,KACJhB,QACAC,WACAgB,WAAW,SACXC,eAAe,eAEf5B,SAAA;eAAAC,EAAC,MAAA,CAAIC,UAAWC,EAAO,uBAAyBH,SAAAQ;iBAC/C,MAAA,CAAIN,UAAWC,EAAO,yBACrBH,SAAA;eAAAC,EAAC,MAAA,CAAIC,UAAWC,EAAO,+BACrBH,wBAAAC,EAAC4B,EAAA,CAAUC,gBAAgB,kBAAkBC,KAAK,KAChD/B,wBAAAC,EAAC,SAAA,CAAQD,SAAAS,QAGZG,oBACE,MAAA,CAAIV,UAAWC,EAAO,qCACrBH,wBAAAC,EAAC4B,EAAA,CAAUC,gBAAgB,YAAYC,KAAK,KACzC/B,eAINA;iBAEF,MAAA,CAAIE,UAAWC,EAAO,8BACrBH,wBAAAC,EAAC+B,EAAA,CACCC,SAAS,qBACTC,SAAS,OACTC,QAAQ,OACRC,MAAM,kBACNC,KAAK,kBAOnB,GAGFjC,EAAYL,QAAUA,EACtBA,EAAQuC,YAAc"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -10,8 +10,14 @@ export { default as AviosCurrencySymbol } from './AviosCurrencySymbol';
|
|
|
10
10
|
export type * from './AviosCurrencySymbol';
|
|
11
11
|
export { default as Badge } from './Badge';
|
|
12
12
|
export type * from './Badge';
|
|
13
|
+
export { default as BannerSectionContent } from './BannerSectionContent';
|
|
14
|
+
export type * from './BannerSectionContent';
|
|
15
|
+
export { default as BannerSectionPlectrum } from './BannerSectionPlectrum';
|
|
16
|
+
export type * from './BannerSectionPlectrum';
|
|
13
17
|
export { default as Box } from './Box';
|
|
14
18
|
export type * from './Box';
|
|
19
|
+
export { default as BoxLink, BoxLinkContext, useBoxLink } from './BoxLink';
|
|
20
|
+
export type * from './BoxLink';
|
|
15
21
|
export { default as Breadcrumbs } from './Breadcrumbs';
|
|
16
22
|
export type * from './Breadcrumbs';
|
|
17
23
|
export { default as Button } from './Button';
|
|
@@ -84,6 +90,8 @@ export { default as IconButton } from './IconButton';
|
|
|
84
90
|
export type * from './IconButton';
|
|
85
91
|
export { default as Image } from './Image';
|
|
86
92
|
export type * from './Image';
|
|
93
|
+
export { default as IntroSection } from './IntroSection';
|
|
94
|
+
export type * from './IntroSection';
|
|
87
95
|
export { default as Label } from './Label';
|
|
88
96
|
export type * from './Label';
|
|
89
97
|
export { default as Link } from './Link';
|
|
@@ -102,12 +110,14 @@ export { default as NumberField } from './NumberField';
|
|
|
102
110
|
export type * from './NumberField';
|
|
103
111
|
export { default as Paragraph } from './Paragraph';
|
|
104
112
|
export type * from './Paragraph';
|
|
113
|
+
export { default as PasswordField } from './PasswordField';
|
|
114
|
+
export type * from './PasswordField';
|
|
105
115
|
export { default as PhoneNumberField } from './PhoneNumberField';
|
|
106
116
|
export type * from './PhoneNumberField';
|
|
107
117
|
export { default as Popover } from './Popover';
|
|
108
118
|
export type * from './Popover';
|
|
109
|
-
export { default as
|
|
110
|
-
export type * from './
|
|
119
|
+
export { default as ProductTile } from './ProductTile';
|
|
120
|
+
export type * from './ProductTile';
|
|
111
121
|
export { default as Radio } from './Radio';
|
|
112
122
|
export type * from './Radio';
|
|
113
123
|
export { default as RadioGroup } from './RadioGroup';
|
package/dist/components/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import '../assets/global.css';/* empty css */import{Accordion as o,AccordionGroup as r}from"./Accordion/Accordion.js";import{AviosCurrencyBadge as e}from"./AviosCurrencyBadge/AviosCurrencyBadge.js";import{AviosCurrency as i}from"./AviosCurrency/AviosCurrency.js";import{AviosBadge as t}from"./AviosBadge/AviosBadge.js";import{AviosCurrencySymbol as m}from"./AviosCurrencySymbol/AviosCurrencySymbol.js";import{Badge as a}from"./Badge/Badge.js";import{
|
|
1
|
+
import '../assets/global.css';/* empty css */import{Accordion as o,AccordionGroup as r}from"./Accordion/Accordion.js";import{AviosCurrencyBadge as e}from"./AviosCurrencyBadge/AviosCurrencyBadge.js";import{AviosCurrency as i}from"./AviosCurrency/AviosCurrency.js";import{AviosBadge as t}from"./AviosBadge/AviosBadge.js";import{AviosCurrencySymbol as m}from"./AviosCurrencySymbol/AviosCurrencySymbol.js";import{Badge as a}from"./Badge/Badge.js";import{BannerSectionContent as s}from"./BannerSectionContent/BannerSectionContent.js";import{BannerSectionPlectrum as n}from"./BannerSectionPlectrum/BannerSectionPlectrum.js";import{Box as p}from"./Box/Box.js";import{BoxLink as d}from"./BoxLink/BoxLink.js";import{BoxLinkContext as l,useBoxLink as f}from"./BoxLink/BoxLinkContext.js";import{Breadcrumbs as j}from"./Breadcrumbs/Breadcrumbs.js";import{Button as u}from"./Button/Button.js";import{ButtonGroup as c}from"./ButtonGroup/ButtonGroup.js";import{Calendar as C}from"./Calendar/Calendar.js";import{CalendarRange as g}from"./CalendarRange/CalendarRange.js";import{CalloutBanner as B}from"./CalloutBanner/CalloutBanner.js";import{default as S}from"./CardSection/CardSection.js";import{Carousel as F}from"./Carousel/Carousel.js";import{Checkbox as b}from"./Checkbox/Checkbox.js";import{CheckboxGroup as x}from"./CheckboxGroup/CheckboxGroup.js";import{ClearFieldButton as T}from"./ClearFieldButton/ClearFieldButton.js";import{ComboBox as L}from"./ComboBox/ComboBox.js";import{CreditCardNumberField as k}from"./CreditCardNumberField/CreditCardNumberField.js";import{CreditCardSecurityCodeField as y}from"./CreditCardSecurityCodeField/CreditCardSecurityCodeField.js";import{Currency as P}from"./Currency/Currency.js";import{D}from"../DateField-rBq9QuR6.js";import{DatePicker as h}from"./DatePicker/DatePicker.js";import{DateRangePicker as I}from"./DateRangePicker/DateRangePicker.js";import{DestinationHeading as v}from"./DestinationHeading/DestinationHeading.js";import{DetailsDisclosure as A}from"./DetailsDisclosure/DetailsDisclosure.js";import{Dialog as H}from"./Dialog/Dialog.js";import{ErrorSummary as N}from"./ErrorSummary/ErrorSummary.js";import{Eyebrow as G}from"./Eyebrow/Eyebrow.js";import{default as R}from"./FieldDescription/FieldDescription.js";import{FieldError as w}from"./FieldError/FieldError.js";import{FieldHeader as E}from"./FieldHeader/FieldHeader.js";import{FieldLabel as M}from"./FieldLabel/FieldLabel.js";import{default as V}from"./Fieldset/Fieldset.js";import{FieldsetHeader as Y}from"./FieldsetHeader/FieldsetHeader.js";import{Form as q}from"./Form/Form.js";import{Grid as z}from"./Grid/Grid.js";import{Heading as J}from"./Heading/Heading.js";import{Icon as K}from"./Icon/Icon.js";import{IconBackdrop as O}from"./IconBackdrop/IconBackdrop.js";import{IconButton as Q}from"./IconButton/IconButton.js";import{Image as U}from"./Image/Image.js";import{IntroSection as W}from"./IntroSection/IntroSection.js";import{Label as X}from"./Label/Label.js";import{default as Z}from"./Link/Link.js";import{ListBox as $}from"./ListBox/ListBox.js";import{ListBoxItem as _}from"./ListBoxItem/ListBoxItem.js";import{default as oo}from"./LoadingSpinner/LoadingSpinner.js";import{Menu as ro}from"./Menu/Menu.js";import{MonthYearField as eo}from"./MonthYearField/MonthYearField.js";import{NumberField as io}from"./NumberField/NumberField.js";import{Paragraph as to}from"./Paragraph/Paragraph.js";import{PasswordField as mo}from"./PasswordField/PasswordField.js";import{PhoneNumberField as ao}from"./PhoneNumberField/PhoneNumberField.js";import"../utils/phoneNumber/phoneNumber.js";import{Popover as so}from"./Popover/Popover.js";import{ProductTile as no}from"./ProductTile/ProductTile.js";import{Radio as po}from"./Radio/Radio.js";import{RadioGroup as lo}from"./RadioGroup/RadioGroup.js";import{SearchField as fo}from"./SearchField/SearchField.js";import{default as jo}from"./Section/Section.js";import{default as uo}from"./SelectCard/SelectCard.js";import{default as co}from"./SelectNative/SelectNative.js";import{SkeletonLoader as Co}from"./SkeletonLoader/SkeletonLoader.js";import{Slider as go}from"./Slider/Slider.js";import{Spacer as Bo}from"./Spacer/Spacer.js";import{SubHeading as So}from"./SubHeading/SubHeading.js";import{Switch as Fo}from"./Switch/Switch.js";import{Tab as bo,TabList as xo,Tabs as To,useTabsContext as Lo}from"./Tabs/Tabs.js";import{T as ko}from"../TabPanel-C7ANBbTA.js";import{Tag as yo}from"./Tag/Tag.js";import{TagGroup as Po}from"./TagGroup/TagGroup.js";import{TextField as Do}from"./TextField/TextField.js";import{TextAreaField as ho}from"./TextAreaField/TextAreaField.js";import{default as Io}from"./ToggleButton/ToggleButton.js";import{default as vo}from"./ToggleIconButton/ToggleIconButton.js";import{Tooltip as Ao}from"./Tooltip/Tooltip.js";import{VisuallyHidden as Ho}from"./VisuallyHidden/VisuallyHidden.js";export{o as Accordion,r as AccordionGroup,t as AviosBadge,i as AviosCurrency,e as AviosCurrencyBadge,m as AviosCurrencySymbol,a as Badge,s as BannerSectionContent,n as BannerSectionPlectrum,p as Box,d as BoxLink,l as BoxLinkContext,j as Breadcrumbs,u as Button,c as ButtonGroup,C as Calendar,g as CalendarRange,B as CalloutBanner,S as CardSection,F as Carousel,b as Checkbox,x as CheckboxGroup,T as ClearFieldButton,L as ComboBox,k as CreditCardNumberField,y as CreditCardSecurityCodeField,P as Currency,D as DateField,h as DatePicker,I as DateRangePicker,v as DestinationHeading,A as DetailsDisclosure,H as Dialog,N as ErrorSummary,G as Eyebrow,R as FieldDescription,w as FieldError,E as FieldHeader,M as FieldLabel,V as Fieldset,Y as FieldsetHeader,q as Form,z as Grid,J as Heading,K as Icon,O as IconBackdrop,Q as IconButton,U as Image,W as IntroSection,X as Label,Z as Link,$ as ListBox,_ as ListBoxItem,oo as LoadingSpinner,ro as Menu,eo as MonthYearField,io as NumberField,to as Paragraph,mo as PasswordField,ao as PhoneNumberField,so as Popover,no as ProductTile,po as Radio,lo as RadioGroup,fo as SearchField,jo as Section,uo as SelectCard,co as SelectNative,Co as SkeletonLoader,go as Slider,Bo as Spacer,So as SubHeading,Fo as Switch,bo as Tab,xo as TabList,ko as TabPanel,To as Tabs,yo as Tag,Po as TagGroup,ho as TextAreaField,Do as TextField,Io as ToggleButton,vo as ToggleIconButton,Ao as Tooltip,Ho as VisuallyHidden,f as useBoxLink,Lo as useTabsContext};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import './assets/global.css';/* empty css */import{Accordion as o,AccordionGroup as e}from"./components/Accordion/Accordion.js";import{AviosCurrencyBadge as r}from"./components/AviosCurrencyBadge/AviosCurrencyBadge.js";import{AviosCurrency as t}from"./components/AviosCurrency/AviosCurrency.js";import{AviosBadge as
|
|
1
|
+
import './assets/global.css';/* empty css */import{Accordion as o,AccordionGroup as e}from"./components/Accordion/Accordion.js";import{AviosCurrencyBadge as r}from"./components/AviosCurrencyBadge/AviosCurrencyBadge.js";import{AviosCurrency as t}from"./components/AviosCurrency/AviosCurrency.js";import{AviosBadge as n}from"./components/AviosBadge/AviosBadge.js";import{AviosCurrencySymbol as m}from"./components/AviosCurrencySymbol/AviosCurrencySymbol.js";import{Badge as s}from"./components/Badge/Badge.js";import{BannerSectionContent as i}from"./components/BannerSectionContent/BannerSectionContent.js";import{BannerSectionPlectrum as p}from"./components/BannerSectionPlectrum/BannerSectionPlectrum.js";import{Box as a}from"./components/Box/Box.js";import{BoxLink as c}from"./components/BoxLink/BoxLink.js";import{BoxLinkContext as d,useBoxLink as l}from"./components/BoxLink/BoxLinkContext.js";import{Breadcrumbs as f}from"./components/Breadcrumbs/Breadcrumbs.js";import{Button as j}from"./components/Button/Button.js";import{ButtonGroup as u}from"./components/ButtonGroup/ButtonGroup.js";import{Calendar as B}from"./components/Calendar/Calendar.js";import{CalendarRange as C}from"./components/CalendarRange/CalendarRange.js";import{CalloutBanner as g}from"./components/CalloutBanner/CalloutBanner.js";import{default as S}from"./components/CardSection/CardSection.js";import{Carousel as F}from"./components/Carousel/Carousel.js";import{Checkbox as b}from"./components/Checkbox/Checkbox.js";import{CheckboxGroup as k}from"./components/CheckboxGroup/CheckboxGroup.js";import{ClearFieldButton as x}from"./components/ClearFieldButton/ClearFieldButton.js";import{ComboBox as T}from"./components/ComboBox/ComboBox.js";import{CreditCardNumberField as L}from"./components/CreditCardNumberField/CreditCardNumberField.js";import{CreditCardSecurityCodeField as h}from"./components/CreditCardSecurityCodeField/CreditCardSecurityCodeField.js";import{Currency as y}from"./components/Currency/Currency.js";import{D as P}from"./DateField-rBq9QuR6.js";import{DatePicker as D}from"./components/DatePicker/DatePicker.js";import{DateRangePicker as I}from"./components/DateRangePicker/DateRangePicker.js";import{DestinationHeading as v}from"./components/DestinationHeading/DestinationHeading.js";import{DetailsDisclosure as A}from"./components/DetailsDisclosure/DetailsDisclosure.js";import{Dialog as H}from"./components/Dialog/Dialog.js";import{ErrorSummary as N}from"./components/ErrorSummary/ErrorSummary.js";import{Eyebrow as G}from"./components/Eyebrow/Eyebrow.js";import{default as R}from"./components/FieldDescription/FieldDescription.js";import{FieldError as w}from"./components/FieldError/FieldError.js";import{FieldHeader as E}from"./components/FieldHeader/FieldHeader.js";import{FieldLabel as M}from"./components/FieldLabel/FieldLabel.js";import{default as V}from"./components/Fieldset/Fieldset.js";import{FieldsetHeader as Y}from"./components/FieldsetHeader/FieldsetHeader.js";import{Form as q}from"./components/Form/Form.js";import{Grid as z}from"./components/Grid/Grid.js";import{Heading as J}from"./components/Heading/Heading.js";import{Icon as K}from"./components/Icon/Icon.js";import{IconBackdrop as O}from"./components/IconBackdrop/IconBackdrop.js";import{IconButton as Q}from"./components/IconButton/IconButton.js";import{Image as U}from"./components/Image/Image.js";import{IntroSection as W}from"./components/IntroSection/IntroSection.js";import{Label as X}from"./components/Label/Label.js";import{default as Z}from"./components/Link/Link.js";import{ListBox as $}from"./components/ListBox/ListBox.js";import{ListBoxItem as _}from"./components/ListBoxItem/ListBoxItem.js";import{default as oo}from"./components/LoadingSpinner/LoadingSpinner.js";import{Menu as eo}from"./components/Menu/Menu.js";import{MonthYearField as ro}from"./components/MonthYearField/MonthYearField.js";import{NumberField as to}from"./components/NumberField/NumberField.js";import{Paragraph as no}from"./components/Paragraph/Paragraph.js";import{PasswordField as mo}from"./components/PasswordField/PasswordField.js";import{PhoneNumberField as so}from"./components/PhoneNumberField/PhoneNumberField.js";import"./utils/phoneNumber/phoneNumber.js";import{Popover as io}from"./components/Popover/Popover.js";import{ProductTile as po}from"./components/ProductTile/ProductTile.js";import{Radio as ao}from"./components/Radio/Radio.js";import{RadioGroup as co}from"./components/RadioGroup/RadioGroup.js";import{SearchField as lo}from"./components/SearchField/SearchField.js";import{default as fo}from"./components/Section/Section.js";import{default as jo}from"./components/SelectCard/SelectCard.js";import{default as uo}from"./components/SelectNative/SelectNative.js";import{SkeletonLoader as Bo}from"./components/SkeletonLoader/SkeletonLoader.js";import{Slider as Co}from"./components/Slider/Slider.js";import{Spacer as go}from"./components/Spacer/Spacer.js";import{SubHeading as So}from"./components/SubHeading/SubHeading.js";import{Switch as Fo}from"./components/Switch/Switch.js";import{Tab as bo,TabList as ko,Tabs as xo,useTabsContext as To}from"./components/Tabs/Tabs.js";import{T as Lo}from"./TabPanel-C7ANBbTA.js";import{Tag as ho}from"./components/Tag/Tag.js";import{TagGroup as yo}from"./components/TagGroup/TagGroup.js";import{TextField as Po}from"./components/TextField/TextField.js";import{TextAreaField as Do}from"./components/TextAreaField/TextAreaField.js";import{default as Io}from"./components/ToggleButton/ToggleButton.js";import{default as vo}from"./components/ToggleIconButton/ToggleIconButton.js";import{Tooltip as Ao}from"./components/Tooltip/Tooltip.js";import{VisuallyHidden as Ho}from"./components/VisuallyHidden/VisuallyHidden.js";import{useBreakpoint as No}from"./utils/breakpoint/hooks/useBreakpoint.js";import{BREAKPOINTS as Go}from"./utils/breakpoint/theme/breakpoints.js";export{o as Accordion,e as AccordionGroup,n as AviosBadge,t as AviosCurrency,r as AviosCurrencyBadge,m as AviosCurrencySymbol,Go as BREAKPOINTS,s as Badge,i as BannerSectionContent,p as BannerSectionPlectrum,a as Box,c as BoxLink,d as BoxLinkContext,f as Breadcrumbs,j as Button,u as ButtonGroup,B as Calendar,C as CalendarRange,g as CalloutBanner,S as CardSection,F as Carousel,b as Checkbox,k as CheckboxGroup,x as ClearFieldButton,T as ComboBox,L as CreditCardNumberField,h as CreditCardSecurityCodeField,y as Currency,P as DateField,D as DatePicker,I as DateRangePicker,v as DestinationHeading,A as DetailsDisclosure,H as Dialog,N as ErrorSummary,G as Eyebrow,R as FieldDescription,w as FieldError,E as FieldHeader,M as FieldLabel,V as Fieldset,Y as FieldsetHeader,q as Form,z as Grid,J as Heading,K as Icon,O as IconBackdrop,Q as IconButton,U as Image,W as IntroSection,X as Label,Z as Link,$ as ListBox,_ as ListBoxItem,oo as LoadingSpinner,eo as Menu,ro as MonthYearField,to as NumberField,no as Paragraph,mo as PasswordField,so as PhoneNumberField,io as Popover,po as ProductTile,ao as Radio,co as RadioGroup,lo as SearchField,fo as Section,jo as SelectCard,uo as SelectNative,Bo as SkeletonLoader,Co as Slider,go as Spacer,So as SubHeading,Fo as Switch,bo as Tab,ko as TabList,Lo as TabPanel,xo as Tabs,ho as Tag,yo as TagGroup,Do as TextAreaField,Po as TextField,Io as ToggleButton,vo as ToggleIconButton,Ao as Tooltip,Ho as VisuallyHidden,l as useBoxLink,No as useBreakpoint,To as useTabsContext};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{jsxs as
|
|
2
|
-
/* @__PURE__ */
|
|
3
|
-
/* @__PURE__ */
|
|
4
|
-
/* @__PURE__ */
|
|
5
|
-
/* @__PURE__ */
|
|
6
|
-
/* @__PURE__ */
|
|
7
|
-
/* @__PURE__ */
|
|
1
|
+
import{jsxs as o,jsx as e}from"react/jsx-runtime";import{useState as t,useRef as n,useEffect as r}from"react";import '../../assets/skeleton.css';import '../../assets/global.css';/* empty css */import"../../components/Accordion/Accordion.js";import"../../components/AviosCurrencySymbol/AviosCurrencySymbol.js";import"../../components/BannerSectionContent/BannerSectionContent.js";import"../../components/BannerSectionPlectrum/BannerSectionPlectrum.js";import{Box as i}from"../../components/Box/Box.js";import"../../components/BoxLink/BoxLink.js";import"../../components/BoxLink/BoxLinkContext.js";import"../../components/Breadcrumbs/Breadcrumbs.js";import"../../components/Button/Button.js";import"../../components/Calendar/Calendar.js";import"../../components/CalendarRange/CalendarRange.js";import"../../components/CalloutBanner/CalloutBanner.js";import"../../components/CardSection/CardSection.js";import"../../IconButton.module-C7YCy-MU.js";import"../../components/Carousel/CarouselButton/CarouselButton.js";import"@react-aria/focus";import"@react-aria/interactions";import"react-aria-components";import"../../components/CheckboxGroup/CheckboxGroup.js";import"../../components/ClearFieldButton/ClearFieldButton.js";import"../../components/ComboBox/ComboBox.js";import"../../components/DatePicker/DatePickerContext.js";import"../../DateField-rBq9QuR6.js";import"../../components/IconButton/IconButton.js";import"@react-aria/datepicker";import"@react-aria/overlays";import{Paragraph as s}from"../../components/Paragraph/Paragraph.js";import{Heading as m}from"../../components/Heading/Heading.js";import"../../components/DetailsDisclosure/DetailsDisclosure.js";import"../../components/Dialog/Dialog.js";import"../../components/Link/Link.js";import"../../components/Fieldset/Fieldset.js";import"../../components/Grid/Grid.js";import"../../components/Image/Image.js";import"../../components/IntroSection/IntroSection.js";import"../../components/Label/Label.js";import"../../components/ListBox/ListBox.js";import"../../components/Menu/Menu.js";import"../../components/MonthYearField/MonthYearField.js";import"../../components/NumberField/NumberField.js";import"../../components/PasswordField/PasswordField.js";import"../../components/PhoneNumberField/PhoneNumberField.js";import"../phoneNumber/phoneNumber.js";import"../../components/ProductTile/ProductTile.js";import"../../components/RadioGroup/RadioGroup.js";import"../../components/Section/Section.js";import"../../components/SelectCard/SelectCard.js";import"../../components/SelectNative/SelectNative.js";/* empty css */import"../../components/SubHeading/SubHeading.js";import"../../components/Tabs/Tabs.js";import"../../components/TextField/TextField.js";import"../../components/TextAreaField/TextAreaField.js";const a=({children:a,initialWidth:c=500,minWidth:p=300,maxWidth:d=800,title:l="Draggable Container",description:u="Drag the right edge to resize and see scroll behavior"})=>{const[j,b]=t(c),[x,h]=t(!1),g=n(null),C=n(0),B=n(c),v=o=>{if(!x)return;const e=o.clientX-C.current,t=Math.max(p,Math.min(d,B.current+e));b(t)},y=()=>{h(!1)};return r(()=>{if(x)return document.addEventListener("mousemove",v),document.addEventListener("mouseup",y),document.body.style.cursor="ew-resize",document.body.style.userSelect="none",()=>{document.removeEventListener("mousemove",v),document.removeEventListener("mouseup",y),document.body.style.cursor="",document.body.style.userSelect=""}},[x]),/* @__PURE__ */o("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:"16px"},children:[
|
|
2
|
+
/* @__PURE__ */o(i,{justifyContent:"center",maxWidth:"600px",flexDirection:"column",children:[
|
|
3
|
+
/* @__PURE__ */e(m,{as:"h3",size:"sm",foregroundColor:"accentSecondary",children:l}),
|
|
4
|
+
/* @__PURE__ */e(i,{children:/* @__PURE__ */e(s,{children:u})})]}),
|
|
5
|
+
/* @__PURE__ */o("div",{ref:g,style:{width:`${j}px`,border:"var(--alto-sem-border-width-sm) dashed var(--alto-sem-color-border-secondary)",borderRadius:"var(--alto-sem-radius-xs)",padding:"var(--alto-sem-space-lg)",position:"relative",transition:x?"none":"width 0.1s ease"},children:[a,
|
|
6
|
+
/* @__PURE__ */e("button",{"aria-label":"Draggable handle",onMouseDown:o=>{h(!0),C.current=o.clientX,B.current=j,o.preventDefault()},style:{position:"absolute",top:0,right:"-3px",bottom:0,width:"6px",cursor:"ew-resize",background:x?"#3498db":"transparent",borderRadius:"0 8px 8px 0",zIndex:10,transition:"background-color 0.2s ease",border:"none",padding:0},onMouseEnter:o=>{x||(o.currentTarget.style.background="rgba(52, 152, 219, 0.3)")},onMouseLeave:o=>{x||(o.currentTarget.style.background="transparent")}}),
|
|
7
|
+
/* @__PURE__ */e("div",{style:{position:"absolute",top:"50%",right:"-1px",transform:"translateY(-50%)",width:"2px",height:"40px",background:x?"#3498db":"#bdc3c7",borderRadius:"1px",opacity:x?1:.6,transition:"all 0.2s ease",pointerEvents:"none"}})]})]})};export{a as DraggableContainer};
|
|
8
8
|
//# sourceMappingURL=DraggableContainer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DraggableContainer.js","sources":["../../../src/utils/stories/DraggableContainer.tsx"],"sourcesContent":["import { useState, useRef, useEffect } from 'react';\nimport { Box, Paragraph, Heading } from '../../components';\n\nexport const DraggableContainer = ({\n children,\n initialWidth = 500,\n minWidth = 300,\n maxWidth = 800,\n title = 'Draggable Container',\n description = 'Drag the right edge to resize and see scroll behavior',\n}: {\n children: React.ReactNode;\n initialWidth?: number;\n minWidth?: number;\n maxWidth?: number;\n title?: string;\n description?: string;\n}) => {\n const [width, setWidth] = useState(initialWidth);\n const [isDragging, setIsDragging] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const dragStartX = useRef<number>(0);\n const dragStartWidth = useRef<number>(initialWidth);\n\n const handleMouseDown = (e: React.MouseEvent) => {\n setIsDragging(true);\n dragStartX.current = e.clientX;\n dragStartWidth.current = width;\n e.preventDefault();\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (!isDragging) return;\n\n const deltaX = e.clientX - dragStartX.current;\n const newWidth = Math.max(\n minWidth,\n Math.min(maxWidth, dragStartWidth.current + deltaX),\n );\n setWidth(newWidth);\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n };\n\n useEffect(() => {\n if (isDragging) {\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n document.body.style.cursor = 'ew-resize';\n document.body.style.userSelect = 'none';\n\n return () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n };\n }\n }, [isDragging]);\n\n return (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '16px',\n }}\n >\n <Box justifyContent=\"center\" maxWidth=\"600px\" flexDirection=\"column\">\n <Heading as=\"h3\" size=\"sm\" foregroundColor=\"accentSecondary\">\n {title}\n </Heading>\n <Box>\n <Paragraph>{description}</Paragraph>\n </Box>\n </Box>\n\n <div\n ref={containerRef}\n style={{\n width: `${width}px`,\n border:\n 'var(--alto-sem-border-width-sm) dashed var(--alto-sem-color-border-secondary)',\n borderRadius: 'var(--alto-sem-radius-xs)',\n padding: 'var(--alto-sem-space-lg)',\n position: 'relative',\n transition: isDragging ? 'none' : 'width 0.1s ease',\n }}\n >\n {children}\n\n {/* Drag Handle */}\n <button\n aria-label=\"Draggable handle\"\n onMouseDown={handleMouseDown}\n style={{\n position: 'absolute',\n top: 0,\n right: '-3px',\n bottom: 0,\n width: '6px',\n cursor: 'ew-resize',\n background: isDragging ? '#3498db' : 'transparent',\n borderRadius: '0 8px 8px 0',\n zIndex: 10,\n transition: 'background-color 0.2s ease',\n border: 'none',\n padding: 0,\n }}\n onMouseEnter={(e) => {\n if (!isDragging) {\n e.currentTarget.style.background = 'rgba(52, 152, 219, 0.3)';\n }\n }}\n onMouseLeave={(e) => {\n if (!isDragging) {\n e.currentTarget.style.background = 'transparent';\n }\n }}\n />\n\n {/* Resize indicator */}\n <div\n style={{\n position: 'absolute',\n top: '50%',\n right: '-1px',\n transform: 'translateY(-50%)',\n width: '2px',\n height: '40px',\n background: isDragging ? '#3498db' : '#bdc3c7',\n borderRadius: '1px',\n opacity: isDragging ? 1 : 0.6,\n transition: 'all 0.2s ease',\n pointerEvents: 'none',\n }}\n />\n </div>\n </div>\n );\n};\n"],"names":["DraggableContainer","children","initialWidth","minWidth","maxWidth","title","description","width","setWidth","useState","isDragging","setIsDragging","containerRef","useRef","dragStartX","dragStartWidth","handleMouseMove","e","deltaX","clientX","current","newWidth","Math","max","min","handleMouseUp","useEffect","document","addEventListener","body","style","cursor","userSelect","removeEventListener","jsxs","display","flexDirection","alignItems","gap","Box","justifyContent","jsx","Heading","as","size","foregroundColor","Paragraph","ref","border","borderRadius","padding","position","transition","onMouseDown","preventDefault","top","right","bottom","background","zIndex","onMouseEnter","currentTarget","onMouseLeave","transform","height","opacity","pointerEvents"],"mappings":"
|
|
1
|
+
{"version":3,"file":"DraggableContainer.js","sources":["../../../src/utils/stories/DraggableContainer.tsx"],"sourcesContent":["import { useState, useRef, useEffect } from 'react';\nimport { Box, Paragraph, Heading } from '../../components';\n\nexport const DraggableContainer = ({\n children,\n initialWidth = 500,\n minWidth = 300,\n maxWidth = 800,\n title = 'Draggable Container',\n description = 'Drag the right edge to resize and see scroll behavior',\n}: {\n children: React.ReactNode;\n initialWidth?: number;\n minWidth?: number;\n maxWidth?: number;\n title?: string;\n description?: string;\n}) => {\n const [width, setWidth] = useState(initialWidth);\n const [isDragging, setIsDragging] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const dragStartX = useRef<number>(0);\n const dragStartWidth = useRef<number>(initialWidth);\n\n const handleMouseDown = (e: React.MouseEvent) => {\n setIsDragging(true);\n dragStartX.current = e.clientX;\n dragStartWidth.current = width;\n e.preventDefault();\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (!isDragging) return;\n\n const deltaX = e.clientX - dragStartX.current;\n const newWidth = Math.max(\n minWidth,\n Math.min(maxWidth, dragStartWidth.current + deltaX),\n );\n setWidth(newWidth);\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n };\n\n useEffect(() => {\n if (isDragging) {\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n document.body.style.cursor = 'ew-resize';\n document.body.style.userSelect = 'none';\n\n return () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n };\n }\n }, [isDragging]);\n\n return (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '16px',\n }}\n >\n <Box justifyContent=\"center\" maxWidth=\"600px\" flexDirection=\"column\">\n <Heading as=\"h3\" size=\"sm\" foregroundColor=\"accentSecondary\">\n {title}\n </Heading>\n <Box>\n <Paragraph>{description}</Paragraph>\n </Box>\n </Box>\n\n <div\n ref={containerRef}\n style={{\n width: `${width}px`,\n border:\n 'var(--alto-sem-border-width-sm) dashed var(--alto-sem-color-border-secondary)',\n borderRadius: 'var(--alto-sem-radius-xs)',\n padding: 'var(--alto-sem-space-lg)',\n position: 'relative',\n transition: isDragging ? 'none' : 'width 0.1s ease',\n }}\n >\n {children}\n\n {/* Drag Handle */}\n <button\n aria-label=\"Draggable handle\"\n onMouseDown={handleMouseDown}\n style={{\n position: 'absolute',\n top: 0,\n right: '-3px',\n bottom: 0,\n width: '6px',\n cursor: 'ew-resize',\n background: isDragging ? '#3498db' : 'transparent',\n borderRadius: '0 8px 8px 0',\n zIndex: 10,\n transition: 'background-color 0.2s ease',\n border: 'none',\n padding: 0,\n }}\n onMouseEnter={(e) => {\n if (!isDragging) {\n e.currentTarget.style.background = 'rgba(52, 152, 219, 0.3)';\n }\n }}\n onMouseLeave={(e) => {\n if (!isDragging) {\n e.currentTarget.style.background = 'transparent';\n }\n }}\n />\n\n {/* Resize indicator */}\n <div\n style={{\n position: 'absolute',\n top: '50%',\n right: '-1px',\n transform: 'translateY(-50%)',\n width: '2px',\n height: '40px',\n background: isDragging ? '#3498db' : '#bdc3c7',\n borderRadius: '1px',\n opacity: isDragging ? 1 : 0.6,\n transition: 'all 0.2s ease',\n pointerEvents: 'none',\n }}\n />\n </div>\n </div>\n );\n};\n"],"names":["DraggableContainer","children","initialWidth","minWidth","maxWidth","title","description","width","setWidth","useState","isDragging","setIsDragging","containerRef","useRef","dragStartX","dragStartWidth","handleMouseMove","e","deltaX","clientX","current","newWidth","Math","max","min","handleMouseUp","useEffect","document","addEventListener","body","style","cursor","userSelect","removeEventListener","jsxs","display","flexDirection","alignItems","gap","Box","justifyContent","jsx","Heading","as","size","foregroundColor","Paragraph","ref","border","borderRadius","padding","position","transition","onMouseDown","preventDefault","top","right","bottom","background","zIndex","onMouseEnter","currentTarget","onMouseLeave","transform","height","opacity","pointerEvents"],"mappings":"8qFAGO,MAAMA,EAAqB,EAChCC,WACAC,eAAe,IACfC,WAAW,IACXC,WAAW,IACXC,QAAQ,sBACRC,cAAc,4DASd,MAAOC,EAAOC,GAAYC,EAASP,IAC5BQ,EAAYC,GAAiBF,GAAS,GACvCG,EAAeC,EAAuB,MACtCC,EAAaD,EAAe,GAC5BE,EAAiBF,EAAeX,GAShCc,EAAmBC,IACvB,IAAKP,EAAY,OAEjB,MAAMQ,EAASD,EAAEE,QAAUL,EAAWM,QAChCC,EAAWC,KAAKC,IACpBpB,EACAmB,KAAKE,IAAIpB,EAAUW,EAAeK,QAAUF,IAE9CV,EAASa,IAGLI,EAAgB,KACpBd,GAAc,IAmBhB,OAhBAe,EAAU,KACR,GAAIhB,EAMF,OALAiB,SAASC,iBAAiB,YAAaZ,GACvCW,SAASC,iBAAiB,UAAWH,GACrCE,SAASE,KAAKC,MAAMC,OAAS,YAC7BJ,SAASE,KAAKC,MAAME,WAAa,OAE1B,KACLL,SAASM,oBAAoB,YAAajB,GAC1CW,SAASM,oBAAoB,UAAWR,GACxCE,SAASE,KAAKC,MAAMC,OAAS,GAC7BJ,SAASE,KAAKC,MAAME,WAAa,KAGpC,CAACtB,mBAGFwB,EAAC,MAAA,CACCJ,MAAO,CACLK,QAAS,OACTC,cAAe,SACfC,WAAY,SACZC,IAAK,QAGPrC,SAAA;eAAAiC,EAACK,GAAIC,eAAe,SAASpC,SAAS,QAAQgC,cAAc,SAC1DnC,SAAA;eAAAwC,EAACC,GAAQC,GAAG,KAAKC,KAAK,KAAKC,gBAAgB,kBACxC5C,SAAAI;eAEHoC,EAACF,EAAA,CACCtC,wBAAAwC,EAACK,EAAA,CAAW7C;eAIhBiC,EAAC,MAAA,CACCa,IAAKnC,EACLkB,MAAO,CACLvB,MAAO,GAAGA,MACVyC,OACE,gFACFC,aAAc,4BACdC,QAAS,2BACTC,SAAU,WACVC,WAAY1C,EAAa,OAAS,mBAGnCT,SAAA,CAAAA;eAGDwC,EAAC,SAAA,CACC,aAAW,mBACXY,YAzEiBpC,IACvBN,GAAc,GACdG,EAAWM,QAAUH,EAAEE,QACvBJ,EAAeK,QAAUb,EACzBU,EAAEqC,kBAsEIxB,MAAO,CACLqB,SAAU,WACVI,IAAK,EACLC,MAAO,OACPC,OAAQ,EACRlD,MAAO,MACPwB,OAAQ,YACR2B,WAAYhD,EAAa,UAAY,cACrCuC,aAAc,cACdU,OAAQ,GACRP,WAAY,6BACZJ,OAAQ,OACRE,QAAS,GAEXU,aAAe3C,IACRP,IACHO,EAAE4C,cAAc/B,MAAM4B,WAAa,4BAGvCI,aAAe7C,IACRP,IACHO,EAAE4C,cAAc/B,MAAM4B,WAAa;eAMzCjB,EAAC,MAAA,CACCX,MAAO,CACLqB,SAAU,WACVI,IAAK,MACLC,MAAO,OACPO,UAAW,mBACXxD,MAAO,MACPyD,OAAQ,OACRN,WAAYhD,EAAa,UAAY,UACrCuC,aAAc,MACdgB,QAASvD,EAAa,EAAI,GAC1B0C,WAAY,gBACZc,cAAe"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alto-avios/alto-ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "A react component library for Alto Design System",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Ian Caldwell IAGL",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"@react-aria/focus": "^3.20.0",
|
|
47
47
|
"@react-aria/i18n": "^3.12.6",
|
|
48
48
|
"@react-aria/interactions": "^3.24.0",
|
|
49
|
+
"@react-aria/link": "^3.7.9",
|
|
49
50
|
"@react-aria/overlays": "^3.26.0",
|
|
50
51
|
"@react-aria/utils": "^3.28.0",
|
|
51
52
|
"@react-stately/calendar": "^3.7.1",
|