Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ahello-pass committed Dec 20, 2024
1 parent c87916b commit e4f34d2
Show file tree
Hide file tree
Showing 8 changed files with 612 additions and 0 deletions.
149 changes: 149 additions & 0 deletions pro/src/ui-kit/MultiSelect/MultiSelect.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
@use "styles/mixins/_fonts.scss" as fonts;
@use "styles/mixins/fonts-design-system.scss" as fonts-design-system;
@use "styles/mixins/_rem.scss" as rem;
@use "styles/mixins/_a11y.scss" as a11y;
@use "styles/mixins/_size.scss" as size;

.container {
display: flex;
flex-direction: column;
width: 100%;
max-width: 400px;
position: relative;
}

.legend {
// @include fonts-design-system.body;
@include fonts.body;

color: var(--color-black);
margin-bottom: 8px;
}

.trigger {
@include fonts.body;

display: flex;
align-items: center;
justify-content: space-between;
padding: 12px;
background-color: var(--color-white);
border: 1px solid var(--color-grey-dark);
border-radius: 10px;
width: 100%;
cursor: pointer;

&:disabled {
background-color: var(--color-grey-light);
border: none;
color: var(--color-black);
}

&:hover {
background: var(--color-grey-light);
}

&:focus {
border: 1px solid var(--color-black);
}

&:focus-visible {
outline: rem.torem(1px) solid var(--color-input-text-color);
outline-offset: rem.torem(2px);
border-radius: rem.torem(8px);
border: 1px solid var(--color-grey-dark);
}

&-selected {
border: 2px solid var(--color-black);
}
}

.trigger-content {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
max-width: 500px;
}

.trigger-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.badge {
// @include fonts-design-system.body-semi-bold-xs;
@include fonts.caption;

display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
background-color: var(--color-primary);
color: var(--color-white);
border-radius: 50%;
}

.chevron {
width: 16px;
height: 16px;
color: var(--color-black);
}

.chevron-open {
transform: rotate(180deg);
}

.item {
display: block;
width: 100%;
text-align: left;
font-size: 14px;
background: none;
border: none;
cursor: pointer;
}

.checkbox {
padding-top: rem.torem(16px);
}

.tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
}

.panel {
position: absolute;
background-color: var(--color-white);
left: 0;
right: 0;
top: rem.torem(48px);
box-shadow: 0 rem.torem(3px) rem.torem(4px) var(--color-medium-shadow);
padding: rem.torem(24px);
}

.search-example {
// @include fonts-design-system.body-semi-bold-xs;
@include fonts.caption;

display: block;
min-height: rem.torem(16px);
color: var(--color-grey-dark);
padding-top: 8px;
padding-bottom: 24px;
}

.visually-hidden {
@include a11y.visually-hidden;
}

.separator {
height: rem.torem(1px);
background: var(--color-grey-medium);
margin-top: rem.torem(12px);
}
29 changes: 29 additions & 0 deletions pro/src/ui-kit/MultiSelect/MultiSelect.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { screen } from '@testing-library/react'
import { axe } from 'vitest-axe'

import {
renderWithProviders,
RenderWithProvidersOptions,
} from 'commons/utils/renderWithProviders'

import { MultiSelect } from './MultiSelect'

const renderMultiSelect = (options?: RenderWithProvidersOptions) => {
return renderWithProviders(<MultiSelect />, { ...options })
}

describe('<MultiSelect />', () => {
it('should render correctly', async () => {
renderMultiSelect()

expect(
await screen.findByRole('heading', { name: /MultiSelect/ })

Check failure on line 20 in pro/src/ui-kit/MultiSelect/MultiSelect.spec.tsx

View workflow job for this annotation

GitHub Actions / Tests pro / Unit tests

ui-kit/MultiSelect/MultiSelect.spec.tsx > <MultiSelect /> > should render correctly

TestingLibraryElementError: Unable to find role="heading" and name `/MultiSelect/` Ignored nodes: comments, script, style <body> <div> <fieldset class="container" style="position: relative;" > <legend class="legend" id=":r0:" /> <button aria-expanded="false" aria-haspopup="listbox" aria-labelledby=":r0:" class="trigger" type="button" > <div class="trigger-content" > <span class="trigger-label" /> </div> <svg aria-hidden="true" class="chevron " viewBox="0 0 48 48" > <use xlink:href="/icons/full-down.svg#icon" /> </svg> </button> <ul class="multi-select-autocomplete-tags" /> </fieldset> </div> </body> Ignored nodes: comments, script, style <body> <div> <fieldset class="container" style="position: relative;" > <legend class="legend" id=":r0:" /> <button aria-expanded="false" aria-haspopup="listbox" aria-labelledby=":r0:" class="trigger" type="button" > <div class="trigger-content" > <span class="trigger-label" /> </div> <svg aria-hidden="true" class="chevron " viewBox="0 0 48 48" > <use xlink:href="/icons/full-down.svg#icon" /> </svg> </button> <ul class="multi-select-autocomplete-tags" /> </fieldset> </div> </body> ❯ waitForWrapper ../node_modules/@testing-library/dom/dist/wait-for.js:163:27 ❯ ../node_modules/@testing-library/dom/dist/query-helpers.js:86:33 ❯ ui-kit/MultiSelect/MultiSelect.spec.tsx:20:20
).toBeInTheDocument()
})

it('should not have accessibility violations', async () => {
const { container } = renderMultiSelect()

expect(await axe(container)).toHaveNoViolations()

Check failure on line 27 in pro/src/ui-kit/MultiSelect/MultiSelect.spec.tsx

View workflow job for this annotation

GitHub Actions / Tests pro / Unit tests

ui-kit/MultiSelect/MultiSelect.spec.tsx > <MultiSelect /> > should not have accessibility violations

Error: expect(received).toHaveNoViolations(expected) Expected the HTML found at $('button') to have no violations: <button type="button" class="trigger" aria-haspopup="listbox" aria-expanded="false" aria-labelledby=":r1:"> Received: "Buttons must have discernible text (button-name)" Fix any of the following: Element does not have inner text that is visible to screen readers aria-label attribute does not exist or is empty aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty Element has no title attribute Element's default semantics were not overridden with role="none" or role="presentation" You can find more information on this issue here: https://dequeuniversity.com/rules/axe/4.8/button-name?application=axeAPI ❯ ui-kit/MultiSelect/MultiSelect.spec.tsx:27:34
})
})
59 changes: 59 additions & 0 deletions pro/src/ui-kit/MultiSelect/MultiSelect.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { StoryObj } from '@storybook/react'
import { withRouter } from 'storybook-addon-remix-react-router'

import { MultiSelect } from './MultiSelect'

export default {
title: 'ui-kit/MultiSelect',
decorators: [withRouter],
component: MultiSelect,
parameters: {
docs: {
story: {
inline: false,
iframeHeight: 380,
},
},
},
}

const defaultOptions = [
{ id: '1', label: '78 - Yvelines' },
{ id: '2', label: '75 - Paris' },
{ id: '3', label: '44 - Nantes' },
{ id: '4', label: '76 - Rouen' },
{ id: '5', label: '77 - Seine et Marne' },
]

const defaultProps = {
options: defaultOptions,
legend: 'Département',
label: 'Selectionner un département',
}

export const Default: StoryObj<typeof MultiSelect> = {
args: {
...defaultProps,
},
}

export const WithDefaultOptions: StoryObj<typeof MultiSelect> = {
args: {
...defaultProps,
defaultOptions: [
{ id: '2', label: '75 - Paris' },
{ id: '3', label: '44 - Nantes' },
],
},
}

export const WithSearchInput: StoryObj<typeof MultiSelect> = {
args: {
...defaultProps,
hasSearch: true,
searchExample: 'Ex : 44 - Nantes',
searchLabel: 'Rechercher des départements',
legend: 'Départements',
label: 'Selectionner des départements',
},
}
Loading

0 comments on commit e4f34d2

Please sign in to comment.