diff --git a/__snapshots__/accordion-item/component/chromium/DBAccordionItem-should-match-screenshot.png b/__snapshots__/accordion-item/component/chromium/DBAccordionItem-should-match-screenshot.png new file mode 100644 index 000000000000..f32ee0f92d46 Binary files /dev/null and b/__snapshots__/accordion-item/component/chromium/DBAccordionItem-should-match-screenshot.png differ diff --git a/__snapshots__/accordion-item/component/mobile-chrome/DBAccordionItem-should-match-screenshot.png b/__snapshots__/accordion-item/component/mobile-chrome/DBAccordionItem-should-match-screenshot.png new file mode 100644 index 000000000000..f32ee0f92d46 Binary files /dev/null and b/__snapshots__/accordion-item/component/mobile-chrome/DBAccordionItem-should-match-screenshot.png differ diff --git a/__snapshots__/accordion-item/component/mobile-safari/DBAccordionItem-should-match-screenshot.png b/__snapshots__/accordion-item/component/mobile-safari/DBAccordionItem-should-match-screenshot.png new file mode 100644 index 000000000000..8707835cfc00 Binary files /dev/null and b/__snapshots__/accordion-item/component/mobile-safari/DBAccordionItem-should-match-screenshot.png differ diff --git a/__snapshots__/accordion-item/component/webkit/DBAccordionItem-should-match-screenshot.png b/__snapshots__/accordion-item/component/webkit/DBAccordionItem-should-match-screenshot.png new file mode 100644 index 000000000000..8707835cfc00 Binary files /dev/null and b/__snapshots__/accordion-item/component/webkit/DBAccordionItem-should-match-screenshot.png differ diff --git a/__snapshots__/accordion-item/showcase/chromium/regular/neutral/DBAccordionItem-should-match-screenshot.png b/__snapshots__/accordion-item/showcase/chromium/regular/neutral/DBAccordionItem-should-match-screenshot.png new file mode 100644 index 000000000000..ea40c4621ffd Binary files /dev/null and b/__snapshots__/accordion-item/showcase/chromium/regular/neutral/DBAccordionItem-should-match-screenshot.png differ diff --git a/__snapshots__/accordion-item/showcase/mobile-chrome/regular/neutral/DBAccordionItem-should-match-screenshot.png b/__snapshots__/accordion-item/showcase/mobile-chrome/regular/neutral/DBAccordionItem-should-match-screenshot.png new file mode 100644 index 000000000000..d3a5be90dd74 Binary files /dev/null and b/__snapshots__/accordion-item/showcase/mobile-chrome/regular/neutral/DBAccordionItem-should-match-screenshot.png differ diff --git a/__snapshots__/accordion-item/showcase/mobile-safari/regular/neutral/DBAccordionItem-should-match-screenshot.png b/__snapshots__/accordion-item/showcase/mobile-safari/regular/neutral/DBAccordionItem-should-match-screenshot.png new file mode 100644 index 000000000000..57f9d513b297 Binary files /dev/null and b/__snapshots__/accordion-item/showcase/mobile-safari/regular/neutral/DBAccordionItem-should-match-screenshot.png differ diff --git a/__snapshots__/accordion-item/showcase/webkit/regular/neutral/DBAccordionItem-should-match-screenshot.png b/__snapshots__/accordion-item/showcase/webkit/regular/neutral/DBAccordionItem-should-match-screenshot.png new file mode 100644 index 000000000000..40a9b1df2d3b Binary files /dev/null and b/__snapshots__/accordion-item/showcase/webkit/regular/neutral/DBAccordionItem-should-match-screenshot.png differ diff --git a/__snapshots__/accordion/component/chromium/DBAccordion-should-match-screenshot.png b/__snapshots__/accordion/component/chromium/DBAccordion-should-match-screenshot.png new file mode 100644 index 000000000000..d0a994bd1e7a Binary files /dev/null and b/__snapshots__/accordion/component/chromium/DBAccordion-should-match-screenshot.png differ diff --git a/__snapshots__/accordion/component/mobile-chrome/DBAccordion-should-match-screenshot.png b/__snapshots__/accordion/component/mobile-chrome/DBAccordion-should-match-screenshot.png new file mode 100644 index 000000000000..d0a994bd1e7a Binary files /dev/null and b/__snapshots__/accordion/component/mobile-chrome/DBAccordion-should-match-screenshot.png differ diff --git a/__snapshots__/accordion/component/mobile-safari/DBAccordion-should-match-screenshot.png b/__snapshots__/accordion/component/mobile-safari/DBAccordion-should-match-screenshot.png new file mode 100644 index 000000000000..5b6487c9aea5 Binary files /dev/null and b/__snapshots__/accordion/component/mobile-safari/DBAccordion-should-match-screenshot.png differ diff --git a/__snapshots__/accordion/component/webkit/DBAccordion-should-match-screenshot.png b/__snapshots__/accordion/component/webkit/DBAccordion-should-match-screenshot.png new file mode 100644 index 000000000000..5b6487c9aea5 Binary files /dev/null and b/__snapshots__/accordion/component/webkit/DBAccordion-should-match-screenshot.png differ diff --git a/__snapshots__/accordion/showcase/chromium/regular/neutral/DBAccordion-should-match-screenshot.png b/__snapshots__/accordion/showcase/chromium/regular/neutral/DBAccordion-should-match-screenshot.png new file mode 100644 index 000000000000..db08c56eaaf1 Binary files /dev/null and b/__snapshots__/accordion/showcase/chromium/regular/neutral/DBAccordion-should-match-screenshot.png differ diff --git a/__snapshots__/accordion/showcase/mobile-chrome/regular/neutral/DBAccordion-should-match-screenshot.png b/__snapshots__/accordion/showcase/mobile-chrome/regular/neutral/DBAccordion-should-match-screenshot.png new file mode 100644 index 000000000000..bf78c34fd55a Binary files /dev/null and b/__snapshots__/accordion/showcase/mobile-chrome/regular/neutral/DBAccordion-should-match-screenshot.png differ diff --git a/__snapshots__/accordion/showcase/mobile-safari/regular/neutral/DBAccordion-should-match-screenshot.png b/__snapshots__/accordion/showcase/mobile-safari/regular/neutral/DBAccordion-should-match-screenshot.png new file mode 100644 index 000000000000..f4591b08e1c8 Binary files /dev/null and b/__snapshots__/accordion/showcase/mobile-safari/regular/neutral/DBAccordion-should-match-screenshot.png differ diff --git a/__snapshots__/accordion/showcase/webkit/regular/neutral/DBAccordion-should-match-screenshot.png b/__snapshots__/accordion/showcase/webkit/regular/neutral/DBAccordion-should-match-screenshot.png new file mode 100644 index 000000000000..0e0199c72720 Binary files /dev/null and b/__snapshots__/accordion/showcase/webkit/regular/neutral/DBAccordion-should-match-screenshot.png differ diff --git a/build-power-apps/DBUI/DBUI.cdsproj b/build-power-apps/DBUI/DBUI.cdsproj index 8bc93739ab63..7e88ff0a1465 100644 --- a/build-power-apps/DBUI/DBUI.cdsproj +++ b/build-power-apps/DBUI/DBUI.cdsproj @@ -44,6 +44,10 @@ + + diff --git a/packages/components/index.html b/packages/components/index.html index 83138c7f578c..374f943cfc29 100644 --- a/packages/components/index.html +++ b/packages/components/index.html @@ -7,9 +7,16 @@
    -
  • - DBBadge -
  • +
  • +DBAccordionItem +
  • + +
  • +DBAccordion +
  • +
  • +DBBadge +
  • Fonts diff --git a/packages/components/overrides/angular/src/components/accordion-item/index.ts b/packages/components/overrides/angular/src/components/accordion-item/index.ts new file mode 100644 index 000000000000..27ab670b43dc --- /dev/null +++ b/packages/components/overrides/angular/src/components/accordion-item/index.ts @@ -0,0 +1 @@ +export { DBAccordionItem, DBAccordionItemModule } from './accordion-item'; diff --git a/packages/components/overrides/angular/src/components/accordion/index.ts b/packages/components/overrides/angular/src/components/accordion/index.ts new file mode 100644 index 000000000000..f1954d19cc05 --- /dev/null +++ b/packages/components/overrides/angular/src/components/accordion/index.ts @@ -0,0 +1 @@ +export { DBAccordion, DBAccordionModule } from './accordion'; diff --git a/packages/components/scripts/post-build/components.js b/packages/components/scripts/post-build/components.js index c29e99e50837..dd6d8145b84a 100644 --- a/packages/components/scripts/post-build/components.js +++ b/packages/components/scripts/post-build/components.js @@ -20,6 +20,25 @@ * }]} */ const getComponents = () => [ + { + name: 'accordion-item' + }, + + { + name: 'accordion', + overwrites: { + angular: [ + { from: 'openItems = []', to: 'openItems: string[] = []' } + ], + react: [ + { + from: 'const ref = useRef(null);', + to: 'const ref = useRef(component);' + } + ] + } + }, + { name: 'badge' }, diff --git a/packages/components/scripts/post-build/vue.js b/packages/components/scripts/post-build/vue.js index d797e9695223..4079313dad92 100644 --- a/packages/components/scripts/post-build/vue.js +++ b/packages/components/scripts/post-build/vue.js @@ -96,7 +96,7 @@ module.exports = (tmp) => { runReplacements( [ { - from: 'immediate: true,', + from: /immediate: true,/g, to: 'immediate: true,\nflush: "post"' } ], diff --git a/packages/components/src/components/accordion-item/accordion-item-web-component.scss b/packages/components/src/components/accordion-item/accordion-item-web-component.scss new file mode 100644 index 000000000000..452e0a7337b8 --- /dev/null +++ b/packages/components/src/components/accordion-item/accordion-item-web-component.scss @@ -0,0 +1 @@ +@forward "accordion-item"; diff --git a/packages/components/src/components/accordion-item/accordion-item.lite.tsx b/packages/components/src/components/accordion-item/accordion-item.lite.tsx new file mode 100644 index 000000000000..1370fc1bcccf --- /dev/null +++ b/packages/components/src/components/accordion-item/accordion-item.lite.tsx @@ -0,0 +1,67 @@ +import { + onMount, + onUpdate, + Show, + Slot, + useMetadata, + useStore +} from '@builder.io/mitosis'; +import { DBAccordionItemState, DBAccordionItemProps } from './model'; +import { cls, uuid } from '../../utils'; +import { DEFAULT_ID } from '../../shared/constants'; + +useMetadata({ + isAttachedToShadowDom: true, + component: { + // MS Power Apps + includeIcon: false, + properties: [] + } +}); + +export default function DBAccordionItem(props: DBAccordionItemProps) { + // This is used as forwardRef + let component: any; + // jscpd:ignore-start + const state = useStore({ + _id: DEFAULT_ID, + toggle: (event: any) => { + // We need this for react https://github.com/facebook/react/issues/15486#issuecomment-488028431 + event?.preventDefault(); + if (props.onToggle) { + props.onToggle(!props.open); + } + } + }); + + onMount(() => { + state._id = props.id || 'accordion-item-' + uuid(); + if (props.stylePath) { + state.stylePath = props.stylePath; + } + }); + // jscpd:ignore-end + + return ( +
    + + + + state.toggle(event)}> + {props.title} + + + + +
    + {props.content} + {props.children} +
    +
    + ); +} diff --git a/packages/components/src/components/accordion-item/accordion-item.scss b/packages/components/src/components/accordion-item/accordion-item.scss new file mode 100644 index 000000000000..7ad09483363f --- /dev/null +++ b/packages/components/src/components/accordion-item/accordion-item.scss @@ -0,0 +1,71 @@ +@use "@db-ui/foundations/build/scss/variables" as *; +@use "@db-ui/foundations/build/scss/variables.global" as var; +@use "@db-ui/foundations/build/scss/helpers/functions" as functions; +@use "@db-ui/foundations/build/scss/icon/icons.helpers" as icons; +@use "@db-ui/foundations/build/scss/helpers/component" as component; +@use "@db-ui/foundations/build/scss/color/color-variants" as col-var; +@use "@db-ui/foundations/build/scss/animation/animations" as animations; +@use "../../styles/form-components" as form; + +@mixin accordion-item-content() { + :not(summary):not(link) { + @content; + } +} + +.db-accordion-item { + @extend %bg-transparent; + @include functions.divider($position: "top"); + + position: relative; + inline-size: 100%; + + @include accordion-item-content() { + padding: var.$db-spacing-fixed-md; + padding-block-end: var.$db-spacing-fixed-lg; + } + + &:last-of-type { + @include functions.divider($position: "bottom", $slot: "after"); + } + + &[aria-disabled="true"] { + pointer-events: none; + opacity: component.$default-opacity; + } + + summary { + @extend %dropdown-icon; + @include col-var.bg-transparent-interactive(false); + + list-style: none; + display: flex; + justify-content: space-between; + padding: var.$db-spacing-fixed-md; + gap: var.$db-spacing-fixed-md; + + &::-webkit-details-marker { + display: none; + } + + &::after { + inset-inline-end: var.$db-spacing-fixed-sm; + } + + &:focus-visible { + // TODO: Evaluate whether this number is intended + border-radius: component.$default-border-radius + 2; + } + } + + &[open] { + @include accordion-item-content() { + animation: accordion-open $db-transition-emotional-straight normal + both; + } + + summary::after { + transform: form.$dropdown-icon-transform; + } + } +} diff --git a/packages/components/src/components/accordion-item/accordion-item.spec.tsx b/packages/components/src/components/accordion-item/accordion-item.spec.tsx new file mode 100644 index 000000000000..7991f1acfa96 --- /dev/null +++ b/packages/components/src/components/accordion-item/accordion-item.spec.tsx @@ -0,0 +1,36 @@ +import { test, expect } from '@playwright/experimental-ct-react'; +import AxeBuilder from '@axe-core/playwright'; + +import { DBAccordionItem } from './index'; +// @ts-ignore - vue can only find it with .ts as file ending +import { DEFAULT_VIEWPORT } from '../../shared/constants.ts'; + +const comp = Test; + +const testComponent = () => { + test('should contain text', async ({ mount }) => { + const component = await mount(comp); + await expect(component).toContainText('Test'); + }); + + test('should match screenshot', async ({ mount }) => { + const component = await mount(comp); + await expect(component).toHaveScreenshot(); + }); +}; + +test.describe('DBAccordionItem', () => { + test.use({ viewport: DEFAULT_VIEWPORT }); + testComponent(); +}); + +test.describe('DBAccordionItem', () => { + test('should not have any A11y issues', async ({ page, mount }) => { + await mount(comp); + const accessibilityScanResults = await new AxeBuilder({ page }) + .include('.db-accordion-item') + .analyze(); + + expect(accessibilityScanResults.violations).toEqual([]); + }); +}); diff --git a/packages/components/src/components/accordion-item/docs/Angular.md b/packages/components/src/components/accordion-item/docs/Angular.md new file mode 100644 index 000000000000..89421c1c13f1 --- /dev/null +++ b/packages/components/src/components/accordion-item/docs/Angular.md @@ -0,0 +1,36 @@ +## Angular + +For general installation and configuration look at the [ngx-components](https://www.npmjs.com/package/@db-ui/ngx-components) package. + +### Load component + +```ts app.module.ts +//app.module.ts +import { DBAccordionItemModule } from '@db-ui/ngx-components'; + +@NgModule({ + ... + imports: [..., DBAccordionItemModule], + ... +}) + +``` + +### Use component + +#### With Slots + +```html app.component.html + + + Title + Content + +``` + +#### With attributes + +```html app.component.html + + +``` diff --git a/packages/components/src/components/accordion-item/docs/HTML.md b/packages/components/src/components/accordion-item/docs/HTML.md new file mode 100644 index 000000000000..dbb7b83a894a --- /dev/null +++ b/packages/components/src/components/accordion-item/docs/HTML.md @@ -0,0 +1,16 @@ +## HTML + +For general installation and configuration look at the [components](https://www.npmjs.com/package/@db-ui/components) package. + +### Use component + +```html index.html + +... + +
    + Title +
    Content
    +
    + +``` diff --git a/packages/components/src/components/accordion-item/docs/Migration.md b/packages/components/src/components/accordion-item/docs/Migration.md new file mode 100644 index 000000000000..897577058d8e --- /dev/null +++ b/packages/components/src/components/accordion-item/docs/Migration.md @@ -0,0 +1,23 @@ +## General + +> **Note** +> For a general installation or migration process check out this [documentation](https://www.npmjs.com/package/@db-ui/components). + +## DB UI Core ➡ DB UI Components + +### class + +| Before | Status | After | Description | +| --------------- | :----: | ------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| `cmp-accordion` | 🔁 | `db-accordion-item` | The old accordion was just 1 item, we split it to combine multiple accordion-items into 1 accordion (which is another component) | + +### props + +| Before | Status | After | Description | +| ---------- | :----: | ----------- | ----------------------------------------------------------- | +| `summary` | 🔁 | `title` | The title/summary of the details element. | +| `emphasis` | ❌ | ❌ | There is no emphasis anymore. | +| `size` | ❌ | ❌ | Controlled by the tonality. | +| | 🆕 | `disabled` | Disable the component. | +| | 🆕 | `content` | Pass in a simple string as fallback to normal children/slot | +| | 🆕 | `slotTitle` | Pass in a custom title (only required for React) | diff --git a/packages/components/src/components/accordion-item/docs/React.md b/packages/components/src/components/accordion-item/docs/React.md new file mode 100644 index 000000000000..a9881822b9a9 --- /dev/null +++ b/packages/components/src/components/accordion-item/docs/React.md @@ -0,0 +1,25 @@ +## React + +For general installation and configuration look at the [react-components](https://www.npmjs.com/package/@db-ui/react-components) package. + +### Use component + +#### With Slots + +```tsx App.tsx +// App.tsx +import { DBAccordionItem } from "@db-ui/react-components"; + +const App = () => Content; +export default App; +``` + +#### With attributes + +```tsx App.tsx +// App.tsx +import { DBAccordionItem } from "@db-ui/react-components"; + +const App = () => ; +export default App; +``` diff --git a/packages/components/src/components/accordion-item/docs/Vue.md b/packages/components/src/components/accordion-item/docs/Vue.md new file mode 100644 index 000000000000..43153a324574 --- /dev/null +++ b/packages/components/src/components/accordion-item/docs/Vue.md @@ -0,0 +1,34 @@ +## Vue + +For general installation and configuration look at the [v-components](https://www.npmjs.com/package/@db-ui/v-components) package. + +### Use component + +#### With Slots + +```vue App.vue + + + + +``` + +#### With attributes + +```vue App.vue + + + + +``` diff --git a/packages/components/src/components/accordion-item/index.html b/packages/components/src/components/accordion-item/index.html new file mode 100644 index 000000000000..d77286d5b03b --- /dev/null +++ b/packages/components/src/components/accordion-item/index.html @@ -0,0 +1,19 @@ + + + + + DBAccordionItem + + + + +
    + + DB Accordion Item + +
    + Und hier ist der Content +
    +
    + + diff --git a/packages/components/src/components/accordion-item/index.ts b/packages/components/src/components/accordion-item/index.ts new file mode 100644 index 000000000000..b010b61cc468 --- /dev/null +++ b/packages/components/src/components/accordion-item/index.ts @@ -0,0 +1 @@ +export { default as DBAccordionItem } from './accordion-item'; diff --git a/packages/components/src/components/accordion-item/model.ts b/packages/components/src/components/accordion-item/model.ts new file mode 100644 index 000000000000..e8fc9caa8ece --- /dev/null +++ b/packages/components/src/components/accordion-item/model.ts @@ -0,0 +1,39 @@ +import { + GlobalProps, + GlobalState, + ToggleEventProps, + ToggleEventState +} from '../../shared/model'; + +export interface DBAccordionItemDefaultProps { + /** + * Alternative for passing only a string instead of children + */ + content?: string; + /** + * The disabled attribute can be set to keep a user from clicking on the element. + */ + disabled?: boolean; + /** + * Initial state for the accordion item + */ + open?: boolean; + /** + * For react only to pass any title element to the specific slot + */ + slotTitle?: any; + /** + * Alternative for passing only a string instead of a slot + */ + title?: string; +} + +export type DBAccordionItemProps = DBAccordionItemDefaultProps & + GlobalProps & + ToggleEventProps; + +export interface DBAccordionItemDefaultState {} + +export type DBAccordionItemState = DBAccordionItemDefaultState & + GlobalState & + ToggleEventState; diff --git a/packages/components/src/components/accordion/accordion-web-component.scss b/packages/components/src/components/accordion/accordion-web-component.scss new file mode 100644 index 000000000000..65bc6f97afa4 --- /dev/null +++ b/packages/components/src/components/accordion/accordion-web-component.scss @@ -0,0 +1 @@ +@forward "accordion"; diff --git a/packages/components/src/components/accordion/accordion.lite.tsx b/packages/components/src/components/accordion/accordion.lite.tsx new file mode 100644 index 000000000000..3aafe0b4fac1 --- /dev/null +++ b/packages/components/src/components/accordion/accordion.lite.tsx @@ -0,0 +1,146 @@ +import { + For, + onMount, + onUpdate, + Show, + useMetadata, + useRef, + useStore +} from '@builder.io/mitosis'; +import { + DBAccordionState, + DBAccordionProps, + DBAccordionItemInterface +} from './model'; +import { cls } from '../../utils'; +import { DBAccordionItem } from '../accordion-item'; + +useMetadata({ + isAttachedToShadowDom: true, + component: { + // MS Power Apps + includeIcon: false, + properties: [] + } +}); + +export default function DBAccordion(props: DBAccordionProps) { + const ref = useRef(null); + // jscpd:ignore-start + const state = useStore({ + openItems: [], + clickedId: '', + initialized: false, + convertItems(items: any[] | string | undefined) { + try { + if (typeof items === 'string') { + return JSON.parse(items); + } + + return items; + } catch (error) { + console.error(error); + } + + return undefined; + }, + 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(() => { + if (props.stylePath) { + state.stylePath = props.stylePath; + } + state.initialized = true; + }); + // jscpd:ignore-end + + onUpdate(() => { + if (ref && state.initialized) { + const childDetails = ref.getElementsByTagName('details'); + if (childDetails) { + let initOpenItems: string[] = []; + Array.from(childDetails).forEach( + (details: HTMLDetailsElement) => { + const id = details.id; + if (details.open) { + initOpenItems.push(id); + } + const summaries = + details.getElementsByTagName('summary'); + if (summaries?.length > 0) { + summaries[0].addEventListener('click', () => { + state.clickedId = id; + }); + } + } + ); + if (props.behaviour === 'single' && initOpenItems.length > 1) { + initOpenItems = [initOpenItems[0]]; + } + state.openItems = initOpenItems; + } + /* Just set the click listener once */ + state.initialized = false; + } + }, [ref, state.initialized]); + + onUpdate(() => { + if (state.clickedId?.length > 0) { + state.handleItemClick(state.clickedId); + state.clickedId = ''; + } + }, [state.clickedId]); + + onUpdate(() => { + if (ref) { + const childDetails = ref.getElementsByTagName('details'); + if (childDetails) { + Array.from(childDetails).forEach( + (details: HTMLDetailsElement) => { + details.open = state.openItems.includes(details.id); + } + ); + } + } + }, [state.openItems]); + + return ( +
    + + + + {props.children} + + + {(item: DBAccordionItemInterface, index: number) => ( + + )} + + +
    + ); +} diff --git a/packages/components/src/components/accordion/accordion.scss b/packages/components/src/components/accordion/accordion.scss new file mode 100644 index 000000000000..00c188bdcb4c --- /dev/null +++ b/packages/components/src/components/accordion/accordion.scss @@ -0,0 +1,3 @@ +.db-accordion { + // No styling for now only JS code for this component +} diff --git a/packages/components/src/components/accordion/accordion.spec.tsx b/packages/components/src/components/accordion/accordion.spec.tsx new file mode 100644 index 000000000000..a58d93cc0939 --- /dev/null +++ b/packages/components/src/components/accordion/accordion.spec.tsx @@ -0,0 +1,43 @@ +import { test, expect } from '@playwright/experimental-ct-react'; +import AxeBuilder from '@axe-core/playwright'; + +import { DBAccordion } from './index'; +// @ts-ignore - vue can only find it with .ts as file ending +import { DEFAULT_VIEWPORT } from '../../shared/constants.ts'; +import { DBAccordionItem } from '../accordion-item'; + +const comp = ( + + + + + +); + +const testComponent = () => { + test('should contain text', async ({ mount }) => { + const component = await mount(comp); + await expect(component).toContainText('Test'); + }); + + test('should match screenshot', async ({ mount }) => { + const component = await mount(comp); + await expect(component).toHaveScreenshot(); + }); +}; + +test.describe('DBAccordion', () => { + test.use({ viewport: DEFAULT_VIEWPORT }); + testComponent(); +}); + +test.describe('DBAccordion', () => { + test('should not have any A11y issues', async ({ page, mount }) => { + await mount(comp); + const accessibilityScanResults = await new AxeBuilder({ page }) + .include('.db-accordion') + .analyze(); + + expect(accessibilityScanResults.violations).toEqual([]); + }); +}); diff --git a/packages/components/src/components/accordion/docs/Angular.md b/packages/components/src/components/accordion/docs/Angular.md new file mode 100644 index 000000000000..204ec31c6d89 --- /dev/null +++ b/packages/components/src/components/accordion/docs/Angular.md @@ -0,0 +1,28 @@ +## Angular + +For general installation and configuration look at the [ngx-components](https://www.npmjs.com/package/@db-ui/ngx-components) package. + +### Load component + +```ts app.module.ts +//app.module.ts +import { DBAccordionModule } from '@db-ui/ngx-components'; + +@NgModule({ + ... + imports: [..., DBAccordionModule], + ... +}) + +``` + +### Use component + +```html app.component.html + + + + + + +``` diff --git a/packages/components/src/components/accordion/docs/HTML.md b/packages/components/src/components/accordion/docs/HTML.md new file mode 100644 index 000000000000..94f5c55dc910 --- /dev/null +++ b/packages/components/src/components/accordion/docs/HTML.md @@ -0,0 +1,26 @@ +## HTML + +For general installation and configuration look at the [components](https://www.npmjs.com/package/@db-ui/components) package. + +### Use component + +```html index.html + +... + +
    +
    + Title 1 +
    Content 1
    +
    +
    + Title 2 +
    Content 2
    +
    +
    + Title 3 +
    Content 3
    +
    +
    + +``` diff --git a/packages/components/src/components/accordion/docs/Migration.md b/packages/components/src/components/accordion/docs/Migration.md new file mode 100644 index 000000000000..5f5eb8a04d6c --- /dev/null +++ b/packages/components/src/components/accordion/docs/Migration.md @@ -0,0 +1,8 @@ +## General + +> **Note** +> For a general installation or migration process check out this [documentation](https://www.npmjs.com/package/@db-ui/components). + +## DB UI Core ➡ DB UI Components + +New Component 🥳 diff --git a/packages/components/src/components/accordion/docs/React.md b/packages/components/src/components/accordion/docs/React.md new file mode 100644 index 000000000000..270eb705e067 --- /dev/null +++ b/packages/components/src/components/accordion/docs/React.md @@ -0,0 +1,19 @@ +## React + +For general installation and configuration look at the [react-components](https://www.npmjs.com/package/@db-ui/react-components) package. + +### Use component + +```tsx App.tsx +// App.tsx +import { DBAccordion } from "@db-ui/react-components"; + +const App = () => ( + + + + + +); +export default App; +``` diff --git a/packages/components/src/components/accordion/docs/Vue.md b/packages/components/src/components/accordion/docs/Vue.md new file mode 100644 index 000000000000..b0419cd22fb5 --- /dev/null +++ b/packages/components/src/components/accordion/docs/Vue.md @@ -0,0 +1,20 @@ +## Vue + +For general installation and configuration look at the [v-components](https://www.npmjs.com/package/@db-ui/v-components) package. + +### Use component + +```vue App.vue + + + + +``` diff --git a/packages/components/src/components/accordion/index.html b/packages/components/src/components/accordion/index.html new file mode 100644 index 000000000000..55988c0aa610 --- /dev/null +++ b/packages/components/src/components/accordion/index.html @@ -0,0 +1,11 @@ + + + + + DBAccordion + + + +
    Test
    + + diff --git a/packages/components/src/components/accordion/index.ts b/packages/components/src/components/accordion/index.ts new file mode 100644 index 000000000000..2c48f4a5f86d --- /dev/null +++ b/packages/components/src/components/accordion/index.ts @@ -0,0 +1 @@ +export { default as DBAccordion } from './accordion'; diff --git a/packages/components/src/components/accordion/model.ts b/packages/components/src/components/accordion/model.ts new file mode 100644 index 000000000000..af00d4c956a9 --- /dev/null +++ b/packages/components/src/components/accordion/model.ts @@ -0,0 +1,34 @@ +import { GlobalProps, GlobalState, InitializedState } from '../../shared/model'; +import { DBAccordionItemDefaultProps } from '../accordion-item/model'; + +export interface DBAccordionItemInterface + extends Omit {} +export interface DBAccordionDefaultProps { + /** + * To allow multiple items open at the same time or only 1 item + */ + behaviour?: 'multiple' | 'single'; + + /** + * Alternative to pass in a simple representation of accordion items + */ + items?: DBAccordionItemInterface[] | string; + + /** + * Informs about the changes in the internal state, which item is open + */ + onChange?: (openAccordionItemIds: string[]) => void; +} + +export type DBAccordionProps = DBAccordionDefaultProps & GlobalProps; + +export interface DBAccordionDefaultState { + clickedId: string; + openItems: string[]; + handleItemClick: (id: string) => void; + convertItems: (items?: any[] | string) => DBAccordionItemInterface[]; +} + +export type DBAccordionState = DBAccordionDefaultState & + GlobalState & + InitializedState; diff --git a/packages/components/src/components/badge/docs/Migration.md b/packages/components/src/components/badge/docs/Migration.md new file mode 100644 index 000000000000..5f5eb8a04d6c --- /dev/null +++ b/packages/components/src/components/badge/docs/Migration.md @@ -0,0 +1,8 @@ +## General + +> **Note** +> For a general installation or migration process check out this [documentation](https://www.npmjs.com/package/@db-ui/components). + +## DB UI Core ➡ DB UI Components + +New Component 🥳 diff --git a/packages/components/src/components/button/button.scss b/packages/components/src/components/button/button.scss index e911ac4a1e94..dca2b91c4d69 100644 --- a/packages/components/src/components/button/button.scss +++ b/packages/components/src/components/button/button.scss @@ -4,15 +4,16 @@ @use "@db-ui/foundations/build/scss/variables.global" as *; @use "@db-ui/foundations/build/scss/color-placeholder" as *; @use "@db-ui/foundations/build/scss/icon/icons.helpers" as *; -@use "@db-ui/foundations/build/scss/color/color-variants" as *; +@use "@db-ui/foundations/build/scss/color/color-variants" as col-var; @use "@db-ui/foundations/build/scss/helpers/component" as *; @use "../../styles/button-components"; .db-button { @extend %default-interactive-component; - @extend %bg-transparent-interactive; @extend %default-button; + @include col-var.bg-transparent-interactive(); + color: $db-colors-neutral-on-bg; block-size: $db-sizing-md; @@ -54,7 +55,7 @@ &[data-variant="solid"] { @extend %transparent-border; - @include get-variant-bg-color(0.08); + @include col-var.get-variant-bg-color(0.08); } &[data-variant="text"] { diff --git a/packages/components/src/components/checkbox/checkbox.scss b/packages/components/src/components/checkbox/checkbox.scss index 182965dc2f23..7c05ed6c7cc7 100644 --- a/packages/components/src/components/checkbox/checkbox.scss +++ b/packages/components/src/components/checkbox/checkbox.scss @@ -4,12 +4,12 @@ @use "@db-ui/foundations/build/scss/color-placeholder" as *; @use "@db-ui/foundations/build/scss/tonality" as *; @use "@db-ui/foundations/build/scss/helpers/component" as *; -@use "@db-ui/foundations/build/scss/color/color-variants" as *; +@use "@db-ui/foundations/build/scss/color/color-variants" as col-var; $font-size-height: calc(var(--db-base-font-size) * var(--db-base-line-height)); .db-checkbox { - @extend %bg-transparent-interactive; + @include col-var.bg-transparent-interactive(); align-content: center; diff --git a/packages/components/src/components/input/input.scss b/packages/components/src/components/input/input.scss index d201c8900170..e6ca0bcaa92d 100644 --- a/packages/components/src/components/input/input.scss +++ b/packages/components/src/components/input/input.scss @@ -9,6 +9,7 @@ @use "@db-ui/foundations/build/scss/color-placeholder" as *; @use "@db-ui/foundations/build/scss/color/color-variants" as *; @use "@db-ui/foundations/build/scss/helpers/component" as *; +@use "../../styles/form-components" as *; :root, .db-ui-regular, @@ -165,7 +166,7 @@ &:has(input:is(:focus, :not(:placeholder-shown))) { &::after { - transform: rotate(-180deg); + transform: $dropdown-icon-transform; } } @@ -261,9 +262,10 @@ ) * #{$db-sizing-md} ); - @extend %bg-transparent-hover; @extend %default-interactive-component; @extend %component-border; + + @include bg-transparent-hover(); @include get-variant-bg-color(0.08); color: $db-colors-neutral-on-bg; diff --git a/packages/components/src/components/main-navigation/main-navigation.scss b/packages/components/src/components/main-navigation/main-navigation.scss index 185a002d9ca9..f0e87fee61c1 100644 --- a/packages/components/src/components/main-navigation/main-navigation.scss +++ b/packages/components/src/components/main-navigation/main-navigation.scss @@ -41,7 +41,7 @@ &:has(~ .db-sub-navigation:focus-visible), &:has(~ .db-sub-navigation:focus-within) { &::after { - transform: rotate(-180deg); + transform: $dropdown-icon-transform; } } } diff --git a/packages/components/src/components/radio/radio.scss b/packages/components/src/components/radio/radio.scss index aeee898b57cd..232f9519e241 100644 --- a/packages/components/src/components/radio/radio.scss +++ b/packages/components/src/components/radio/radio.scss @@ -4,12 +4,12 @@ @use "@db-ui/foundations/build/scss/color-placeholder" as *; @use "@db-ui/foundations/build/scss/helpers/font" as *; @use "@db-ui/foundations/build/scss/helpers/component" as *; -@use "@db-ui/foundations/build/scss/color/color-variants" as *; +@use "@db-ui/foundations/build/scss/color/color-variants" as col-var; $font-size-height: calc(var(--db-base-font-size) * var(--db-base-line-height)); .db-radio { - @extend %bg-transparent-interactive; + @include col-var.bg-transparent-interactive(); appearance: none; diff --git a/packages/components/src/components/select/select.scss b/packages/components/src/components/select/select.scss index 0fadd9f1578d..91835c9121ab 100644 --- a/packages/components/src/components/select/select.scss +++ b/packages/components/src/components/select/select.scss @@ -19,7 +19,7 @@ &:has(select:focus-within) { &::after { - transform: rotate(-180deg); + transform: $dropdown-icon-transform; } } } @@ -37,9 +37,9 @@ --has-status: 0; @extend %db-overwrite-font-size-sm; @extend %select-icon; - @extend %bg-transparent-hover; @extend %default-interactive-component; @extend %component-border; + @include bg-transparent-hover(); @include get-variant-bg-color(0.08); position: relative; diff --git a/packages/components/src/components/tab-bar/model.ts b/packages/components/src/components/tab-bar/model.ts index a008e4840bab..f22f160265ae 100644 --- a/packages/components/src/components/tab-bar/model.ts +++ b/packages/components/src/components/tab-bar/model.ts @@ -12,7 +12,7 @@ export type DBTabBarDefaultProps = { export type DBTabBarProps = DBTabBarDefaultProps & GlobalProps; export type DBTabBarDefaultState = { - convertTabs: (tabs?: any[] | string) => DBTabProps[]; + convertTabs: (tabs?: any[] | string | undefined) => DBTabProps[]; }; export type DBTabBarState = DBTabBarDefaultState & GlobalState; diff --git a/packages/components/src/components/tag/tag.scss b/packages/components/src/components/tag/tag.scss index 880468cdc664..d36423c4f8cf 100644 --- a/packages/components/src/components/tag/tag.scss +++ b/packages/components/src/components/tag/tag.scss @@ -4,7 +4,6 @@ @use "@db-ui/foundations/build/scss/variables.global" as *; @use "@db-ui/foundations/build/scss/color-placeholder" as *; @use "@db-ui/foundations/build/scss/helpers/component" as *; -@use "@db-ui/foundations/build/scss/color/color-variants" as *; @use "@db-ui/foundations/build/scss/helpers/font" as *; @use "../../styles/button-components" as *; @use "../../styles/tag-components" as *; diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 5e900f42fa6d..906f86ead905 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -19,5 +19,8 @@ export * from './components/code-docs'; export * from './components/select'; export * from './components/tag'; export * from './components/navigation-item'; +export * from './components/accordion'; + +export * from './components/accordion-item'; export * from './components/main-navigation'; export * from './components/badge'; diff --git a/packages/components/src/shared/model.ts b/packages/components/src/shared/model.ts index 2d8512ce48e9..29000f615628 100644 --- a/packages/components/src/shared/model.ts +++ b/packages/components/src/shared/model.ts @@ -238,7 +238,7 @@ export type ToggleEventProps = { }; export type ToggleEventState = { - toggle?: () => void; + toggle?: (event?: any) => void; }; export type CloseEventProps = { diff --git a/packages/components/src/styles/db-ui-components.scss b/packages/components/src/styles/db-ui-components.scss index e4226ef37592..5d9db1fd60a3 100644 --- a/packages/components/src/styles/db-ui-components.scss +++ b/packages/components/src/styles/db-ui-components.scss @@ -23,12 +23,20 @@ @use "../components/navigation-item/navigation-item" as *; @use "../components/badge/badge" as *; +@use "../components/accordion/accordion" as *; + +@use "../components/accordion-item/accordion-item" as *; @use "../components/main-navigation/main-navigation" as *; @forward "dialog-init"; // angular-workaround dbmain-navigation, db-main-navigation, +// angular-workaround +dbaccordion-item, +db-accordion-item, +dbaccordion, +db-accordion, dbbadge, db-badge, dbnavigation-item, diff --git a/packages/components/src/styles/form-components.scss b/packages/components/src/styles/form-components.scss index 8ef293683e55..82bd3e0845be 100644 --- a/packages/components/src/styles/form-components.scss +++ b/packages/components/src/styles/form-components.scss @@ -4,6 +4,7 @@ @use "@db-ui/foundations/build/scss/variables.global" as *; $dropdown-icon-transition: transform $db-transition-emotional-straight; +$dropdown-icon-transform: rotate(-180deg); %dropdown-icon { @include icon(glyph(expand-more), 24, "outline", "after"); diff --git a/packages/foundations/scss/animation/_animations.scss b/packages/foundations/scss/animation/_animations.scss index a3074facd13d..86ffff5bf2e5 100644 --- a/packages/foundations/scss/animation/_animations.scss +++ b/packages/foundations/scss/animation/_animations.scss @@ -81,3 +81,15 @@ $animation-hide-timing: 0.4s cubic-bezier(0.49, 0.1, 0.16, 1) normal both; transform: translateY(-110%); } } + +@keyframes accordion-open { + 0% { + opacity: 0; + transform: translateY(-50%); + } + + 100% { + opacity: 1; + transform: translateY(0%); + } +} diff --git a/packages/foundations/scss/color/_color-variants.scss b/packages/foundations/scss/color/_color-variants.scss index 3c73a80a3925..d493ff847725 100644 --- a/packages/foundations/scss/color/_color-variants.scss +++ b/packages/foundations/scss/color/_color-variants.scss @@ -42,20 +42,32 @@ $color-variants: "neutral", "neutral-strong", "primary", "critical", @include get-variant-bg-color(0); } -%bg-transparent-hover { +@mixin bg-transparent-hover($with-enabled: true) { @extend %bg-transparent; - &:enabled { + @if ($with-enabled) { + &:enabled { + &:hover { + @include get-variant-bg-color(0.16); + } + } + } @else { &:hover { @include get-variant-bg-color(0.16); } } } -%bg-transparent-interactive { - @extend %bg-transparent-hover; +@mixin bg-transparent-interactive($with-enabled: true) { + @include bg-transparent-hover($with-enabled); - &:enabled { + @if ($with-enabled) { + &:enabled { + &:active { + @include get-variant-bg-color(0.24); + } + } + } @else { &:active { @include get-variant-bg-color(0.24); } diff --git a/showcases/angular-showcase/src/app/app.module.ts b/showcases/angular-showcase/src/app/app.module.ts index a9d57f3e32ce..39b59390d323 100644 --- a/showcases/angular-showcase/src/app/app.module.ts +++ b/showcases/angular-showcase/src/app/app.module.ts @@ -21,6 +21,8 @@ import { DBDrawerModule, DBTagModule, DBNavigationItemModule, + DBAccordionModule, + DBAccordionItemModule, DBMainNavigationModule, DBBadgeModule } from '../../../../output/angular/src'; @@ -31,6 +33,8 @@ import { NavigationContentDirective } from '../../../../output/angular/src/compo import { BadgeComponent } from './components/badge/badge.component'; import { AppComponent } from './app.component'; import { AppRoutingModule } from './app.routing.module'; +import { AccordionComponent } from './components/accordion/accordion.component'; +import { AccordionItemComponent } from './components/accordion-item/accordion-item.component'; import { FormComponent } from './components/form/form.component'; import { ButtonComponent } from './components/button/button.component'; import { LinkComponent } from './components/link/link.component'; @@ -52,6 +56,8 @@ import { MainNavigationComponent } from './components/main-navigation/main-navig @NgModule({ declarations: [ + AccordionItemComponent, + AccordionComponent, MainNavigationComponent, BadgeComponent, NavigationItemComponent, @@ -78,6 +84,8 @@ import { MainNavigationComponent } from './components/main-navigation/main-navig NavigationContentDirective ], imports: [ + DBAccordionItemModule, + DBAccordionModule, DBBadgeModule, DBMainNavigationModule, DBNavigationItemModule, diff --git a/showcases/angular-showcase/src/app/components/accordion-item/accordion-item.component.html b/showcases/angular-showcase/src/app/components/accordion-item/accordion-item.component.html new file mode 100644 index 000000000000..71d30123274f --- /dev/null +++ b/showcases/angular-showcase/src/app/components/accordion-item/accordion-item.component.html @@ -0,0 +1,22 @@ + + + + {{ exampleName }} + + + diff --git a/showcases/angular-showcase/src/app/components/accordion-item/accordion-item.component.ts b/showcases/angular-showcase/src/app/components/accordion-item/accordion-item.component.ts new file mode 100644 index 000000000000..03f2a40e491a --- /dev/null +++ b/showcases/angular-showcase/src/app/components/accordion-item/accordion-item.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; +import defaultComponentVariants from '../../../../../shared/accordion-item.json'; + +@Component({ + selector: 'app-accordion-item', + templateUrl: './accordion-item.component.html' +}) +export class AccordionItemComponent { + variants = defaultComponentVariants; + + openId?: string; + + getId = (exampleIndex: number, variantIndex: number) => + `${variantIndex}${exampleIndex}`; + + toggle = (exampleIndex: number, variantIndex: number) => { + this.openId = + this.openId === this.getId(exampleIndex, variantIndex) + ? undefined + : this.getId(exampleIndex, variantIndex); + }; + + isOpen = (exampleIndex: number, variantIndex: number, open?: boolean) => + this.openId === this.getId(exampleIndex, variantIndex) ? true : open; +} diff --git a/showcases/angular-showcase/src/app/components/accordion/accordion.component.html b/showcases/angular-showcase/src/app/components/accordion/accordion.component.html new file mode 100644 index 000000000000..148b6b6c9e4f --- /dev/null +++ b/showcases/angular-showcase/src/app/components/accordion/accordion.component.html @@ -0,0 +1,32 @@ + + + + {{ exampleName }} + + + + + + + + + diff --git a/showcases/angular-showcase/src/app/components/accordion/accordion.component.ts b/showcases/angular-showcase/src/app/components/accordion/accordion.component.ts new file mode 100644 index 000000000000..22477f21d936 --- /dev/null +++ b/showcases/angular-showcase/src/app/components/accordion/accordion.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import defaultComponentVariants from '../../../../../shared/accordion.json'; + +@Component({ + selector: 'app-accordion', + templateUrl: './accordion.component.html' +}) +export class AccordionComponent { + variants = defaultComponentVariants; +} diff --git a/showcases/angular-showcase/src/app/utils/navigation-item.ts b/showcases/angular-showcase/src/app/utils/navigation-item.ts index 696004bfe41f..34d13736f23c 100644 --- a/showcases/angular-showcase/src/app/utils/navigation-item.ts +++ b/showcases/angular-showcase/src/app/utils/navigation-item.ts @@ -1,4 +1,6 @@ import { Routes } from '@angular/router'; +import { AccordionItemComponent } from '../components/accordion-item/accordion-item.component'; +import { AccordionComponent } from '../components/accordion/accordion.component'; import { BadgeComponent } from '../components/badge/badge.component'; import { NavigationItemComponent } from '../components/navigation-item/navigation-item.component'; import { MainNavigationComponent } from '../components/main-navigation/main-navigation.component'; @@ -65,7 +67,17 @@ export const NAVIGATION_ITEMS: NavItem[] = [ label: 'Infotext', component: InfotextComponent }, - { path: '04/tag', label: 'Tag', component: TagComponent } + { path: '04/tag', label: 'Tag', component: TagComponent }, + { + path: '04/accordion', + label: 'Accordion', + component: AccordionComponent + }, + { + path: '04/accordion-item', + label: 'AccordionItem', + component: AccordionItemComponent + } ]) }, { diff --git a/showcases/e2e/accordion-item/showcase-accordion-item.spec.ts b/showcases/e2e/accordion-item/showcase-accordion-item.spec.ts new file mode 100644 index 000000000000..0257de46c1b6 --- /dev/null +++ b/showcases/e2e/accordion-item/showcase-accordion-item.spec.ts @@ -0,0 +1,7 @@ +import { test } from '@playwright/test'; +// @ts-expect-error - required for playwright +import { getDefaultScreenshotTest } from '../default.ts'; + +test.describe('DBAccordionItem', () => { + getDefaultScreenshotTest('04/accordion-item'); +}); diff --git a/showcases/e2e/accordion/showcase-accordion.spec.ts b/showcases/e2e/accordion/showcase-accordion.spec.ts new file mode 100644 index 000000000000..ef2891352088 --- /dev/null +++ b/showcases/e2e/accordion/showcase-accordion.spec.ts @@ -0,0 +1,7 @@ +import { test } from '@playwright/test'; +// @ts-expect-error - required for playwright +import { getDefaultScreenshotTest } from '../default.ts'; + +test.describe('DBAccordion', () => { + getDefaultScreenshotTest('04/accordion'); +}); diff --git a/showcases/patternhub/components/component-parser/data.ts b/showcases/patternhub/components/component-parser/data.ts index 816fb4b4b445..ce6ffd254cc9 100644 --- a/showcases/patternhub/components/component-parser/data.ts +++ b/showcases/patternhub/components/component-parser/data.ts @@ -6,6 +6,8 @@ export type ComponentType = { index?: string | number; type?: /* Template hygen type */ | 'main-navigation' + | 'accordion-item' + | 'accordion' | 'badge' | 'navigation-item' | 'tag' diff --git a/showcases/patternhub/components/component-parser/index.tsx b/showcases/patternhub/components/component-parser/index.tsx index bf92d5681866..f8f1dfb63134 100644 --- a/showcases/patternhub/components/component-parser/index.tsx +++ b/showcases/patternhub/components/component-parser/index.tsx @@ -17,7 +17,9 @@ import { DBRadio, DBSection, DBSelect, - DBTag + DBTag, + DBAccordion, + DBAccordionItem } from '../src'; import type { ComponentParserType, ComponentType } from './data'; @@ -224,6 +226,22 @@ const ComponentSwitch = ({ ); } + if (type === 'accordion') { + return ( + + {resolvedContent} + + ); + } + + if (type === 'accordion-item') { + return ( + + {resolvedContent} + + ); + } + if (type === 'main-navigation') { return ( diff --git a/showcases/patternhub/components/navigation/nav-item.tsx b/showcases/patternhub/components/navigation/nav-item.tsx index a4987237439e..cd49b2907478 100644 --- a/showcases/patternhub/components/navigation/nav-item.tsx +++ b/showcases/patternhub/components/navigation/nav-item.tsx @@ -3,29 +3,21 @@ import Link from 'next/link'; import { DBNavigationItem } from '../../../../output/react/src'; import type { NavigationItem } from '../../data/routes'; +const isRouteActive = (pathname: string, navItem: NavigationItem): boolean => + navItem.path === '/' + ? pathname === '/' + : pathname.includes(`${navItem.path}/`) || + pathname === navItem.path || + Boolean( + navItem.subNavigation?.find((subItem) => { + return pathname.includes(`${subItem.path}/`); + }) + ); + const NavItem = ({ navItem }: { navItem: NavigationItem }) => { const router = useRouter(); - const isActive = - navItem.path === '/' - ? router.pathname === '/' - : router.pathname.includes(navItem.path ?? '') || - Boolean( - navItem.subNavigation?.find((subItem) => - router.pathname.includes(subItem.path ?? '') - ) - ) || - Boolean( - navItem.subNavigation?.find((subItem) => - subItem.subNavigation?.find( - (subSubItem) => - router.pathname.includes( - subSubItem.path ?? '' - ) && - router.pathname.includes(navItem.path ?? '') - ) - ) - ); + const isActive = isRouteActive(router.pathname, navItem); return ( { return `${optionName}="primary"`; } - if (tsType.name === 'signature' && tsType.raw === '() => void') { - return `${optionName}={() => console.log("Click")}`; - } - - if (tsType.name === 'signature' && tsType.raw === '() => void') { - return `${optionName}={() => console.log("${optionName}")}`; - } - if (tsType.name === 'signature' && tsType.raw === '(event: any) => void') { return `${optionName}={(event) => console.log(event)}`; } @@ -68,6 +60,13 @@ const getOption = (optionName, tsType) => { return `${optionName}={(event) => console.log(event)}`; } + if ( + tsType.name === 'signature' && + tsType.raw.includes('openAccordionItemIds') + ) { + return `${optionName}={(openAccordionItemIds) => console.log(openAccordionItemIds)}`; + } + if (tsType.name === 'signature' && tsType.type === 'object') { return `${optionName}={{${tsType.signature?.properties?.map( (property) => diff --git a/showcases/react-showcase/src/components/accordion-item/index.tsx b/showcases/react-showcase/src/components/accordion-item/index.tsx new file mode 100644 index 000000000000..3d4aabcef1d8 --- /dev/null +++ b/showcases/react-showcase/src/components/accordion-item/index.tsx @@ -0,0 +1,37 @@ +import { useState } from 'react'; +import { DBAccordionItem } from '../../../../../output/react/src'; +import DefaultComponent from '../index'; +import defaultComponentVariants from '../../../../shared/accordion-item.json'; +import type { DBAccordionItemProps } from '../../../../../output/react/src/components/accordion-item/model'; +import { getVariants } from '../data'; + +const getAccordionItem = ({ + children, + disabled, + open, + title +}: DBAccordionItemProps) => { + const [openAcc, setOpenAcc] = useState(open ?? false); + return ( + + {children} + + ); +}; + +const AccordionItemComponent = () => { + return ( + + ); +}; + +export default AccordionItemComponent; diff --git a/showcases/react-showcase/src/components/accordion/index.tsx b/showcases/react-showcase/src/components/accordion/index.tsx new file mode 100644 index 000000000000..d10ad9b1a307 --- /dev/null +++ b/showcases/react-showcase/src/components/accordion/index.tsx @@ -0,0 +1,35 @@ +import { + DBAccordion, + DBAccordionItem, + DBInfotext +} from '../../../../../output/react/src'; +import DefaultComponent from '../index'; +import defaultComponentVariants from '../../../../shared/accordion.json'; +import type { DBAccordionProps } from '../../../../../output/react/src/components/accordion/model'; +import { getVariants } from '../data'; + +const getAccordion = ({ behaviour, children }: DBAccordionProps) => ( + <> + + {children} + + + + + + + +); + +const AccordionComponent = () => { + return ( + + ); +}; + +export default AccordionComponent; diff --git a/showcases/react-showcase/src/utils/navigation-item.tsx b/showcases/react-showcase/src/utils/navigation-item.tsx index 5a1120715e81..6ff9401e8312 100644 --- a/showcases/react-showcase/src/utils/navigation-item.tsx +++ b/showcases/react-showcase/src/utils/navigation-item.tsx @@ -1,3 +1,5 @@ +import AccordionItemComponent from '../components/accordion-item'; +import AccordionComponent from '../components/accordion'; import MainNavigationComponent from '../components/main-navigation'; import BadgeComponent from '../components/badge'; import NavigationItemComponent from '../components/navigation-item'; @@ -77,7 +79,17 @@ export const NAVIGATION_ITEMS: NavigationItem[] = [ label: 'Infotext', component: }, - { path: 'tag', label: 'Tag', component: } + { path: 'tag', label: 'Tag', component: }, + { + path: 'accordion', + label: 'Accordion', + component: + }, + { + path: 'accordion-item', + label: 'AccordionItem', + component: + } ]) }, { diff --git a/showcases/shared/accordion-item.json b/showcases/shared/accordion-item.json new file mode 100644 index 000000000000..dfa7168c58f6 --- /dev/null +++ b/showcases/shared/accordion-item.json @@ -0,0 +1,61 @@ +[ + { + "name": "Tonality", + "examples": [ + { + "name": "functional", + "className": "db-ui-functional", + "props": { + "title": "functional" + } + }, + { + "name": "regular (Default)", + "className": "db-ui-regular", + "props": { + "title": "regular (Default)" + } + }, + { + "name": "expressive", + "className": "db-ui-expressive", + "props": { + "title": "expressive" + } + } + ] + }, + { + "name": "States", + "examples": [ + { + "name": "Enabled (Default)", + "props": { + "title": "Enabled (Default)" + } + }, + { + "name": "Disabled", + "props": { + "title": "Disabled", + "disabled": true + } + }, + { + "name": "Open", + "props": { + "title": "Open", + "open": true + } + }, + { + "name": "Open Disabled", + "props": { + "title": "Open Disabled", + "open": true, + "disabled": true + } + } + ] + } +] diff --git a/showcases/shared/accordion.json b/showcases/shared/accordion.json new file mode 100644 index 000000000000..a733600f71fc --- /dev/null +++ b/showcases/shared/accordion.json @@ -0,0 +1,69 @@ +[ + { + "name": "Tonality", + "examples": [ + { + "name": "functional", + "className": "db-ui-functional", + "props": {}, + "code": { + "html": "The accordion is a pure JS Component", + "angular": "\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t", + "react": "\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t", + "vue": "\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t" + } + }, + { + "name": "regular (Default)", + "className": "db-ui-regular", + "props": {}, + "code": { + "html": "The accordion is a pure JS Component", + "angular": "\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t", + "react": "\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t", + "vue": "\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t" + } + }, + { + "name": "expressive", + "className": "db-ui-expressive", + "props": {}, + "code": { + "html": "The accordion is a pure JS Component", + "angular": "\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t", + "react": "\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t", + "vue": "\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t" + } + } + ] + }, + { + "name": "Behaviour", + "examples": [ + { + "name": "Multiple (Default)", + "props": { + "behaviour": "multiple" + }, + "code": { + "html": "The accordion is a pure JS Component", + "angular": "\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t", + "react": "\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t", + "vue": "\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t" + } + }, + { + "name": "Single", + "props": { + "behaviour": "single" + }, + "code": { + "html": "The accordion is a pure JS Component", + "angular": "\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t", + "react": "\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t", + "vue": "\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t" + } + } + ] + } +] diff --git a/showcases/vue-showcase/src/components/accordion-item/AccordionItem.vue b/showcases/vue-showcase/src/components/accordion-item/AccordionItem.vue new file mode 100644 index 000000000000..7f06805063bb --- /dev/null +++ b/showcases/vue-showcase/src/components/accordion-item/AccordionItem.vue @@ -0,0 +1,41 @@ + + + diff --git a/showcases/vue-showcase/src/components/accordion/Accordion.vue b/showcases/vue-showcase/src/components/accordion/Accordion.vue new file mode 100644 index 000000000000..8ddbcef42dd7 --- /dev/null +++ b/showcases/vue-showcase/src/components/accordion/Accordion.vue @@ -0,0 +1,26 @@ + + + diff --git a/showcases/vue-showcase/src/utils/navigation-items.ts b/showcases/vue-showcase/src/utils/navigation-items.ts index 900a188e0a1e..9d4a532e092c 100644 --- a/showcases/vue-showcase/src/utils/navigation-items.ts +++ b/showcases/vue-showcase/src/utils/navigation-items.ts @@ -1,4 +1,6 @@ import type { RouteRecordRaw } from 'vue-router'; +import AccordionItem from '../components/accordion-item/AccordionItem.vue'; +import Accordion from '../components/accordion/Accordion.vue'; import Badge from '../components/badge/Badge.vue'; import NavigationItem from '../components/navigation-item/NavigationItem.vue'; import MainNavigation from '../components/main-navigation/MainNavigation.vue'; @@ -65,7 +67,13 @@ export const navigationItems: NavItem[] = [ label: 'Infotext', component: Infotext }, - { path: '/04/tag', label: 'Tag', component: Tag } + { path: '/04/tag', label: 'Tag', component: Tag }, + { path: '/04/accordion', label: 'Accordion', component: Accordion }, + { + path: '/04/accordion-item', + label: 'AccordionItem', + component: AccordionItem + } ]) }, {