Skip to content

Commit

Permalink
feat(layout-item): Adds new layout-item component to arrange content …
Browse files Browse the repository at this point in the history
…and actions. #6743
  • Loading branch information
driskull committed May 2, 2023
1 parent d3b0652 commit 89e0a92
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/components/layout-item/layout-item.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { hidden, renders, slots } from "../../tests/commonTests";
import { SLOTS } from "./resources";

describe("calcite-layout-item", () => {
describe("renders", () => {
renders("calcite-layout-item", { display: "flex" });
});

it("honors hidden attribute", async () => hidden("calcite-layout-item"));

it("has slots", () => slots("calcite-layout-item", SLOTS));
});
59 changes: 59 additions & 0 deletions src/components/layout-item/layout-item.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
:host {
@apply flex flex-col flex-1;
}

.container {
@apply text-color-2
flex
flex-auto
font-sans
font-normal
items-stretch;
}

.content {
@apply flex
flex-auto
flex-col
justify-center;
}

.content-start {
@apply justify-start;
}

.content-end {
@apply justify-end;
}

.content-start,
.content-end {
@apply flex-initial;
}

.actions-start,
.actions-end,
.content-start,
.content-end {
@apply flex items-center;
}

.content-start,
.content-end {
::slotted(calcite-icon) {
@apply self-center mx-3;
}
}

.actions-start,
.actions-end {
::slotted(calcite-action) {
@apply self-stretch;

color: inherit;
}
}

[hidden] {
display: none;
}
117 changes: 117 additions & 0 deletions src/components/layout-item/layout-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { Component, h, Host, State, VNode } from "@stencil/core";
import { slotChangeHasAssignedElement } from "../../utils/dom";
import { CSS, SLOTS } from "./resources";

/**
* @slot - A slot for adding content.
* @slot actions-start - A slot for adding actionable `calcite-action` elements before the content of the component.
* @slot content-start - A slot for adding non-actionable elements before content of the component.
* @slot content-end - A slot for adding non-actionable elements after content of the component.
* @slot actions-end - A slot for adding actionable `calcite-action` elements after the content of the component.
*/
@Component({
tag: "calcite-layout-item",
styleUrl: "layout-item.scss",
shadow: true
})
export class LayoutItem {
// --------------------------------------------------------------------------
//
// Private Properties
//
// --------------------------------------------------------------------------

@State() hasActionsStart = false;

@State() hasActionsEnd = false;

@State() hasContentStart = false;

@State() hasContentEnd = false;

// --------------------------------------------------------------------------
//
// Render Methods
//
// --------------------------------------------------------------------------

renderActionsStart(): VNode {
const { hasActionsStart } = this;
return (
<div class={CSS.actionsStart} hidden={!hasActionsStart} key="actions-start-container">
<slot name={SLOTS.actionsStart} onSlotchange={this.handleActionsStartSlotChange} />
</div>
);
}

renderActionsEnd(): VNode {
const { hasActionsEnd } = this;
return (
<div class={CSS.actionsEnd} hidden={!hasActionsEnd} key="actions-end-container">
<slot name={SLOTS.actionsEnd} onSlotchange={this.handleActionsEndSlotChange} />
</div>
);
}

renderContentStart(): VNode {
const { hasContentStart } = this;
return (
<div class={CSS.contentStart} hidden={!hasContentStart}>
<slot name={SLOTS.contentStart} onSlotchange={this.handleContentStartSlotChange} />
</div>
);
}

renderDefaultContent(): VNode {
return (
<div class={CSS.content}>
<slot />
</div>
);
}

renderContentEnd(): VNode {
const { hasContentEnd } = this;
return (
<div class={CSS.contentEnd} hidden={!hasContentEnd}>
<slot name={SLOTS.contentEnd} onSlotchange={this.handleContentEndSlotChange} />
</div>
);
}

render(): VNode {
return (
<Host>
<div class={CSS.container}>
{this.renderActionsStart()}
{this.renderContentStart()}
{this.renderDefaultContent()}
{this.renderContentEnd()}
{this.renderActionsEnd()}
</div>
</Host>
);
}

// --------------------------------------------------------------------------
//
// Private Methods
//
// --------------------------------------------------------------------------

handleActionsStartSlotChange = (event: Event): void => {
this.hasActionsStart = slotChangeHasAssignedElement(event);
};

handleActionsEndSlotChange = (event: Event): void => {
this.hasActionsEnd = slotChangeHasAssignedElement(event);
};

handleContentStartSlotChange = (event: Event): void => {
this.hasContentStart = slotChangeHasAssignedElement(event);
};

handleContentEndSlotChange = (event: Event): void => {
this.hasContentEnd = slotChangeHasAssignedElement(event);
};
}
15 changes: 15 additions & 0 deletions src/components/layout-item/resources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const CSS = {
container: "container",
actionsStart: "actions-start",
contentStart: "content-start",
content: "content",
contentEnd: "content-end",
actionsEnd: "actions-end"
};

export const SLOTS = {
actionsStart: "actions-start",
contentStart: "content-start",
contentEnd: "content-end",
actionsEnd: "actions-end"
};
66 changes: 66 additions & 0 deletions src/demos/layout-item.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Layout Item</title>

<style>
.parent-flex {
display: flex;
justify-content: space-between;
font-size: var(--calcite-font-size-0);
align-items: center;
padding: 12px 0;
margin-left: 10%;
width: 70%;
}

.header,
.parent-flex {
color: var(--calcite-ui-text-3);
font-family: var(--calcite-sans-family);
font-weight: var(--calcite-font-weight-medium);
}

.header {
margin-left: 10%;
font-size: var(--calcite-font-size-4);
}

.child-flex {
flex: 1 0 21%;
padding-right: 10%;
}

.child-flex-padding {
padding: 25px 0;
padding-right: 10%;
}

hr {
margin: 50px 0;
border-top: 1px solid var(--calcite-ui-border-2);
}
</style>
<script src="./_assets/head.js"></script>
<script type="module" src="./_assets/demo-form.js"></script>
</head>

<body>
<demo-dom-swapper>
<calcite-panel>
<div slot="header-content">Header!</div>
<p>Slotted content!</p>
<calcite-layout-item slot="footer">
<calcite-action text="select" icon="check" slot="actions-start"></calcite-action>
<div slot="content-start">content-start</div>
Default content
<div slot="content-end">content-end</div>
<calcite-action text="delete" icon="trash" slot="actions-end"></calcite-action>
</calcite-layout-item>
</calcite-panel>
</demo-dom-swapper>
</body>
</html>
7 changes: 7 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,13 @@ <h1 id="calcite-demo">Calcite demo</h1>
</a>
</div>

<div>
<a href="/demos/layout-item.html">
<calcite-action scale="s" text="Layout Item" alignment="start" text-enabled appearance="solid">
</calcite-action>
</a>
</div>

<div>
<a href="/demos/link.html">
<calcite-action scale="s" text="Link" alignment="start" text-enabled appearance="solid"> </calcite-action>
Expand Down
1 change: 1 addition & 0 deletions stencil.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const create: () => Config = () => ({
{ components: ["calcite-input-message"] },
{ components: ["calcite-input-time-picker", "calcite-time-picker"] },
{ components: ["calcite-label"] },
{ components: ["calcite-layout-item"] },
{ components: ["calcite-link"] },
{ components: ["calcite-loader"] },
{ components: ["calcite-list", "calcite-list-item", "calcite-list-item-group"] },
Expand Down

0 comments on commit 89e0a92

Please sign in to comment.