Skip to content

Commit 4f65bdd

Browse files
authored
feat(tile-group): add Tile Group component (#8806)
**Related Issues:** #8615 #6691 #6662 ## Summary This PR adds the new `calcite-tile-group` component. It includes these responsiveness features that address #6691: - Wrapped Tiles match width of Tiles above - Wrapped Tiles match height of tallest Tile in the group The changes in this PR were extracted from and depend on the changes in #8681. --------- Co-authored-by: Erik Harper <eriklharper@pm.me>
1 parent 802ccf2 commit 4f65bdd

File tree

11 files changed

+2209
-7
lines changed

11 files changed

+2209
-7
lines changed

packages/calcite-components/src/components.d.ts

+39
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ import { TableMessages } from "./components/table/assets/table/t9n";
8484
import { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n";
8585
import { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n";
8686
import { TextAreaMessages } from "./components/text-area/assets/text-area/t9n";
87+
import { TileGroupLayout } from "./components/tile-group/interfaces";
8788
import { TileSelectType } from "./components/tile-select/interfaces";
8889
import { TileSelectGroupLayout } from "./components/tile-select-group/interfaces";
8990
import { TipMessages } from "./components/tip/assets/tip/t9n";
@@ -170,6 +171,7 @@ export { TableMessages } from "./components/table/assets/table/t9n";
170171
export { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n";
171172
export { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n";
172173
export { TextAreaMessages } from "./components/text-area/assets/text-area/t9n";
174+
export { TileGroupLayout } from "./components/tile-group/interfaces";
173175
export { TileSelectType } from "./components/tile-select/interfaces";
174176
export { TileSelectGroupLayout } from "./components/tile-select-group/interfaces";
175177
export { TipMessages } from "./components/tip/assets/tip/t9n";
@@ -4985,6 +4987,20 @@ export namespace Components {
49854987
*/
49864988
"scale": Scale;
49874989
}
4990+
interface CalciteTileGroup {
4991+
/**
4992+
* When `true`, interaction is prevented and the component is displayed with lower opacity.
4993+
*/
4994+
"disabled": boolean;
4995+
/**
4996+
* Defines the layout of the component. Use `"horizontal"` for rows, and `"vertical"` for a single column.
4997+
*/
4998+
"layout": TileGroupLayout;
4999+
/**
5000+
* Specifies the size of the component.
5001+
*/
5002+
"scale": Scale;
5003+
}
49885004
interface CalciteTileSelect {
49895005
/**
49905006
* When `true`, the component is checked.
@@ -7140,6 +7156,12 @@ declare global {
71407156
prototype: HTMLCalciteTileElement;
71417157
new (): HTMLCalciteTileElement;
71427158
};
7159+
interface HTMLCalciteTileGroupElement extends Components.CalciteTileGroup, HTMLStencilElement {
7160+
}
7161+
var HTMLCalciteTileGroupElement: {
7162+
prototype: HTMLCalciteTileGroupElement;
7163+
new (): HTMLCalciteTileGroupElement;
7164+
};
71437165
interface HTMLCalciteTileSelectElementEventMap {
71447166
"calciteTileSelectChange": void;
71457167
}
@@ -7421,6 +7443,7 @@ declare global {
74217443
"calcite-tabs": HTMLCalciteTabsElement;
74227444
"calcite-text-area": HTMLCalciteTextAreaElement;
74237445
"calcite-tile": HTMLCalciteTileElement;
7446+
"calcite-tile-group": HTMLCalciteTileGroupElement;
74247447
"calcite-tile-select": HTMLCalciteTileSelectElement;
74257448
"calcite-tile-select-group": HTMLCalciteTileSelectGroupElement;
74267449
"calcite-time-picker": HTMLCalciteTimePickerElement;
@@ -12490,6 +12513,20 @@ declare namespace LocalJSX {
1249012513
*/
1249112514
"scale"?: Scale;
1249212515
}
12516+
interface CalciteTileGroup {
12517+
/**
12518+
* When `true`, interaction is prevented and the component is displayed with lower opacity.
12519+
*/
12520+
"disabled"?: boolean;
12521+
/**
12522+
* Defines the layout of the component. Use `"horizontal"` for rows, and `"vertical"` for a single column.
12523+
*/
12524+
"layout"?: TileGroupLayout;
12525+
/**
12526+
* Specifies the size of the component.
12527+
*/
12528+
"scale"?: Scale;
12529+
}
1249312530
interface CalciteTileSelect {
1249412531
/**
1249512532
* When `true`, the component is checked.
@@ -12992,6 +13029,7 @@ declare namespace LocalJSX {
1299213029
"calcite-tabs": CalciteTabs;
1299313030
"calcite-text-area": CalciteTextArea;
1299413031
"calcite-tile": CalciteTile;
13032+
"calcite-tile-group": CalciteTileGroup;
1299513033
"calcite-tile-select": CalciteTileSelect;
1299613034
"calcite-tile-select-group": CalciteTileSelectGroup;
1299713035
"calcite-time-picker": CalciteTimePicker;
@@ -13116,6 +13154,7 @@ declare module "@stencil/core" {
1311613154
"calcite-tabs": LocalJSX.CalciteTabs & JSXBase.HTMLAttributes<HTMLCalciteTabsElement>;
1311713155
"calcite-text-area": LocalJSX.CalciteTextArea & JSXBase.HTMLAttributes<HTMLCalciteTextAreaElement>;
1311813156
"calcite-tile": LocalJSX.CalciteTile & JSXBase.HTMLAttributes<HTMLCalciteTileElement>;
13157+
"calcite-tile-group": LocalJSX.CalciteTileGroup & JSXBase.HTMLAttributes<HTMLCalciteTileGroupElement>;
1311913158
"calcite-tile-select": LocalJSX.CalciteTileSelect & JSXBase.HTMLAttributes<HTMLCalciteTileSelectElement>;
1312013159
"calcite-tile-select-group": LocalJSX.CalciteTileSelectGroup & JSXBase.HTMLAttributes<HTMLCalciteTileSelectGroupElement>;
1312113160
"calcite-time-picker": LocalJSX.CalciteTimePicker & JSXBase.HTMLAttributes<HTMLCalciteTimePickerElement>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export type TileGroupLayout = "vertical" | "horizontal";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# calcite-tile-group
2+
3+
<!-- Auto Generated Below -->
4+
5+
## Properties
6+
7+
| Property | Attribute | Description | Type | Default |
8+
| ---------- | ---------- | ------------------------------------------------------------------------------------------------------- | ---------------------------- | -------------- |
9+
| `disabled` | `disabled` | When `true`, interaction is prevented and the component is displayed with lower opacity. | `boolean` | `false` |
10+
| `layout` | `layout` | Defines the layout of the component. Use `"horizontal"` for rows, and `"vertical"` for a single column. | `"horizontal" \| "vertical"` | `"horizontal"` |
11+
| `scale` | `scale` | Specifies the size of the component. | `"l" \| "m" \| "s"` | `"m"` |
12+
13+
## Slots
14+
15+
| Slot | Description |
16+
| ---- | ------------------------------------------ |
17+
| | A slot for adding `calcite-tile` elements. |
18+
19+
---
20+
21+
*Built with [StencilJS](https://stenciljs.com/)*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const CSS = {
2+
tileGroup: "tile-group",
3+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { newE2EPage } from "@stencil/core/testing";
2+
import { accessible, defaults, disabled, reflects, renders, hidden } from "../../tests/commonTests";
3+
import { html } from "../../../support/formatting";
4+
5+
describe("calcite-tile-group", () => {
6+
describe("renders", () => {
7+
renders("calcite-tile-group", { display: "inline-block" });
8+
});
9+
10+
describe("honors hidden attribute.", () => {
11+
hidden("calcite-tile-group");
12+
});
13+
14+
describe("accessible", () => {
15+
accessible(`<calcite-tile-group></calcite-tile-group>`);
16+
});
17+
18+
describe("defaults", () => {
19+
defaults("calcite-tile-group", [
20+
{ propertyName: "layout", defaultValue: "horizontal" },
21+
{ propertyName: "scale", defaultValue: "m" },
22+
]);
23+
});
24+
25+
describe("reflects", () => {
26+
reflects("calcite-tile-group", [
27+
{ propertyName: "layout", value: "horizontal" },
28+
{ propertyName: "scale", value: "m" },
29+
]);
30+
});
31+
32+
describe("disabled", () => {
33+
disabled(
34+
html`<calcite-tile-group>
35+
<calcite-tile></calcite-tile>
36+
<calcite-tile></calcite-tile>
37+
<calcite-tile></calcite-tile>
38+
</calcite-tile-group>`,
39+
{ focusTarget: "none" },
40+
);
41+
});
42+
43+
describe("disabled with link tiles", () => {
44+
disabled(
45+
html`<calcite-tile-group>
46+
<calcite-tile
47+
heading="Tile heading lorem ipsum"
48+
href="/"
49+
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."
50+
icon="layers"
51+
></calcite-tile>
52+
<calcite-tile
53+
heading="Tile heading lorem ipsum"
54+
href="/"
55+
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."
56+
icon="layers"
57+
></calcite-tile>
58+
<calcite-tile
59+
heading="Tile heading lorem ipsum"
60+
href="/"
61+
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."
62+
icon="layers"
63+
></calcite-tile>
64+
</calcite-tile-group>`,
65+
{ focusTarget: "child" },
66+
);
67+
});
68+
69+
describe("prop passing", () => {
70+
it("tiles receive parent scale prop on initial load and when scale attribute is mutated", async () => {
71+
const page = await newE2EPage();
72+
await page.setContent(html`
73+
<calcite-tile-group scale="s">
74+
<calcite-tile></calcite-tile>
75+
<calcite-tile></calcite-tile>
76+
<calcite-tile></calcite-tile>
77+
</calcite-tile-group>
78+
`);
79+
80+
let tiles = await page.findAll("calcite-tile");
81+
tiles.forEach((tile) => {
82+
expect(tile.getAttribute("scale")).toBe("s");
83+
});
84+
85+
await page.$eval("calcite-tile-group", (element: HTMLCalciteTileGroupElement) =>
86+
element.setAttribute("scale", "l"),
87+
);
88+
await page.waitForChanges();
89+
90+
tiles = await page.findAll("calcite-tile");
91+
tiles.forEach((tile) => {
92+
expect(tile.getAttribute("scale")).toBe("l");
93+
});
94+
});
95+
});
96+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
:host {
2+
box-sizing: border-box;
3+
display: inline-block;
4+
5+
.tile-group {
6+
display: grid;
7+
grid-auto-rows: minmax(auto, 1fr);
8+
}
9+
10+
::slotted(calcite-tile) {
11+
margin-block-end: var(--calcite-spacing-px);
12+
margin-inline-end: var(--calcite-spacing-px);
13+
}
14+
}
15+
16+
:host([scale="s"]) {
17+
.tile-group {
18+
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
19+
}
20+
}
21+
:host([scale="m"]) {
22+
.tile-group {
23+
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
24+
}
25+
}
26+
:host([scale="l"]) {
27+
.tile-group {
28+
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
29+
}
30+
}
31+
32+
:host([layout="vertical"]) {
33+
.tile-group {
34+
display: flex;
35+
flex-direction: column;
36+
}
37+
}
38+
39+
@include disabled();
40+
@include base-component();

0 commit comments

Comments
 (0)