diff --git a/all.js b/all.js
index bc4175c..77ddd8f 100644
--- a/all.js
+++ b/all.js
@@ -6,6 +6,8 @@
*/
import './buttons/elevated-button.js'
import './buttons/button.js'
+import './carousel/carousel.js'
+import './carousel/carousel-item.js'
import './buttons/filled-tonal-button.js'
import './buttons/outlined-button.js'
import './buttons/text-button.js'
@@ -48,6 +50,8 @@ import './text/text-field.js'
// LINT.IfChange(exports)
// go/keep-sorted start
export * from './buttons/button.js'
+export * from './carousel/carousel.js'
+export * from './carousel/carousel-item.js'
export * from './checkbox/checkbox.js'
export * from './chips/chip.js'
export * from './chips/chip-set.js'
diff --git a/carousel/carousel-item.js b/carousel/carousel-item.js
new file mode 100644
index 0000000..1122642
--- /dev/null
+++ b/carousel/carousel-item.js
@@ -0,0 +1,32 @@
+import { html, LitElement, css } from 'lit'
+
+export class CarouselItem extends LitElement {
+ static properties = {}
+
+ constructor() {
+ super()
+ }
+
+ render() {
+ return html`
+
+
+
+ `
+ }
+
+ static styles = css`
+ :host {
+ display: block;
+ scroll-snap-align: start;
+ flex-shrink: 0;
+ }
+ .item {
+ display: block;
+ border-radius: var(--md-carousel-item-shape, 24px);
+ overflow: hidden;
+ }
+ `
+}
+
+customElements.define('md-carousel-item', CarouselItem)
diff --git a/carousel/carousel.js b/carousel/carousel.js
new file mode 100644
index 0000000..b75ee3b
--- /dev/null
+++ b/carousel/carousel.js
@@ -0,0 +1,41 @@
+import { html, LitElement, css } from 'lit'
+
+export class Carousel extends LitElement {
+ static properties = {}
+
+ constructor() {
+ super()
+ }
+
+ render() {
+ return html`
+
+
+
+ `
+ }
+
+ static styles = css`
+ :host {
+ display: block;
+ }
+ .carousel {
+ display: flex;
+ overflow-x: auto;
+ scroll-snap-type: x mandatory;
+ scrollbar-width: none; /* Firefox */
+ -ms-overflow-style: none; /* IE and Edge */
+ gap: 8px; /* Optional gap */
+ padding: 16px;
+ scroll-behavior: smooth;
+ }
+ .carousel::-webkit-scrollbar {
+ display: none; /* Chrome, Safari and Opera */
+ }
+ ::slotted(*) {
+ scroll-snap-align: start;
+ }
+ `
+}
+
+customElements.define('md-carousel', Carousel)
diff --git a/common.js b/common.js
index d063462..15f8797 100644
--- a/common.js
+++ b/common.js
@@ -7,6 +7,8 @@
* for production.
*/
import './buttons/button.js'
+import './carousel/carousel.js'
+import './carousel/carousel-item.js'
import './checkbox/checkbox.js'
import './chips/chip.js'
import './chips/chip-set.js'
@@ -27,6 +29,8 @@ import './tabs/tabs.js'
import './text/text-field.js'
export * from './buttons/button.js'
+export * from './carousel/carousel.js'
+export * from './carousel/carousel-item.js'
export * from './checkbox/checkbox.js'
export * from './chips/chip.js'
export * from './chips/chip-set.js'
diff --git a/demo/components/expressive-component.js b/demo/components/expressive-component.js
index 540b698..8bac8fb 100644
--- a/demo/components/expressive-component.js
+++ b/demo/components/expressive-component.js
@@ -298,6 +298,50 @@ class ExpressiveComponent extends LitElement {
value-end="75">
+ Carousel
+
+
+
+
+

+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+

+
+
+
+
+
+
Cards
diff --git a/demo/index.html b/demo/index.html
index bb1a109..9c20b82 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -58,6 +58,8 @@
import 'material/snackbar/snackbar.js'
import 'material/app/bar.js'
import 'material/progress/progress.js'
+ import 'material/carousel/carousel.js'
+ import 'material/carousel/carousel-item.js'
import './components/expressive-component.js'