diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..ab28f3e --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "tabWidth": 4 +} \ No newline at end of file diff --git a/README.md b/README.md index 5a46ab7..6548b6f 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ several variations: | Slot | Description | |-----------------|--------------------------------------------------------------------------------------------| -| `slot="image"` | Placed full-width at the top of the card with a roughly 16:10 aspect ratio. | +| `slot="image"` | Placed full-width at the top of the card. | | `slot="icon"` | Centered at the top of the card with ample spacing. | | `slot="footer"` | Content remains at the bottom of the card when the card is stretched to fit a larger area. | diff --git a/samples/index.html b/samples/index.html index f8d58e7..1efcad4 100644 --- a/samples/index.html +++ b/samples/index.html @@ -2,16 +2,121 @@ - - + + Card Component - + + + + + - - + +
+ + +
+ + + +

Image Card

+

Card with an image and a footer button.

+
Learn More About Student Life
+
+ +

Plain Card

+

A card with just a heading, text, and a footer with two buttons.

+ +
+ + + +

+ Clickable Card +

+

A card that is clickable with an image, plus a footer with one button.

+
Contact Us
+
+ + +

Aspect Ratio

+

A card where a taller image is forced into the specified aspect ratio.

+
+ + +

+ Clickable Icon +

+

A card with an icon, and the card is clickable.

+
+ + +

+ Aspect Ratio Icon +

+

A card with an icon, where the space around the icon has an aspect ratio.

+
Contact Us
+
+ + +

+ Student Life +

+

Animal sciences students extend their learning and career networks beyond the classroom.

+
Contact Us
+
+
diff --git a/src/ilw-card.css b/src/ilw-card.css index e69de29..5ae9f4c 100644 --- a/src/ilw-card.css +++ b/src/ilw-card.css @@ -0,0 +1,33 @@ +@layer base { + :root { + --ilw-card--aspect-ratio: 16/10; + --ilw-card--content-padding-top: 1rem; + --ilw-card--content-padding-right: 2rem; + --ilw-card--content-padding-bottom: 1rem; + --ilw-card--content-padding-left: 2rem; + --ilw-card--font-size: 1.2em; + + --ilw-card--background: var(--ilw-background--color); + --ilw-card--heading-color: var(--il-orange); + } + + ilw-card { + border: 1px solid var(--il-blue); + } + + ilw-card [slot=image] { + width: 100%; + } + + ilw-card [slot=icon] { + max-height: 80px; + max-width: 120px; + } + + + ilw-card > h2:first-of-type, + ilw-card > h3:first-of-type, + ilw-card > h4:first-of-type { + margin-top: 0; + } +} \ No newline at end of file diff --git a/src/ilw-card.js b/src/ilw-card.js index 37e5f5f..ba5d976 100644 --- a/src/ilw-card.js +++ b/src/ilw-card.js @@ -1,12 +1,19 @@ -import { LitElement, html } from 'lit'; +import {LitElement, html} from 'lit'; import styles from './ilw-card.styles'; import './ilw-card.css'; +import {classMap} from 'lit/directives/class-map.js'; +import {styleMap} from 'lit/directives/style-map.js'; + class Card extends LitElement { static get properties() { return { - theme: { type: String, attribute: true } + theme: {}, + clickable: {type: Boolean}, + align: {}, + aspectRatio: {}, + _hasGraphic: {state: true, type: Boolean}, }; } @@ -16,19 +23,52 @@ class Card extends LitElement { constructor() { super(); - this.align = ''; - this.focus = ''; - this.shadow = false; - this.collapse = false; - this.theme = ''; + this.align = 'left'; + this.theme = 'white'; + this.aspectRatio = ''; + this.clickable = false; + this._hasGraphic = false; + } + + _slotsChanged() { + const images = this.shadowRoot.querySelector('slot[name=image]'); + if (images.assignedElements().length > 0) { + this._hasGraphic = true; + return; + } + const icons = this.shadowRoot.querySelector('slot[name=icon]'); + if (icons.assignedElements().length > 0) { + this._hasGraphic = true; + return; + } + this._hasGraphic = false; } render() { + const classes = { + graphic: this._hasGraphic, + card: true, + 'force-ratio': !!this.aspectRatio + } + const styles = { + '--ilw-card--aspect-ratio': this.aspectRatio ? this.aspectRatio : null + } return html` -
- -
- `; +
+
+ +
+ +
+
+
+ +
+ +
+ `; } } diff --git a/src/ilw-card.styles.js b/src/ilw-card.styles.js index 9b256ee..efbb143 100644 --- a/src/ilw-card.styles.js +++ b/src/ilw-card.styles.js @@ -1,5 +1,60 @@ -import { css } from 'lit'; +import { css } from "lit"; export default css` + :host { + display: flex; + flex-direction: column; + container-type: inline-size; + } -`; \ No newline at end of file + article { + position: relative; + flex: 1; + display: flex; + flex-direction: column; + justify-content: stretch; + } + + .card-graphic { + display: none; + position: relative; + } + + .graphic .card-graphic { + display: block; + min-height: 80px; + } + + .force-ratio .card-graphic { + aspect-ratio: var(--ilw-card--aspect-ratio); + width: 100%; + } + + .force-ratio .card-graphic ::slotted([slot="image"]) { + aspect-ratio: var(--ilw-card--aspect-ratio); + width: 100%; + object-fit: cover; + } + + .card-icon { + position: absolute; + top: var(--ilw-card--content-padding-top); + left: 0; + right: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: center; + } + + .card-content { + font-size: var(--ilw-card--font-size); + padding: var(--ilw-card--content-padding-top) var(--ilw-card--content-padding-right) 0 var(--ilw-card--content-padding-left); + + flex: 1; + } + + .card-footer { + padding: 0 var(--ilw-card--content-padding-right) var(--ilw-card--content-padding-bottom) var(--ilw-card--content-padding-left); + } +`;