Skip to content

Commit

Permalink
feat(tile-group): add Tile Group component (#8806)
Browse files Browse the repository at this point in the history
**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>
  • Loading branch information
eriklharper and eriklharper authored Feb 22, 2024
1 parent 802ccf2 commit 4f65bdd
Show file tree
Hide file tree
Showing 11 changed files with 2,209 additions and 7 deletions.
39 changes: 39 additions & 0 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import { TableMessages } from "./components/table/assets/table/t9n";
import { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n";
import { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n";
import { TextAreaMessages } from "./components/text-area/assets/text-area/t9n";
import { TileGroupLayout } from "./components/tile-group/interfaces";
import { TileSelectType } from "./components/tile-select/interfaces";
import { TileSelectGroupLayout } from "./components/tile-select-group/interfaces";
import { TipMessages } from "./components/tip/assets/tip/t9n";
Expand Down Expand Up @@ -170,6 +171,7 @@ export { TableMessages } from "./components/table/assets/table/t9n";
export { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n";
export { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n";
export { TextAreaMessages } from "./components/text-area/assets/text-area/t9n";
export { TileGroupLayout } from "./components/tile-group/interfaces";
export { TileSelectType } from "./components/tile-select/interfaces";
export { TileSelectGroupLayout } from "./components/tile-select-group/interfaces";
export { TipMessages } from "./components/tip/assets/tip/t9n";
Expand Down Expand Up @@ -4985,6 +4987,20 @@ export namespace Components {
*/
"scale": Scale;
}
interface CalciteTileGroup {
/**
* When `true`, interaction is prevented and the component is displayed with lower opacity.
*/
"disabled": boolean;
/**
* Defines the layout of the component. Use `"horizontal"` for rows, and `"vertical"` for a single column.
*/
"layout": TileGroupLayout;
/**
* Specifies the size of the component.
*/
"scale": Scale;
}
interface CalciteTileSelect {
/**
* When `true`, the component is checked.
Expand Down Expand Up @@ -7140,6 +7156,12 @@ declare global {
prototype: HTMLCalciteTileElement;
new (): HTMLCalciteTileElement;
};
interface HTMLCalciteTileGroupElement extends Components.CalciteTileGroup, HTMLStencilElement {
}
var HTMLCalciteTileGroupElement: {
prototype: HTMLCalciteTileGroupElement;
new (): HTMLCalciteTileGroupElement;
};
interface HTMLCalciteTileSelectElementEventMap {
"calciteTileSelectChange": void;
}
Expand Down Expand Up @@ -7421,6 +7443,7 @@ declare global {
"calcite-tabs": HTMLCalciteTabsElement;
"calcite-text-area": HTMLCalciteTextAreaElement;
"calcite-tile": HTMLCalciteTileElement;
"calcite-tile-group": HTMLCalciteTileGroupElement;
"calcite-tile-select": HTMLCalciteTileSelectElement;
"calcite-tile-select-group": HTMLCalciteTileSelectGroupElement;
"calcite-time-picker": HTMLCalciteTimePickerElement;
Expand Down Expand Up @@ -12490,6 +12513,20 @@ declare namespace LocalJSX {
*/
"scale"?: Scale;
}
interface CalciteTileGroup {
/**
* When `true`, interaction is prevented and the component is displayed with lower opacity.
*/
"disabled"?: boolean;
/**
* Defines the layout of the component. Use `"horizontal"` for rows, and `"vertical"` for a single column.
*/
"layout"?: TileGroupLayout;
/**
* Specifies the size of the component.
*/
"scale"?: Scale;
}
interface CalciteTileSelect {
/**
* When `true`, the component is checked.
Expand Down Expand Up @@ -12992,6 +13029,7 @@ declare namespace LocalJSX {
"calcite-tabs": CalciteTabs;
"calcite-text-area": CalciteTextArea;
"calcite-tile": CalciteTile;
"calcite-tile-group": CalciteTileGroup;
"calcite-tile-select": CalciteTileSelect;
"calcite-tile-select-group": CalciteTileSelectGroup;
"calcite-time-picker": CalciteTimePicker;
Expand Down Expand Up @@ -13116,6 +13154,7 @@ declare module "@stencil/core" {
"calcite-tabs": LocalJSX.CalciteTabs & JSXBase.HTMLAttributes<HTMLCalciteTabsElement>;
"calcite-text-area": LocalJSX.CalciteTextArea & JSXBase.HTMLAttributes<HTMLCalciteTextAreaElement>;
"calcite-tile": LocalJSX.CalciteTile & JSXBase.HTMLAttributes<HTMLCalciteTileElement>;
"calcite-tile-group": LocalJSX.CalciteTileGroup & JSXBase.HTMLAttributes<HTMLCalciteTileGroupElement>;
"calcite-tile-select": LocalJSX.CalciteTileSelect & JSXBase.HTMLAttributes<HTMLCalciteTileSelectElement>;
"calcite-tile-select-group": LocalJSX.CalciteTileSelectGroup & JSXBase.HTMLAttributes<HTMLCalciteTileSelectGroupElement>;
"calcite-time-picker": LocalJSX.CalciteTimePicker & JSXBase.HTMLAttributes<HTMLCalciteTimePickerElement>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type TileGroupLayout = "vertical" | "horizontal";
21 changes: 21 additions & 0 deletions packages/calcite-components/src/components/tile-group/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# calcite-tile-group

<!-- Auto Generated Below -->

## Properties

| Property | Attribute | Description | Type | Default |
| ---------- | ---------- | ------------------------------------------------------------------------------------------------------- | ---------------------------- | -------------- |
| `disabled` | `disabled` | When `true`, interaction is prevented and the component is displayed with lower opacity. | `boolean` | `false` |
| `layout` | `layout` | Defines the layout of the component. Use `"horizontal"` for rows, and `"vertical"` for a single column. | `"horizontal" \| "vertical"` | `"horizontal"` |
| `scale` | `scale` | Specifies the size of the component. | `"l" \| "m" \| "s"` | `"m"` |

## Slots

| Slot | Description |
| ---- | ------------------------------------------ |
| | A slot for adding `calcite-tile` elements. |

---

*Built with [StencilJS](https://stenciljs.com/)*
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const CSS = {
tileGroup: "tile-group",
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { newE2EPage } from "@stencil/core/testing";
import { accessible, defaults, disabled, reflects, renders, hidden } from "../../tests/commonTests";
import { html } from "../../../support/formatting";

describe("calcite-tile-group", () => {
describe("renders", () => {
renders("calcite-tile-group", { display: "inline-block" });
});

describe("honors hidden attribute.", () => {
hidden("calcite-tile-group");
});

describe("accessible", () => {
accessible(`<calcite-tile-group></calcite-tile-group>`);
});

describe("defaults", () => {
defaults("calcite-tile-group", [
{ propertyName: "layout", defaultValue: "horizontal" },
{ propertyName: "scale", defaultValue: "m" },
]);
});

describe("reflects", () => {
reflects("calcite-tile-group", [
{ propertyName: "layout", value: "horizontal" },
{ propertyName: "scale", value: "m" },
]);
});

describe("disabled", () => {
disabled(
html`<calcite-tile-group>
<calcite-tile></calcite-tile>
<calcite-tile></calcite-tile>
<calcite-tile></calcite-tile>
</calcite-tile-group>`,
{ focusTarget: "none" },
);
});

describe("disabled with link tiles", () => {
disabled(
html`<calcite-tile-group>
<calcite-tile
heading="Tile heading lorem ipsum"
href="/"
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."
icon="layers"
></calcite-tile>
<calcite-tile
heading="Tile heading lorem ipsum"
href="/"
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."
icon="layers"
></calcite-tile>
<calcite-tile
heading="Tile heading lorem ipsum"
href="/"
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."
icon="layers"
></calcite-tile>
</calcite-tile-group>`,
{ focusTarget: "child" },
);
});

describe("prop passing", () => {
it("tiles receive parent scale prop on initial load and when scale attribute is mutated", async () => {
const page = await newE2EPage();
await page.setContent(html`
<calcite-tile-group scale="s">
<calcite-tile></calcite-tile>
<calcite-tile></calcite-tile>
<calcite-tile></calcite-tile>
</calcite-tile-group>
`);

let tiles = await page.findAll("calcite-tile");
tiles.forEach((tile) => {
expect(tile.getAttribute("scale")).toBe("s");
});

await page.$eval("calcite-tile-group", (element: HTMLCalciteTileGroupElement) =>
element.setAttribute("scale", "l"),
);
await page.waitForChanges();

tiles = await page.findAll("calcite-tile");
tiles.forEach((tile) => {
expect(tile.getAttribute("scale")).toBe("l");
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
:host {
box-sizing: border-box;
display: inline-block;

.tile-group {
display: grid;
grid-auto-rows: minmax(auto, 1fr);
}

::slotted(calcite-tile) {
margin-block-end: var(--calcite-spacing-px);
margin-inline-end: var(--calcite-spacing-px);
}
}

:host([scale="s"]) {
.tile-group {
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}
}
:host([scale="m"]) {
.tile-group {
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}
}
:host([scale="l"]) {
.tile-group {
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}
}

:host([layout="vertical"]) {
.tile-group {
display: flex;
flex-direction: column;
}
}

@include disabled();
@include base-component();
Loading

0 comments on commit 4f65bdd

Please sign in to comment.