🎨(react) enhance Input component styles

update Input 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:13:40 +02:00
committed by NathanVss
parent e002cfde0f
commit d7ae9fc9d1
5 changed files with 71 additions and 53 deletions

View File

@@ -8,29 +8,27 @@ export const InputPassword = (props: Omit<InputProps, "rightIcon">) => {
const { className, ...otherProps } = props; const { className, ...otherProps } = props;
const customClassName = "c__input--password"; const customClassName = "c__input--password";
const { t } = useCunningham(); const { t } = useCunningham();
return ( return (
<Input <Input
{...otherProps} {...otherProps}
className={className + " " + customClassName} className={`${className} ${customClassName}`}
type={showPassword ? "text" : "password"} type={showPassword ? "text" : "password"}
rightIcon={ rightIcon={
showPassword ? (
<Button <Button
onClick={() => setShowPassword(false)} onClick={() => setShowPassword(!showPassword)}
icon={<span className="material-icons">visibility_off</span>} icon={
color="tertiary-text" <span className="material-icons">
{showPassword ? "visibility_off" : "visibility"}
</span>
}
color="tertiary"
variant="neutral"
size="small" size="small"
aria-label={t("components.forms.input.password.hide_password")} aria-label={t(
`components.forms.input.password.${showPassword ? "hide" : "show"}_password`
)}
/> />
) : (
<Button
onClick={() => setShowPassword(true)}
icon={<span className="material-icons">visibility</span>}
color="tertiary-text"
size="small"
aria-label={t("components.forms.input.password.show_password")}
/>
)
} }
/> />
); );

View File

@@ -5,7 +5,11 @@
border-style: var(--c--components--forms-input--border-style); border-style: var(--c--components--forms-input--border-style);
background-color: var(--c--components--forms-input--background-color); background-color: var(--c--components--forms-input--background-color);
display: flex; 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 1rem; padding: 0 1rem;
gap: 1rem; gap: 1rem;
cursor: text; cursor: text;
@@ -25,7 +29,7 @@
flex-grow: 1; flex-grow: 1;
text-overflow: ellipsis; text-overflow: ellipsis;
background-color: transparent; background-color: transparent;
font-family: var(--c--theme--font--families--base); font-family: var(--c--globals--font--families--base);
@extend %text-style; @extend %text-style;
&__icon-left, &__icon-left,
@@ -34,12 +38,13 @@
align-items: center; align-items: center;
} }
&::-webkit-outer-spin-button, &::-webkit-inner-spin-button { &::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none; -webkit-appearance: none;
margin: 0; margin: 0;
} }
&[type=number] { &[type="number"] {
-moz-appearance: textfield; -moz-appearance: textfield;
} }
@@ -54,21 +59,28 @@
label { label {
position: absolute; position: absolute;
font-size: var(--c--theme--font--sizes--s); font-size: var(--c--globals--font--sizes--s);
left: 0; left: 0;
top: 0.75rem; top: 0.75rem;
transition: all var(--c--theme--transitions--duration) var(--c--theme--transitions--ease-out); transition: all var(--c--globals--transitions--duration)
color: var(--c--theme--colors--greyscale-600); var(--c--globals--transitions--ease-out);
color: var(--c--components--forms-input--label-color);
&.placeholder { &.placeholder {
color: var(--c--components--forms-input--placeholder-color) !important;
@extend %text-style; @extend %text-style;
top: 18px; top: 18px;
} }
} }
&:hover { &:hover {
&:not(.c__input__wrapper--disabled) {
border-radius: var(--c--components--forms-input--border-radius--hover); border-radius: var(--c--components--forms-input--border-radius--hover);
border-color: var(--c--components--forms-input--border-color--hover); border-color: var(--c--components--forms-input--border-color--hover);
box-shadow: 0 0 0 1px
var(--c--components--forms-input--border-color--hover);
}
} }
/** Modifiers. */ /** Modifiers. */
@@ -78,8 +90,11 @@
} }
&:focus-within { &:focus-within {
box-shadow: 0 0 0 1px var(--c--components--forms-input--border-color--focus) !important;
border-radius: var(--c--components--forms-input--border-radius--focus); border-radius: var(--c--components--forms-input--border-radius--focus);
border-color: var(--c--components--forms-input--border-color--focus) !important; border-color: var(
--c--components--forms-input--border-color--focus
) !important;
label { label {
color: var(--c--components--forms-input--label-color--focus); color: var(--c--components--forms-input--label-color--focus);
@@ -88,46 +103,47 @@
&--disabled { &--disabled {
cursor: default; cursor: default;
border-color: var(--c--theme--colors--greyscale-200); border-color: var(--c--contextuals--border--semantic--neutral--tertiary);
.c__input { .c__input {
color: var(--c--components--forms-input--value-color--disabled); color: var(--c--components--forms-input--value-color--disabled);
} }
&:hover { &:hover {
border-color: var(--c--theme--colors--greyscale-200); border-color: var(--c--contextuals--border--semantic--neutral--tertiary);
} }
} }
&--success { &--success {
border-color: var(--c--theme--colors--success-600); border-color: var(--c--contextuals--border--semantic--success--primary);
.labelled-box label { .labelled-box label {
color: var(--c--theme--colors--success-600); color: var(--c--contextuals--border--semantic--success--primary);
} }
&:not(.c__input__wrapper--disabled) { &:not(.c__input__wrapper--disabled) {
&:hover { &:hover {
border-color: var(--c--theme--colors--success-800); border-color: var(--c--contextuals--border--semantic--success--primary);
color: var(--c--theme--colors--success-800); color: var(--c--contextuals--content--semantic--success--primary);
.labelled-box label { .labelled-box label {
color: var(--c--theme--colors--success-800); color: var(--c--contextuals--content--semantic--success--primary);
} }
} }
} }
} }
&--error { &--error {
border-color: var(--c--theme--colors--danger-600); border-color: var(--c--contextuals--border--semantic--error--secondary);
&:not(.c__input__wrapper--disabled) { &:not(.c__input__wrapper--disabled) {
&:hover { &:hover {
border-color: var(--c--theme--colors--danger-800); // border-color: var(--c--contextuals--border--semantic--error--primary);
color: var(--c--theme--colors--danger-800); // color: var(--c--contextuals--content--semantic--error--primary);
// box-shadow: 0 0 0 1px var(--c--contextuals--border--semantic--error--primary);
label { label {
color: var(--c--theme--colors--danger-800); // color: var(--c--contextuals--content--semantic--error--primary);
} }
} }
} }
@@ -139,4 +155,3 @@
font-size: 1.5rem; font-size: 1.5rem;
} }
} }

View File

@@ -232,6 +232,7 @@ describe("<Input/>", () => {
text: "my text", text: "my text",
textItems: ["my text item 1", "my text item 2"], textItems: ["my text item 1", "my text item 2"],
rightText: "my right text", rightText: "my right text",
disabled: false,
}; };
render(<Input {...propsInput} />); render(<Input {...propsInput} />);

View File

@@ -163,7 +163,7 @@ export const Controlled = () => {
const [value, setValue] = React.useState("I am controlled"); const [value, setValue] = React.useState("I am controlled");
return ( return (
<div> <div>
<div className="clr-greyscale-900"> <div className="clr-gray-900">
Value: <span>{value}</span> Value: <span>{value}</span>
</div> </div>
<Input <Input
@@ -259,7 +259,7 @@ export const ReactHookForm = () => {
mode: "onChange", mode: "onChange",
reValidateMode: "onChange", reValidateMode: "onChange",
resolver: yupResolver(inputExampleSchema), resolver: yupResolver(inputExampleSchema),
}, }
); );
return ( return (

View File

@@ -1,18 +1,22 @@
import { DefaultTokens } from "@openfun/cunningham-tokens"; import { DefaultTokens } from "@openfun/cunningham-tokens";
export const tokens = (defaults: DefaultTokens) => ({ export const tokens = (defaults: DefaultTokens) => ({
"font-weight": defaults.theme.font.weights.regular, "font-weight": defaults.globals.font.weights.regular,
"font-size": defaults.theme.font.sizes.l, "font-size": defaults.globals.font.sizes.md,
"border-radius": "8px", "border-radius": "8px",
"border-radius--hover": "2px", "border-radius--hover": "4px",
"border-radius--focus": "2px", "border-radius--focus": "4px",
"border-width": "1px", "border-width": "1px",
"border-color": defaults.theme.colors["greyscale-300"], "border-width--hover": "1px",
"border-color--hover": defaults.theme.colors["greyscale-500"], "border-width--focus": "1px",
"border-color--focus": defaults.theme.colors["primary-600"], "border-color": defaults.contextuals.border.semantic.neutral.tertiary,
"border-color--hover": defaults.contextuals.border.semantic.neutral.tertiary,
"border-color--focus": defaults.contextuals.border.semantic.brand.primary,
"border-style": "solid", "border-style": "solid",
"label-color--focus": defaults.theme.colors["primary-600"], "placeholder-color": defaults.contextuals.content.semantic.neutral.tertiary,
"background-color": defaults.theme.colors["greyscale-000"], "label-color": defaults.contextuals.content.semantic.neutral.tertiary,
"value-color": defaults.theme.colors["greyscale-900"], "label-color--focus": defaults.contextuals.content.semantic.brand.primary,
"value-color--disabled": defaults.theme.colors["greyscale-800"], "background-color": defaults.contextuals.background.surface.secondary,
"value-color": defaults.contextuals.content.semantic.neutral.primary,
"value-color--disabled": defaults.contextuals.content.semantic.disabled.primary,
}); });