Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Select)!: introduce 2.0 component #1899

Merged
merged 1 commit into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/components/InputField/InputField-v2.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
\*------------------------------------*/

/**
* Wraps the Label and the optional/required indicator.
* Wraps the Label and the optional/required hint.
* TODO-AH: map the overline styles between Select and InputField
*/
.input-field__overline {
display: flex;
Expand Down
41 changes: 19 additions & 22 deletions src/components/InputLabel/InputLabel-v2.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import clsx from 'clsx';
import React from 'react';
import type { ReactNode } from 'react';
import React, { type ReactNode } from 'react';
import type { Size } from '../../util/variant-types';
import styles from './InputLabel-v2.module.css';

export type InputLabelProps = {
// Component API
/**
* Text to render in label.
*/
Expand All @@ -17,6 +17,7 @@ export type InputLabelProps = {
* ID of input that label is associated with.
*/
htmlFor: string;
// Design API
/**
* Size of the label.
*
Expand All @@ -34,25 +35,21 @@ export type InputLabelProps = {
*
* Label associated with an input element such as a radio or checkbox.
*/
export const InputLabel = ({
children,
className,
htmlFor,
size = 'lg',
disabled,
}: InputLabelProps) => {
const componentClassName = clsx(
styles['label'],
size === 'md' && styles['label--md'],
size === 'lg' && styles['label--lg'],
disabled && styles['label--disabled'],
className,
);
return (
<label className={componentClassName} htmlFor={htmlFor}>
{children}
</label>
);
};
export const InputLabel = React.forwardRef<HTMLLabelElement, InputLabelProps>(
({ children, className, htmlFor, size = 'lg', disabled }, ref) => {
const componentClassName = clsx(
styles['label'],
size === 'md' && styles['label--md'],
size === 'lg' && styles['label--lg'],
disabled && styles['label--disabled'],
className,
);
return (
<label className={componentClassName} htmlFor={htmlFor} ref={ref}>
{children}
</label>
);
},
);

InputLabel.displayName = 'InputLabel';
4 changes: 2 additions & 2 deletions src/components/PopoverListItem/PopoverListItem-v2.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@
}

.popover-list-item__icon {
padding-right: 1rem;
padding-right: 0.5rem;
}

.popover-list-item__no-icon {
/* right padding applies space for the icon itself and the padding for that icon container */
padding-right: 2rem;
padding-right: 1.5rem;
}

.popover-list-item__sub-label {
Expand Down
155 changes: 155 additions & 0 deletions src/components/Select/Select-v2.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
@import '../../design-tokens/mixins.css';

/*------------------------------------*\
# SELECT
\*------------------------------------*/

/**
* Select field used to select one option from a list of options.
*/
.select {
position: relative;
}

/**
* Wraps the Label and the optional/required hint.
* TODO-AH: map the overline styles between Select and InputField
*/
.select__overline {
display: flex;
margin-bottom: 0.25rem;
gap: 0.25rem;
}

.select__overline--no-label {
justify-content: flex-start;
}

/**
* The container for the individual select options.
*/
.select__options {
max-height: 25vh;
z-index: 100;
}

/**
* The button to trigger the display of the select field.
*/
.select-button {
font: var(--eds-theme-typography-form-input);

width: 100%;
padding: 0.5rem;

border: var(--eds-border-width-sm) solid;
border-radius: calc(var(--eds-theme-border-radius-objects-sm) * 1px);

display: flex;
justify-content: space-between;
align-items: center;
gap: 0.5rem;

cursor: pointer;

/* TODO-AH: handle placeholder color when no value is selected */
color: var(--eds-theme-color-text-utility-default-primary);
background-color: var(--eds-theme-color-form-background);
}

/**
* The caret icon to decorate the select trigger button, animated to rotate.
*/
.select-button__icon {
flex-shrink: 0;
transform: rotate(0);

transition: transform var(--eds-anim-move-medium) ease-out;

@media (prefers-reduced-motion) {
transition: none;
}
}

.select-button__text--truncated {
/* TODO-AH: use as mixin */
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}

.select-button__icon--reversed {
transform: rotate(180deg);
}

.select__footer {
display: flex;
justify-content: space-between;
}

.select--has-fieldNote {
margin-bottom: 0.25rem;
}

/**
* Label on top of the select trigger button to label the select field.
*/
.select__label {
font: var(--eds-theme-typography-form-label);
color: var(--eds-theme-color-text-utility-default-primary);
}

.select__label--disabled {
color: var(--eds-theme-color-text-utility-disabled-primary);
}

.select__option {
color: var(--eds-theme-color-text-utility-interactive-secondary);
}

.select__option-text {
color: var(--eds-theme-color-text-utility-default-primary);
}

.select__required-text {
color: var(--eds-theme-color-text-utility-default-secondary);
}

.select-button:disabled {
cursor: not-allowed;

color: var(--eds-theme-color-text-utility-disabled-primary);
border-color: var(--eds-theme-color-border-utility-disabled);
background-color: var(--eds-theme-color-background-utility-disabled-low-emphasis);
}

.select-button:focus-visible {
border-color: var(--eds-theme-color-border-utility-focus);
outline: var(--eds-border-width-sm) solid var(--eds-theme-color-border-utility-focus);
}

.select-button--error {
border-color: var(--eds-theme-color-border-utility-critical);

&:hover {
border-color: var(--eds-theme-color-border-utility-critical-hover);
}

&:focus-visible {
border-color: var(--eds-theme-color-border-utility-critical);
outline: var(--eds-border-width-sm) solid var(--eds-theme-color-border-utility-critical);
}
}

.select-button--warning {
border-color: var(--eds-theme-color-border-utility-warning);

&:hover {
border-color: var(--eds-theme-color-border-utility-warning-hover);
}

&:focus-visible {
border-color: var(--eds-theme-color-border-utility-warning);
outline: var(--eds-border-width-sm) solid var(--eds-theme-color-border-utility-warning);
}
}
Loading
Loading