Skip to content

Commit

Permalink
APP-17219 web component accordion (#401)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sqrrl authored Oct 5, 2023
1 parent eed6fac commit 4d80367
Show file tree
Hide file tree
Showing 13 changed files with 823 additions and 4 deletions.
7 changes: 7 additions & 0 deletions .changeset/smooth-games-tease.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@getflip/swirl-components": minor
"@getflip/swirl-components-angular": minor
"@getflip/swirl-components-react": minor
---

Add swirl-accordion and swirl-accordion-item components
63 changes: 59 additions & 4 deletions packages/swirl-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* It contains typing information for all components that exist in this project.
*/
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { SwirlHeadingLevel } from "./components/swirl-heading/swirl-heading";
import { SwirlActionListItemIntent, SwirlActionListItemSize } from "./components/swirl-action-list-item/swirl-action-list-item";
import { SwirlAppLayoutMobileView } from "./components/swirl-app-layout/swirl-app-layout";
import { SwirlAutocompleteSuggestion, SwirlAutocompleteValue } from "./components/swirl-autocomplete/swirl-autocomplete";
Expand All @@ -28,7 +29,7 @@ import { SwirlFileViewerPdfViewMode, SwirlFileViewerPdfZoom } from "./components
import { SwirlFileViewerPdfViewMode as SwirlFileViewerPdfViewMode1, SwirlFileViewerPdfZoom as SwirlFileViewerPdfZoom1 } from "./components/swirl-file-viewer/viewers/swirl-file-viewer-pdf/swirl-file-viewer-pdf";
import { SwirlFormControlLabelPosition } from "./components/swirl-form-control/swirl-form-control";
import { SwirlFormGroupOrientation } from "./components/swirl-form-group/swirl-form-group";
import { SwirlHeadingAlign, SwirlHeadingLevel, SwirlHeadingTag } from "./components/swirl-heading/swirl-heading";
import { SwirlHeadingAlign, SwirlHeadingLevel as SwirlHeadingLevel1, SwirlHeadingTag } from "./components/swirl-heading/swirl-heading";
import { SwirlIconSize } from "./components/swirl-icon/swirl-icon.types";
import { SwirlInlineErrorSize } from "./components/swirl-inline-error/swirl-inline-error";
import { SwirlInlineNotificationAriaRole, SwirlInlineNotificationIntent } from "./components/swirl-inline-notification/swirl-inline-notification";
Expand Down Expand Up @@ -63,6 +64,7 @@ import { SwirlToastIntent } from "./components/swirl-toast/swirl-toast";
import { SwirlToastConfig, SwirlToastMessage } from "./components/swirl-toast-provider/swirl-toast-provider";
import { SwirlToolbarOrientation } from "./components/swirl-toolbar/swirl-toolbar";
import { SwirlTooltipPosition } from "./components/swirl-tooltip/swirl-tooltip";
export { SwirlHeadingLevel } from "./components/swirl-heading/swirl-heading";
export { SwirlActionListItemIntent, SwirlActionListItemSize } from "./components/swirl-action-list-item/swirl-action-list-item";
export { SwirlAppLayoutMobileView } from "./components/swirl-app-layout/swirl-app-layout";
export { SwirlAutocompleteSuggestion, SwirlAutocompleteValue } from "./components/swirl-autocomplete/swirl-autocomplete";
Expand All @@ -86,7 +88,7 @@ export { SwirlFileViewerPdfViewMode, SwirlFileViewerPdfZoom } from "./components
export { SwirlFileViewerPdfViewMode as SwirlFileViewerPdfViewMode1, SwirlFileViewerPdfZoom as SwirlFileViewerPdfZoom1 } from "./components/swirl-file-viewer/viewers/swirl-file-viewer-pdf/swirl-file-viewer-pdf";
export { SwirlFormControlLabelPosition } from "./components/swirl-form-control/swirl-form-control";
export { SwirlFormGroupOrientation } from "./components/swirl-form-group/swirl-form-group";
export { SwirlHeadingAlign, SwirlHeadingLevel, SwirlHeadingTag } from "./components/swirl-heading/swirl-heading";
export { SwirlHeadingAlign, SwirlHeadingLevel as SwirlHeadingLevel1, SwirlHeadingTag } from "./components/swirl-heading/swirl-heading";
export { SwirlIconSize } from "./components/swirl-icon/swirl-icon.types";
export { SwirlInlineErrorSize } from "./components/swirl-inline-error/swirl-inline-error";
export { SwirlInlineNotificationAriaRole, SwirlInlineNotificationIntent } from "./components/swirl-inline-notification/swirl-inline-notification";
Expand Down Expand Up @@ -124,6 +126,27 @@ export { SwirlTooltipPosition } from "./components/swirl-tooltip/swirl-tooltip";
export namespace Components {
interface FileManager {
}
interface SwirlAccordion {
}
interface SwirlAccordionItem {
/**
* Collapsed the accordion item.
*/
"collapse": () => Promise<void>;
"description"?: string;
"disabled"?: boolean;
/**
* Expands the accordion item.
*/
"expand": () => Promise<void>;
"heading": string;
"headingLevel"?: SwirlHeadingLevel;
"initiallyOpen"?: boolean;
/**
* Toggles the accordion item.
*/
"toggle": () => Promise<void>;
}
interface SwirlActionList {
}
interface SwirlActionListItem {
Expand Down Expand Up @@ -578,7 +601,7 @@ export namespace Components {
"as"?: SwirlHeadingTag;
"balance"?: boolean;
"headingId"?: string;
"level"?: SwirlHeadingLevel;
"level"?: SwirlHeadingLevel1;
"lines"?: number;
"text": string;
"truncate"?: boolean;
Expand Down Expand Up @@ -1752,6 +1775,10 @@ export namespace Components {
interface SwirlVisuallyHidden {
}
}
export interface SwirlAccordionItemCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLSwirlAccordionItemElement;
}
export interface SwirlAppBarCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLSwirlAppBarElement;
Expand Down Expand Up @@ -1923,6 +1950,18 @@ declare global {
prototype: HTMLFileManagerElement;
new (): HTMLFileManagerElement;
};
interface HTMLSwirlAccordionElement extends Components.SwirlAccordion, HTMLStencilElement {
}
var HTMLSwirlAccordionElement: {
prototype: HTMLSwirlAccordionElement;
new (): HTMLSwirlAccordionElement;
};
interface HTMLSwirlAccordionItemElement extends Components.SwirlAccordionItem, HTMLStencilElement {
}
var HTMLSwirlAccordionItemElement: {
prototype: HTMLSwirlAccordionItemElement;
new (): HTMLSwirlAccordionItemElement;
};
interface HTMLSwirlActionListElement extends Components.SwirlActionList, HTMLStencilElement {
}
var HTMLSwirlActionListElement: {
Expand Down Expand Up @@ -3725,6 +3764,8 @@ declare global {
};
interface HTMLElementTagNameMap {
"file-manager": HTMLFileManagerElement;
"swirl-accordion": HTMLSwirlAccordionElement;
"swirl-accordion-item": HTMLSwirlAccordionItemElement;
"swirl-action-list": HTMLSwirlActionListElement;
"swirl-action-list-item": HTMLSwirlActionListItemElement;
"swirl-action-list-section": HTMLSwirlActionListSectionElement;
Expand Down Expand Up @@ -4029,6 +4070,16 @@ declare global {
declare namespace LocalJSX {
interface FileManager {
}
interface SwirlAccordion {
}
interface SwirlAccordionItem {
"description"?: string;
"disabled"?: boolean;
"heading": string;
"headingLevel"?: SwirlHeadingLevel;
"initiallyOpen"?: boolean;
"onExpansionChange"?: (event: SwirlAccordionItemCustomEvent<boolean>) => void;
}
interface SwirlActionList {
}
interface SwirlActionListItem {
Expand Down Expand Up @@ -4431,7 +4482,7 @@ declare namespace LocalJSX {
"as"?: SwirlHeadingTag;
"balance"?: boolean;
"headingId"?: string;
"level"?: SwirlHeadingLevel;
"level"?: SwirlHeadingLevel1;
"lines"?: number;
"text": string;
"truncate"?: boolean;
Expand Down Expand Up @@ -5523,6 +5574,8 @@ declare namespace LocalJSX {
}
interface IntrinsicElements {
"file-manager": FileManager;
"swirl-accordion": SwirlAccordion;
"swirl-accordion-item": SwirlAccordionItem;
"swirl-action-list": SwirlActionList;
"swirl-action-list-item": SwirlActionListItem;
"swirl-action-list-section": SwirlActionListSection;
Expand Down Expand Up @@ -5829,6 +5882,8 @@ declare module "@stencil/core" {
export namespace JSX {
interface IntrinsicElements {
"file-manager": LocalJSX.FileManager & JSXBase.HTMLAttributes<HTMLFileManagerElement>;
"swirl-accordion": LocalJSX.SwirlAccordion & JSXBase.HTMLAttributes<HTMLSwirlAccordionElement>;
"swirl-accordion-item": LocalJSX.SwirlAccordionItem & JSXBase.HTMLAttributes<HTMLSwirlAccordionItemElement>;
"swirl-action-list": LocalJSX.SwirlActionList & JSXBase.HTMLAttributes<HTMLSwirlActionListElement>;
"swirl-action-list-item": LocalJSX.SwirlActionListItem & JSXBase.HTMLAttributes<HTMLSwirlActionListItemElement>;
"swirl-action-list-section": LocalJSX.SwirlActionListSection & JSXBase.HTMLAttributes<HTMLSwirlActionListSectionElement>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
@import "../../styles/media-queries.css";

:host {
display: block;

& * {
box-sizing: border-box;
}

&(:last-child) .accordion-item {
border-bottom: 0.0625rem solid var(--s-border-default);
}
}

.accordion-item {
display: grid;
align-content: start;
border-top: 0.0625rem solid var(--s-border-default);
transition: grid-template-rows 0.15s;
grid-template-rows: auto 0fr;
will-change: grid-template-rows;

@media (prefers-reduced-motion) {
transition: none;
}
}

.accordion-item--expanded {
grid-template-rows: auto 1fr;

& .accordion-item__content {
padding-top: var(--s-space-16);
padding-bottom: var(--s-space-16);
animation: accordion-overflow 0.01s;
animation-delay: 0.15s;
animation-fill-mode: forwards;

@media (--from-desktop-without-touch) {
padding-top: var(--s-space-8);
}
}
}

.accordion-item__heading {
margin: 0;
padding: 0;
font-size: var(--s-font-size-base);
font-weight: var(--s-font-weight-semibold);

@media (--from-desktop-without-touch) {
font-size: var(--s-font-size-sm);
}
}

.accordion-item__toggle {
display: flex;
width: 100%;
padding: 0;
padding-top: var(--s-space-16);
padding-bottom: var(--s-space-16);
align-items: center;
border: none;
color: var(--s-text-default);
background-color: var(--s-surface-default);
font: inherit;
line-height: var(--s-line-height-lg);
text-align: start;
cursor: pointer;
gap: var(--s-space-16);

&:hover {
background-color: var(--s-surface-hovered);
}

&:active {
background-color: var(--s-surface-pressed);
}

&:disabled {
color: var(--s-text-disabled);
background-color: var(--s-surface-default);
cursor: default;

& .text {
color: var(--s-text-disabled);
}
}

&:focus:not(:focus-visible) {
outline: none;
}

&:focus-visible {
outline-color: var(--s-focus-default);
}

@media (--from-desktop-without-touch) {
line-height: var(--s-line-height-sm);
}
}

.accordion-item__toggle-text {
flex-grow: 1;
}

.accordion-item__icon {
display: inline-flex;
padding-right: var(--s-space-8);
flex-shrink: 0;
}

.accordion-item__content {
overflow: hidden;
padding-top: 0;
padding-bottom: 0;
transition: padding-top 0.15s, padding-bottom 0.15s;
animation: accordion-display 0.01s;
animation-delay: 0.15s;
animation-fill-mode: forwards;

@media (prefers-reduced-motion) {
transition: none;
}
}

@keyframes accordion-overflow {
from {
overflow: hidden;
}
to {
overflow: visible;
}
}

@keyframes accordion-display {
from {
display: block;
}
to {
display: none;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Controls, Canvas, Meta, Story } from "@storybook/addon-docs";
import * as Stories from "./swirl-accordion-item.stories";

<Meta title="Components/SwirlAccordionItem" />

# SwirlAccordionItem

The SwirlAccordionItem component is used to provide a collapsible section of
content. It is always contained within a
[SwirlAccordion](?path=/docs/components-swirlaccordion--docs) component.

- **[Figma Design Specs](https://www.figma.com/file/iRHiAFsHxnzux8gQ9EjlZe/Swirl-Components?node-id=5488%3A32622&mode=dev)**
- **[Source Code](https://github.com/flip-corp/swirl/tree/main/packages/swirl-components/src/components/swirl-accordion-item)**

## Usage

<Canvas of={Stories.SwirlAccordionItem} sourceState="shown"></Canvas>

<Controls of={Stories.SwirlAccordionItem} />

## Theming

| Variable | Usage |
| -------------------- | ----------------- |
| `--s-border-default` | Separator color |
| `--s-text-subdued` | Description color |

## Accessibility

See [SwirlAccordion](?path=/docs/components-swirlaccordion--docs).
Loading

0 comments on commit 4d80367

Please sign in to comment.