Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ refactor(carousel): move logic to util to be used in other components #1544

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"docs/assets/*"
],
"words": [
"Swiper",
"swiper",
"fhlyaiq",
"adipiscing",
"adipisicing",
Expand Down
32 changes: 23 additions & 9 deletions packages/core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { BalConfigState } from "./utils/config";
import { AccordionState, BalAriaForm as BalAriaForm1, BalConfigState as BalConfigState1 } from "./interfaces";
import { BalCarouselItemData, BalSlide } from "./components/bal-carousel/bal-carousel.type";
import { BalCheckboxOption } from "./components/bal-checkbox/bal-checkbox.type";
import { BalAriaForm } from "./utils/form";
import { BalOption } from "./utils/dropdown";
Expand All @@ -20,7 +19,6 @@ import { BalStepOption } from "./components/bal-steps/bal-step.type";
import { BalTabOption } from "./components/bal-tabs/bal-tab.type";
export { BalConfigState } from "./utils/config";
export { AccordionState, BalAriaForm as BalAriaForm1, BalConfigState as BalConfigState1 } from "./interfaces";
export { BalCarouselItemData, BalSlide } from "./components/bal-carousel/bal-carousel.type";
export { BalCheckboxOption } from "./components/bal-checkbox/bal-checkbox.type";
export { BalAriaForm } from "./utils/form";
export { BalOption } from "./utils/dropdown";
Expand Down Expand Up @@ -386,8 +384,9 @@ export namespace Components {
* If `true` the carousel uses the full height
*/
"fullHeight": boolean;
"getContainerId": () => Promise<string>;
/**
* Defines the role of the carousel.
* @deprecated Defines the role of the carousel.
*/
"htmlRole": 'tablist' | 'list' | '';
/**
Expand All @@ -402,11 +401,11 @@ export namespace Components {
* Defines how many slides are visible in the container for the user. `auto` will use the size of the actual item content
*/
"itemsPerView": 'auto' | 1 | 2 | 3 | 4;
"next": (steps?: number) => Promise<BalSlide | undefined>;
"next": (steps?: number) => Promise<void>;
/**
* PUBLIC METHODS ------------------------------------------------------
*/
"previous": (steps?: number) => Promise<BalSlide | undefined>;
"previous": (steps?: number) => Promise<void>;
/**
* If `true` vertical scrolling on mobile is enabled.
*/
Expand All @@ -433,13 +432,12 @@ export namespace Components {
* The type of button.
*/
"elementType": BalProps.BalButtonElementType;
"getData": () => Promise<BalCarouselItemData>;
/**
* Specifies the URL of the page the link goes to
*/
"href"?: string;
/**
* Defines the role of the carousel.
* @deprecated Defines the role of the carousel.
*/
"htmlRole": 'tab' | 'listitem' | '';
/**
Expand Down Expand Up @@ -721,6 +719,10 @@ export namespace Components {
* If `true`, in Angular reactive forms the control will not be set invalid
*/
"autoInvalidOff": boolean;
/**
* Indicates whether the value of the control can be automatically completed by the browser.
*/
"autocomplete": BalProps.BalInputAutocomplete;
/**
* Closes the accordion
*/
Expand Down Expand Up @@ -3328,6 +3330,10 @@ export namespace Components {
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
*/
"autocapitalize": string;
/**
* Indicates whether the value of the control can be automatically completed by the browser.
*/
"autocomplete": BalProps.BalInputAutocomplete;
/**
* This Boolean attribute lets you specify that a form control should have input focus when the page loads.
*/
Expand Down Expand Up @@ -5431,7 +5437,7 @@ declare namespace LocalJSX {
*/
"fullHeight"?: boolean;
/**
* Defines the role of the carousel.
* @deprecated Defines the role of the carousel.
*/
"htmlRole"?: 'tablist' | 'list' | '';
/**
Expand Down Expand Up @@ -5481,7 +5487,7 @@ declare namespace LocalJSX {
*/
"href"?: string;
/**
* Defines the role of the carousel.
* @deprecated Defines the role of the carousel.
*/
"htmlRole"?: 'tab' | 'listitem' | '';
/**
Expand Down Expand Up @@ -5792,6 +5798,10 @@ declare namespace LocalJSX {
* If `true`, in Angular reactive forms the control will not be set invalid
*/
"autoInvalidOff"?: boolean;
/**
* Indicates whether the value of the control can be automatically completed by the browser.
*/
"autocomplete"?: BalProps.BalInputAutocomplete;
/**
* Closes the datepicker popover after selection
*/
Expand Down Expand Up @@ -8398,6 +8408,10 @@ declare namespace LocalJSX {
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
*/
"autocapitalize"?: string;
/**
* Indicates whether the value of the control can be automatically completed by the browser.
*/
"autocomplete"?: BalProps.BalInputAutocomplete;
/**
* This Boolean attribute lets you specify that a form control should have input focus when the page loads.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import {
State,
} from '@stencil/core'
import { BEM } from '../../../utils/bem'
import { BalCarouselItemData } from '../bal-carousel.type'
import { Attributes } from '../../../interfaces'
import { rLCP, waitAfterFramePaint } from '../../../utils/helpers'
import { inheritAttributes } from '../../../utils/attributes'
import { toKebabCase } from 'packages/core/src/utils/string'

@Component({
tag: 'bal-carousel-item',
Expand All @@ -26,6 +26,7 @@ export class CarouselItem implements ComponentInterface {
@Element() el!: HTMLElement

@State() isLargestContentfulPaintDone = false
@State() containerId = ''

/**
* Src path to the image
Expand All @@ -38,6 +39,7 @@ export class CarouselItem implements ComponentInterface {
@Prop({ reflect: true }) label = ''

/**
* @deprecated
* Defines the role of the carousel.
*/
@Prop() htmlRole: 'tab' | 'listitem' | '' = 'listitem'
Expand All @@ -50,12 +52,12 @@ export class CarouselItem implements ComponentInterface {
/**
* The name of the button, which is submitted with the form data.
*/
@Prop({ reflect: true }) name?: string = ''
@Prop({ reflect: true }) name?: string = undefined

/**
* The value of the button, which is submitted with the form data.
*/
@Prop({ reflect: true }) value?: string | number = ''
@Prop({ reflect: true }) value?: string | number = undefined

/**
* Specifies the URL of the page the link goes to
Expand Down Expand Up @@ -115,13 +117,7 @@ export class CarouselItem implements ComponentInterface {

componentWillLoad() {
this.imageInheritAttributes = inheritAttributes(this.el, ['alt'])
}

@Method() async getData(): Promise<BalCarouselItemData> {
return {
clientWidth: this.el.clientWidth,
label: this.label,
}
this.getContainerId()
}

@Method()
Expand All @@ -132,6 +128,11 @@ export class CarouselItem implements ComponentInterface {
}
}

async getContainerId(): Promise<void> {
const parentEl = this.el.closest('bal-carousel') as HTMLBalCarouselElement
this.containerId = await parentEl.getContainerId()
}

private onClick = (ev: MouseEvent) => {
if (this.href !== undefined) {
this.balNavigate.emit(ev)
Expand All @@ -152,9 +153,13 @@ export class CarouselItem implements ComponentInterface {

const isProduct = !!this.color && !!this.label

const parentEl = this.el.closest('bal-carousel') as HTMLBalCarouselElement
const role = parentEl && parentEl.controls === 'tabs' ? 'tabpanel' : 'listitem'
const id = `${this.containerId}-${toKebabCase(this.label)}`

if (!isProduct) {
return (
<Host role={this.htmlRole} class={{ ...itemEl.class() }}>
<Host id={id} role={role} class={{ ...itemEl.class() }} aria-label={this.label}>
{this.isLargestContentfulPaintDone && this.src !== undefined ? (
<img draggable={false} onDragStart={() => false} src={this.src} {...this.imageInheritAttributes} />
) : (
Expand Down Expand Up @@ -183,7 +188,7 @@ export class CarouselItem implements ComponentInterface {
}

return (
<Host role={this.htmlRole} class={{ ...itemEl.class() }}>
<Host id={id} role={role} aria-label={this.label} class={{ ...itemEl.class() }}>
<TagType
{...attrs}
class={{ ...button.class(), ...button.modifier(`color-${this.color}`).class() }}
Expand Down
114 changes: 14 additions & 100 deletions packages/core/src/components/bal-carousel/bal-carousel.sass
Original file line number Diff line number Diff line change
@@ -1,37 +1,13 @@
@import '@baloise/ds-styles/sass/mixins'
@import './bal-carousel.vars'

.bal-carousel
display: block
position: relative

.bal-carousel__inner
display: block
position: relative
margin-left: auto
margin-right: auto
position: relative
overflow: hidden
list-style: none
padding: 0
touch-action: pan-y
@import '../../utils/swiper/swiper'

.bal-carousel--full-height
height: 100%

.bal-carousel__inner--full-height
height: 100%

.bal-carousel__inner__container
position: relative
width: 100%
height: 100%
display: flex
box-sizing: content-box
transition-property: transform
transition-duration: 0ms
transform: translate3d(0px,0px,0px)

.bal-carousel__inner__container--border
padding-bottom: var(--bal-border-width-normal)

Expand Down Expand Up @@ -62,46 +38,10 @@
transform: translateZ(0)
-webkit-backface-visibility: hidden
backface-visibility: hidden
round: linear-gradient(90deg, rgba(255, 255, 255, 0), var(--bal-carousel-inner-shadow-right-background-inverted-after) 50%)

.bal-carousel__inner--shadow-left::before,
.bal-carousel__inner--shadow-right::after
position: absolute
width: 3rem
height: 100%
top: 0

.bal-carousel__inner--shadow-left::before
content: ''
left: 0
background: linear-gradient(90deg, var(--bal-carousel-inner-shadow-left-background-before) 50%, rgba(255, 255, 255, 0) 100%)

.bal-carousel__inner--shadow-right::after
content: ''
right: 0
background: linear-gradient(90deg, rgba(255, 255, 255, 0), var(--bal-carousel-inner-shadow-right-background-after) 50%)

.bal-carousel__inner--shadow-left.bal-carousel__inner--inverted::before
background: linear-gradient(90deg, var(--bal-carousel-inner-shadow-left-background-inverted-before) 50%, rgba(255, 255, 255, 0) 100%)

.bal-carousel__inner--shadow-right.bal-carousel__inner--inverted::after
background: linear-gradient(90deg, rgba(255, 255, 255, 0), var(--bal-carousel-inner-shadow-right-background-inverted-after) 50%)

.bal-carousel__inner
&--items-per-view-auto
.bal-carousel__item
width: auto
&--items-per-view-1
.bal-carousel__item
width: 100%
&--items-per-view-2
.bal-carousel__item
width: 50%
&--items-per-view-3
.bal-carousel__item
width: 33.3333%
&--items-per-view-4
.bal-carousel__item
width: 25%
// Card
// --------------------------------------------------

.bal-carousel--card
.bal-carousel__inner--shadow-left::before,
Expand Down Expand Up @@ -137,6 +77,9 @@
padding-left: 2.5rem
padding-right: 2.5rem

// Tabs
// --------------------------------------------------

.bal-carousel--controls-sticky
.bal-carousel__controls--tabs
position: sticky
Expand All @@ -155,6 +98,9 @@
.button
padding: .5rem !important

// Image
// --------------------------------------------------

.bal-carousel--image
.bal-carousel__inner
border-radius: var(--bal-carousel-image-border-radius)
Expand All @@ -180,7 +126,6 @@
.bal-carousel__item
position: relative
flex: 0 0 100%

& > img
height: 100%
width: 100%
Expand All @@ -189,6 +134,9 @@
user-drag: none
user-zoom: fixed

// Product slider
// --------------------------------------------------

.bal-carousel--product
.bal-carousel__inner__container
gap: 1rem
Expand Down Expand Up @@ -261,6 +209,7 @@
width: 5rem
height: 5rem
pointer-events: none

.bal-carousel__item__button__label
font-weight: var(--bal-font-weight-bold)
color: var(--bal-carousel-product-item-button-label-text-color)
Expand All @@ -270,38 +219,3 @@
overflow: hidden
line-height: 1.15rem
word-break: break-word

.bal-carousel__controls--large
+mobile
display: flex
justify-content: center
width: 100%
gap: 2rem
margin-top: 1rem

+tablet
.bal-carousel__controls__button
position: absolute
top: calc(50% - 24px)
z-index: 7
.bal-carousel__controls__button--left
left: 0
.bal-carousel__controls__button--right
right: 0

.bal-carousel__controls__button--hidden
display: none !important
visibility: none !important

.bal-carousel__controls--small
.bal-carousel__controls__button
position: absolute
top: calc(50% - 1rem)
z-index: 7
.bal-carousel__controls__button--left
left: 0
.bal-carousel__controls__button--right
right: 0
.bal-carousel__controls__button--hidden
display: none !important
visibility: hidden !important
Loading
Loading