Skip to content

Commit

Permalink
chore: WIP card implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
marvel-uiuc committed Jul 31, 2024
1 parent 3e32762 commit deac1e1
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 19 deletions.
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"tabWidth": 4
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. |

Expand Down
115 changes: 110 additions & 5 deletions samples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,121 @@
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Card Component</title>
<link rel="stylesheet" href="https://cdn.brand.illinois.edu/illinois.css">
<link rel="stylesheet" href="https://dev.toolkit.illinois.edu/ilw-global/3.0.0-alpha/ilw-global.css">
<script type="module" src="/src/ilw-card.js"></script>
<script type="module" src="https://dev.toolkit.illinois.edu/ilw-grid/1.0.0-alpha/ilw-grid.js"></script>
<link rel="stylesheet" href="https://dev.toolkit.illinois.edu/ilw-grid/1.0.0-alpha/ilw-grid.css">
<script type="module" src="../src/ilw-card.js"></script>
<style>
body {
padding: 15px;
font-size: 16px;
font-family: var(--il-font-sans);
background: #f4f4f4;
}
.theme-select {
font-size: 24px;
padding-bottom: 15px;
}
.theme-select select {
font-size: 24px;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", () => {
const url = new URL(location);
let theme = url.searchParams.get("theme");
console.log(url, theme);
if (theme) {
document.querySelectorAll("ilw-card").forEach((el) => {
el.setAttribute("theme", theme);
});
document.getElementById("theme").value = theme;
}

document.getElementById("theme").addEventListener("change", (ev) => {
document.querySelectorAll("ilw-card").forEach((el) => {
el.setAttribute("theme", ev.target.value);
})
const url = new URL(location);
url.searchParams.set("theme", ev.target.value);
history.pushState({}, "", url);
})
})
</script>
</head>

<body style="margin: 0; padding: 0;">
<ilw-card></ilw-card>
<body>
<div class="theme-select">
<label for="theme">Theme: </label>
<select id="theme">
<option value="white">white</option>
<option value="gray">gray</option>
<option value="blue">blue</option>
<option value="orange">orange</option>
<option value="blue-gradient">blue-gradient</option>
<option value="orange-gradient">orange-gradient</option>
</select>
</div>
<ilw-grid innerwidth="350px">
<ilw-card>
<img src="https://fastly.picsum.photos/id/159/320/200.jpg?hmac=5rPdtfpYQaZopnmOHhelxv5a6GuLOqcRsxSbZsZIQZY"
alt="" slot="image">
<h3>Image Card</h3>
<p>Card with an image and a footer button.</p>
<div slot="footer"><a href="#" class="ilw-button">Learn More <span class="ilw-sr-only">About Student Life</span></a></div>
</ilw-card>
<ilw-card>
<h3>Plain Card</h3>
<p>A card with just a heading, text, and a footer with two buttons.</p>
<ul class="ilw-buttons" slot="footer">
<li><a href="#">Learn More <span class="ilw-sr-only">About Student Life</span></a></li>
<li><a href="#">Contact Us</a></li>
</ul>
</ilw-card>

<ilw-card clickable>
<img src="https://fastly.picsum.photos/id/821/320/200.jpg?hmac=RVG3Kon-1NU2_36rEvVVfR70VetoI3lqNuGyXKKbHCU"
alt="" slot="image">
<h3>
<a href="#">Clickable Card</a>
</h3>
<p>A card that is clickable with an image, plus a footer with one button.</p>
<div slot="footer"><a href="#" class="ilw-button">Contact Us</a></div>
</ilw-card>
<ilw-card aspectRatio="16/9">
<img src="https://fastly.picsum.photos/id/621/320/320.jpg?hmac=QYx5v9naC2WU4ngKEtULKj1XbCm31KgnttbRi2uj1OI"
alt="" slot="image">
<h3>Aspect Ratio</h3>
<p>A card where a taller image is forced into the specified aspect ratio.</p>
</ilw-card>
<ilw-card clickable>
<img src="https://cdn.brand.illinois.edu/icons/solid/blue/alumni.svg" alt="" slot="icon">
<h3>
<a href="#">Clickable Icon</a>
</h3>
<p>A card with an icon, and the card is clickable.</p>
</ilw-card>
<ilw-card aspectRatio="3/1">
<img src="https://cdn.brand.illinois.edu/icons/solid/blue/alumni.svg" alt="" slot="icon">
<h3>
Aspect Ratio Icon
</h3>
<p>A card with an icon, where the space around the icon has an aspect ratio.</p>
<div slot="footer"><a href="#" class="ilw-button">Contact Us</a></div>
</ilw-card>
<ilw-card>
<img src="https://cdn.brand.illinois.edu/icons/solid/blue/alumni.svg" alt="" slot="icon">
<h3>
<a href="#">Student Life</a>
</h3>
<p>Animal sciences students extend their learning and career networks beyond the classroom. </p>
<div slot="footer"><a href="#" class="ilw-button">Contact Us</a></div>
</ilw-card>
</ilw-grid>
</body>

</html>
33 changes: 33 additions & 0 deletions src/ilw-card.css
Original file line number Diff line number Diff line change
@@ -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;
}
}
62 changes: 51 additions & 11 deletions src/ilw-card.js
Original file line number Diff line number Diff line change
@@ -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},
};
}

Expand All @@ -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`
<div>
<slot></slot>
</div>
`;
<article class=${classMap(classes)} style=${styleMap(styles)}>
<div class="card-graphic">
<slot name="image" @slotchange=${this._slotsChanged}></slot>
<div class="card-icon">
<slot name="icon" @slotchange=${this._slotsChanged}></slot>
</div>
</div>
<div class="card-content">
<slot></slot>
</div>
<div class="card-footer">
<slot name="footer"></slot>
</div>
</article>
`;
}
}

Expand Down
59 changes: 57 additions & 2 deletions src/ilw-card.styles.js
Original file line number Diff line number Diff line change
@@ -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;
}
`;
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);
}
`;

0 comments on commit deac1e1

Please sign in to comment.