0
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-01-30 22:52:24 +01:00

Make carousel indicators actual buttons

This commit is contained in:
Patrick H. Lauke 2021-01-03 13:06:58 +02:00 committed by XhmikosR
parent 1fd34a1a2c
commit a882614c45
9 changed files with 70 additions and 59 deletions

View File

@ -90,6 +90,7 @@ const SELECTOR_ITEM = '.carousel-item'
const SELECTOR_ITEM_IMG = '.carousel-item img' const SELECTOR_ITEM_IMG = '.carousel-item img'
const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev' const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'
const SELECTOR_INDICATORS = '.carousel-indicators' const SELECTOR_INDICATORS = '.carousel-indicators'
const SELECTOR_INDICATOR = '[data-bs-target]'
const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]' const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'
const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]' const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'
@ -405,18 +406,21 @@ class Carousel extends BaseComponent {
_setActiveIndicatorElement(element) { _setActiveIndicatorElement(element) {
if (this._indicatorsElement) { if (this._indicatorsElement) {
const indicators = SelectorEngine.find(SELECTOR_ACTIVE, this._indicatorsElement) const activeIndicators = SelectorEngine.find(SELECTOR_ACTIVE, this._indicatorsElement)
for (let i = 0; i < indicators.length; i++) { for (let i = 0; i < activeIndicators.length; i++) {
indicators[i].classList.remove(CLASS_NAME_ACTIVE) activeIndicators[i].classList.remove(CLASS_NAME_ACTIVE)
activeIndicators[i].removeAttribute('aria-current')
} }
const nextIndicator = this._indicatorsElement.children[ const indicators = SelectorEngine.find(SELECTOR_INDICATOR, this._indicatorsElement)
this._getItemIndex(element)
]
if (nextIndicator) { for (let i = 0; i < indicators.length; i++) {
nextIndicator.classList.add(CLASS_NAME_ACTIVE) if (Number.parseInt(indicators[i].getAttribute('data-bs-slide-to'), 10) === this._getItemIndex(element)) {
indicators[i].classList.add(CLASS_NAME_ACTIVE)
indicators[i].setAttribute('aria-current', 'true')
break
}
} }
} }
} }

View File

@ -20,11 +20,11 @@
</button> </button>
<div id="carouselExampleIndicators" class="carousel slide mt-2" data-bs-ride="carousel"> <div id="carouselExampleIndicators" class="carousel slide mt-2" data-bs-ride="carousel">
<ol class="carousel-indicators"> <div class="carousel-indicators">
<li data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0"></li> <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" aria-label="Slide 1"></button>
<li data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1" class="active"></li> <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1" class="active" aria-current="true" aria-label="Slide 2"></button>
<li data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2"></li> <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2" aria-label="Slide 3"></button>
</ol> </div>
<div class="carousel-inner"> <div class="carousel-inner">
<div class="carousel-item"> <div class="carousel-item">

View File

@ -659,11 +659,11 @@ describe('Carousel', () => {
it('should update indicators if present', done => { it('should update indicators if present', done => {
fixtureEl.innerHTML = [ fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">', '<div id="myCarousel" class="carousel slide">',
' <ol class="carousel-indicators">', ' <div class="carousel-indicators">',
' <li data-bs-target="#myCarousel" data-bs-slide-to="0" class="active"></li>', ' <button type="button" id="firstIndicator" data-bs-target="myCarousel" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>',
' <li id="secondIndicator" data-bs-target="#myCarousel" data-bs-slide-to="1"></li>', ' <button type="button" id="secondIndicator" data-bs-target="myCarousel" data-bs-slide-to="1" aria-label="Slide 2"></button>',
' <li data-bs-target="#myCarousel" data-bs-slide-to="2"></li>', ' <button type="button" data-bs-target="myCarousel" data-bs-slide-to="2" aria-label="Slide 3"></button>',
' </ol>', ' </div>',
' <div class="carousel-inner">', ' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>', ' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item" data-bs-interval="7">item 2</div>', ' <div class="carousel-item" data-bs-interval="7">item 2</div>',
@ -673,11 +673,15 @@ describe('Carousel', () => {
].join('') ].join('')
const carouselEl = fixtureEl.querySelector('#myCarousel') const carouselEl = fixtureEl.querySelector('#myCarousel')
const firstIndicator = fixtureEl.querySelector('#firstIndicator')
const secondIndicator = fixtureEl.querySelector('#secondIndicator') const secondIndicator = fixtureEl.querySelector('#secondIndicator')
const carousel = new Carousel(carouselEl) const carousel = new Carousel(carouselEl)
carouselEl.addEventListener('slid.bs.carousel', () => { carouselEl.addEventListener('slid.bs.carousel', () => {
expect(firstIndicator.classList.contains('active')).toEqual(false)
expect(firstIndicator.hasAttribute('aria-current')).toEqual(false)
expect(secondIndicator.classList.contains('active')).toEqual(true) expect(secondIndicator.classList.contains('active')).toEqual(true)
expect(secondIndicator.getAttribute('aria-current')).toEqual('true')
done() done()
}) })

View File

@ -18,11 +18,11 @@
<p>The transition duration should be around 2s. Also, the carousel shouldn't slide when its window/tab is hidden. Check the console log.</p> <p>The transition duration should be around 2s. Also, the carousel shouldn't slide when its window/tab is hidden. Check the console log.</p>
<div id="carousel-example-generic" class="carousel slide" data-bs-ride="carousel"> <div id="carousel-example-generic" class="carousel slide" data-bs-ride="carousel">
<ol class="carousel-indicators"> <div class="carousel-indicators">
<li data-bs-target="#carousel-example-generic" data-bs-slide-to="0" class="active"></li> <button type="button" data-bs-target="#carousel-example-generic" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<li data-bs-target="#carousel-example-generic" data-bs-slide-to="1"></li> <button type="button" data-bs-target="#carousel-example-generic" data-bs-slide-to="1" aria-label="Slide 2"></button>
<li data-bs-target="#carousel-example-generic" data-bs-slide-to="2"></li> <button type="button" data-bs-target="#carousel-example-generic" data-bs-slide-to="2" aria-label="Slide 3"></button>
</ol> </div>
<div class="carousel-inner"> <div class="carousel-inner">
<div class="carousel-item active"> <div class="carousel-item active">
<img src="https://i.imgur.com/iEZgY7Y.jpg" alt="First slide"> <img src="https://i.imgur.com/iEZgY7Y.jpg" alt="First slide">

View File

@ -150,10 +150,10 @@
background-image: escape-svg($carousel-control-next-icon-bg); background-image: escape-svg($carousel-control-next-icon-bg);
} }
// Optional indicator pips // Optional indicator pips/controls
// //
// Add an ordered list with the following class and add a list item for each // Add an container (such as a list) with the following class and add an item (ideally a focusable control,
// slide your carousel holds. // like a button) with data-bs-target for each slide your carousel holds.
.carousel-indicators { .carousel-indicators {
position: absolute; position: absolute;
@ -163,23 +163,26 @@
z-index: 2; z-index: 2;
display: flex; display: flex;
justify-content: center; justify-content: center;
padding-left: 0; // override <ol> default padding: 0;
// Use the .carousel-control's width as margin so we don't overlay those // Use the .carousel-control's width as margin so we don't overlay those
margin-right: $carousel-control-width; margin-right: $carousel-control-width;
margin-bottom: 1rem;
margin-left: $carousel-control-width; margin-left: $carousel-control-width;
list-style: none; list-style: none;
li { [data-bs-target] {
box-sizing: content-box; box-sizing: content-box;
flex: 0 1 auto; flex: 0 1 auto;
width: $carousel-indicator-width; width: $carousel-indicator-width;
height: $carousel-indicator-height; height: $carousel-indicator-height;
padding: 0;
margin-right: $carousel-indicator-spacer; margin-right: $carousel-indicator-spacer;
margin-left: $carousel-indicator-spacer; margin-left: $carousel-indicator-spacer;
text-indent: -999px; text-indent: -999px;
cursor: pointer; cursor: pointer;
background-color: $carousel-indicator-active-bg; background-color: $carousel-indicator-active-bg;
background-clip: padding-box; background-clip: padding-box;
border: 0;
// Use transparent borders to increase the hit area by 10px on top and bottom. // Use transparent borders to increase the hit area by 10px on top and bottom.
border-top: $carousel-indicator-hit-area-height solid transparent; border-top: $carousel-indicator-hit-area-height solid transparent;
border-bottom: $carousel-indicator-hit-area-height solid transparent; border-bottom: $carousel-indicator-hit-area-height solid transparent;
@ -216,7 +219,7 @@
filter: $carousel-dark-control-icon-filter; filter: $carousel-dark-control-icon-filter;
} }
.carousel-indicators li { .carousel-indicators [data-bs-target] {
background-color: $carousel-dark-indicator-active-bg; background-color: $carousel-dark-indicator-active-bg;
} }

View File

@ -78,11 +78,11 @@ You can also add the indicators to the carousel, alongside the controls, too.
{{< example >}} {{< example >}}
<div id="carouselExampleIndicators" class="carousel slide" data-bs-ride="carousel"> <div id="carouselExampleIndicators" class="carousel slide" data-bs-ride="carousel">
<ol class="carousel-indicators"> <div class="carousel-indicators">
<li data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" class="active"></li> <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<li data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1"></li> <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1" aria-label="Slide 2"></button>
<li data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2"></li> <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2" aria-label="Slide 3"></button>
</ol> </div>
<div class="carousel-inner"> <div class="carousel-inner">
<div class="carousel-item active"> <div class="carousel-item active">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#555" background="#777" text="First slide" >}} {{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#555" background="#777" text="First slide" >}}
@ -111,11 +111,11 @@ Add captions to your slides easily with the `.carousel-caption` element within a
{{< example >}} {{< example >}}
<div id="carouselExampleCaptions" class="carousel slide" data-bs-ride="carousel"> <div id="carouselExampleCaptions" class="carousel slide" data-bs-ride="carousel">
<ol class="carousel-indicators"> <div class="carousel-indicators">
<li data-bs-target="#carouselExampleCaptions" data-bs-slide-to="0" class="active"></li> <button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<li data-bs-target="#carouselExampleCaptions" data-bs-slide-to="1"></li> <button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="1" aria-label="Slide 2"></button>
<li data-bs-target="#carouselExampleCaptions" data-bs-slide-to="2"></li> <button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="2" aria-label="Slide 3"></button>
</ol> </div>
<div class="carousel-inner"> <div class="carousel-inner">
<div class="carousel-item active"> <div class="carousel-item active">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#555" background="#777" text="First slide" >}} {{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#555" background="#777" text="First slide" >}}
@ -240,11 +240,11 @@ Add `.carousel-dark` to the `.carousel` for darker controls, indicators, and cap
{{< example >}} {{< example >}}
<div id="carouselExampleDark" class="carousel carousel-dark slide" data-bs-ride="carousel"> <div id="carouselExampleDark" class="carousel carousel-dark slide" data-bs-ride="carousel">
<ol class="carousel-indicators"> <div class="carousel-indicators">
<li data-bs-target="#carouselExampleDark" data-bs-slide-to="0" class="active"></li> <button type="button" data-bs-target="#carouselExampleDark" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<li data-bs-target="#carouselExampleDark" data-bs-slide-to="1"></li> <button type="button" data-bs-target="#carouselExampleDark" data-bs-slide-to="1" aria-label="Slide 2"></button>
<li data-bs-target="#carouselExampleDark" data-bs-slide-to="2"></li> <button type="button" data-bs-target="#carouselExampleDark" data-bs-slide-to="2" aria-label="Slide 3"></button>
</ol> </div>
<div class="carousel-inner"> <div class="carousel-inner">
<div class="carousel-item active" data-bs-interval="10000"> <div class="carousel-item active" data-bs-interval="10000">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#aaa" background="#f5f5f5" text="First slide" >}} {{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#aaa" background="#f5f5f5" text="First slide" >}}

View File

@ -37,11 +37,11 @@ extra_css:
<main> <main>
<div id="myCarousel" class="carousel slide" data-bs-ride="carousel"> <div id="myCarousel" class="carousel slide" data-bs-ride="carousel">
<ol class="carousel-indicators"> <div class="carousel-indicators">
<li data-bs-target="#myCarousel" data-bs-slide-to="0" class="active"></li> <button type="button" data-bs-target="#myCarousel" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<li data-bs-target="#myCarousel" data-bs-slide-to="1"></li> <button type="button" data-bs-target="#myCarousel" data-bs-slide-to="1" aria-label="Slide 2"></button>
<li data-bs-target="#myCarousel" data-bs-slide-to="2"></li> <button type="button" data-bs-target="#myCarousel" data-bs-slide-to="2" aria-label="Slide 3"></button>
</ol> </div>
<div class="carousel-inner"> <div class="carousel-inner">
<div class="carousel-item active"> <div class="carousel-item active">
{{< placeholder width="100%" height="100%" background="#777" color="#777" text="false" title="false" >}} {{< placeholder width="100%" height="100%" background="#777" color="#777" text="false" title="false" >}}

View File

@ -36,11 +36,11 @@ extra_css:
<main> <main>
<div id="myCarousel" class="carousel slide" data-bs-ride="carousel"> <div id="myCarousel" class="carousel slide" data-bs-ride="carousel">
<ol class="carousel-indicators"> <div class="carousel-indicators">
<li data-bs-target="#myCarousel" data-bs-slide-to="0" class="active"></li> <button type="button" data-bs-target="#myCarousel" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<li data-bs-target="#myCarousel" data-bs-slide-to="1"></li> <button type="button" data-bs-target="#myCarousel" data-bs-slide-to="1" aria-label="Slide 2"></button>
<li data-bs-target="#myCarousel" data-bs-slide-to="2"></li> <button type="button" data-bs-target="#myCarousel" data-bs-slide-to="2" aria-label="Slide 3"></button>
</ol> </div>
<div class="carousel-inner"> <div class="carousel-inner">
<div class="carousel-item active"> <div class="carousel-item active">
{{< placeholder width="100%" height="100%" background="#777" color="#777" text="false" title="false" >}} {{< placeholder width="100%" height="100%" background="#777" color="#777" text="false" title="false" >}}

View File

@ -862,11 +862,11 @@ direction: rtl
<div> <div>
{{< example show_markup="false" >}} {{< example show_markup="false" >}}
<div id="carouselExampleCaptions" class="carousel slide" data-bs-ride="carousel"> <div id="carouselExampleCaptions" class="carousel slide" data-bs-ride="carousel">
<ol class="carousel-indicators"> <div class="carousel-indicators">
<li data-bs-target="#carouselExampleCaptions" data-bs-slide-to="0" class="active"></li> <button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<li data-bs-target="#carouselExampleCaptions" data-bs-slide-to="1"></li> <button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="1" aria-label="Slide 2"></button>
<li data-bs-target="#carouselExampleCaptions" data-bs-slide-to="2"></li> <button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="2" aria-label="Slide 3"></button>
</ol> </div>
<div class="carousel-inner"> <div class="carousel-inner">
<div class="carousel-item active"> <div class="carousel-item active">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#555" background="#777" text="الشريحة الأولى" >}} {{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#555" background="#777" text="الشريحة الأولى" >}}