Skip to content

Commit

Permalink
Merge pull request #180 from BouyguesTelecom/update/select
Browse files Browse the repository at this point in the history
Update/select
  • Loading branch information
JulienMora authored Oct 31, 2024
2 parents 5074acc + 91d8692 commit 3b1e4e5
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 172 deletions.
93 changes: 43 additions & 50 deletions examples/react-template/screens/Select.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Button, Divider, Spacer, Title, TitleLevels} from '@trilogy-ds/react'
import {IconName, Section, Select, SelectOption} from '@trilogy-ds/react/components'
import { Button, Divider, Spacer, Title, TitleLevels } from '@trilogy-ds/react'
import { IconName, Section, Select, SelectOption } from '@trilogy-ds/react/components'
import * as React from 'react'

export const SelectView = (): JSX.Element => {
Expand All @@ -12,10 +12,10 @@ export const SelectView = (): JSX.Element => {
<>
<Section>
<Title>Custom select</Title>
<Divider/>
<Spacer size={20}/>
<Divider />
<Spacer size={20} />
<Title level={TitleLevels.TWO}>Unique option</Title>
<Spacer size={20}/>
<Spacer size={20} />
<Title level={TitleLevels.FOUR}>Not nullable</Title>
<Select
disabled
Expand All @@ -28,65 +28,63 @@ export const SelectView = (): JSX.Element => {
setOption(e.selectValue)
}}
>
<SelectOption id='id_four' value='disabled' label='disabled' disabled iconName='tri-bell'/>
<SelectOption id='id_one' value='opt_one' label='Virgile' iconName='tri-bell'/>
<SelectOption id='id_two' value='opt_two' label='Toto' iconName='tri-bell'/>
<SelectOption id='id_three' value='Venus' label='Venus' iconName='tri-bell'/>
<SelectOption id='id_four' value='disabled' label='disabled' disabled iconName='tri-bell' />
<SelectOption id='id_one' value='opt_one' label='Virgile' iconName='tri-bell' />
<SelectOption id='id_two' value='opt_two' label='Toto' iconName='tri-bell' />
<SelectOption id='id_three' value='Venus' label='Venus' iconName='tri-bell' />
</Select>
<Button onClick={() => setOption('Venus')} variant='PRIMARY'>
Set value 3
</Button>
<Spacer size={20}/>
<Spacer size={20} />

<Title level={TitleLevels.FOUR}>nullable</Title>
<Select
nullable
name='option'
label='label'
id='id'
iconName={IconName.ALERT}
selected={optionNullable}
onChange={(e) => {
setOptionNullable(e.selectValue)
}}
>
<SelectOption id='id_one' value='opt_one' label='Virgile'/>
<SelectOption id='id_four' value='disabled' label='disabled' disabled/>
<SelectOption id='id_two' value='opt_two' label='Toto'/>
<SelectOption id='id_three' value='Venus' label='Venus'/>
<SelectOption id='id_one' value='opt_one' label='Virgile' />
<SelectOption id='id_four' value='disabled' label='disabled' disabled />
<SelectOption id='id_two' value='opt_two' label='Toto' />
<SelectOption id='id_three' value='Venus' label='Venus' />
</Select>
<Button onClick={() => setOptionNullable(undefined)} variant='PRIMARY'>
Set Null
</Button>
<Button onClick={() => setOptionNullable('opt_one')} variant='PRIMARY'>
Set One
</Button>
<Spacer size={20}/>
<Spacer size={20} />

<Title level={TitleLevels.TWO}>Multiple options</Title>
<Spacer size={20}/>
<Spacer size={20} />
<Title level={TitleLevels.FOUR}>Not nullable</Title>
<Select
multiple
name='option'
label='label'
id='id'
iconName={IconName.ALERT}
selected={options}
onChange={(e) => {
e?.selectedOptions && setOptions(e.selectedOptions)
}}
>
<SelectOption id='id_one' value='opt_one' label='Virgile'/>
<SelectOption id='id_two' value='opt_two' label='Toto'/>
<SelectOption id='id_four' value='disabled' label='disabled' disabled/>
<SelectOption id='id_three' value='Venus' label='Venus'/>
<SelectOption id='id_one' value='opt_one' label='Virgile' />
<SelectOption id='id_two' value='opt_two' label='Toto' />
<SelectOption id='id_four' value='disabled' label='disabled' disabled />
<SelectOption id='id_three' value='Venus' label='Venus' />
</Select>
<Button onClick={() => setOptions((prev) => [...prev, 'Venus'])} variant='PRIMARY'>
Set Venus
</Button>

<Spacer size={20}/>
<Spacer size={20} />
<Title level={TitleLevels.FOUR}>nullable</Title>
<Select
nullable
Expand All @@ -100,10 +98,10 @@ export const SelectView = (): JSX.Element => {
e?.selectedOptions && setOptionsNullable(e.selectedOptions)
}}
>
<SelectOption id='id_one' value='opt_one' label='Virgile'/>
<SelectOption id='id_two' value='opt_two' label='Toto'/>
<SelectOption id='id_three' value='Venus' label='Venus'/>
<SelectOption id='id_four' value='disabled' label='disabled' disabled/>
<SelectOption id='id_one' value='opt_one' label='Virgile' />
<SelectOption id='id_two' value='opt_two' label='Toto' />
<SelectOption id='id_three' value='Venus' label='Venus' />
<SelectOption id='id_four' value='disabled' label='disabled' disabled />
</Select>
<Button onClick={() => setOptionsNullable([])} variant='PRIMARY'>
Set Null
Expand All @@ -115,47 +113,42 @@ export const SelectView = (): JSX.Element => {

<Section>
<Title>Native select {'(web)'}</Title>
<Divider/>
<Spacer size={20}/>
<Title level={TitleLevels.TWO}>Unique option</Title>
<Spacer size={20}/>
<Title level={TitleLevels.FOUR}>Not nullable</Title>
<Divider />
<Spacer size={20} />
<Title level={TitleLevels.FOUR}>Not icon</Title>
<Select
native
name='option'
label='label'
id='select-native-id'
iconName={IconName.ALERT}
selected={option}
onChange={(e) => {
e?.selectValue && setOption(e.selectValue)
}}
>
<SelectOption id='id_one' value='opt_one' label='Virgile'/>
<SelectOption id='id_two' value='opt_two' label='Toto'/>
<SelectOption id='id_three' value='Venus' label='Venus'/>
<SelectOption id='id_four' value='disabled' label='disabled' disabled/>
<SelectOption id='id_one' value='opt_one' label='Virgile' />
<SelectOption id='id_two' value='opt_two' label='Toto' />
<SelectOption id='id_three' value='Venus' label='Venus' />
<SelectOption id='id_four' value='disabled' label='disabled' disabled />
</Select>
<Spacer size={20}/>
<Title level={TitleLevels.TWO}>multiple option</Title>
<Spacer size={20}/>
<Title level={TitleLevels.FOUR}>Not nullable</Title>

<Title level={TitleLevels.FOUR}>With icon</Title>
<Select
multiple
iconName='tri-alert'
native
name='option'
id='id'
selected={options}
label='label'
id='select-native-id'
selected={option}
onChange={(e) => {
e?.selectedOptions && setOptions(e.selectedOptions)
e?.selectValue && setOption(e.selectValue)
}}
>
<SelectOption id='id_one' value='opt_one' label='Virgile'/>
<SelectOption id='id_two' value='opt_two' label='Toto'/>
<SelectOption id='id_three' value='Venus' label='Venus'/>
<SelectOption id='id_four' value='disabled' label='disabled' disabled/>
<SelectOption id='id_one' value='opt_one' label='Virgile' />
<SelectOption id='id_two' value='opt_two' label='Toto' />
<SelectOption id='id_three' value='Venus' label='Venus' />
<SelectOption id='id_four' value='disabled' label='disabled' disabled />
</Select>
<Spacer size={20}/>
</Section>
</>
)
Expand Down
2 changes: 1 addition & 1 deletion packages/react/components/select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { SelectDynamic, SelectNative } from './web'
* @param selected {string|number} Selected OptionItem for Native
* @param iconName {IconName} icon for left of selector
* @param disabled {boolean} disable Select
* @param multiple {boolean} select multiple options
* @param multiple {boolean} select multiple options (for dynamic select only)
* @param nullable {boolean} Unselect Select Option Item
* - -------------------------- WEB PROPERTIES -------------------------------
* @param className {string} Additionnal CSS Classes
Expand Down
7 changes: 3 additions & 4 deletions packages/react/components/select/web/SelectDynamic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ const SelectDynamic = ({

const isChecked = useCallback(
(value: string) =>
(multiple && selectedValues && typeof selectedValues !== 'string' && typeof selectedValues !== 'number'
multiple && selectedValues && typeof selectedValues !== 'string' && typeof selectedValues !== 'number'
? selectedValues?.includes(value)
: selectedValues === value),
: selectedValues === value,
[multiple, selectedValues],
)

Expand Down Expand Up @@ -89,7 +89,6 @@ const SelectDynamic = ({
selectedOptions.push(...opts)
return opts
}
setIsFocused(false)
selectedOptions.push(value)
return value
})
Expand Down Expand Up @@ -210,6 +209,7 @@ const SelectDynamic = ({
selectedOptions: opts,
})
if (child.props.onClick) child.props.onClick()
if (!multiple) setIsFocused(false)
},
}
return <SelectOption {...props} key={`${reactId}_${index}`} />
Expand All @@ -226,7 +226,6 @@ const SelectDynamic = ({
placeholder={label}
onFocus={onFocus}
customIconLeft={iconName}
customIconRight={focused ? 'tri-arrow-up' : 'tri-arrow-down'}
onBlur={onBlur}
onClick={onClickInput}
className={hashClass(styled, clsx(focused && 'focus'))}
Expand Down
119 changes: 50 additions & 69 deletions packages/react/components/select/web/SelectNative.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import clsx from 'clsx'
import * as React from 'react'

import { hashClass } from '@/helpers/hashClassesHelpers'
import { has, is } from '@/services/classify'
import { Icon, IconSize } from '@/components/icon'
import { ParamEventSelectFocus, SelectProps } from '@/components/select/SelectProps'
import { Icon } from '@/components/icon'
import { SelectOption } from '@/components/select'
import { ParamEventSelectFocus, SelectProps } from '@/components/select/SelectProps'
import { useTrilogyContext } from '@/context/index'
import { hashClass } from '@/helpers/hashClassesHelpers'
import { has } from '@/services/classify'

const SelectNative = ({
onChange,
Expand All @@ -26,26 +26,15 @@ const SelectNative = ({
...others
}: SelectProps): JSX.Element => {
const { styled } = useTrilogyContext()
const selectClasses = React.useMemo(() => hashClass(styled, clsx('select', className)), [styled, className, iconName])

const [focused, setIsFocused] = React.useState<boolean>(false)
const [selectedValues, setSelectedValues] = React.useState(selected)

React.useEffect(() => {
setSelectedValues(selected)
}, [selected])
const selectClasses = React.useMemo(() => hashClass(styled, clsx('select', className)), [styled, className])

const classes = React.useMemo(
() => ({
input: hashClass(
styled,
clsx('input', disabled && is('disabled'), 'select-native', multiple && 'multiple', className),
),
control: hashClass(
styled,
clsx('control', has('dynamic-placeholder'), iconName && 'has-icons-left', iconName && 'has-icons-right'),
),
}),
[styled, disabled, iconName, className, multiple],
const controlClass = React.useMemo(
() => hashClass(styled, clsx('control', has('dynamic-placeholder'), iconName && 'has-icons-left')),
[styled, iconName],
)

const handleFocus = React.useCallback((e: ParamEventSelectFocus) => {
Expand All @@ -58,59 +47,51 @@ const SelectNative = ({
onBlur && onBlur(e)
}, [])

React.useEffect(() => {
setSelectedValues(selected)
}, [selected])

return (
<div className={selectClasses}>
<div className={hashClass(styled, clsx('field', focused && 'focus'))}>
<div className={classes.control}>
<div className={classes.input}>
<select
multiple={multiple}
className={hashClass(styled, clsx(!label && 'no-label'))}
value={selectedValues}
aria-label={accessibilityLabel}
data-testid={testId}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
const selectedV = Array.from(e.target.selectedOptions).map((select) => select.value)
setSelectedValues(selectedV)
if (onChange) {
onChange({
selectValue: e.target.value,
selectName: e.target.name,
selectId: e.target.id,
name: e.target.name,
selectedOptions: selectedV,
})
}
}}
onFocus={handleFocus}
onBlur={handleBlur}
id={id ? String(id) : undefined}
name={name}
disabled={disabled}
{...others}
role='listbox'
>
{React.Children.map(children, (child) => {
if (!React.isValidElement(child)) return null
const props = {
...child.props,
native: 'true',
}
return <SelectOption {...props} />
})}
</select>
</div>
<div className={controlClass}>
<select
className={hashClass(styled, clsx(!label && 'no-label'))}
value={selectedValues}
aria-label={accessibilityLabel}
data-testid={testId}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
const selectedV = Array.from(e.target.selectedOptions).map((select) => select.value)
setSelectedValues(selectedV)
if (onChange) {
onChange({
selectValue: e.target.value,
selectName: e.target.name,
selectId: e.target.id,
name: e.target.name,
selectedOptions: selectedV,
})
}
}}
onFocus={handleFocus}
onBlur={handleBlur}
id={id ? String(id) : undefined}
name={name}
disabled={disabled}
role='listbox'
{...others}
>
{React.Children.map(children, (child) => {
if (!React.isValidElement(child)) return null
const props = {
...child.props,
native: 'true',
}
return <SelectOption {...props} />
})}
</select>
{label && !multiple && <label htmlFor={id}>{label}</label>}
{iconName && (
<div>
<Icon name={iconName} size='small' />
</div>
)}
{!multiple && (
<div>
<Icon className='icon-right' name={focused ? 'tri-arrow-up' : 'tri-arrow-down'} size={IconSize.SMALL} />
</div>
)}
{iconName && <Icon name={iconName} size='small' />}
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 3b1e4e5

Please sign in to comment.