diff --git a/src/components/boolean/boolean.scss b/src/components/boolean/boolean.scss new file mode 100644 index 00000000..332fc815 --- /dev/null +++ b/src/components/boolean/boolean.scss @@ -0,0 +1,21 @@ +@import "../../settings/style"; + +.mykn-boolean { + align-items: center; + border-radius: var(--border-radus-m); + display: inline-flex; + font-size: var(--typography-font-size-body-s); + justify-content: center; + height: var(--typography-line-height-body-s); + width: var(--typography-line-height-body-s); + + &--value-true { + background-color: var(--theme-color-success-background); + color: var(--theme-color-success-body); + } + + &--explicit#{&}--value-false { + background-color: var(--theme-color-danger-background); + color: var(--theme-color-danger-body); + } +} diff --git a/src/components/boolean/boolean.stories.tsx b/src/components/boolean/boolean.stories.tsx new file mode 100644 index 00000000..9df50b9f --- /dev/null +++ b/src/components/boolean/boolean.stories.tsx @@ -0,0 +1,84 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { expect, within } from "@storybook/test"; +import React from "react"; + +import { Body, H1, H2, H3, P } from "../typography"; +import { Boolean } from "./boolean"; + +const meta = { + title: "Icon/Boolean", + component: Boolean, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const True: Story = { + args: { + value: true, + labelTrue: "This value is true", + labelFalse: "This value is false", + }, + play: ({ canvasElement }) => { + const canvas = within(canvasElement); + const boolean = canvas.getByLabelText("This value is true"); + expect(boolean).toBeVisible(); + expect(boolean.children).toHaveLength(1); + }, +}; + +export const False: Story = { + args: { + value: false, + labelTrue: "This value is true", + labelFalse: "This value is false", + }, + play: ({ canvasElement }) => { + const canvas = within(canvasElement); + const boolean = canvas.getByLabelText("This value is false"); + expect(boolean).toBeVisible(); + expect(boolean.children).toHaveLength(0); + }, +}; + +export const ExplicitFalse: Story = { + args: { + explicit: true, + value: false, + labelTrue: "This value is true", + labelFalse: "This value is false", + }, + play: ({ canvasElement }) => { + const canvas = within(canvasElement); + const boolean = canvas.getByLabelText("This value is false"); + expect(boolean.children).toHaveLength(1); + }, +}; + +export const BooleanInText: Story = { + args: { + value: true, + labelTrue: "This value is true", + labelFalse: "This value is false", + }, + render: (args) => ( + +

+ The quick brown fox jumps over the lazy dog +

+

+ The quick brown fox jumps over the lazy dog +

+

+ The quick brown fox jumps over the lazy dog +

+

+ The quick brown fox jumps over the lazy dog{" "} + +

+

+ The quick brown fox jumps over the lazy dog +

+ + ), +}; diff --git a/src/components/boolean/boolean.tsx b/src/components/boolean/boolean.tsx new file mode 100644 index 00000000..caad5cb6 --- /dev/null +++ b/src/components/boolean/boolean.tsx @@ -0,0 +1,46 @@ +import clsx from "clsx"; +import React from "react"; + +import { Outline } from "../../components/icon"; +import "./boolean.scss"; + +export type BooleanProps = { + /** The accessible label when value is true. */ + labelTrue: string; + + /** The accessible label when value is false. */ + labelFalse: string; + + /** The value. */ + value: boolean; + + /** Show an icon, even if value is false. */ + explicit?: boolean; +}; + +/** + * Boolean component, shows a checkmark if `value` is `true`. If `value` is + * `false` the icon is hidden, unless `explicit` is `true`. + * @param children + * @param props + * @constructor + */ +export const Boolean: React.FC = ({ + explicit = false, + value, + labelTrue, + labelFalse, + ...props +}) => ( +
+ {value && } + {!value && explicit && } +
+); diff --git a/src/components/boolean/index.ts b/src/components/boolean/index.ts new file mode 100644 index 00000000..fc03593d --- /dev/null +++ b/src/components/boolean/index.ts @@ -0,0 +1 @@ +export * from "./boolean"; diff --git a/src/components/button/button.scss b/src/components/button/button.scss index 3d6db4d7..76350e5f 100644 --- a/src/components/button/button.scss +++ b/src/components/button/button.scss @@ -1,4 +1,4 @@ -@use '../../settings/style'; +@use "../../settings/style"; .mykn-button { --mykn-button-color-background: var(--theme-color-primary-800); @@ -12,8 +12,9 @@ padding: var(--spacing-v-s) var(--spacing-h-s); background-color: var(--mykn-button-color-background); border: 1px solid var(--mykn-button-color-border); - border-radius: 4px; - box-shadow: 0 calc(var(--mykn-button-offset) * -1) var(--mykn-button-color-shadow); + border-radius: var(--border-radus-m); + box-shadow: 0 calc(var(--mykn-button-offset) * -1) + var(--mykn-button-color-shadow); box-sizing: border-box; color: var(--mykn-button-color-text); cursor: pointer; @@ -26,10 +27,10 @@ line-height: var(--typography-line-height-body-s); text-align: center; text-decoration: none; - transition: all var(--animation-duration-fast) var(--animation-timing-function); + transition: all var(--animation-duration-fast) + var(--animation-timing-function); transform: translateY(var(--mykn-button-offset)); - &--variant-primary { &:focus, &:hover { @@ -37,7 +38,7 @@ --mykn-button-offset: -2px; } - &[aria-expanded=true], + &[aria-expanded="true"], &:active { --mykn-button-color-background: var(--theme-color-primary-800); --mykn-button-offset: 0px; @@ -55,7 +56,7 @@ --mykn-button-offset: -2px; } - &[aria-expanded=true], + &[aria-expanded="true"], &:active { --mykn-button-color-background: var(--typography-color-background); --mykn-button-offset: 0px; diff --git a/src/components/card/card.scss b/src/components/card/card.scss index e0ad5753..532622ff 100644 --- a/src/components/card/card.scss +++ b/src/components/card/card.scss @@ -1,6 +1,6 @@ .mykn-card { background-color: var(--typography-color-background); - border-radius: 12px; + border-radius: var(--border-radus-l); box-sizing: border-box; padding: var(--spacing-v-xxl) var(--spacing-h-xxl); diff --git a/src/components/dropdown/dropdown.scss b/src/components/dropdown/dropdown.scss index 2afa89bb..c1353ca6 100644 --- a/src/components/dropdown/dropdown.scss +++ b/src/components/dropdown/dropdown.scss @@ -18,7 +18,7 @@ &__dropdown { width: fit-content; border: 1px solid var(--theme-color-primary-800); - border-radius: 4px; + border-radius: var(--border-radus-m); box-sizing: border-box; padding: 2px; z-index: 1000; diff --git a/src/components/form/select/select.scss b/src/components/form/select/select.scss index 214561a7..a1cf99ac 100644 --- a/src/components/form/select/select.scss +++ b/src/components/form/select/select.scss @@ -4,7 +4,7 @@ align-items: center; background: var(--typography-color-background); border: 1px solid var(--theme-color-primary-800); - border-radius: 6px; + border-radius: var(--border-radus-m); box-sizing: border-box; color: var(--typography-color-body); cursor: pointer; @@ -51,7 +51,7 @@ &__dropdown { background: var(--typography-color-background); border: 1px solid var(--theme-color-primary-800); - border-radius: 4px; + border-radius: var(--border-radus-m); box-sizing: border-box; min-width: 100%; padding: var(--spacing-v-s) 0; diff --git a/src/components/index.ts b/src/components/index.ts index eaaaa227..2a9661fc 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,4 +1,5 @@ // Auto-generated file. Do not modify manually. +export * from "./boolean"; export * from "./button"; export * from "./card"; export * from "./dropdown"; diff --git a/src/settings/_style.scss b/src/settings/_style.scss index 96ebe0e3..c93aefbf 100644 --- a/src/settings/_style.scss +++ b/src/settings/_style.scss @@ -24,7 +24,16 @@ --theme-shade-300: #eaeaea; --theme-shade-0: #fff; + --theme-color-success-body: #0b4f00; + --theme-color-success-background: #e9ffe9; + + --theme-color-danger-body: #ff4545; + --theme-color-danger-background: #{rgba(#ff4545, 0.1)}; + /// SPACING + --border-radus-l: 12px; + --border-radus-m: 6px; + --gutter-h-desktop: 12px; --gutter-v-desktop: 24px;