From 7c580e9969a50eea0250b837e5ba5daa12430dd7 Mon Sep 17 00:00:00 2001 From: Julian Roeland Date: Wed, 31 Jan 2024 16:44:59 +0100 Subject: [PATCH] :sparkles: #19 - feat: Implemented the Tabs component --- src/components/button/button.scss | 19 +++++- src/components/button/button.tsx | 16 +++-- src/components/index.ts | 1 + src/components/tabs/index.ts | 1 + src/components/tabs/tabs.scss | 35 +++++++++++ src/components/tabs/tabs.stories.tsx | 78 ++++++++++++++++++++++++ src/components/tabs/tabs.tsx | 88 ++++++++++++++++++++++++++++ src/lib/format/string.ts | 12 ++++ src/settings/tokens.css | 12 ++++ 9 files changed, 257 insertions(+), 5 deletions(-) create mode 100644 src/components/tabs/index.ts create mode 100644 src/components/tabs/tabs.scss create mode 100644 src/components/tabs/tabs.stories.tsx create mode 100644 src/components/tabs/tabs.tsx create mode 100644 src/lib/format/string.ts diff --git a/src/components/button/button.scss b/src/components/button/button.scss index 657660f6..775e1926 100644 --- a/src/components/button/button.scss +++ b/src/components/button/button.scss @@ -1,4 +1,5 @@ .mykn-button { + $self: &; --mykn-button-color-background: var(--theme-color-primary-800); --mykn-button-color-shadow: var(--theme-shade-1000); --mykn-button-color-text: var(--theme-shade-0); @@ -47,9 +48,14 @@ } &--variant-primary { + &#{$self}--active, // TODO &:focus, &:hover { --mykn-button-color-background: var(--theme-color-primary-700); + } + + &:focus, + &:hover { --mykn-button-offset: -2px; } @@ -66,9 +72,14 @@ --mykn-button-color-shadow: currentColor; --mykn-button-color-text: var(--typography-color-body); + &#{$self}--active, &:focus, &:hover { --mykn-button-color-background: var(--theme-color-primary-200); + } + + &:focus, + &:hover { --mykn-button-offset: -2px; } @@ -84,9 +95,15 @@ --mykn-button-color-shadow: currentColor; --mykn-button-color-text: var(--theme-shade-700); + &#{$self}--active, + &:focus, + &:hover { + --mykn-button-color-background: var(--theme-color-primary-100); + --mykn-button-color-text: var(--theme-color-primary-800); + } + &:focus, &:hover { - --mykn-button-color-background: var(--theme-color-primary-200); --mykn-button-offset: -2px; } diff --git a/src/components/button/button.tsx b/src/components/button/button.tsx index fe53c65c..632244e5 100644 --- a/src/components/button/button.tsx +++ b/src/components/button/button.tsx @@ -4,6 +4,7 @@ import React, { LegacyRef } from "react"; import "./button.scss"; type BaseButtonProps = { + active?: boolean; square?: boolean; variant?: "primary" | "outline" | "transparent"; }; @@ -16,16 +17,19 @@ export type ButtonLinkProps = React.AnchorHTMLAttributes & /** * Button component + * @param active * @param variant + * @param square * @param props * @constructor */ export const Button = React.forwardRef( - ({ square = false, variant = "primary", ...props }, ref) => { + ({ active, square = false, variant = "primary", ...props }, ref) => { return ( + {index < tabs.length - 1 && } + + ))} + + {tabs.map((tab, index) => ( + + ))} + + ); +}; + +export type TabProps = React.PropsWithChildren<{ + label: string; + id?: string; +}>; + +/** + * A tab component meant to be used as a child of the Tabs component. It is used to define the label and content of a tab. + * @param label - The label of the tab + * @param id - The id of the tab + * @param children - The content of the tab + */ +export const Tab: React.FC = ({ children }) => { + // Just a placeholder, as actual rendering does not happen here + return <>{children}; +}; diff --git a/src/lib/format/string.ts b/src/lib/format/string.ts new file mode 100644 index 00000000..9e3698c3 --- /dev/null +++ b/src/lib/format/string.ts @@ -0,0 +1,12 @@ +/** + * Converts "Some object name" to "some-object-name". + * @param input + */ +export const slugify = (input: string): string => { + return input + .toLowerCase() // Convert to lowercase + .replace(/\s+/g, "-") // Replace spaces with hyphens + .replace(/[^\w-]+/g, "") // Remove non-word characters (excluding hyphens) + .replace(/--+/g, "-") // Replace multiple hyphens with a single hyphen + .replace(/^-+|-+$/g, ""); // Remove leading and trailing hyphens +}; diff --git a/src/settings/tokens.css b/src/settings/tokens.css index b1e264b2..fd88f37c 100644 --- a/src/settings/tokens.css +++ b/src/settings/tokens.css @@ -11,6 +11,7 @@ --theme-color-primary-600: #8d75e6; --theme-color-primary-400: #bdb0ed; --theme-color-primary-200: #ecf1ff; + --theme-color-primary-100: #f2eeff; --theme-color-tertiary-800: #0f172a; --theme-color-tertiary-700: #1e293b; @@ -19,9 +20,13 @@ --theme-shade-1000: #000; --theme-shade-900: #272727; + --theme-shade-800: #4b4b4b; --theme-shade-700: #545454; --theme-shade-400: #b3b3b3; --theme-shade-300: #eaeaea; + --theme-shade-200: #e6e6e6; + --theme-shade-100: #f1f1f1; + --theme-shade-50: #fcfcfc; --theme-shade-0: #fff; --theme-color-success-body: #0b4f00; @@ -33,6 +38,7 @@ /* SPACING */ --border-radus-l: 12px; --border-radus-m: 6px; + --border-radus-s: 4px; --gutter-h-desktop: 12px; --gutter-v-desktop: 24px; @@ -46,12 +52,18 @@ --spacing-h-m: 8px; --spacing-v-m: 8px; + --spacing-h-l: 16px; + --spacing-v-l: 16px; + --spacing-h-xl: 20px; --spacing-v-xl: 50px; --spacing-h-xxl: 32px; --spacing-v-xxl: 32px; + --spacing-h-xxxl: 40px; + --spacing-v-xxxl: 40px; + /* TYPOGRAPHY */ --typography-color-background: var(--theme-shade-0); --typography-color-h: var(--theme-shade-900);