diff --git a/src/components/Select/Select.stories.tsx b/src/components/Select/Select.stories.tsx
index 02139589..8e2dbfe4 100644
--- a/src/components/Select/Select.stories.tsx
+++ b/src/components/Select/Select.stories.tsx
@@ -1,6 +1,7 @@
import type { Meta } from '@storybook/react';
import Select, { SelectProps } from './Select';
+import { SelectVariants } from './types';
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta = {
title: 'Components/Select',
@@ -24,6 +25,11 @@ const argTypes = {
type: 'boolean',
},
},
+ showCustomIcon: {
+ control: {
+ type: 'boolean',
+ },
+ },
invalid: {
control: {
type: 'boolean',
@@ -54,6 +60,12 @@ const argTypes = {
type: 'select',
},
},
+ variant: {
+ options: [SelectVariants.default, SelectVariants.tertiary],
+ control: {
+ type: 'select',
+ },
+ },
value: {
control: {
type: 'text',
@@ -90,14 +102,45 @@ Playground.args = {
playgroundWidth: 300,
className: 'input-test-class',
defaultValue: 'Option 2',
+ showCustomIcon: false,
disabled: false,
invalid: false,
invalidText: 'Error message',
labelText: 'Label text',
readOnly: false,
size: 'md',
+ variant: SelectVariants.default,
warn: false,
warnText: 'Warning message that is really long can wrap to more lines.',
};
Playground.argTypes = argTypes;
+
+export const Tertiary = ({ playgroundWidth, ...args }: StoryProps) => (
+
+
+
+);
+
+Tertiary.args = {
+ showCustomIcon: true,
+ variant: SelectVariants.tertiary,
+};
+
+Tertiary.argTypes = {
+ variant: {
+ options: [SelectVariants.default, SelectVariants.tertiary],
+ control: {
+ type: 'select',
+ },
+ defaultValue: SelectVariants.tertiary,
+ },
+};
diff --git a/src/components/Select/Select.test.tsx b/src/components/Select/Select.test.tsx
index dba36ab6..e4a31965 100644
--- a/src/components/Select/Select.test.tsx
+++ b/src/components/Select/Select.test.tsx
@@ -3,9 +3,17 @@ import userEvent from '@testing-library/user-event';
import * as React from 'react';
import Select from './Select';
+import { px } from '../../utils';
describe('A Select', () => {
const reqProps = { labelText: 'My Test Label', id: 'test-id' };
+ const mockLabel = 'Test Label';
+ const mockOptions = (
+ <>
+
+
+ >
+ );
it('will render a default value if passed', () => {
const testRef = React.createRef();
@@ -54,4 +62,36 @@ describe('A Select', () => {
await userEvent.selectOptions(screen.getByTestId('test-id'), ['option one']);
await waitFor(() => expect(mockedOnChange.mock.calls).toHaveLength(0));
});
+
+ it('should toggle --open and --closed classes on click', async () => {
+ render(
+ ,
+ );
+
+ const selectElement = screen.getByTestId('test-select');
+
+ // Initial state should be closed
+ expect(selectElement).toHaveClass(`${px}-input__select--closed`);
+
+ // Simulate click to open
+ await userEvent.click(selectElement);
+ expect(selectElement).toHaveClass(`${px}-input__select--open`);
+
+ // Simulate blur to close
+ await userEvent.tab();
+ expect(selectElement).toHaveClass(`${px}-input__select--closed`);
+ });
+
+ it('should apply --tertiary class when variant is tertiary', () => {
+ render(
+ ,
+ );
+
+ const selectElement = screen.getByTestId('test-select-tertiary');
+ expect(selectElement).toHaveClass(`${px}-input__select--tertiary`);
+ });
});
diff --git a/src/components/Select/Select.tsx b/src/components/Select/Select.tsx
index 562da613..d59284e9 100644
--- a/src/components/Select/Select.tsx
+++ b/src/components/Select/Select.tsx
@@ -1,15 +1,23 @@
import * as React from 'react';
import classnames from 'classnames';
-
import { px, useNormalizedInputProps } from '../../utils';
-
import { InputProps } from '../Input/Input';
+import './select.scss';
+import { SelectVariants } from './types';
export interface SelectProps extends InputProps {
/**
* Option elements that are selectable
*/
children: React.ReactNode;
+ /**
+ * Determines if you want to show the icon
+ */
+ showCustomIcon?: boolean;
+ /**
+ * Determines the variant of the select
+ */
+ variant: SelectVariants;
}
/**
@@ -31,6 +39,8 @@ const Select = React.forwardRef(
disabled,
hideLabel,
id,
+ showCustomIcon = false,
+ variant = SelectVariants.default,
inline,
invalid,
invalidText,
@@ -48,6 +58,9 @@ const Select = React.forwardRef(
) => {
const type = 'select';
const inputProps = useNormalizedInputProps({ disabled, id, invalid, invalidText, readOnly, type, warn, warnText });
+ const [isOpen, setIsOpen] = React.useState(false);
+ const handleIsOpen = () => setIsOpen((prev) => !prev);
+ const closeDropdown = () => setIsOpen(false);
const wrapperClassnames = classnames(`${px}-${type}-input`, `${px}-input`, `${px}-input--${size}`, {
[`${px}-input--inline`]: inline,
@@ -58,19 +71,32 @@ const Select = React.forwardRef(
[`${className}__wrapper`]: className,
});
+ const selectClassnames = classnames(`${px}-input__input`, {
+ className,
+ [`${px}-input__select--open`]: isOpen && showCustomIcon,
+ [`${px}-input__select--closed`]: !isOpen && showCustomIcon,
+ [`${px}-input__select--tertiary`]: variant === SelectVariants.tertiary,
+ });
+
+ const handleClick = (e: React.MouseEvent) => {
+ handleIsOpen();
+ onClick?.(e);
+ };
+
return (