feat(accordion)!: integrate Accordion with v11 (#1947)

This commit is contained in:
Eric Liu 2024-04-21 10:50:00 -07:00 committed by GitHub
commit 0e8909ae59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 261 additions and 456 deletions

View file

@ -1,27 +1,30 @@
<script>
/** @extends {"./AccordionSkeleton.svelte"} AccordionSkeletonProps */
// @ts-check
/**
* Specify alignment of accordion item chevron icon
* Specify the alignment of the accordion item chevron icon.
* @type {"start" | "end"}
*/
export let align = "end";
/**
* Specify the size of the accordion
* @type {"sm" | "lg"}
* Set to `true` to flush the accordion content text.
*
* **Note**: does not work with `align="start"`.
*/
export let size = undefined;
export let flush = false;
/** Set to `true` to disable the accordion */
/**
* Specify the size of the accordion.
* @type {"sm" | "md" | "lg"}
*/
export let size = "md";
/** Set to `true` to disable all accordion items. */
export let disabled = false;
/** Set to `true` to display the skeleton state */
export let skeleton = false;
import { setContext } from "svelte";
import { writable } from "svelte/store";
import AccordionSkeleton from "./AccordionSkeleton.svelte";
const disableItems = writable(disabled);
@ -30,31 +33,14 @@
setContext("Accordion", { disableItems });
</script>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
{#if skeleton}
<AccordionSkeleton
{...$$restProps}
align="{align}"
size="{size}"
on:click
on:mouseover
on:mouseenter
on:mouseleave
/>
{:else}
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<ul
class:bx--accordion="{true}"
class:bx--accordion--start="{align === 'start'}"
class:bx--accordion--end="{align === 'end'}"
class:bx--accordion--sm="{size === 'sm'}"
class:bx--accordion--lg="{size === 'lg' || size === 'xl'}"
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave
>
<slot />
</ul>
{/if}
<ul
class:bx--accordion="{true}"
class:bx--accordion--start="{align === 'start'}"
class:bx--accordion--end="{align === 'end'}"
class:bx--accordion--flush="{flush && align !== 'start'}"
class:bx--layout--size-sm="{size === 'sm'}"
class:bx--layout--size-md="{size === 'md'}"
class:bx--layout--size-lg="{size === 'lg'}"
>
<slot />
</ul>

View file

@ -1,47 +1,44 @@
<script>
// @ts-check
/**
* Specify the title of the accordion item heading.
* Alternatively, use the "title" slot (e.g., `<div slot="title">...</div>`)
* Use the "title" slot for custom elements.
* @example <svelte:fragment slot="title">...</svelte:fragment>
*/
export let title = "title";
/** Set to `true` to open the first accordion item */
/** Set to `true` to open the first accordion item. */
export let open = false;
/** Set to `true` to disable the accordion item */
/** Set to `true` to disable the accordion item. */
export let disabled = false;
/** Specify the ARIA label for the accordion item chevron icon */
/** Specify the ARIA label for the accordion item chevron icon. */
export let iconDescription = "Expand/Collapse";
import { onMount, getContext } from "svelte";
import { getContext } from "svelte";
import ChevronRight from "../icons/ChevronRight.svelte";
let initialDisabled = disabled;
// Internal id for controls
const id = "ccs-" + Math.random().toString(36);
const ctx = getContext("Accordion");
const unsubscribe = ctx.disableItems.subscribe((value) => {
if (!value && initialDisabled) return;
disabled = value;
});
/** @type {{ disableItems: import("svelte/store").Writable<boolean>; }} */
const { disableItems } = getContext("Accordion") ?? {};
$: disabled = disableItems ? $disableItems === true : disabled;
/** @type {undefined | "expanding" | "collapsing"} */
let animation = undefined;
onMount(() => {
return () => {
unsubscribe();
};
});
</script>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<li
class:bx--accordion__item="{true}"
class:bx--accordion__item--active="{open}"
class:bx--accordion__item--active="{open && !disabled}"
class:bx--accordion__item--disabled="{disabled}"
class:bx--accordion__item--expanding="{animation === 'expanding'}"
class:bx--accordion__item--collapsing="{animation === 'collapsing'}"
{...$$restProps}
on:animationend
on:animationend="{() => {
animation = undefined;
@ -51,6 +48,7 @@
type="button"
class:bx--accordion__heading="{true}"
title="{iconDescription}"
aria-controls="{id}"
aria-expanded="{open}"
disabled="{disabled}"
on:click
@ -73,7 +71,9 @@
<slot name="title">{title}</slot>
</div>
</button>
<div class:bx--accordion__content="{true}">
<slot />
<div class:bx--accordion__wrapper="{true}">
<div id="{id}" class:bx--accordion__content="{true}">
<slot />
</div>
</div>
</li>

View file

@ -1,40 +1,44 @@
<script>
/** Specify the number of accordion items to render */
// @ts-check
/** Specify the number of accordion items. */
export let count = 4;
/**
* Specify alignment of accordion item chevron icon
* Specify the alignment of the accordion item chevron icon.
* @type {"start" | "end"}
*/
export let align = "end";
/**
* Specify the size of the accordion
* @type {"sm" | "xl"}
* Set to `true` to flush the accordion content text.
*
* **Note**: does not work with `align="start"`.
*/
export let size = undefined;
export let flush = false;
/** Set to `false` to close the first accordion item */
export let open = true;
/**
* Specify the size of the accordion.
* @type {"sm" | "md" | "lg"}
*/
export let size = "md";
/** Set to `true` to expand the first accordion item */
export let open = false;
import ChevronRight from "../icons/ChevronRight.svelte";
import SkeletonText from "../SkeletonText/SkeletonText.svelte";
</script>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<ul
class:bx--skeleton="{true}"
class:bx--accordion="{true}"
class:bx--accordion--start="{align === 'start'}"
class:bx--accordion--end="{align === 'end'}"
class:bx--accordion--sm="{size === 'sm'}"
class:bx--accordion--xl="{size === 'xl'}"
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave
class:bx--accordion--flush="{flush && align !== 'start'}"
class:bx--layout--size-sm="{size === 'sm'}"
class:bx--layout--size-md="{size === 'md'}"
class:bx--layout--size-lg="{size === 'lg'}"
>
{#if open}
<li
@ -52,7 +56,7 @@
</div>
</li>
{/if}
{#each Array.from({ length: open ? count - 1 : count }, (_, i) => i) as item (item)}
{#each Array.from({ length: open ? count - 1 : count }) as item}
<li class:bx--accordion__item="{true}">
<span class:bx--accordion__heading="{true}">
<ChevronRight class="bx--accordion__arrow" />