Skip to content

Commit

Permalink
feat(tile): add visual scales (#8496)
Browse files Browse the repository at this point in the history
**Related Issue:** #4759 

## Summary

This PR adds a `scale` property to control visual display for small,
medium and large scales.

---------

Co-authored-by: Erik Harper <[email protected]>
  • Loading branch information
eriklharper and eriklharper authored Jan 12, 2024
1 parent 6e643e2 commit 7638ec4
Show file tree
Hide file tree
Showing 6 changed files with 399 additions and 55 deletions.
8 changes: 8 additions & 0 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4950,6 +4950,10 @@ export namespace Components {
* When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`).
*/
"iconFlipRtl": boolean;
/**
* Specifies the size of the component.
*/
"scale": Scale;
}
interface CalciteTileSelect {
/**
Expand Down Expand Up @@ -12424,6 +12428,10 @@ declare namespace LocalJSX {
* When `true`, the icon will be flipped when the element direction is right-to-left (`"rtl"`).
*/
"iconFlipRtl"?: boolean;
/**
* Specifies the size of the component.
*/
"scale"?: Scale;
}
interface CalciteTileSelect {
/**
Expand Down
119 changes: 75 additions & 44 deletions packages/calcite-components/src/components/tile/tile.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,31 @@

.container {
@apply pointer-events-none
grid
grid-cols-1
gap-2;
grid
grid-cols-1;
gap: var(--calcite-spacing-md);
}

.content {
@apply flex
flex-auto
flex-col
justify-center
gap-2;
// set width handles slotted content and heading word wrap
flex-auto
flex-col
justify-center;
inline-size: 10%;
}

.content-container {
@apply focus-base
text-color-2
flex
w-full
flex-auto
items-stretch
p-0;
text-color-2
flex
w-full
flex-auto
items-stretch
p-0;
}

.content-slot-container {
@apply bg-foreground-1 flex items-center;
@apply flex items-center;

&:first-child {
padding-inline: 0 0.75rem;
Expand All @@ -47,36 +45,71 @@
}

.heading {
@apply text-n1-wrap
text-color-2
pointer-events-none
break-words
font-medium
duration-150
ease-in-out;
@apply pointer-events-none
break-words;
color: var(--calcite-color-text-2);
font-size: var(--calcite-font-size--1);
font-weight: 500;
line-height: 1.20313rem;
}
.large-visual {
@apply items-center
text-center;
min-block-size: theme("spacing.48");
.icon {
@apply flex
justify-center
self-end;
calcite-icon {
align-self: self-end;
block-size: 64px;
inline-size: 64px;
justify-self: center;
}
.content-container {
@apply self-center;
}
}
.description {
@apply text-n2-wrap
text-color-3
break-words
pointer-events-none
duration-150
ease-in-out;
@apply break-words
pointer-events-none;
color: var(--calcite-color-text-3);
font-size: var(--calcite-font-size--2);
font-weight: 400;
line-height: 1.03125rem;
}
}

:host([scale="s"]) {
.container {
gap: var(--calcite-spacing-sm);
}
.heading {
font-size: var(--calcite-font-size--2);
line-height: 1.03125rem;
}
.description {
font-size: var(--calcite-font-size--3);
line-height: 0.85938rem;
}
}

:host([scale="l"]) {
.container {
gap: var(--calcite-spacing-xl);
}
.heading {
font-size: var(--calcite-font-size-0);
line-height: 1.375rem;
}
.description {
font-size: var(--calcite-font-size--1);
line-height: 1.20313rem;
}
}

:host(:not([href])) {
calcite-icon {
color: var(--calcite-color-text-3);
}
}

:host([href]),
:host([href]:hover) {
.heading {
Expand All @@ -85,8 +118,14 @@
}
}
:host(:not([embed])) {
@apply p-3;
box-shadow: 0 0 0 1px var(--calcite-color-border-2);
padding: var(--calcite-spacing-md);
}
:host(:not([embed])[scale="s"]) {
padding: var(--calcite-spacing-sm);
}
:host(:not([embed])[scale="l"]) {
padding: var(--calcite-spacing-xl);
}
:host(:not([embed])[href]:hover) {
@apply cursor-pointer;
Expand All @@ -96,26 +135,18 @@
box-shadow: 0 0 0 3px var(--calcite-color-brand);
}
:host([icon][heading]:not([description]):not([embed])) {
@apply p-0;
}
:host([icon][heading]:not([description])) {
.icon {
@apply flex justify-center;
}
.large-visual {
@apply text-center;
}
padding: 0px;
}

@include disabled();

:host(:hover),
:host([active]) {
.heading {
@apply text-color-1;
color: var(--calcite-color-text-1);
}
.description {
@apply text-color-2;
color: var(--calcite-color-text-2);
}
}

Expand Down
36 changes: 36 additions & 0 deletions packages/calcite-components/src/components/tile/tile.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,46 @@ export const simple = (): string => html`
${boolean("hidden", false)}
href="${text("href", "#")}"
icon="${select("icon", iconNames, "layer")}"
scale="${select("scale", ["s", "m", "l"], "m")}"
>
</calcite-tile>
`;

export const scales = (): string => html`
<div style="width: 300px">
<calcite-label scale="s"
>small
<calcite-tile
description="Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collab on thinking to further the overall."
heading="Tile title lorem ipsum"
icon="layers"
scale="s"
>
</calcite-tile>
</calcite-label>
<calcite-label scale="m"
>medium
<calcite-tile
description="Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collab on thinking to further the overall."
heading="Tile title lorem ipsum"
icon="layers"
scale="m"
>
</calcite-tile>
</calcite-label>
<calcite-label scale="l"
>large
<calcite-tile
description="Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collab on thinking to further the overall."
heading="Tile title lorem ipsum"
icon="layers"
scale="l"
>
</calcite-tile>
</calcite-label>
</div>
`;

export const largeTile = (): string => html`
<calcite-tile
${boolean("active", false)}
Expand Down
18 changes: 7 additions & 11 deletions packages/calcite-components/src/components/tile/tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
updateHostInteraction,
} from "../../utils/interactive";
import { SLOTS } from "./resources";
import { Scale } from "../interfaces";

/**
* @slot content-start - A slot for adding non-actionable elements before the component's content.
Expand Down Expand Up @@ -75,6 +76,11 @@ export class Tile implements ConditionalSlotComponent, InteractiveComponent {

@Prop({ reflect: true }) iconFlipRtl = false;

/**
* Specifies the size of the component.
*/
@Prop({ reflect: true }) scale: Scale = "m";

// --------------------------------------------------------------------------
//
// Private Properties
Expand Down Expand Up @@ -112,20 +118,10 @@ export class Tile implements ConditionalSlotComponent, InteractiveComponent {
renderTile(): VNode {
const { icon, el, heading, description, iconFlipRtl } = this;
const isLargeVisual = heading && icon && !description;
const iconStyle = isLargeVisual
? {
height: "64px",
width: "64px",
}
: undefined;

return (
<div class={{ container: true, "large-visual": isLargeVisual }}>
{icon && (
<div class="icon">
<calcite-icon flipRtl={iconFlipRtl} icon={icon} scale="l" style={iconStyle} />
</div>
)}
{icon && <calcite-icon flipRtl={iconFlipRtl} icon={icon} scale="l" />}
<div class="content-container">
{getSlotted(el, SLOTS.contentStart) ? (
<div class="content-slot-container">
Expand Down
Loading

0 comments on commit 7638ec4

Please sign in to comment.