🎨(react) enhance Select component styles

update Select token and css files with new css variables introduce
with the new tokens architectures
This commit is contained in:
Nathan Panchout
2025-08-22 10:14:28 +02:00
committed by NathanVss
parent 2a65010ecd
commit 2123aedb72
7 changed files with 82 additions and 64 deletions

View File

@@ -1,4 +1,4 @@
@use 'src/utils' as *;
@use "src/utils" as *;
.c__select {
position: relative;
@@ -9,7 +9,11 @@
border-color: var(--c--components--forms-select--border-color);
border-style: var(--c--components--forms-select--border-style);
display: flex;
transition: border var(--c--theme--transitions--duration) var(--c--theme--transitions--ease-out), border-radius var(--c--theme--transitions--duration) var(--c--theme--transitions--ease-out);
transition:
border var(--c--globals--transitions--duration)
var(--c--globals--transitions--ease-out),
border-radius var(--c--globals--transitions--duration)
var(--c--globals--transitions--ease-out);
padding: 0 0.75rem;
gap: 1rem;
box-sizing: border-box;
@@ -30,7 +34,8 @@
border-color: var(--c--components--forms-select--border-color--hover);
}
&:focus-within, &--focus {
&:focus-within,
&--focus {
border-radius: var(--c--components--forms-select--border-radius--focus);
border-color: var(--c--components--forms-select--border-color--focus);
@@ -83,22 +88,23 @@
span {
font-size: 1.25rem;
transition: all var(--c--theme--transitions--duration) var(--c--theme--transitions--ease-out);
transition: all var(--c--globals--transitions--duration)
var(--c--globals--transitions--ease-out);
&.opened {
transform: rotate(180deg);
}
}
&__clear {
color: var(--c--theme--colors--greyscale-500);
color: var(--c--contextuals--content--semantic--neutral--secondary);
}
&__separator {
background-color: var(--c--theme--colors--greyscale-400);
background-color: var(--c--contextuals--content--semantic--neutral--tertiary);
height: 24px;
width: 1px;
}
&__open {
color: var(--c--theme--colors--greyscale-900);
color: var(--c--contextuals--content--semantic--neutral--primary);
}
}
}
@@ -140,11 +146,15 @@
cursor: pointer;
&--highlight {
background-color: var(--c--components--forms-select--item-background-color--hover);
background-color: var(
--c--components--forms-select--item-background-color--hover
);
}
&--selected {
background-color: var(--c--components--forms-select--item-background-color--selected);
background-color: var(
--c--components--forms-select--item-background-color--selected
);
}
&--disabled {
@@ -154,7 +164,7 @@
}
&__empty-placeholder {
color: var(--c--theme--colors--greyscale-600);
color: var(--c--contextuals--content--semantic--neutral--secondary);
font-style: italic;
}
@@ -179,62 +189,60 @@
/** Modifiers */
&--disabled {
.c__select__wrapper {
border-color: var(--c--theme--colors--greyscale-200);
border-color: var(--c--contextuals--border--semantic--neutral--tertiary);
cursor: default;
label, input {
label,
input {
cursor: default;
}
.c__select__inner__value {
color: var(--c--components--forms-select--value-color--disabled)
color: var(--c--components--forms-select--value-color--disabled);
}
}
&:hover {
border-color: var(--c--theme--colors--greyscale-200);
border-color: var(--c--contextuals--border--semantic--neutral--tertiary-hover);
}
}
&--error {
.c__select__wrapper {
border-color: var(--c--theme--colors--danger-600);
border-color: var(--c--contextuals--border--semantic--error--secondary);
label {
color: var(--c--theme--colors--danger-600);
color: var(--c--contextuals--content--semantic--error--secondary);
}
}
&:not(.c__select__wrapper--disabled) {
.c__select__wrapper:hover {
border-color: var(--c--theme--colors--danger-800);
border-color: var(--c--contextuals--border--semantic--error--primary);
label {
color: var(--c--theme--colors--danger-800);
color: var(--c--contextuals--content--semantic--error--primary);
}
}
}
}
&--success {
.c__select__wrapper {
border-color: var(--c--theme--colors--success-600);
border-color: var(--c--contextuals--border--semantic--success--secondary);
label {
color: var(--c--theme--colors-success-600);
color: var(--c--contextuals--content--semantic--success--secondary);
}
}
&:not(.c__select__wrapper--disabled) {
.c__select__wrapper:hover {
border-color: var(--c--theme--colors--success-800);
border-color: var(--c--contextuals--border--semantic--success--primary);
label {
color: var(--c--theme--colors--success-800);
color: var(--c--contextuals--content--semantic--success--primary);
}
}
}
@@ -288,14 +296,17 @@
}
.c__select__inner {
&__value {
gap: 0.25rem;
&__pill {
background-color: var(--c--components--forms-select--multi-pill-background-color);
background-color: var(
--c--components--forms-select--multi-pill-background-color
);
padding: 0.125rem 0.5rem;
border-radius: var(--c--components--forms-select--multi-pill-border-radius);
border-radius: var(
--c--components--forms-select--multi-pill-border-radius
);
display: inline-flex;
align-items: center;
gap: 0.25rem;
@@ -317,7 +328,7 @@
height: auto;
.material-icons {
font-size: 1.1250rem;
font-size: 1.125rem;
}
}
}
@@ -340,7 +351,7 @@
}
&::after {
content: attr(data-value) ' ';
content: attr(data-value) " ";
visibility: hidden;
white-space: pre-wrap;
}
@@ -348,7 +359,6 @@
}
}
/** Modifiers */
&.c__select--populated {

View File

@@ -101,7 +101,7 @@ export const SelectMonoAux = ({
"c__select--" + state,
{
"c__select--disabled": disabled,
},
}
)}
onBlur={() =>
onBlur?.({ target: { value: downshiftReturn.selectedItem?.value } })
@@ -138,10 +138,11 @@ export const SelectMonoAux = ({
{clearable && !disabled && downshiftReturn.selectedItem && (
<>
<Button
color="tertiary-text"
color="tertiary"
variant="neutral"
size="nano"
aria-label={t(
"components.forms.select.clear_button_aria_label",
"components.forms.select.clear_button_aria_label"
)}
className="c__select__inner__actions__clear"
onClick={(e) => {
@@ -156,7 +157,8 @@ export const SelectMonoAux = ({
)}
<Button
color="tertiary-text"
color="tertiary"
variant="neutral"
size="nano"
className="c__select__inner__actions__open"
icon={

View File

@@ -569,7 +569,7 @@ export const ReactHookForm = () => {
}}
onSubmit={methods.handleSubmit(onSubmit)}
>
<div className="clr-greyscale-900">
<div className="clr-gray-900">
Where will the 2024 Olympics take place?
</div>
<RhfSelect

View File

@@ -24,14 +24,14 @@ import { SelectMultiMenu } from ":/components/Forms/Select/multi-menu";
*/
export function getMultiOptionsFilter(
selectedOptions: Option[],
inputValue?: string,
inputValue?: string
) {
const optionsFilter = getOptionsFilter(inputValue);
return (option: Option) => {
return (
!selectedOptions.find(
(selectedOption) =>
optionToValue(selectedOption) === optionToValue(option),
optionToValue(selectedOption) === optionToValue(option)
) && optionsFilter(option)
);
};
@@ -83,7 +83,7 @@ export const SelectMultiAux = ({ children, ...props }: SelectMultiAuxProps) => {
"c__select--populated": props.selectedItems.length > 0,
"c__select--monoline": props.monoline,
"c__select--multiline": !props.monoline,
},
}
)}
>
<div
@@ -117,10 +117,11 @@ export const SelectMultiAux = ({ children, ...props }: SelectMultiAuxProps) => {
props.selectedItems.length > 0 && (
<>
<Button
color="tertiary-text"
color="tertiary"
variant="neutral"
size="nano"
aria-label={t(
"components.forms.select.clear_all_button_aria_label",
"components.forms.select.clear_all_button_aria_label"
)}
className="c__select__inner__actions__clear"
onClick={(e) => {
@@ -134,7 +135,8 @@ export const SelectMultiAux = ({ children, ...props }: SelectMultiAuxProps) => {
</>
)}
<Button
color="tertiary-text"
color="tertiary"
variant="neutral"
size="nano"
className="c__select__inner__actions__open"
icon={

View File

@@ -39,7 +39,8 @@ const SelectedItemsChips = ({
<SelectedOption option={selectedItemForRender} {...props} />
<Button
tabIndex={-1}
color="tertiary-text"
color="tertiary"
variant="neutral"
disabled={disabled}
size="small"
aria-label={t("components.forms.select.clear_button_aria_label")}
@@ -48,7 +49,7 @@ const SelectedItemsChips = ({
onClick={(e) => {
e.stopPropagation();
useMultipleSelectionReturn.removeSelectedItem(
selectedItemForRender,
selectedItemForRender
);
}}
icon={<span className="material-icons">close</span>}

View File

@@ -97,7 +97,7 @@ export const Controlled = () => {
const [value, setValue] = useState([OPTIONS[6].value, OPTIONS[8].value]);
return (
<div>
<div className="clr-greyscale-900">
<div className="clr-gray-900">
Value: <span>{JSON.stringify(value)}</span>
</div>
<Select
@@ -160,7 +160,7 @@ export const SearchableControlled = () => {
const [value, setValue] = useState([OPTIONS[6].value, OPTIONS[8].value]);
return (
<div>
<div className="clr-greyscale-900">
<div className="clr-gray-900">
Value: <span>{JSON.stringify(value)}</span>
</div>
<Select
@@ -509,7 +509,7 @@ export const ReactHookForm = () => {
.test({
test: (cityList) =>
cityList.every((city) =>
[CitiesOptionEnum.PARIS, CitiesOptionEnum.TOKYO].includes(city),
[CitiesOptionEnum.PARIS, CitiesOptionEnum.TOKYO].includes(city)
),
message: "Wrong answer!",
}),
@@ -535,7 +535,7 @@ export const ReactHookForm = () => {
}}
onSubmit={methods.handleSubmit(onSubmit)}
>
<div className="clr-greyscale-900">
<div className="clr-gray-900">
Which cities are capital of countries ?
</div>
<RhfSelect

View File

@@ -1,28 +1,31 @@
import { DefaultTokens } from "@openfun/cunningham-tokens";
export const tokens = (defaults: DefaultTokens) => ({
"border-color": defaults.theme.colors["greyscale-300"],
"border-color--focus": defaults.theme.colors["primary-600"],
"border-color--hover": defaults.theme.colors["greyscale-500"],
"border-color": defaults.contextuals.border.semantic.neutral.tertiary,
"border-color--focus": defaults.contextuals.border.semantic.brand.primary,
"border-color--hover": defaults.contextuals.border.semantic.neutral.secondary,
"border-radius": "8px",
"border-radius--focus": "2px",
"border-radius--hover": "2px",
"border-style": "solid",
"border-width": "1px",
"value-color": defaults.theme.colors["greyscale-900"],
"value-color--disabled": defaults.theme.colors["greyscale-800"],
"font-size": defaults.theme.font.sizes.l,
"value-color": defaults.contextuals.content.semantic.neutral.primary,
"value-color--disabled": defaults.contextuals.content.semantic.disabled.primary,
"font-size": defaults.globals.font.sizes.md,
height: "3.5rem",
"item-background-color--hover": defaults.theme.colors["greyscale-200"],
"item-background-color--selected": defaults.theme.colors["primary-100"],
"item-color": defaults.theme.colors["greyscale-800"],
"item-color--disabled": defaults.theme.colors["greyscale-500"],
"item-font-size": defaults.theme.font.sizes.l,
"background-color": defaults.theme.colors["greyscale-000"],
"menu-background-color": defaults.theme.colors["greyscale-000"],
"label-color--focus": defaults.theme.colors["primary-600"],
"multi-pill-background-color": defaults.theme.colors["greyscale-200"],
"item-background-color--hover":
defaults.contextuals.background.semantic.neutral["tertiary-hover"],
"item-background-color--selected":
defaults.contextuals.background.semantic.brand.secondary,
"item-color": defaults.contextuals.content.semantic.neutral.primary,
"item-color--disabled": defaults.contextuals.content.semantic.disabled.secondary,
"item-font-size": defaults.globals.font.sizes.md,
"background-color": defaults.contextuals.background.surface.primary,
"menu-background-color": defaults.contextuals.background.surface.primary,
"label-color--focus": defaults.contextuals.border.semantic.brand.primary,
"multi-pill-background-color":
defaults.contextuals.background.semantic.neutral.tertiary,
"multi-pill-border-radius": "2px",
"multi-pill-max-width": "68%",
"multi-pill-font-size": defaults.theme.font.sizes.m,
"multi-pill-font-size": defaults.globals.font.sizes.md,
});