diff --git a/scss/components/_card.scss b/scss/components/_card.scss index 6046aa1..9297d37 100644 --- a/scss/components/_card.scss +++ b/scss/components/_card.scss @@ -15,6 +15,7 @@ line-height: var(--#{$prefix}card-line-height); border-radius: var(--#{$prefix}card-radius); border: var(--#{$prefix}card-border); + color: var(--#{$prefix}main-text-color); .card-image { width: 100%; diff --git a/scss/components/_index.scss b/scss/components/_index.scss index 83fdbbe..691f088 100644 --- a/scss/components/_index.scss +++ b/scss/components/_index.scss @@ -1,9 +1,10 @@ +@use "./breadcrumb"; +@use "./card"; +@use "./chips"; @use "./containers"; -@use "./button"; @use "./modal"; -@use "./chips"; +@use "./list-group"; @use "./spinner"; -@use "./breadcrumb"; -@use "./card"; @use "./promo-card"; -@use "./form/index"; +@use "./button/index" as button; +@use "./form/index" as form; diff --git a/scss/components/_list-group.scss b/scss/components/_list-group.scss new file mode 100644 index 0000000..cb52ef5 --- /dev/null +++ b/scss/components/_list-group.scss @@ -0,0 +1,70 @@ +@use "../variables/global" as *; + +.list-group { + --#{$prefix}list-group-padding-x: 1rem; + --#{$prefix}list-group-padding-y: 0.5rem; + --#{$prefix}list-group-color: var(--#{$prefix}main-text-color); + --#{$prefix}list-group-bg: transparent; + --#{$prefix}list-group-item-gap: 0.5rem; + --#{$prefix}list-group-border-radius: var(--#{$prefix}border-radius); + --#{$prefix}list-group-border-width: var(--#{$prefix}border-width); + --#{$prefix}list-group-border-color: var(--#{$prefix}border-color); + --#{$prefix}list-group-border-style: solid; + --#{$prefix}list-group-border: var(--#{$prefix}list-group-border-width) + var(--#{$prefix}list-group-border-style) var(--#{$prefix}list-group-border-color); + + position: relative; + display: flex; + flex-direction: column; + margin: 0; + padding: 0; + border: var(--#{$prefix}list-group-border); + border-radius: var(--#{$prefix}border-radius); + color: var(--#{$prefix}list-group-color); + + &.list-group-flush { + border: none; + border-radius: 0; + } + + &.list-group-horizontal { + border: 0; + flex-direction: row; + + .list-group-item { + border: var(--#{$prefix}list-group-border); + border-radius: 0; + + &:first-child { + border-right: 0; + border-top-left-radius: var(--#{$prefix}border-radius); + border-bottom-left-radius: var(--#{$prefix}border-radius); + } + + &:last-child { + border-left: 0; + border-top-right-radius: var(--#{$prefix}border-radius); + border-bottom-right-radius: var(--#{$prefix}border-radius); + } + } + } + + .list-group-item { + padding: var(--#{$prefix}list-group-padding-y) var(--#{$prefix}list-group-padding-x); + display: flex; + align-items: center; + gap: var(--#{$prefix}list-group-item-gap); + + &:not(:last-child) { + border-bottom: var(--#{$prefix}list-group-border); + } + } + + &.list-group-border-none { + border: none; + + .list-group-item { + border: none; + } + } +} diff --git a/scss/components/_modal.scss b/scss/components/_modal.scss index 8cef4a1..34e073c 100644 --- a/scss/components/_modal.scss +++ b/scss/components/_modal.scss @@ -120,12 +120,6 @@ font-weight: var(--#{$prefix}font-weight-700); line-height: 1.5; } - - .modal-close { - // TODO: Update to icon styles - font-size: var(--#{$prefix}font-size-xxl); - cursor: pointer; - } } .modal-body { diff --git a/scss/components/_promo-card.scss b/scss/components/_promo-card.scss index 19d98fc..7243fc0 100644 --- a/scss/components/_promo-card.scss +++ b/scss/components/_promo-card.scss @@ -39,6 +39,7 @@ flex-direction: column; align-items: flex-start; justify-content: flex-start; + color: var(--#{$prefix}main-text-color); gap: var(--#{$prefix}promo-card-gap); padding: var(--#{$prefix}promo-card-padding); line-height: var(--#{$prefix}promo-card-line-height); diff --git a/scss/components/_button.scss b/scss/components/button/_button.scss similarity index 97% rename from scss/components/_button.scss rename to scss/components/button/_button.scss index dbec5a2..17e5cbf 100644 --- a/scss/components/_button.scss +++ b/scss/components/button/_button.scss @@ -1,5 +1,5 @@ @use "sass:map"; -@use "../variables/global" as *; +@use "../../variables/global" as *; .btn { --#{$prefix}btn-weight: 400; @@ -15,6 +15,7 @@ --#{$prefix}btn-border: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color); --#{$prefix}btn-border-color: var(--#{$prefix}btn-bg); + --#{$prefix}btn-transition: ease-in-out; display: inline-block; padding: var(--#{$prefix}btn-padding-y) var(--#{$prefix}btn-padding-x); diff --git a/scss/components/button/_close.scss b/scss/components/button/_close.scss new file mode 100644 index 0000000..edd4531 --- /dev/null +++ b/scss/components/button/_close.scss @@ -0,0 +1,58 @@ +@use "../../variables/global" as *; + +.btn-close { + --#{$prefix}-btn-close-height: 1rem; + --#{$prefix}-btn-close-width: 1rem; + --#{$prefix}-btn-close-padding: 0.25rem; + --#{$prefix}-btn-close-bg: transparent; + --#{$prefix}-btn-close-opacity: 0.8; + --#{$prefix}-btn-close-hover-opacity: 1; + --#{$prefix}-btn-close-disabled-opacity: 0.5; + --#{$prefix}-btn-close-transition: ease-in-out; + --#{$prefix}-btn-close-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e"); + + display: inline-flex; + justify-content: center; + align-items: center; + cursor: pointer; + width: var(--#{$prefix}-btn-close-width); + height: var(--#{$prefix}-btn-close-height); + padding: var(--#{$prefix}-btn-close-padding); + opacity: var(--#{$prefix}-btn-close-opacity); + background-image: var(--#{$prefix}-btn-close-image); + background-size: var(--#{$prefix}-btn-close-width) var(--#{$prefix}-btn-close-height); + background-color: var(--#{$prefix}-btn-close-bg); + background-repeat: no-repeat; + background-position: center; + transition: opacity ease-in-out 0.15s; + + &:hover, + &:focus { + outline: none; + opacity: var(--#{$prefix}-btn-close-hover-opacity); + } + + &:disabled { + cursor: not-allowed; + opacity: var(--#{$prefix}-btn-close-disabled-opacity); + } + + &.btn-close-sm { + --#{$prefix}-btn-close-height: 0.75rem; + --#{$prefix}-btn-close-width: 0.75rem; + --#{$prefix}-btn-close-padding: 0.125rem; + } + + &.btn-close-lg { + --#{$prefix}-btn-close-height: 1.5rem; + --#{$prefix}-btn-close-width: 1.5rem; + --#{$prefix}-btn-close-padding: 0.5rem; + } + + &.btn-close-black { + --#{$prefix}-btn-close-opacity: 0.5; + --#{$prefix}-btn-close-hover-opacity: 0.75; + --#{$prefix}-btn-close-disabled-opacity: 0.2; + --#{$prefix}-btn-close-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e"); + } +} diff --git a/scss/components/button/_group.scss b/scss/components/button/_group.scss new file mode 100644 index 0000000..da29569 --- /dev/null +++ b/scss/components/button/_group.scss @@ -0,0 +1,59 @@ +@use "sass:map"; +@use "../../variables/global" as *; + +.btn-group { + --#{$prefix}btn-group-radius: var(--#{$prefix}border-radius); + + position: relative; + display: inline-flex; + vertical-align: middle; + border-radius: var(--#{$prefix}border-radius); + background-color: transparent; + + .btn { + position: relative; + flex: 1 1 auto; + border-radius: 0; + + &:first-child { + border-top-left-radius: var(--#{$prefix}btn-group-radius); + border-bottom-left-radius: var(--#{$prefix}btn-group-radius); + } + + &:last-child { + border-top-right-radius: var(--#{$prefix}btn-group-radius); + border-bottom-right-radius: var(--#{$prefix}btn-group-radius); + } + } + + &.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center; + + .btn { + &:first-child { + border-radius: 0; + + border-top-left-radius: var(--#{$prefix}btn-group-radius); + border-top-right-radius: var(--#{$prefix}btn-group-radius); + } + + &:last-child { + border-radius: 0; + border-bottom-left-radius: var(--#{$prefix}btn-group-radius); + border-bottom-right-radius: var(--#{$prefix}btn-group-radius); + } + } + } +} + +@each $size, $styles in $button-sizes { + .btn-group-#{"" + $size} { + .btn { + --#{$prefix}btn-font-size: #{map.get($styles, font-size)}; + --#{$prefix}btn-padding-x: #{map.get($styles, padding-x)}; + --#{$prefix}btn-padding-y: #{map.get($styles, padding-y)}; + } + } +} diff --git a/scss/components/button/_index.scss b/scss/components/button/_index.scss new file mode 100644 index 0000000..11ce133 --- /dev/null +++ b/scss/components/button/_index.scss @@ -0,0 +1,3 @@ +@use "./button"; +@use "./group"; +@use "./close"; diff --git a/scss/variables/_global.scss b/scss/variables/_global.scss index ede8276..38e9963 100644 --- a/scss/variables/_global.scss +++ b/scss/variables/_global.scss @@ -100,7 +100,7 @@ $color-variations: ( $border-vars: ( width: 1px, style: solid, - color: map.get($base-colors, black), + color: #ededee, radius: 0.375rem, ) !default; @@ -210,7 +210,7 @@ $button-variations: ( $form-utilities: ( bg-color: #26776d, - border-color: #ededee, + border-color: map.get($border-vars, color), box-shadow: 0 0 0 0.25rem rgba(#26776d, 0.25), ); diff --git a/stories/Introduction.mdx b/stories/Introduction.mdx index f12133e..b7bd87c 100644 --- a/stories/Introduction.mdx +++ b/stories/Introduction.mdx @@ -1,10 +1,12 @@ import Logo from './assets/logo.png'; -

Educata Styles

+
+

Educata Styles

-Educata Styles + Educata Styles -

- Educata's styling package. The [project code](https://github.com/educata/educata-style) is - licensed under the [MIT License](https://github.com/educata/educata-style/blob/main/LICENSE). -

\ No newline at end of file +

+ Educata's styling package. The [project code](https://github.com/educata/educata-style) is + licensed under the [MIT License](https://github.com/educata/educata-style/blob/main/LICENSE). +

+
diff --git a/stories/components/button-group/button-group.mdx b/stories/components/button-group/button-group.mdx new file mode 100644 index 0000000..8c9147f --- /dev/null +++ b/stories/components/button-group/button-group.mdx @@ -0,0 +1,35 @@ +import { Canvas, Meta } from '@storybook/blocks'; + +import * as ButtonGroupStories from './button-group.stories.ts'; + +# Button groups + +Group a series of buttons together on a single line or stack them in a vertical column. + +## Example + +Wrap a series of buttons with `.btn` in `.btn-group`. + + + +### Mixed + + + +### Outlined styles + + + + + +### Vertical + +Add the `.btn-group-vertical` class to stack buttons vertically. + + + +### Sizes + +Add the `.btn-group-sm` or `.btn-group-lg` class to create small or large button groups. + + \ No newline at end of file diff --git a/stories/components/button-group/button-group.stories.ts b/stories/components/button-group/button-group.stories.ts new file mode 100644 index 0000000..1727119 --- /dev/null +++ b/stories/components/button-group/button-group.stories.ts @@ -0,0 +1,149 @@ +import { Meta, StoryObj } from "@storybook/html"; +import { VARIATIONS } from "../../shared"; + +const meta: Meta = { + title: "Components/Button Group", +}; + +export default meta; +type Story = StoryObj; + +export const Example: Story = { + tags: ["!dev"], + render: () => { + return ` +
+ + + +
+`; + }, +}; + +export const Mixed: Story = { + tags: ["!dev"], + render: () => { + return ` +
+ + + +
+`; + }, +}; + +export const Outlined: Story = { + tags: ["!dev"], + render: () => { + return ` +
+ + + +
+`; + }, +}; + +export const OutlinedMixed: Story = { + tags: ["!dev"], + render: () => { + return ` +
+ + + +
+`; + }, +}; + +export const Vertical: Story = { + tags: ["!dev"], + render: () => { + return ` +
+ + + + +
+`; + }, +}; + +export const Sizes: Story = { + tags: ["!dev"], + render: () => { + return ` +
+ + + +
+
+ + + +
+
+ + + +
+`; + }, +}; + +export const Group: Story = { + args: { + count: 3, + vertical: false, + size: "default", + variation: "secondary", + }, + argTypes: { + count: { + control: { + type: "range", + min: 1, + max: 9, + }, + }, + size: { + control: "select", + options: ["sm", "default", "lg"], + }, + variation: { + control: "select", + options: VARIATIONS, + }, + }, + parameters: { + backgrounds: { + default: "dark", + }, + }, + render: (args) => { + return ` +
+ ${new Array(args.count) + .fill(0) + .map((_, i) => { + return ``; + }) + .join("")} +
+`; + }, +}; diff --git a/stories/components/close-button/close-button.mdx b/stories/components/close-button/close-button.mdx new file mode 100644 index 0000000..047fcb6 --- /dev/null +++ b/stories/components/close-button/close-button.mdx @@ -0,0 +1,33 @@ +import { Canvas, Meta } from '@storybook/blocks'; + +import * as CloseButton from './close-button.stories.ts'; + +# Close button + +A generic close button for dismissing content like modals and alerts. + +## Example + +Provide an option to dismiss or close a component with `.btn-close`. + + + +> Be sure to include text for screen readers, as we've done with `aria-label`. + +## Disabled state + +Disabled close buttons change their opacity. + + + +## Dark variant + +The dark variant of the close button is used in dark mode. + + + +## Sizes + +The close button can be used in different sizes. We have a small and large variant. + + \ No newline at end of file diff --git a/stories/components/close-button/close-button.stories.ts b/stories/components/close-button/close-button.stories.ts new file mode 100644 index 0000000..bd80316 --- /dev/null +++ b/stories/components/close-button/close-button.stories.ts @@ -0,0 +1,76 @@ +import { Meta, StoryObj } from "@storybook/html"; +import { VARIATIONS } from "../../shared"; + +const meta: Meta = { + title: "Components/Close button", +}; + +export default meta; +type Story = StoryObj; + +export const Example: Story = { + tags: ["!dev"], + render: () => { + return ` + +`; + }, +}; + +export const Disabled: Story = { + tags: ["!dev"], + render: () => { + return ` + +`; + }, +}; + +export const Black: Story = { + tags: ["!dev"], + render: () => { + return ` + + +`; + }, +}; + +export const Sizes: Story = { + tags: ["!dev"], + render: () => { + return ` + + + +`; + }, +}; + +export const Button: Story = { + args: { + size: "default", + dark: false, + disabled: false, + }, + argTypes: { + size: { + control: "select", + options: ["sm", "default", "lg"], + }, + }, + parameters: { + backgrounds: { + default: "dark", + }, + }, + render: (args) => { + return ` +
+ +
+`; + }, +}; diff --git a/stories/components/list-group/list-group.mdx b/stories/components/list-group/list-group.mdx new file mode 100644 index 0000000..6e22e7c --- /dev/null +++ b/stories/components/list-group/list-group.mdx @@ -0,0 +1,40 @@ +import { Canvas, Meta } from '@storybook/blocks'; + +import * as ChipStories from './list-group.stories.ts'; + +# List group + +List groups are a flexible and powerful component for displaying a series of content. Modify and extend them to support just about any content within. + +## Basic example + +The most basic list group is an unordered list with list items and the proper classes. Build upon it with the options that follow, or with your own CSS as needed. + + + +## Flush + +Add `.list-group-flush` to remove some borders and rounded corners to render list group items edge-to-edge in a parent container (e.g., cards). + + + +## Border none + +Add `.list-group-border-none` to remove the border from the list group. + + + +## Horizontal + +Add `.list-group-horizontal` to change the layout of list group items. + + + +## Some example + +You can use almost everything inside of a list group item. Inside group items, we use `flex` to align items. + +For example checkbox and radios: + + + \ No newline at end of file diff --git a/stories/components/list-group/list-group.stories.ts b/stories/components/list-group/list-group.stories.ts new file mode 100644 index 0000000..06d1f09 --- /dev/null +++ b/stories/components/list-group/list-group.stories.ts @@ -0,0 +1,147 @@ +import { Meta, StoryObj } from "@storybook/html"; +import { VARIATIONS } from "../../shared"; + +const meta: Meta = { + title: "Components/List group", +}; + +export default meta; +type Story = StoryObj; + +export const Example: Story = { + tags: ["!dev"], + render: () => { + return ` +
    +
  • An item
  • +
  • A second item
  • +
  • A third item
  • +
  • A fourth item
  • +
  • And a fifth one
  • +
+`; + }, +}; + +export const BorderNone: Story = { + tags: ["!dev"], + render: () => { + return ` +
    +
  • An item
  • +
  • A second item
  • +
  • A third item
  • +
  • A fourth item
  • +
  • And a fifth one
  • +
+`; + }, +}; + +export const Flush: Story = { + tags: ["!dev"], + render: () => { + return ` +
    +
  • An item
  • +
  • A second item
  • +
  • A third item
  • +
  • A fourth item
  • +
  • And a fifth one
  • +
+`; + }, +}; + +export const Horizontal: Story = { + tags: ["!dev"], + render: () => { + return ` +
    +
  • An item
  • +
  • A second item
  • +
  • A third item
  • +
+`; + }, +}; + +export const Checkbox: Story = { + tags: ["!dev"], + render: () => { + return ` +
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
+`; + }, +}; + +export const Radio: Story = { + tags: ["!dev"], + render: () => { + return ` +
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
+`; + }, +}; + +export const ListGroup: Story = { + args: { + count: 3, + isHorizontal: false, + isFlush: false, + }, + argTypes: { + count: { + control: { + type: "range", + min: 1, + max: 9, + }, + }, + }, + parameters: { + backgrounds: { + default: "dark", + }, + }, + render: (args) => { + return ` +
    + ${Array.from({ length: args.count }, (_, i) => { + return ` +
  • + List item ${i + 1} +
  • + `; + }).join("")} +`; + }, +}; diff --git a/stories/components/modal/modal.mdx b/stories/components/modal/modal.mdx index 6f660bd..e66b7c6 100644 --- a/stories/components/modal/modal.mdx +++ b/stories/components/modal/modal.mdx @@ -8,7 +8,7 @@ The structure inside it should be the same for every modal.