Skip to content

Commit

Permalink
add sp-section-title
Browse files Browse the repository at this point in the history
  • Loading branch information
ko-noguchi committed Dec 27, 2024
1 parent fa493dd commit 5c13fe3
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 0 deletions.
45 changes: 45 additions & 0 deletions src/components/sectionTitle/section-title.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
:host {
display: block;
}

.container {
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
}

.main {
display: flex;
align-items: center;
gap: 16px;
}

.heading {
display: flex;
align-items: center;
gap: 8px;
}

.text-links {
display: flex;
flex-shrink: 0;
align-items: center;
gap: 16px;
}

.buttons {
display: flex;
flex-shrink: 0;
align-items: center;
gap: 8px;
}

h2 {
margin-block: 3px;
padding-inline-start: 8px;
font-size: 14px;
font-weight: bold;
line-height: 1.6;
position: relative;
}
97 changes: 97 additions & 0 deletions src/components/sectionTitle/sp-section-title.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// @ts-ignore
import resetStyle from "@acab/reset.css?inline" assert { type: "css" };
// @ts-ignore
import foundationStyle from "../foundation.css?inline" assert { type: "css" };
// @ts-ignore
import sectionTitleStyle from "./section-title.css?inline" assert { type: "css" };

const styles = new CSSStyleSheet();
styles.replaceSync(`${resetStyle} ${foundationStyle} ${sectionTitleStyle}`);

export class SpSectionTitle extends HTMLElement {
#headingElement = document.createElement("h2");
#textLinkSlotElement = document.createElement("slot");
#buttonSlotElement = document.createElement("slot");

set text(value: string) {
this.#headingElement.textContent = value;
}

static get observedAttributes() {
return ["text"];
}

constructor() {
super();
this.attachShadow({ mode: "open" });

this.shadowRoot!.adoptedStyleSheets = [styles];

this.#textLinkSlotElement.name = "text-links";
this.#buttonSlotElement.name = "buttons";
}

connectedCallback() {
this.shadowRoot!.appendChild(this.#createContainer());

if (this.#textLinkSlotElement.assignedElements().length === 0) {
this.shadowRoot!.querySelector(".text-links")?.remove();
}

if (this.#buttonSlotElement.assignedElements().length === 0) {
this.shadowRoot!.querySelector(".buttons")?.remove();
}
}

attributeChangedCallback(name: string, oldValue: string, newValue: string) {
if (name === "text" && oldValue !== newValue) {
this.text = newValue;
}
}

#createContainer() {
const container = document.createElement("div");
container.classList.add("container");
container.appendChild(this.#createMain());
container.appendChild(this.#createButtons());
return container;
}

#createMain() {
const main = document.createElement("div");
main.classList.add("main");
main.appendChild(this.#createHeadingBlock());
main.appendChild(this.#createTextLinks());
return main;
}

#createHeadingBlock() {
const div = document.createElement("div");
div.classList.add("heading");
div.appendChild(this.#headingElement);
return div;
}

#createTextLinks() {
const div = document.createElement("div");
div.classList.add("text-links");
div.appendChild(this.#textLinkSlotElement);
return div;
}

#createButtons() {
const div = document.createElement("div");
div.classList.add("buttons");
div.appendChild(this.#buttonSlotElement);
return div;
}
}

declare global {
interface HTMLElementTagNameMap {
"sp-section-title": SpSectionTitle;
}
}

customElements.get("sp-section-title") ||
customElements.define("sp-section-title", SpSectionTitle);
69 changes: 69 additions & 0 deletions stories/sectionTitle/sp-section-title.story.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import "../../src/components/sectionTitle/sp-section-title";
import "../../src/components/button/sp-button";
import "@sp-design/token/lib/speeda-tokens.css";
import { Meta, StoryObj } from "@storybook/web-components";
import { html } from "lit";

const meta: Meta = {
component: "sp-section-title",
argTypes: {
text: { type: "string" },
},
args: {
text: "Section Title",
},
};
export default meta;

type Story = StoryObj;

export const Basic: Story = {};

export const WithTextLinks: Story = {
render: (args) => html`
<sp-section-title text=${args.text}>
<a
href="#"
slot="text-links"
style="font-size: 12px; color: var(--color-semantic-text-text-link);"
>TextLink1</a
>
<a
href="#"
slot="text-links"
style="font-size: 12px; color: var(--color-semantic-text-text-link);"
>TextLink2</a
>
</sp-section-title>
`,
};

export const WithButtons: Story = {
render: (args) => html`
<sp-section-title text=${args.text}>
<sp-button text="Button1" slot="buttons"></sp-button>
<sp-button text="Button2" slot="buttons"></sp-button>
</sp-section-title>
`,
};

export const WithFullContents: Story = {
render: (args) => html`
<sp-section-title text=${args.text}>
<a
href="#"
slot="text-links"
style="font-size: 12px; color: var(--color-semantic-text-text-link);"
>TextLink1</a
>
<a
href="#"
slot="text-links"
style="font-size: 12px; color: var(--color-semantic-text-text-link);"
>TextLink2</a
>
<sp-button text="Button1" slot="buttons"></sp-button>
<sp-button text="Button2" slot="buttons"></sp-button>
</sp-section-title>
`,
};

0 comments on commit 5c13fe3

Please sign in to comment.