Skip to content

Commit

Permalink
Merge branch 'main' into fix-patternhub-next-previous
Browse files Browse the repository at this point in the history
  • Loading branch information
nmerget authored Nov 20, 2024
2 parents 5f934e7 + aebd21d commit 0eec75c
Show file tree
Hide file tree
Showing 35 changed files with 248 additions and 190 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/components/scripts/post-build/angular.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ export default (tmp?: boolean) => {
{
from: '} from "../../utils"',
to: ', enableCustomElementAttributePassing } from "../../utils"'
},
{
from: /this.ref.nativeElement/g,
to: 'this.ref?.nativeElement'
}
];

Expand Down
10 changes: 1 addition & 9 deletions packages/components/scripts/post-build/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,7 @@ export const getComponents = (): Component[] => [
},

{
name: 'tag',
overwrites: {
angular: [
{
from: /this.ref.nativeElement/g,
to: 'this.ref?.nativeElement'
}
]
}
name: 'tag'
},
{
name: 'checkbox',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,25 @@ export default function DBAccordionItem(props: DBAccordionItemProps) {
// jscpd:ignore-end

return (
<details
ref={ref}
id={state._id}
class={cls('db-accordion-item', props.className)}
aria-disabled={getBooleanAsString(props.disabled)}
open={state._open}
name={props.name}>
<summary onClick={(event) => state.toggle(event)}>
<Show when={props.headlinePlain}>{props.headlinePlain}</Show>
<Show when={!props.headlinePlain}>
<Slot name="headline" />
</Show>
</summary>
<div>
<Show when={props.content}>{props.content}</Show>
<Show when={!props.content}>{props.children}</Show>
</div>
</details>
<li id={state._id} class={cls('db-accordion-item', props.className)}>
<details
aria-disabled={getBooleanAsString(props.disabled)}
ref={ref}
open={state._open}>
<summary onClick={(event) => state.toggle(event)}>
<Show when={props.headlinePlain}>
{props.headlinePlain}
</Show>
<Show when={!props.headlinePlain}>
<Slot name="headline" />
</Show>
</summary>
<div>
<Show when={props.content} else={props.children}>
{props.content}
</Show>
</div>
</details>
</li>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,33 @@ $db-accordion-item-border-radius: variables.$db-border-radius-sm;
position: relative;
inline-size: 100%;
border-radius: $db-accordion-item-border-radius;
list-style-type: "";

> details {
&[open] {
summary + div {
@media screen and (prefers-reduced-motion: no-preference) {
animation: accordion-open #{variables.$db-transition-straight-emotional}
normal both;
}
}

summary::after {
transform: form-components.$dropdown-icon-transform;
}
}

&[aria-disabled="true"] {
pointer-events: none;
opacity: component.$default-disabled;
}
}

summary + div {
padding: variables.$db-spacing-fixed-md;
padding-block-end: variables.$db-spacing-fixed-lg;
}

&[aria-disabled="true"] {
pointer-events: none;
opacity: component.$default-disabled;
}

summary {
@extend %dropdown-icon;
@extend %db-overwrite-font-size-md;
Expand Down Expand Up @@ -54,17 +70,4 @@ $db-accordion-item-border-radius: variables.$db-border-radius-sm;
border-radius: variables.$db-border-radius-xs;
}
}

&[open] {
summary + div {
@media screen and (prefers-reduced-motion: no-preference) {
animation: accordion-open #{variables.$db-transition-straight-emotional}
normal both;
}
}

summary::after {
transform: form-components.$dropdown-icon-transform;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const testA11y = () => {
await mount(comp);
const accessibilityScanResults = await new AxeBuilder({ page })
.include('.db-accordion-item')
// Showcase uses <li> outside of <ul> in this case
// TODO: Let's investigate whether we could prevent this deactivation later on
.disableRules(['listitem'])
.analyze();

expect(accessibilityScanResults.violations).toEqual([]);
Expand Down
4 changes: 0 additions & 4 deletions packages/components/src/components/accordion-item/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ export type DBAccordionItemDefaultProps = {
* Title of the accordion-item as plain text
*/
headlinePlain?: string;
/**
* Set details name for exclusive accordions, see https://chromestatus.com/feature/6710427028815872
*/
name?: string;
};

export type DBAccordionItemProps = DBAccordionItemDefaultProps &
Expand Down
121 changes: 57 additions & 64 deletions packages/components/src/components/accordion/accordion.lite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@ import {
} from '@builder.io/mitosis';
import { DBAccordionItemDefaultProps } from '../accordion-item/model';
import { DBAccordionProps, DBAccordionState } from './model';
import { cls } from '../../utils';
import { cls, uuid } from '../../utils';
import DBAccordionItem from '../accordion-item/accordion-item.lite';
import { DEFAULT_ID } from '../../shared/constants';

useMetadata({});

export default function DBAccordion(props: DBAccordionProps) {
const ref = useRef<HTMLDivElement>(null);
const ref = useRef<HTMLUListElement>(null);
// jscpd:ignore-start
const state = useStore<DBAccordionState>({
openItems: [],
clickedId: '',
_id: DEFAULT_ID,
_name: '',
initialized: false,
_initOpenIndexDone: false,
convertItems(
items: unknown[] | string | undefined
): DBAccordionItemDefaultProps[] {
Expand All @@ -35,89 +37,80 @@ export default function DBAccordion(props: DBAccordionProps) {
}

return [];
},
handleItemClick: (id: string) => {
if (state.openItems.includes(id)) {
if (props.behaviour === 'single') {
state.openItems = [];
} else {
state.openItems = state.openItems.filter(
(oItem) => oItem !== id
);
}
} else if (props.behaviour === 'single') {
state.openItems = [id];
} else {
state.openItems = [...state.openItems, id];
}

if (props.onChange) {
props.onChange(state.openItems);
}
}
});

onMount(() => {
state._id = props.id || 'accordion-' + uuid();
state.initialized = true;
state._initOpenIndexDone = true;
});
// jscpd:ignore-end

onUpdate(() => {
if (ref && state.initialized) {
const childDetails = ref.getElementsByTagName('details');
if (childDetails) {
let initOpenItems: string[] = [];
Array.from<HTMLDetailsElement>(childDetails).forEach(
(details: HTMLDetailsElement, index: number) => {
const id = details.id;
if (
details.open ||
props.initOpenIndex?.includes(index)
) {
initOpenItems.push(id);
}
const summaries =
details.getElementsByTagName('summary');
if (summaries?.length > 0) {
summaries[0].addEventListener('click', () => {
state.clickedId = id;
});
}
// If we have a single behaviour we first check for
// props.name otherwise for state_id
if (state.initialized) {
if (props.behaviour === 'single') {
if (props.name) {
if (state._name !== props.name) {
state._name = props.name;
}
} else {
if (state._name !== state._id && state._id) {
state._name = state._id;
}
);
if (props.behaviour === 'single' && initOpenItems.length > 1) {
initOpenItems = [initOpenItems[0]];
}
state.openItems = initOpenItems;
state.initialized = false;
} else {
state._name = '';
}
}
}, [ref, state.initialized]);

onUpdate(() => {
if (state.clickedId?.length > 0) {
state.handleItemClick(state.clickedId);
state.clickedId = '';
}
}, [state.clickedId]);
}, [state.initialized, props.name, props.behaviour, state._id]);

onUpdate(() => {
if (ref) {
const childDetails = ref.getElementsByTagName('details');
if (childDetails) {
Array.from<HTMLDetailsElement>(childDetails).forEach(
(details: HTMLDetailsElement) => {
details.open = state.openItems.includes(details.id);
for (const details of Array.from<HTMLDetailsElement>(
childDetails
)) {
if (state._name === '') {
details.removeAttribute('name');
} else {
details.name = state._name;
}
);
}
}
}
}, [ref, state._name]);

onUpdate(() => {
if (ref && state._initOpenIndexDone) {
if (props?.initOpenIndex && props.initOpenIndex?.length > 0) {
const childDetails = ref.getElementsByTagName('details');
if (childDetails) {
const initOpenIndex =
props.behaviour === 'single' &&
props.initOpenIndex.length > 1
? [props.initOpenIndex[0]] // use only one index for behaviour=single
: props.initOpenIndex;
Array.from<HTMLDetailsElement>(childDetails).forEach(
(details: HTMLDetailsElement, index: number) => {
if (initOpenIndex.includes(index)) {
details.open = true;
}
}
);
}
}
state._initOpenIndexDone = false;
}
}, [state.openItems]);
}, [ref, state._initOpenIndexDone, props.initOpenIndex]);

return (
<div
<ul
ref={ref}
id={props.id}
id={state._id}
class={cls('db-accordion', props.className)}
data-variant={props.variant}>
<Show when={!props.items}>{props.children}</Show>
Expand All @@ -133,6 +126,6 @@ export default function DBAccordion(props: DBAccordionProps) {
)}
</For>
</Show>
</div>
</ul>
);
}
4 changes: 4 additions & 0 deletions packages/components/src/components/accordion/accordion.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ The styling for the spacings between the items is defined in the accordion, wher
The spacings are not part of the styling of the accordion items themselves.
*/
.db-accordion {
padding: 0;
margin: 0;
list-style-type: "";

/*
default variant: prop variant is not set
*/
Expand Down
14 changes: 10 additions & 4 deletions packages/components/src/components/accordion/accordion.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ const openAccordion: any = (

const actionAccordion: any = (
<DBAccordion behaviour="single">
<DBAccordionItem data-testid="item1" headline="Test">
<DBAccordionItem data-testid="item1" headlinePlain="Test">
<DBButton data-testid="button">Click me</DBButton>
</DBAccordionItem>
<DBAccordionItem data-testid="item2" headline="Test 2">
<DBAccordionItem data-testid="item2" headlinePlain="Test 2">
<DBTextarea data-testid="textarea" />
</DBAccordionItem>
<DBAccordionItem disabled={true} data-testid="item3" headline="Test 3">
<DBAccordionItem
disabled={true}
data-testid="item3"
headlinePlain="Test 3">
<DBButton data-testid="button2">Click me</DBButton>
</DBAccordionItem>
</DBAccordion>
Expand Down Expand Up @@ -75,7 +78,10 @@ const testAction = () => {
await component.getByTestId('item2').click();
await expect(component.getByTestId('button')).toBeHidden();
await expect(component.getByTestId('textarea')).toBeVisible();
await expect(component.getByTestId('item3')).toBeDisabled();
await expect(
component.getByTestId('item3')
// VUE: .getByRole('group')
).toBeDisabled();
});

test('click inside item works', async ({ mount }) => {
Expand Down
Loading

0 comments on commit 0eec75c

Please sign in to comment.