diff --git a/all.js b/all.js
index bc4175c..8728a07 100644
--- a/all.js
+++ b/all.js
@@ -43,6 +43,8 @@ import './tabs/primary-tab.js'
import './tabs/secondary-tab.js'
import './tabs/tabs.js'
import './text/text-field.js'
+import './carousel/carousel.js'
+import './carousel/carousel-item.js'
// go/keep-sorted end
// LINT.ThenChange(:exports)
// LINT.IfChange(exports)
@@ -74,3 +76,5 @@ export * from './switch/switch.js'
export * from './tabs/tab.js'
export * from './tabs/tabs.js'
export * from './text/text-field.js'
+export * from './carousel/carousel.js'
+export * from './carousel/carousel-item.js'
diff --git a/carousel/carousel-item.js b/carousel/carousel-item.js
new file mode 100644
index 0000000..bd8b2f4
--- /dev/null
+++ b/carousel/carousel-item.js
@@ -0,0 +1,32 @@
+import { LitElement, html, css } from 'lit';
+
+/**
+ * A Material Design carousel item component.
+ */
+export class CarouselItem extends LitElement {
+ static get styles() {
+ return css`
+ :host {
+ display: block;
+ scroll-snap-align: start;
+ flex: 0 0 auto;
+ }
+ `;
+ }
+
+ constructor() {
+ super();
+ this.internals = this.attachInternals();
+ this.internals.role = 'listitem';
+ }
+
+ render() {
+ return html`
+
+
+
+ `;
+ }
+}
+
+customElements.define('md-carousel-item', CarouselItem);
diff --git a/carousel/carousel.js b/carousel/carousel.js
new file mode 100644
index 0000000..e92a3a0
--- /dev/null
+++ b/carousel/carousel.js
@@ -0,0 +1,50 @@
+import { LitElement, html, css } from 'lit';
+
+/**
+ * A Material Design carousel component.
+ */
+export class Carousel extends LitElement {
+ static get styles() {
+ return css`
+ :host {
+ display: block;
+ width: 100%;
+ overflow-x: auto;
+ overscroll-behavior-x: contain;
+ scroll-snap-type: x mandatory;
+ scrollbar-width: none; /* Firefox */
+ }
+
+ :host::-webkit-scrollbar {
+ display: none; /* Safari and Chrome */
+ }
+
+ .container {
+ display: flex;
+ gap: 8px; /* Default gap */
+ }
+
+ ::slotted(*) {
+ scroll-snap-align: start;
+ flex: 0 0 auto;
+ }
+ `;
+ }
+
+ constructor() {
+ super();
+ this.internals = this.attachInternals();
+ this.internals.role = 'list';
+ this.internals.ariaLabel = 'Carousel';
+ }
+
+ render() {
+ return html`
+
+
+
+ `;
+ }
+}
+
+customElements.define('md-carousel', Carousel);
diff --git a/common.js b/common.js
index d063462..45747e6 100644
--- a/common.js
+++ b/common.js
@@ -25,6 +25,8 @@ import './select/select-option.js'
import './tabs/primary-tab.js'
import './tabs/tabs.js'
import './text/text-field.js'
+import './carousel/carousel.js'
+import './carousel/carousel-item.js'
export * from './buttons/button.js'
export * from './checkbox/checkbox.js'
@@ -45,3 +47,5 @@ export * from './select/select-option.js'
export * from './tabs/tab.js'
export * from './tabs/tabs.js'
export * from './text/text-field.js'
+export * from './carousel/carousel.js'
+export * from './carousel/carousel-item.js'
diff --git a/package-lock.json b/package-lock.json
index c787dc2..d33e15b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2199,8 +2199,7 @@
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1107588.tgz",
"integrity": "sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg==",
"dev": true,
- "license": "BSD-3-Clause",
- "peer": true
+ "license": "BSD-3-Clause"
},
"node_modules/diff": {
"version": "5.2.0",
@@ -4352,7 +4351,6 @@
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"rollup": "dist/bin/rollup"
},
@@ -4934,7 +4932,6 @@
"integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"