Update select input component

This commit is contained in:
adilallo
2026-02-04 13:10:14 -07:00
parent 255f16477c
commit 0e7985287f
5 changed files with 285 additions and 410 deletions
+12 -75
View File
@@ -75,55 +75,11 @@ export default function ComponentsPreview() {
<div className="bg-[var(--color-surface-default-secondary)] rounded-[var(--radius-300,12px)] p-[var(--spacing-scale-032)] space-y-[var(--spacing-scale-024)]">
<div className="space-y-[var(--spacing-scale-016)]">
<div>
<h3 className="font-inter text-[20px] leading-[24px] font-semibold text-[var(--color-content-default-primary)] mb-[var(--spacing-scale-012)]">
All Sizes
</h3>
<div className="space-y-[var(--spacing-scale-016)]">
<SelectInput
label="Small Select Input"
placeholder="Choose an option"
size="small"
value={selectValue}
onChange={(data) => setSelectValue(data.target.value)}
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
<SelectInput
label="Medium Select Input"
placeholder="Choose an option"
size="medium"
value={selectValue}
onChange={(data) => setSelectValue(data.target.value)}
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
<SelectInput
label="Large Select Input"
placeholder="Choose an option"
size="large"
value={selectValue}
onChange={(data) => setSelectValue(data.target.value)}
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
</div>
</div>
<div>
<h3 className="font-inter text-[20px] leading-[24px] font-semibold text-[var(--color-content-default-primary)] mb-[var(--spacing-scale-012)]">
States
</h3>
<div className="space-y-[var(--spacing-scale-016)]">
<div className="space-y-[var(--spacing-scale-016)]">
<SelectInput
label="Default Select Input"
placeholder="Choose an option"
@@ -134,6 +90,17 @@ export default function ComponentsPreview() {
{ value: "option3", label: "Option 3" },
]}
/>
<SelectInput
label="Interactive Select Input (click = active)"
placeholder="Choose an option"
value={selectValue}
onChange={(data) => setSelectValue(data.target.value)}
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
<SelectInput
label="Disabled Select Input"
placeholder="Choose an option"
@@ -158,36 +125,6 @@ export default function ComponentsPreview() {
/>
</div>
</div>
<div>
<h3 className="font-inter text-[20px] leading-[24px] font-semibold text-[var(--color-content-default-primary)] mb-[var(--spacing-scale-012)]">
Label Variants
</h3>
<div className="space-y-[var(--spacing-scale-016)]">
<SelectInput
label="Default Label"
placeholder="Choose an option"
value=""
labelVariant="default"
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
<SelectInput
label="Horizontal Label"
placeholder="Choose an option"
value=""
labelVariant="horizontal"
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
</div>
</div>
</div>
</div>
</section>
@@ -22,12 +22,10 @@ const SelectInputContainer = forwardRef<HTMLButtonElement, SelectInputProps>(
{
id,
label,
labelVariant = "default",
size = "medium",
state = "default",
state: externalState = "default",
disabled = false,
error = false,
placeholder = "Select an option",
placeholder = "Choose an option",
className = "",
children,
value,
@@ -45,6 +43,14 @@ const SelectInputContainer = forwardRef<HTMLButtonElement, SelectInputProps>(
const selectRef = useRef<HTMLButtonElement>(null);
const menuRef = useRef<HTMLDivElement>(null);
// Internal state management: track if focused and how (mouse vs keyboard)
const [isFocused, setIsFocused] = useState(false);
const [focusMethod, setFocusMethod] = useState<"mouse" | "keyboard" | null>(null);
const wasMouseDownRef = useRef(false);
// Determine if we should auto-manage focus (only when state is "default" or undefined)
const shouldAutoManageFocus = externalState === "default" || externalState === undefined;
// Sync internal state with external value prop
useEffect(() => {
if (value !== undefined && value !== selectedValue) {
@@ -69,7 +75,6 @@ const SelectInputContainer = forwardRef<HTMLButtonElement, SelectInputProps>(
if (onChange) {
onChange({ target: { value: optionValue, text: optionText } });
}
// Return focus to the select button for accessibility
if (selectRef.current) {
selectRef.current.focus();
}
@@ -77,6 +82,13 @@ const SelectInputContainer = forwardRef<HTMLButtonElement, SelectInputProps>(
[onChange],
);
// Handle mouse down to detect mouse clicks
const handleMouseDown = useCallback(() => {
if (!disabled && shouldAutoManageFocus) {
wasMouseDownRef.current = true;
}
}, [disabled, shouldAutoManageFocus]);
// Handle select button click
const handleSelectClick = useCallback(() => {
if (!disabled) {
@@ -99,145 +111,47 @@ const SelectInputContainer = forwardRef<HTMLButtonElement, SelectInputProps>(
[disabled, isOpen],
);
const getSizeStyles = (): string => {
const baseStyles = "w-full";
// Handle focus to detect mouse vs keyboard
const handleFocus = useCallback(() => {
if (disabled) return;
switch (size) {
case "small": {
const smallHeight =
labelVariant === "horizontal" ? "h-[30px]" : "h-[32px]";
return `${baseStyles} ${smallHeight} pl-[12px] pr-[36px] py-[8px] text-[10px] leading-[14px]`;
}
case "medium":
return `${baseStyles} h-[36px] pl-[12px] pr-[36px] py-[8px] text-[14px] leading-[20px]`;
case "large":
return `${baseStyles} h-[40px] pl-[12px] pr-[40px] py-[8px] text-[16px] leading-[24px]`;
default:
return `${baseStyles} h-[36px] pl-[12px] pr-[36px] py-[8px] text-[14px] leading-[20px]`;
const method = wasMouseDownRef.current ? "mouse" : "keyboard";
if (shouldAutoManageFocus) {
setIsFocused(true);
setFocusMethod(method);
wasMouseDownRef.current = false;
}
};
}, [disabled, shouldAutoManageFocus]);
const getLabelSizeStyles = (): string => {
switch (size) {
case "small":
return "text-[12px] leading-[14px]";
case "medium":
return "text-[14px] leading-[16px]";
case "large":
return "text-[16px] leading-[20px]";
default:
return "text-[14px] leading-[16px]";
// Handle blur
const handleBlur = useCallback(() => {
if (shouldAutoManageFocus) {
setIsFocused(false);
setFocusMethod(null);
wasMouseDownRef.current = false;
}
};
}, [shouldAutoManageFocus]);
const getStateStyles = (): {
select: string;
label: string;
} => {
if (disabled) {
return {
select:
"bg-[var(--color-content-default-secondary)] border-[var(--color-border-default-tertiary)] cursor-not-allowed opacity-40",
label: "text-[var(--color-content-default-secondary)]",
};
}
// Determine actual state:
// - Active: when clicked (mouse focus) or when dropdown is open
// - Focus: when tabbed (keyboard focus)
// - Default: when not focused
const actualState = shouldAutoManageFocus
? isOpen || isFocused
? focusMethod === "mouse" || isOpen
? "active"
: "focus"
: "default"
: externalState;
if (error) {
return {
select: "border-[var(--color-border-default-utility-negative)]",
label: "text-[var(--color-content-default-secondary)]",
};
}
switch (state) {
case "hover":
return {
select:
"border-[var(--color-border-default-tertiary)] shadow-[0_0_0_2px_var(--color-border-default-tertiary)]",
label: "text-[var(--color-content-default-secondary)]",
};
case "focus":
return {
select:
"border-[var(--color-border-default-utility-info)] shadow-[0_0_5px_3px_#3281F8]",
label: "text-[var(--color-content-default-secondary)]",
};
default:
return {
select: "border-[var(--color-border-default-tertiary)]",
label: "text-[var(--color-content-default-secondary)]",
};
}
};
const getBorderRadius = (): string => {
switch (size) {
case "small":
return "rounded-[var(--measures-radius-small)]";
case "medium":
return "rounded-[var(--measures-radius-medium)]";
case "large":
return "rounded-[var(--measures-radius-large)]";
default:
return "rounded-[var(--measures-radius-medium)]";
}
};
const sizeStyles = getSizeStyles();
const labelSizeStyles = getLabelSizeStyles();
const stateStyles = getStateStyles();
const borderRadius = getBorderRadius();
const selectClasses = `
${sizeStyles}
${stateStyles.select}
${borderRadius}
bg-[var(--color-background-default-primary)]
text-[var(--color-content-default-primary)]
border
font-inter
font-normal
appearance-none
cursor-pointer
transition-all
duration-200
focus:outline-none
focus-visible:border focus-visible:border-[var(--color-border-default-utility-info)] focus-visible:shadow-[0_0_5px_3px_#3281F8]
text-left
justify-start
hover:shadow-[0_0_0_2px_var(--color-border-default-tertiary)]
${className}
`
.trim()
.replace(/\s+/g, " ");
const labelClasses = `
${labelSizeStyles}
${stateStyles.label}
font-inter
font-medium
block
mb-[4px]
`
.trim()
.replace(/\s+/g, " ");
const containerClasses =
labelVariant === "horizontal"
? "flex items-center gap-[12px]"
: "flex flex-col";
const chevronClasses = `${
size === "large" ? "w-5 h-5" : "w-4 h-4"
} text-[var(--color-content-default-primary)] transition-transform duration-200 ${
isOpen ? "rotate-180" : ""
}`;
// Determine if select is filled (has selected value)
const isFilled = Boolean(selectedValue && selectedValue.trim().length > 0);
// Get display text for selected value
const getDisplayText = (): string => {
if (!selectedValue) return placeholder;
// Handle options prop
if (options && Array.isArray(options)) {
const selectedOption = options.find(
(option) => option.value === selectedValue,
@@ -245,7 +159,6 @@ const SelectInputContainer = forwardRef<HTMLButtonElement, SelectInputProps>(
return selectedOption ? selectedOption.label : placeholder;
}
// Handle children (option elements)
const selectedOption = Children.toArray(children).find(
(
child,
@@ -270,11 +183,9 @@ const SelectInputContainer = forwardRef<HTMLButtonElement, SelectInputProps>(
<SelectInputView
label={label}
placeholder={placeholder}
size={size}
state={state}
state={actualState}
disabled={disabled}
error={error}
labelVariant={labelVariant}
className={className}
options={options}
selectId={selectId}
@@ -282,12 +193,12 @@ const SelectInputContainer = forwardRef<HTMLButtonElement, SelectInputProps>(
isOpen={isOpen}
selectedValue={selectedValue}
displayText={getDisplayText()}
selectClasses={selectClasses}
labelClasses={labelClasses}
containerClasses={containerClasses}
chevronClasses={chevronClasses}
isFilled={isFilled}
onButtonClick={handleSelectClick}
onButtonKeyDown={handleKeyDown}
onButtonMouseDown={handleMouseDown}
onButtonFocus={handleFocus}
onButtonBlur={handleBlur}
onOptionClick={handleOptionSelect}
selectRef={selectRef}
menuRef={menuRef}
+123 -41
View File
@@ -1,4 +1,5 @@
import React, { Children, type ReactNode } from "react";
import { getAssetPath, ASSETS } from "../../../lib/assetUtils";
import SelectDropdown from "../SelectDropdown";
import SelectOption from "../SelectOption";
import type { SelectOptionData } from "./SelectInput.types";
@@ -6,11 +7,9 @@ import type { SelectOptionData } from "./SelectInput.types";
export interface SelectInputViewProps {
label?: string;
placeholder: string;
size: "small" | "medium" | "large";
state: "default" | "hover" | "focus";
state: "default" | "active" | "hover" | "focus";
disabled: boolean;
error: boolean;
labelVariant: "default" | "horizontal";
className: string;
options?: SelectOptionData[];
children?: ReactNode;
@@ -20,13 +19,13 @@ export interface SelectInputViewProps {
isOpen: boolean;
selectedValue: string;
displayText: string;
selectClasses: string;
labelClasses: string;
containerClasses: string;
chevronClasses: string;
isFilled: boolean;
// Callbacks
onButtonClick: () => void;
onButtonKeyDown: (_e: React.KeyboardEvent<HTMLButtonElement>) => void;
onButtonMouseDown?: () => void;
onButtonFocus?: () => void;
onButtonBlur?: () => void;
onOptionClick: (_value: string, _text: string) => void;
// Refs
selectRef: React.RefObject<HTMLButtonElement>;
@@ -39,10 +38,9 @@ export interface SelectInputViewProps {
export function SelectInputView({
label,
placeholder: _placeholder,
size,
state,
disabled,
error: _error,
labelVariant: _labelVariant,
error,
options,
children,
selectId,
@@ -50,12 +48,12 @@ export function SelectInputView({
isOpen,
selectedValue,
displayText,
selectClasses,
labelClasses,
containerClasses,
chevronClasses,
isFilled,
onButtonClick,
onButtonKeyDown,
onButtonMouseDown,
onButtonFocus,
onButtonBlur,
onOptionClick,
selectRef,
menuRef,
@@ -63,48 +61,132 @@ export function SelectInputView({
ariaInvalid,
...props
}: SelectInputViewProps) {
// Styles based on Figma design
const containerClasses = "flex flex-col gap-[8px]";
const labelClasses = "text-[14px] leading-[20px] font-medium font-inter text-[var(--color-content-default-primary)]";
// Button styles per Figma
const getButtonClasses = (): string => {
const baseClasses = `
w-full
h-[40px]
px-[12px]
py-[8px]
text-[16px]
font-medium
leading-[20px]
rounded-[8px]
border
border-solid
flex
items-center
justify-between
gap-[12px]
transition-all
duration-200
focus:outline-none
focus:ring-0
cursor-pointer
appearance-none
m-0
`.trim().replace(/\s+/g, " ");
if (disabled) {
return `${baseClasses} bg-[var(--color-surface-default-secondary)] text-[var(--color-content-inverse-tertiary,#2d2d2d)] border-[var(--color-border-default-primary)] cursor-not-allowed opacity-40`;
}
if (error) {
return `${baseClasses} bg-[var(--color-surface-default-primary)] text-[var(--color-content-default-primary)] border-2 border-[var(--color-border-default-utility-negative)]`;
}
if (state === "focus") {
// Focus state: secondary background, tertiary border, with focus ring
return `${baseClasses} bg-[var(--color-surface-default-secondary)] text-[var(--color-content-default-primary)] border border-solid border-[var(--color-border-default-tertiary)]`;
}
if (state === "active" || isOpen) {
// Active state per Figma: secondary background, tertiary border
return `${baseClasses} bg-[var(--color-surface-default-secondary)] text-[var(--color-content-default-primary)] border-[var(--color-border-default-tertiary)]`;
}
// Default state per Figma: secondary background, primary border (subtle)
return `${baseClasses} bg-[var(--color-surface-default-secondary)] text-[var(--color-content-default-primary)] border-[var(--color-border-default-primary)]`;
};
const buttonClasses = getButtonClasses();
// Text color based on filled state
const textColorClass = isFilled
? "text-[var(--color-content-default-primary)]"
: "text-[var(--color-content-default-tertiary,#b4b4b4)]";
// Chevron icon
const chevronClasses = `w-5 h-5 text-[var(--color-content-default-primary)] transition-transform duration-200 ${
isOpen ? "rotate-180" : ""
}`;
return (
<div className={containerClasses}>
{label && (
<label
id={labelId}
htmlFor={selectId}
className={`${labelClasses} text-[var(--color-content-default-secondary)]`}
>
{label}
</label>
<div className="flex flex-wrap gap-[var(--measures-spacing-200,4px_8px)] items-baseline pr-[var(--measures-spacing-100,4px)] relative shrink-0 w-full">
<div className="flex gap-[var(--measures-spacing-050,2px)] items-center relative shrink-0">
<label
id={labelId}
className={labelClasses}
>
{label}
</label>
<div className="relative shrink-0 size-[12px]">
<img
src={getAssetPath(ASSETS.ICON_HELP)}
alt="Help"
className="block max-w-none size-full"
/>
</div>
</div>
</div>
)}
<div className="relative">
<button
ref={selectRef}
id={selectId}
disabled={disabled}
className={selectClasses}
className={buttonClasses}
aria-labelledby={ariaLabelledby}
aria-invalid={ariaInvalid}
aria-expanded={isOpen}
aria-haspopup="listbox"
onClick={onButtonClick}
onKeyDown={onButtonKeyDown}
{...props}
onMouseDown={onButtonMouseDown}
onFocus={onButtonFocus}
onBlur={onButtonBlur}
>
<span className="text-left">{displayText}</span>
<span className={`flex-1 text-left pr-[32px] ${textColorClass}`}>
{displayText}
</span>
<div className="flex items-center justify-center shrink-0">
<svg
className={chevronClasses}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M19 9l-7 7-7-7"
/>
</svg>
</div>
</button>
<div className="absolute inset-y-0 right-0 flex items-center pr-[12px] pointer-events-none">
<svg
className={chevronClasses}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M19 9l-7 7-7-7"
/>
</svg>
</div>
{state === "focus" && (
<div
className="absolute border-2 border-solid border-[var(--color-border-inverse-primary)] inset-0 rounded-[8px] shadow-[0px_0px_0px_2px_var(--color-border-default-primary)] pointer-events-none z-10"
aria-hidden="true"
/>
)}
{isOpen && (
<div
@@ -117,7 +199,7 @@ export function SelectInputView({
<SelectOption
key={option.value}
selected={option.value === selectedValue}
size={size}
size="medium"
onClick={() => onOptionClick(option.value, option.label)}
>
{option.label}
@@ -136,7 +218,7 @@ export function SelectInputView({
<SelectOption
key={optionProps.value}
selected={optionProps.value === selectedValue}
size={size}
size="medium"
onClick={() =>
onOptionClick(
optionProps.value,
+97 -150
View File
@@ -4,18 +4,13 @@ import SelectInput from "../app/components/SelectInput";
export default {
title: "Forms/SelectInput",
component: SelectInput,
parameters: {
layout: "centered",
},
argTypes: {
size: {
control: { type: "select" },
options: ["small", "medium", "large"],
},
labelVariant: {
control: { type: "select" },
options: ["default", "horizontal"],
},
state: {
control: { type: "select" },
options: ["default", "hover", "focus", "error", "disabled"],
options: ["default", "active", "focus"],
},
disabled: {
control: { type: "boolean" },
@@ -48,178 +43,130 @@ const Template = (args) => {
);
};
// Default story
export const Default = Template.bind({});
Default.args = {
label: "Default Select Input",
placeholder: "Select",
};
export const Small = Template.bind({});
Small.args = {
label: "Small Select Input",
size: "small",
placeholder: "Select",
};
export const Medium = Template.bind({});
Medium.args = {
label: "Medium Select Input",
size: "medium",
placeholder: "Select",
};
export const Large = Template.bind({});
Large.args = {
label: "Large Select Input",
size: "large",
placeholder: "Select",
};
export const DefaultLabel = Template.bind({});
DefaultLabel.args = {
label: "Default (Top Label)",
labelVariant: "default",
placeholder: "Select",
};
export const HorizontalLabel = Template.bind({});
HorizontalLabel.args = {
label: "Horizontal (Left Label)",
labelVariant: "horizontal",
placeholder: "Select",
placeholder: "Choose an option",
state: "default",
};
// States
export const Active = Template.bind({});
Active.args = {
label: "Active State",
state: "default",
placeholder: "Select",
};
export const Hover = Template.bind({});
Hover.args = {
label: "Hover State",
state: "hover",
placeholder: "Select",
placeholder: "Choose an option",
state: "active",
};
export const Focus = Template.bind({});
Focus.args = {
label: "Focus State",
placeholder: "Choose an option",
state: "focus",
placeholder: "Select",
};
export const Error = Template.bind({});
Error.args = {
label: "Error State",
placeholder: "Choose an option",
error: true,
placeholder: "Select",
};
export const Disabled = Template.bind({});
Disabled.args = {
label: "Disabled State",
placeholder: "Choose an option",
disabled: true,
placeholder: "Select",
};
export const Interactive = Template.bind({});
// Interactive example
export const Interactive = (args) => {
const [value, setValue] = useState("");
return (
<div className="space-y-4">
<SelectInput
{...args}
value={value}
onChange={(data) => setValue(data.target.value)}
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
<p className="text-sm text-gray-600">Current value: "{value}"</p>
</div>
);
};
Interactive.args = {
label: "Interactive Select Input",
placeholder: "Choose an option",
state: "default",
};
// Comparison stories
export const AllSizes = () => {
const [smallValue, setSmallValue] = useState("");
const [mediumValue, setMediumValue] = useState("");
const [largeValue, setLargeValue] = useState("");
return (
<div className="space-y-4">
<SelectInput
label="Small"
size="small"
value={smallValue}
onChange={(data) => setSmallValue(data.target.value)}
placeholder="Select"
options={[
{ value: "item1", label: "Context Menu Item 1" },
{ value: "item2", label: "Context Menu Item 2" },
{ value: "item3", label: "Context Menu Item 3" },
]}
/>
<SelectInput
label="Medium"
size="medium"
value={mediumValue}
onChange={(data) => setMediumValue(data.target.value)}
placeholder="Select"
options={[
{ value: "item1", label: "Context Menu Item 1" },
{ value: "item2", label: "Context Menu Item 2" },
{ value: "item3", label: "Context Menu Item 3" },
]}
/>
<SelectInput
label="Large"
size="large"
value={largeValue}
onChange={(data) => setLargeValue(data.target.value)}
placeholder="Select"
options={[
{ value: "item1", label: "Context Menu Item 1" },
{ value: "item2", label: "Context Menu Item 2" },
{ value: "item3", label: "Context Menu Item 3" },
]}
/>
// All states comparison
export const AllStates = () => (
<div className="space-y-6">
<div>
<h3 className="text-lg font-semibold mb-4">Select Input States</h3>
<div className="space-y-4">
<SelectInput
label="Default State"
placeholder="Choose an option"
value=""
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
<SelectInput
label="Active State"
placeholder="Choose an option"
state="active"
value=""
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
<SelectInput
label="Focus State"
placeholder="Choose an option"
state="focus"
value=""
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
<SelectInput
label="Error State"
placeholder="Choose an option"
error={true}
value=""
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
<SelectInput
label="Disabled State"
placeholder="Choose an option"
disabled={true}
value=""
options={[
{ value: "option1", label: "Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
]}
/>
</div>
</div>
);
};
export const AllStates = () => {
const [defaultValue, setDefaultValue] = useState("");
const [errorValue, setErrorValue] = useState("");
const [disabledValue, setDisabledValue] = useState("");
return (
<div className="space-y-4">
<SelectInput
label="Default State"
value={defaultValue}
onChange={(data) => setDefaultValue(data.target.value)}
placeholder="Select"
options={[
{ value: "item1", label: "Context Menu Item 1" },
{ value: "item2", label: "Context Menu Item 2" },
{ value: "item3", label: "Context Menu Item 3" },
]}
/>
<SelectInput
label="Error State"
error={true}
value={errorValue}
onChange={(data) => setErrorValue(data.target.value)}
placeholder="Select"
options={[
{ value: "item1", label: "Context Menu Item 1" },
{ value: "item2", label: "Context Menu Item 2" },
{ value: "item3", label: "Context Menu Item 3" },
]}
/>
<SelectInput
label="Disabled State"
disabled={true}
value={disabledValue}
onChange={(data) => setDisabledValue(data.target.value)}
placeholder="Select"
options={[
{ value: "item1", label: "Context Menu Item 1" },
{ value: "item2", label: "Context Menu Item 2" },
{ value: "item3", label: "Context Menu Item 3" },
]}
/>
</div>
);
};
</div>
);
+1 -3
View File
@@ -16,9 +16,7 @@ componentTestSuite<SelectInputProps>({
],
} as SelectInputProps,
requiredProps: ["options"],
optionalProps: {
size: "medium",
},
optionalProps: {},
primaryRole: "button",
testCases: {
renders: true,