From 408c27ecf60d0e1429c6e8dc585815d2dc9c8669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Boukorras?= Date: Mon, 12 Jun 2023 13:36:55 +0200 Subject: [PATCH] feat(react): accordion component --- .../src/components/accordion/accordion.scss | 124 ++++++++++ packages/core/src/components/index.scss | 3 + .../accordion/accordion.stories.tsx | 109 +++++++++ .../src/components/accordion/accordion.tsx | 219 ++++++++++++++++++ packages/react/src/components/index.ts | 1 + yarn.lock | 15 ++ 6 files changed, 471 insertions(+) create mode 100644 packages/core/src/components/accordion/accordion.scss create mode 100644 packages/react/src/components/accordion/accordion.stories.tsx create mode 100644 packages/react/src/components/accordion/accordion.tsx diff --git a/packages/core/src/components/accordion/accordion.scss b/packages/core/src/components/accordion/accordion.scss new file mode 100644 index 000000000..2c7b29982 --- /dev/null +++ b/packages/core/src/components/accordion/accordion.scss @@ -0,0 +1,124 @@ +@use '../../helpers'; +@use '../../mixins'; + +@mixin Accordion() { + @if not mixins.includes('Accordion') { + @include _Accordion(); + } +} + +@mixin _Accordion() { + .ods-accordion-box:not(.-separated) { + background-color: helpers.color('background-surface'); + border: 1px solid helpers.color('border-separator'); + border-radius: helpers.border-radius('large'); + overflow: hidden; + } + + .ods-accordion-item { + overflow: hidden; + position: relative; + + &:not(:last-child) { + border-bottom: 1px solid helpers.color('border-separator'); + } + } + + .-separated > .ods-accordion-item { + background-color: helpers.color('background-surface'); + border: 1px solid helpers.color('border-separator'); + border-radius: helpers.border-radius('large'); + + &:not(:last-child) { + margin-bottom: helpers.space(2); + } + } + + .ods-accordion-toggler { + @include helpers.font('400-regular'); + align-items: center; + background-color: transparent; + border: 0; + cursor: pointer; + display: flex; + gap: helpers.space(2); + justify-content: flex-start; + outline-offset: helpers.space(-0.5); + padding: var(--padding); + transition: background-color linear 0.2s; + width: 100%; + + &:hover { + background-color: helpers.color('background-action-subtle-hover'); + } + + &:active { + background-color: helpers.color('background-action-subtle'); + } + } + + .ods-accordion-secondary-content { + * { + margin: 0; + } + } + + .ods-accordion-chevron { + transition: transform linear 0.2s; + } + + .-open > .ods-accordion-toggler > .ods-accordion-chevron { + transform: rotateZ(180deg); + } + + .ods-accordion-title { + @include helpers.font('400-bold'); + margin-right: auto; + } + + .ods-accordion-content-wrapper { + box-sizing: border-box; + overflow: hidden; + position: absolute; + transition: height ease-in-out 0.3s; + visibility: hidden; + will-change: height; + + &.-ready { + position: relative; + visibility: visible; + } + + &.-with-separator { + position: relative; + } + + &.-with-separator::before { + border-bottom: 1px solid helpers.color('border-separator'); + content: ''; + left: var(--padding); + position: absolute; + right: var(--padding); + top: 0; + } + } + + .-with-separator > .ods-accordion-content { + margin-top: var(--padding); + } + + .ods-accordion-content { + animation: fadeIn 0.4s; + margin: helpers.space(1) var(--padding) var(--padding); + } + + @keyframes fadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } + } +} diff --git a/packages/core/src/components/index.scss b/packages/core/src/components/index.scss index f1a7e78c2..fc1dd84aa 100644 --- a/packages/core/src/components/index.scss +++ b/packages/core/src/components/index.scss @@ -42,6 +42,8 @@ @forward './tooltip/tooltip'; @use './validation/validation'; @forward './validation/validation'; +@use './accordion/accordion.scss'; +@forward './accordion/accordion.scss'; @mixin components() { @include asterisk.Asterisk(); @@ -66,4 +68,5 @@ @include textarea.Textarea(); @include tooltip.Tooltip(); @include validation.Validation(); + @include accordion.Accordion(); } diff --git a/packages/react/src/components/accordion/accordion.stories.tsx b/packages/react/src/components/accordion/accordion.stories.tsx new file mode 100644 index 000000000..860e47e97 --- /dev/null +++ b/packages/react/src/components/accordion/accordion.stories.tsx @@ -0,0 +1,109 @@ +import { Accordion, Icon, type AccordionProps } from '@onfido/castor-react'; +import React from 'react'; +import { Meta, Story } from '../../../../../docs'; + +export default { + title: 'React/Accordion', + component: Accordion, + args: { + list: [ + { + title: <>Long text, + name: '1', + iconName: 'book-open', + content: ( +
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Vestibulum non augue facilisis, accumsan magna ut, tempus turpis. + Aenean quis bibendum nulla, ut luctus arcu. Sed et porta ante. + Donec commodo mi sit amet est pharetra, ut sagittis velit rhoncus. + Fusce risus arcu, feugiat a dapibus eget, commodo eleifend dui. + Nunc quam leo, aliquam id nisi a, dictum eleifend orci. Morbi + lacinia felis dolor, sed sagittis nisi hendrerit ut. Phasellus + iaculis rutrum ipsum in sollicitudin. Mauris faucibus commodo + elementum. Nunc in augue sit amet sem elementum congue. Fusce + mollis lorem augue. Aenean quis sem iaculis, tempor nunc ut, + sollicitudin risus. Nulla sem sem, bibendum eu velit vel, semper + placerat risus. +

+

+ Nunc aliquam elit erat, semper egestas nisi volutpat non. Duis sed + ultrices ipsum. Nulla non nisl a magna sodales interdum tempor ut + mi. Quisque ut aliquet sem. Aliquam erat volutpat. In molestie + fermentum mi eu scelerisque. Vestibulum in lacinia quam. +

+

+ Integer sit amet tristique est. Nunc porttitor nunc nec luctus + dignissim. Integer at nisi ipsum. Cras aliquet justo leo, a + condimentum dolor imperdiet quis. Cras viverra erat at ornare + venenatis. Donec in facilisis mauris. Aliquam sit amet maximus + ligula. Proin gravida elit mi, eget maximus mi consequat auctor. + Aliquam erat volutpat. +

+

+ Nunc ultrices ligula sit amet elit placerat, eu rutrum massa + bibendum. Praesent et pulvinar ipsum. Vestibulum justo justo, + auctor sed ligula sit amet, posuere maximus ipsum. Aenean nec arcu + dui. Integer non sagittis nisi. Aenean placerat vehicula lacinia. + Mauris blandit massa dui. Vivamus ut nisl nunc. Suspendisse non + risus non nibh mattis maximus at id enim. Mauris bibendum est + eros, eu consequat tellus finibus eu. Sed euismod nec tellus ac + elementum. Duis non lectus congue, rhoncus mi eget, vestibulum + odio. Morbi iaculis venenatis augue non euismod. +

+

+ Class aptent taciti sociosqu ad litora torquent per conubia + nostra, per inceptos himenaeos. Ut lectus elit, mollis ut lectus + at, tempor bibendum purus. Donec volutpat facilisis mi, id laoreet + purus fermentum a. Proin pharetra tristique magna, non fermentum + odio accumsan in. In neque odio, pretium at lectus nec, pulvinar + eleifend massa. Sed placerat urna at lorem auctor rhoncus. Morbi + metus ligula, ullamcorper ut erat fringilla, congue tempor arcu. + Vestibulum dapibus nec elit et iaculis. +

+
+ ), + }, + { + title: <>List, + iconName: 'list-ul', + name: '2', + content: ( + + ), + }, + { + title: <>Empty, + name: '2', + secondaryContent: