@jotyping/jo-designsystem 0.1.1-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/.prettierignore +3 -0
  2. package/.prettierrc +1 -0
  3. package/.storybook/main.ts +18 -0
  4. package/.storybook/preview.ts +15 -0
  5. package/README.md +20 -0
  6. package/dist/components/button/jd-button.js +42 -0
  7. package/dist/components/button/jd-button.js.map +1 -0
  8. package/dist/components/button/jd-button.scss.js +5 -0
  9. package/dist/components/button/jd-button.scss.js.map +1 -0
  10. package/dist/components/flash/jd-flash.js +74 -0
  11. package/dist/components/flash/jd-flash.js.map +1 -0
  12. package/dist/components/flash/jd-flash.scss.js +5 -0
  13. package/dist/components/flash/jd-flash.scss.js.map +1 -0
  14. package/dist/components/footer/jd-footer.js +50 -0
  15. package/dist/components/footer/jd-footer.js.map +1 -0
  16. package/dist/components/footer/jd-footer.scss.js +5 -0
  17. package/dist/components/footer/jd-footer.scss.js.map +1 -0
  18. package/dist/components/header/jd-header.js +69 -0
  19. package/dist/components/header/jd-header.js.map +1 -0
  20. package/dist/components/header/jd-header.scss.js +5 -0
  21. package/dist/components/header/jd-header.scss.js.map +1 -0
  22. package/dist/components/heading/jd-heading.js +63 -0
  23. package/dist/components/heading/jd-heading.js.map +1 -0
  24. package/dist/components/heading/jd-heading.scss.js +5 -0
  25. package/dist/components/heading/jd-heading.scss.js.map +1 -0
  26. package/dist/components/icon/icon-data.js +47 -0
  27. package/dist/components/icon/icon-data.js.map +1 -0
  28. package/dist/components/icon/jd-icon.js +58 -0
  29. package/dist/components/icon/jd-icon.js.map +1 -0
  30. package/dist/components/icon/jd-icon.scss.js +5 -0
  31. package/dist/components/icon/jd-icon.scss.js.map +1 -0
  32. package/dist/components/icon-button/jd-icon-button.js +52 -0
  33. package/dist/components/icon-button/jd-icon-button.js.map +1 -0
  34. package/dist/components/icon-button/jd-icon-button.scss.js +5 -0
  35. package/dist/components/icon-button/jd-icon-button.scss.js.map +1 -0
  36. package/dist/components/image-link/jd-image-link.js +63 -0
  37. package/dist/components/image-link/jd-image-link.js.map +1 -0
  38. package/dist/components/image-link/jd-image-link.scss.js +5 -0
  39. package/dist/components/image-link/jd-image-link.scss.js.map +1 -0
  40. package/dist/components/link/jd-link.js +43 -0
  41. package/dist/components/link/jd-link.js.map +1 -0
  42. package/dist/components/link/jd-link.scss.js +5 -0
  43. package/dist/components/link/jd-link.scss.js.map +1 -0
  44. package/dist/components/modal/jd-modal.js +86 -0
  45. package/dist/components/modal/jd-modal.js.map +1 -0
  46. package/dist/components/modal/jd-modal.scss.js +5 -0
  47. package/dist/components/modal/jd-modal.scss.js.map +1 -0
  48. package/dist/components/navigation/jd-navigation.js +44 -0
  49. package/dist/components/navigation/jd-navigation.js.map +1 -0
  50. package/dist/components/navigation/jd-navigation.scss.js +5 -0
  51. package/dist/components/navigation/jd-navigation.scss.js.map +1 -0
  52. package/dist/components/tag/jd-tag.js +36 -0
  53. package/dist/components/tag/jd-tag.js.map +1 -0
  54. package/dist/components/tag/jd-tag.scss.js +5 -0
  55. package/dist/components/tag/jd-tag.scss.js.map +1 -0
  56. package/dist/fonts/satoshi-black.ttf +0 -0
  57. package/dist/fonts/satoshi-bold.ttf +0 -0
  58. package/dist/fonts/satoshi-italic.ttf +0 -0
  59. package/dist/fonts/satoshi-medium.ttf +0 -0
  60. package/dist/fonts/satoshi-regular.ttf +0 -0
  61. package/dist/index.js +27 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/stores/breakpoint-store.js +13 -0
  64. package/dist/stores/breakpoint-store.js.map +1 -0
  65. package/dist/vite.svg +1 -0
  66. package/eslint.config.js +12 -0
  67. package/index.html +18 -0
  68. package/license.md +0 -0
  69. package/package.json +46 -0
  70. package/public/fonts/satoshi-black.ttf +0 -0
  71. package/public/fonts/satoshi-bold.ttf +0 -0
  72. package/public/fonts/satoshi-italic.ttf +0 -0
  73. package/public/fonts/satoshi-medium.ttf +0 -0
  74. package/public/fonts/satoshi-regular.ttf +0 -0
  75. package/public/vite.svg +1 -0
  76. package/src/assets/lit.svg +1 -0
  77. package/src/components/button/jd-button.scss +56 -0
  78. package/src/components/button/jd-button.ts +28 -0
  79. package/src/components/button/stories/jd-button.stories.ts +44 -0
  80. package/src/components/flash/jd-flash.scss +47 -0
  81. package/src/components/flash/jd-flash.ts +65 -0
  82. package/src/components/flash/stories/jd-flash.stories.ts +62 -0
  83. package/src/components/footer/jd-footer.scss +42 -0
  84. package/src/components/footer/jd-footer.ts +42 -0
  85. package/src/components/footer/stories/jd-footer.stories.ts +20 -0
  86. package/src/components/header/jd-header.scss +48 -0
  87. package/src/components/header/jd-header.ts +58 -0
  88. package/src/components/header/stories/jd-header.stories.ts +52 -0
  89. package/src/components/heading/jd-heading.scss +48 -0
  90. package/src/components/heading/jd-heading.ts +49 -0
  91. package/src/components/heading/stories/jd-heading.stories.ts +47 -0
  92. package/src/components/icon/icon-data.ts +45 -0
  93. package/src/components/icon/jd-icon.scss +35 -0
  94. package/src/components/icon/jd-icon.ts +66 -0
  95. package/src/components/icon/stories/jd-icon.stories.ts +62 -0
  96. package/src/components/icon-button/jd-icon-button.scss +36 -0
  97. package/src/components/icon-button/jd-icon-button.ts +51 -0
  98. package/src/components/icon-button/stories/jd-icon-button.stories.ts +93 -0
  99. package/src/components/image-link/jd-image-link.scss +41 -0
  100. package/src/components/image-link/jd-image-link.ts +36 -0
  101. package/src/components/image-link/stories/jd-image-link.stories.ts +46 -0
  102. package/src/components/link/jd-link.scss +29 -0
  103. package/src/components/link/jd-link.ts +25 -0
  104. package/src/components/link/stories/jd-link.stories.ts +42 -0
  105. package/src/components/modal/jd-modal.scss +91 -0
  106. package/src/components/modal/jd-modal.ts +75 -0
  107. package/src/components/modal/stories/jd-modal.stories.ts +54 -0
  108. package/src/components/navigation/jd-navigation.scss +17 -0
  109. package/src/components/navigation/jd-navigation.ts +32 -0
  110. package/src/components/navigation/stories/jd-navigation.stories.ts +47 -0
  111. package/src/components/tag/jd-tag.scss +19 -0
  112. package/src/components/tag/jd-tag.ts +23 -0
  113. package/src/components/tag/stories/jd-tag.stories.ts +20 -0
  114. package/src/components.ts +12 -0
  115. package/src/index.ts +12 -0
  116. package/src/stores/breakpoint-store.ts +16 -0
  117. package/src/styles/_colors.scss +10 -0
  118. package/src/styles/_fonts.scss +72 -0
  119. package/src/styles/_mixins.scss +112 -0
  120. package/src/styles/_reset.scss +62 -0
  121. package/src/styles/variables.scss +13 -0
  122. package/src/vite-env.d.ts +1 -0
  123. package/tsconfig.build.json +12 -0
  124. package/tsconfig.json +47 -0
  125. package/vite.config.ts +26 -0
@@ -0,0 +1,56 @@
1
+ @use "/src/styles/mixins.scss" as mixins;
2
+ @use "/src/styles/colors.scss" as colors;
3
+
4
+ :host {
5
+ display: inline-block;
6
+ }
7
+
8
+ :host([active]) button {
9
+ &.primary {
10
+ color: colors.$color-black;
11
+ background-color: colors.$color-white;
12
+ }
13
+ &.secondary {
14
+ color: #3a3a3a;
15
+ background-color: colors.$color-white;
16
+ outline: 3px solid colors.$color-black;
17
+ outline-offset: -3px;
18
+ &:hover {
19
+ outline: 4px solid colors.$color-black;
20
+ outline-offset: -4px;
21
+ }
22
+ }
23
+ }
24
+
25
+ button {
26
+ @include mixins.font-button;
27
+ padding: 0 20px;
28
+ border-radius: 28px;
29
+ cursor: pointer;
30
+ transition: background-color 0.3s;
31
+ height: 56px;
32
+ border: none;
33
+ white-space: nowrap;
34
+ overflow: hidden;
35
+ text-overflow: ellipsis;
36
+ &.primary {
37
+ color: colors.$color-black;
38
+ background-color: colors.$color-white;
39
+ outline: 3px solid colors.$color-black;
40
+ outline-offset: -3px;
41
+ &:hover {
42
+ outline: 4px solid colors.$color-black;
43
+ outline-offset: -4px;
44
+ }
45
+ }
46
+ &.secondary {
47
+ color: #3a3a3a;
48
+ background-color: colors.$color-white;
49
+ outline: 1px solid colors.$color-neutral-200;
50
+ outline-offset: -1px;
51
+ &:hover {
52
+ outline: 3px solid colors.$color-neutral-200;
53
+ outline-offset: -3px;
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,28 @@
1
+ import { LitElement, html, unsafeCSS } from "lit";
2
+ import { customElement, property } from "lit/decorators.js";
3
+ import "../../components";
4
+ import style from "./jd-button.scss?inline";
5
+
6
+ @customElement("jd-button")
7
+ export class JdButton extends LitElement {
8
+ static styles = unsafeCSS(style);
9
+
10
+ /**
11
+ * Button type, can be "primary" or "secondary".
12
+ */
13
+ @property({ type: String }) type: "primary" | "secondary" = "primary";
14
+
15
+ render() {
16
+ return html`
17
+ <button class=${this.type}>
18
+ <slot></slot>
19
+ </button>
20
+ `;
21
+ }
22
+ }
23
+
24
+ declare global {
25
+ interface HTMLElementTagNameMap {
26
+ "jd-button": JdButton;
27
+ }
28
+ }
@@ -0,0 +1,44 @@
1
+ import type { Meta, StoryObj } from "@storybook/web-components-vite";
2
+ import { html } from "lit-html";
3
+ import "../jd-button.ts";
4
+
5
+ type JdButtonArgs = {
6
+ type: "primary" | "secondary";
7
+ };
8
+
9
+ const meta: Meta<JdButtonArgs> = {
10
+ title: "Components/Button",
11
+ component: "jd-button",
12
+ argTypes: {
13
+ type: {
14
+ control: { type: "select" },
15
+ options: ["primary", "secondary"],
16
+ description: "Type of the button",
17
+ defaultValue: "primary",
18
+ },
19
+ },
20
+ };
21
+
22
+ export default meta;
23
+ type Story = StoryObj<JdButtonArgs>;
24
+
25
+ const DefaultExample = (args: JdButtonArgs) => {
26
+ const onClick = () => {
27
+ console.log("Button clicked!");
28
+ };
29
+ return html`<jd-button type=${args.type} @click=${onClick}>
30
+ Click me
31
+ </jd-button>`;
32
+ };
33
+
34
+ export const DefaultStory: Story = {
35
+ name: "Default",
36
+ render: DefaultExample.bind({}),
37
+ args: { type: "primary" },
38
+ };
39
+
40
+ export const SecondaryStory: Story = {
41
+ name: "Secondary",
42
+ render: DefaultExample.bind({}),
43
+ args: { type: "secondary" },
44
+ };
@@ -0,0 +1,47 @@
1
+ @use "/src/styles/mixins.scss" as mixins;
2
+ @use "/src/styles/colors.scss" as colors;
3
+
4
+ :host {
5
+ display: inline-block;
6
+ }
7
+
8
+ .flash-wrapper {
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: 15px;
12
+ &.upside-down {
13
+ flex-direction: column-reverse;
14
+ }
15
+ }
16
+
17
+ .title-wrapper {
18
+ &.m,
19
+ &.l {
20
+ @include mixins.font-02-subheadline;
21
+ }
22
+ &.s {
23
+ @include mixins.font-03-subheadline;
24
+ }
25
+ &.red {
26
+ color: colors.$color-accent-red;
27
+ }
28
+ &.purple {
29
+ color: colors.$color-accent-purple;
30
+ }
31
+ &.blue {
32
+ color: colors.$color-accent-blue;
33
+ }
34
+ }
35
+
36
+ .icon-wrapper {
37
+ color: colors.$color-black;
38
+ &.m,
39
+ &.l {
40
+ width: 72px;
41
+ height: 72px;
42
+ }
43
+ &.s {
44
+ width: 52px;
45
+ height: 52px;
46
+ }
47
+ }
@@ -0,0 +1,65 @@
1
+ import { LitElement, html, unsafeCSS } from "lit";
2
+ import { customElement, property } from "lit/decorators.js";
3
+ import style from "./jd-flash.scss?inline";
4
+ import { classMap } from "lit/directives/class-map.js";
5
+ import "../../components";
6
+ import { SignalWatcher } from "@lit-labs/signals";
7
+ import { breakpoint } from "../../stores/breakpoint-store";
8
+
9
+ @customElement("jd-flash")
10
+ export class JdFlash extends SignalWatcher(LitElement) {
11
+ static styles = unsafeCSS(style);
12
+
13
+ @property({ type: String }) size: "s" | "m" | "l" | "auto" = "auto";
14
+ @property({ type: String }) color: "red" | "purple" | "blue" = "red";
15
+ @property({ type: String }) iconPosition: "top" | "bottom" = "bottom";
16
+ @property({ type: String }) iconName:
17
+ | "fire"
18
+ | "puzzle"
19
+ | "lightning"
20
+ | "arrow-right"
21
+ | "arrow-circle-left"
22
+ | "burger-menu"
23
+ | "chat" = "fire";
24
+
25
+ render() {
26
+ const flashWrapperClasses = {
27
+ "flash-wrapper": true,
28
+ "upside-down": this.iconPosition === "top",
29
+ };
30
+
31
+ const titleWrapperClasses = {
32
+ "title-wrapper": true,
33
+ [this.size === "auto" ? breakpoint.get() : this.size]: true,
34
+ [this.color]: true,
35
+ };
36
+
37
+ const iconWrapperClasses = {
38
+ "icon-wrapper": true,
39
+ [this.size === "auto" ? breakpoint.get() : this.size]: true,
40
+ };
41
+
42
+ return html`
43
+ <div class=${classMap(flashWrapperClasses)}>
44
+ <div class=${classMap(titleWrapperClasses)}>
45
+ <slot name="title"></slot>
46
+ </div>
47
+ <div class=${classMap(iconWrapperClasses)}>
48
+ <jd-icon
49
+ iconName=${this.iconName}
50
+ color=${this.color}
51
+ size=${this.size === "s" || breakpoint.get() === "s"
52
+ ? "48px"
53
+ : "72px"}
54
+ ></jd-icon>
55
+ </div>
56
+ </div>
57
+ `;
58
+ }
59
+ }
60
+
61
+ declare global {
62
+ interface HTMLElementTagNameMap {
63
+ "jd-flash": JdFlash;
64
+ }
65
+ }
@@ -0,0 +1,62 @@
1
+ import type { Meta, StoryObj } from "@storybook/web-components-vite";
2
+ import { html } from "lit-html";
3
+ import "../jd-flash";
4
+
5
+ const meta: Meta = {
6
+ title: "Components/Flash",
7
+ component: "jd-flash",
8
+ argTypes: {
9
+ size: {
10
+ control: { type: "select" },
11
+ options: ["s", "m", "l", "auto"],
12
+ description: "Size of the flash",
13
+ defaultValue: "auto",
14
+ },
15
+ color: {
16
+ control: { type: "select" },
17
+ options: ["red", "purple", "blue"],
18
+ description: "Color of the flash",
19
+ defaultValue: "red",
20
+ },
21
+ iconPosition: {
22
+ control: { type: "select" },
23
+ options: ["top", "bottom"],
24
+ description: "Icon position",
25
+ defaultValue: "top",
26
+ },
27
+ iconName: {
28
+ control: { type: "select" },
29
+ options: [
30
+ "fire",
31
+ "puzzle",
32
+ "lightning",
33
+ "arrow-right",
34
+ "arrow-circle-left",
35
+ "burger-menu",
36
+ "chat",
37
+ ],
38
+ description: "Icon name",
39
+ defaultValue: "top",
40
+ },
41
+ },
42
+ };
43
+
44
+ export default meta;
45
+ type Story = StoryObj;
46
+
47
+ const DefaultExample = ({ ...args }) => {
48
+ return html`<jd-flash
49
+ size=${args.size}
50
+ color=${args.color}
51
+ iconPosition=${args.iconPosition}
52
+ iconName=${args.iconName}
53
+ >
54
+ <div slot="title">Flash<br />Title</div>
55
+ </jd-flash>`;
56
+ };
57
+
58
+ export const DefaultStory: Story = {
59
+ name: "Default",
60
+ render: DefaultExample.bind({}),
61
+ args: { size: "auto", color: "red", iconPosition: "top", iconName: "fire" },
62
+ };
@@ -0,0 +1,42 @@
1
+ @use "/src/styles/mixins.scss" as mixins;
2
+ @use "/src/styles/colors.scss" as colors;
3
+
4
+ :host {
5
+ display: block;
6
+ }
7
+ .footer-wrapper {
8
+ display: flex;
9
+ justify-content: start;
10
+ border-top: 2px solid colors.$color-black;
11
+ @include mixins.font-03-copy;
12
+ &.s {
13
+ flex-direction: column;
14
+ justify-content: center;
15
+ width: calc(100% - 64px);
16
+ margin: 0 32px;
17
+ height: 140px;
18
+ }
19
+ &.m {
20
+ flex-direction: row;
21
+ align-items: center;
22
+ width: calc(100% - 80px);
23
+ margin: 0 40px;
24
+ height: 78px;
25
+ }
26
+ &.l {
27
+ flex-direction: row;
28
+ align-items: center;
29
+ width: calc(100% - 192px);
30
+ margin: 0 96px;
31
+ height: 94px;
32
+ }
33
+ }
34
+
35
+ .dot {
36
+ display: flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ width: 28px;
40
+ height: 28px;
41
+ color: colors.$color-black;
42
+ }
@@ -0,0 +1,42 @@
1
+ import { LitElement, html, nothing, unsafeCSS } from "lit";
2
+ import { customElement } from "lit/decorators.js";
3
+ import style from "./jd-footer.scss?inline";
4
+ import "../../components";
5
+ import { SignalWatcher } from "@lit-labs/signals";
6
+ import { breakpoint } from "../../stores/breakpoint-store";
7
+ import { classMap } from "lit/directives/class-map.js";
8
+
9
+ @customElement("jd-footer")
10
+ export class JdFooter extends SignalWatcher(LitElement) {
11
+ static styles = unsafeCSS(style);
12
+
13
+ render() {
14
+ const footerWrapperClass = {
15
+ "footer-wrapper": true,
16
+ [breakpoint.get()]: true,
17
+ };
18
+
19
+ return html`
20
+ <div class=${classMap(footerWrapperClass)}>
21
+ <jd-modal>
22
+ <jd-link slot="button">Impressum</jd-link>
23
+ <div>Impressum content</div>
24
+ </jd-modal>
25
+ ${breakpoint.get() !== "s"
26
+ ? html`<jd-icon iconName="circle"></jd-icon>`
27
+ : nothing}
28
+ <jd-link href="#" target="_blank">Github</jd-link>
29
+ ${breakpoint.get() !== "s"
30
+ ? html`<jd-icon iconName="circle"></jd-icon>`
31
+ : nothing}
32
+ <jd-link href="#" target="_blank">Contact</jd-link>
33
+ </div>
34
+ `;
35
+ }
36
+ }
37
+
38
+ declare global {
39
+ interface HTMLElementTagNameMap {
40
+ "jd-footer": JdFooter;
41
+ }
42
+ }
@@ -0,0 +1,20 @@
1
+ import type { Meta, StoryObj } from "@storybook/web-components-vite";
2
+ import { html } from "lit-html";
3
+ import "../jd-footer.ts";
4
+
5
+ const meta: Meta = {
6
+ title: "Components/Footer",
7
+ component: "jd-footer",
8
+ };
9
+
10
+ export default meta;
11
+ type Story = StoryObj;
12
+
13
+ const DefaultExample = () => {
14
+ return html`<jd-footer></jd-footer>`;
15
+ };
16
+
17
+ export const DefaultStory: Story = {
18
+ name: "Default",
19
+ render: DefaultExample.bind({}),
20
+ };
@@ -0,0 +1,48 @@
1
+ @use "/src/styles/mixins.scss" as mixins;
2
+ @use "/src/styles/colors.scss" as colors;
3
+
4
+ :host {
5
+ display: block;
6
+ }
7
+
8
+ .header-wrapper {
9
+ display: flex;
10
+ flex-direction: row;
11
+ justify-content: space-between;
12
+ align-items: center;
13
+ &.s {
14
+ width: calc(100% - 64px);
15
+ margin: 0 32px;
16
+ }
17
+ &.m {
18
+ width: calc(100% - 80px);
19
+ margin: 0 40px;
20
+ }
21
+ &.l {
22
+ width: calc(100% - 192px);
23
+ margin: 0 96px;
24
+ }
25
+ }
26
+
27
+ .burger-wrapper {
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+ }
32
+
33
+ .nav-wrapper {
34
+ width: 100%;
35
+ display: flex;
36
+ justify-content: center;
37
+ padding-bottom: 100px;
38
+ }
39
+
40
+ .empty-div-desktop {
41
+ width: 88px;
42
+ }
43
+
44
+ .logo {
45
+ @include mixins.font-logo;
46
+ color: colors.$color-black;
47
+ cursor: pointer;
48
+ }
@@ -0,0 +1,58 @@
1
+ import { LitElement, html, unsafeCSS, nothing } from "lit";
2
+ import { customElement, state } from "lit/decorators.js";
3
+ import style from "./jd-header.scss?inline";
4
+ import "../../components";
5
+ import { SignalWatcher } from "@lit-labs/signals";
6
+ import { breakpoint } from "../../stores/breakpoint-store";
7
+ import { classMap } from "lit/directives/class-map.js";
8
+
9
+ @customElement("jd-header")
10
+ export class JdHeader extends SignalWatcher(LitElement) {
11
+ static styles = unsafeCSS(style);
12
+
13
+ @state() private showModal = false;
14
+
15
+ render() {
16
+ const headerWrapperClass = {
17
+ "header-wrapper": true,
18
+ [breakpoint.get()]: true,
19
+ };
20
+
21
+ return html`
22
+ <div class=${classMap(headerWrapperClass)}>
23
+ <div class="logo">joflow</div>
24
+ ${breakpoint.get() !== "s"
25
+ ? html`<div>
26
+ <slot></slot>
27
+ </div>`
28
+ : html`<div class="burger-wrapper">
29
+ <jd-icon-button
30
+ iconName="burger-menu"
31
+ @click=${() => {
32
+ this.showModal = !this.showModal;
33
+ console.log("Modal state:", this.showModal);
34
+ }}
35
+ ></jd-icon-button>
36
+ </div>`}
37
+ ${breakpoint.get() === "l"
38
+ ? html`<div class="empty-div-desktop"></div>`
39
+ : nothing}
40
+ </div>
41
+ <jd-modal
42
+ type="header"
43
+ .show=${this.showModal && breakpoint.get() === "s"}
44
+ id="modal"
45
+ >
46
+ <div class="nav-wrapper">
47
+ <slot></slot>
48
+ </div>
49
+ </jd-modal>
50
+ `;
51
+ }
52
+ }
53
+
54
+ declare global {
55
+ interface HTMLElementTagNameMap {
56
+ "jd-header": JdHeader;
57
+ }
58
+ }
@@ -0,0 +1,52 @@
1
+ import type { Meta, StoryObj } from "@storybook/web-components-vite";
2
+ import { html } from "lit-html";
3
+ import "../jd-header.ts";
4
+
5
+ const meta: Meta = {
6
+ title: "Components/Header",
7
+ component: "jd-header",
8
+ parameters: {
9
+ layout: "fullscreen",
10
+ },
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj;
15
+
16
+ const DefaultExample = () => {
17
+ const buttons = ["Work", "About", "Hello"];
18
+ let activeIndex = 0;
19
+
20
+ function handleClick(index: number) {
21
+ activeIndex = index;
22
+ document.querySelectorAll("jd-button").forEach((btn, i) => {
23
+ btn.toggleAttribute("active", i === activeIndex);
24
+ });
25
+ console.log(`Button clicked: Index ${index}, Label ${buttons[index]}`);
26
+ }
27
+
28
+ setTimeout(() => {
29
+ document.querySelectorAll("jd-button").forEach((btn, i) => {
30
+ btn.toggleAttribute("active", i === activeIndex);
31
+ btn.addEventListener("click", () => handleClick(i));
32
+ });
33
+ });
34
+ return html`<jd-header
35
+ ><div style="width: 100%; display: flex; justify-content: center;">
36
+ <jd-navigation>
37
+ ${buttons.map(
38
+ (label, index) => html`
39
+ <jd-button type="secondary" ?active=${index === activeIndex}>
40
+ ${label}
41
+ </jd-button>
42
+ `,
43
+ )}
44
+ </jd-navigation>
45
+ </div></jd-header
46
+ >`;
47
+ };
48
+
49
+ export const DefaultStory: Story = {
50
+ name: "Default",
51
+ render: DefaultExample.bind({}),
52
+ };
@@ -0,0 +1,48 @@
1
+ @use "/src/styles/mixins.scss" as mixins;
2
+ @use "/src/styles/colors.scss" as colors;
3
+
4
+ :host {
5
+ display: inline-block;
6
+ }
7
+
8
+ .heading-wrapper {
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: 32px;
12
+ }
13
+
14
+ .title-wrapper {
15
+ color: colors.$color-black;
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: 0px;
19
+ &.l {
20
+ @include mixins.font-01-headline;
21
+ }
22
+ &.m {
23
+ @include mixins.font-02-headline;
24
+ }
25
+ &.s {
26
+ @include mixins.font-03-headline;
27
+ }
28
+ }
29
+
30
+ .subtitle-wrapper {
31
+ color: colors.$color-black;
32
+ &.l {
33
+ @include mixins.font-01-subheadline;
34
+ }
35
+ &.m {
36
+ @include mixins.font-02-subheadline;
37
+ }
38
+ &.s {
39
+ @include mixins.font-03-subheadline;
40
+ }
41
+ }
42
+
43
+ .title-line-two-wrapper {
44
+ display: flex;
45
+ flex-direction: row;
46
+ gap: 30px;
47
+ align-items: baseline;
48
+ }
@@ -0,0 +1,49 @@
1
+ import { LitElement, html, unsafeCSS } from "lit";
2
+ import { customElement, property } from "lit/decorators.js";
3
+ import style from "./jd-heading.scss?inline";
4
+ import { classMap } from "lit/directives/class-map.js";
5
+ import { SignalWatcher } from "@lit-labs/signals";
6
+ import { breakpoint } from "../../stores/breakpoint-store";
7
+ import "../../components";
8
+
9
+ @customElement("jd-heading")
10
+ export class JdHeading extends SignalWatcher(LitElement) {
11
+ static styles = unsafeCSS(style);
12
+
13
+ @property({ type: String }) size: "l" | "m" | "s" | "auto" = "auto";
14
+
15
+ render() {
16
+ const titleWrapperClasses = {
17
+ "title-wrapper": true,
18
+ [this.size === "auto" ? breakpoint.get() : this.size]: true,
19
+ };
20
+
21
+ const subTitleWrapperClasses = {
22
+ "subtitle-wrapper": true,
23
+ [this.size === "auto" ? breakpoint.get() : this.size]: true,
24
+ };
25
+
26
+ return html`
27
+ <div class="heading-wrapper">
28
+ <div class=${classMap(titleWrapperClasses)}>
29
+ <slot name="title-line-one"></slot>
30
+ <div class="title-line-two-wrapper">
31
+ <slot name="title-line-two"></slot>
32
+ <div class=${classMap(subTitleWrapperClasses)}>
33
+ <slot name="subtitle-right"></slot>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ <div class=${classMap(subTitleWrapperClasses)}>
38
+ <slot name="subtitle-bottom"></slot>
39
+ </div>
40
+ </div>
41
+ `;
42
+ }
43
+ }
44
+
45
+ declare global {
46
+ interface HTMLElementTagNameMap {
47
+ "jd-heading": JdHeading;
48
+ }
49
+ }