diff --git a/packages/web/src/components/gcds-select/readme.md b/packages/web/src/components/gcds-select/readme.md
index 53f2f18b9..0aa9d77a0 100644
--- a/packages/web/src/components/gcds-select/readme.md
+++ b/packages/web/src/components/gcds-select/readme.md
@@ -11,19 +11,23 @@ A select provides a large list of options for single selection.
## Properties
-| Property | Attribute | Description | Type | Default |
-| ----------------------- | --------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------- | ----------- |
-| `defaultValue` | `default-value` | The default value is an optional value that gets displayed before the user selects an option. | `string` | `undefined` |
-| `disabled` | `disabled` | Specifies if a select element is disabled or not. | `boolean` | `false` |
-| `errorMessage` | `error-message` | Error message for an invalid select element. | `string` | `undefined` |
-| `hint` | `hint` | Hint displayed below the label. | `string` | `undefined` |
-| `label` _(required)_ | `label` | Form field label. | `string` | `undefined` |
-| `name` _(required)_ | `name` | Name attribute for select form element. | `string` | `undefined` |
-| `required` | `required` | Specifies if a form field is required or not. | `boolean` | `false` |
-| `selectId` _(required)_ | `select-id` | Id attribute for a select element. | `string` | `undefined` |
-| `validateOn` | `validate-on` | Set event to call validator | `"blur" \| "other" \| "submit"` | `'blur'` |
-| `validator` | `validator` | Array of validators | `(string \| ValidatorEntry \| Validator
)[]` | `undefined` |
-| `value` | `value` | Value for a select element. | `string` | `undefined` |
+| Property | Attribute | Description | Type | Default |
+| ----------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- | ----------- |
+| `autocomplete` | `autocomplete` | String to have autocomplete enabled. | `string` | `undefined` |
+| `autofocus` | `autofocus` | If true, the select will be focused on component render | `boolean` | `undefined` |
+| `defaultValue` | `default-value` | The default value is an optional value that gets displayed before the user selects an option. | `string` | `undefined` |
+| `disabled` | `disabled` | Specifies if a select element is disabled or not. | `boolean` | `false` |
+| `errorMessage` | `error-message` | Error message for an invalid select element. | `string` | `undefined` |
+| `form` | `form` | The ID of the form that the select field belongs to. | `string` | `undefined` |
+| `hint` | `hint` | Hint displayed below the label. | `string` | `undefined` |
+| `label` _(required)_ | `label` | Form field label. | `string` | `undefined` |
+| `name` _(required)_ | `name` | Name attribute for select form element. | `string` | `undefined` |
+| `required` | `required` | Specifies if a form field is required or not. | `boolean` | `false` |
+| `selectId` _(required)_ | `select-id` | Id attribute for a select element. | `string` | `undefined` |
+| `validateOn` | `validate-on` | Set event to call validator | `"blur" \| "other" \| "submit"` | `'blur'` |
+| `validator` | `validator` | Array of validators | `(string \| ValidatorEntry \| Validator)[]` | `undefined` |
+| `validity` | `validity` | Read-only property of the select, returns a ValidityState object that represents the validity states this element is in. | `ValidityState` | `undefined` |
+| `value` | `value` | Value for a select element. | `string` | `undefined` |
## Events
@@ -40,6 +44,26 @@ A select provides a large list of options for single selection.
## Methods
+### `checkValidity() => Promise`
+
+Check the validity of gcds-select
+
+#### Returns
+
+Type: `Promise`
+
+
+
+### `getValidationMessage() => Promise`
+
+Get validationMessage of gcds-select
+
+#### Returns
+
+Type: `Promise`
+
+
+
### `validate() => Promise`
Call any active validators
diff --git a/packages/web/src/components/gcds-select/stories/gcds-select.stories.tsx b/packages/web/src/components/gcds-select/stories/gcds-select.stories.tsx
index 570f53c20..5da6f7097 100644
--- a/packages/web/src/components/gcds-select/stories/gcds-select.stories.tsx
+++ b/packages/web/src/components/gcds-select/stories/gcds-select.stories.tsx
@@ -27,6 +27,28 @@ export default {
required: true,
},
},
+ autocomplete: {
+ control: 'text',
+ table: {
+ type: { summary: 'string' },
+ defaultValue: { summary: '-' },
+ },
+ },
+ autofocus: {
+ control: { type: 'select' },
+ options: [false, true],
+ table: {
+ type: { summary: 'boolean' },
+ defaultValue: { summary: false },
+ },
+ },
+ form: {
+ control: 'text',
+ table: {
+ type: { summary: 'string' },
+ defaultValue: { summary: '-' },
+ },
+ },
name: {
name: 'name',
control: 'text',
@@ -163,6 +185,9 @@ const Template = args =>
${args.required ? `required` : null}
${args.errorMessage ? `error-message="${args.errorMessage}"` : null}
${args.disabled ? `disabled` : null}
+ ${args.autocomplete ? `autocomplete="${args.autocomplete}"` : null}
+ ${args.autofocus ? `autofocus` : null}
+ ${args.form ? `form="${args.form}"` : null}
${args.validateOn != 'blur' ? `validate-on="${args.validateOn}"` : null}
${args.lang != 'en' ? `lang="${args.lang}"` : null}
>
@@ -180,6 +205,9 @@ const Template = args =>
${args.required ? `required` : null}
${args.errorMessage ? `errorMessage="${args.errorMessage}"` : null}
${args.disabled ? `disabled` : null}
+ ${args.autocomplete ? `autocomplete="${args.autocomplete}"` : null}
+ ${args.autofocus ? `autofocus` : null}
+ ${args.form ? `form="${args.form}"` : null}
${args.validateOn != 'blur' ? `validateOn="${args.validateOn}"` : null}
${args.lang != 'en' ? `lang="${args.lang}"` : null}
>
@@ -198,6 +226,9 @@ const TemplatePlayground = args => `
${args.required ? `required` : null}
${args.errorMessage ? `error-message="${args.errorMessage}"` : null}
${args.disabled ? `disabled` : null}
+ ${args.autocomplete ? `autocomplete="${args.autocomplete}"` : null}
+ ${args.autofocus ? `autofocus` : null}
+ ${args.form ? `form="${args.form}"` : null}
${args.validateOn != 'blur' ? `validate-on="${args.validateOn}"` : null}
${args.lang != 'en' ? `lang="${args.lang}"` : null}
>
@@ -221,6 +252,9 @@ Default.args = {
lang: 'en',
validateOn: 'blur',
default: selectOptions,
+ autofocus: false,
+ autocomplete: '',
+ form: '',
};
// ------ Select states ------
@@ -236,6 +270,9 @@ Disabled.args = {
lang: 'en',
validateOn: 'blur',
default: selectOptions,
+ autofocus: false,
+ autocomplete: '',
+ form: '',
};
export const Error = Template.bind({});
@@ -250,6 +287,9 @@ Error.args = {
lang: 'en',
validateOn: 'blur',
default: selectOptions,
+ autofocus: false,
+ autocomplete: '',
+ form: '',
};
export const Required = Template.bind({});
@@ -263,6 +303,41 @@ Required.args = {
lang: 'en',
validateOn: 'blur',
default: selectOptions,
+ autofocus: false,
+ autocomplete: '',
+ form: '',
+};
+
+export const Autocomplete = Template.bind({});
+Autocomplete.args = {
+ selectId: 'select-required',
+ label: 'Label',
+ name: 'select',
+ hint: 'Hint / Example message.',
+ defaultValue: 'Select option.',
+ required: false,
+ lang: 'en',
+ validateOn: 'blur',
+ default: selectOptions,
+ autofocus: false,
+ autocomplete: 'on',
+ form: '',
+};
+
+export const Form = Template.bind({});
+Form.args = {
+ selectId: 'select-required',
+ label: 'Label',
+ name: 'select',
+ hint: 'Hint / Example message.',
+ defaultValue: 'Select option.',
+ required: false,
+ lang: 'en',
+ validateOn: 'blur',
+ default: selectOptions,
+ autofocus: false,
+ autocomplete: '',
+ form: 'formID',
};
// ------ Select without default value ------
@@ -276,6 +351,9 @@ WithoutDefaultValue.args = {
lang: 'en',
validateOn: 'blur',
default: selectOptions,
+ autofocus: false,
+ autocomplete: '',
+ form: '',
};
// ------ Select events & properties ------
@@ -294,6 +372,9 @@ Props.args = {
lang: 'en',
validateOn: 'blur',
default: selectOptions,
+ autofocus: false,
+ autocomplete: '',
+ form: '',
};
// ------ Select playground ------
@@ -312,4 +393,7 @@ Playground.args = {
lang: 'en',
validateOn: 'blur',
default: selectOptions,
+ autofocus: false,
+ autocomplete: '',
+ form: '',
};
diff --git a/packages/web/src/components/gcds-select/stories/overview.mdx b/packages/web/src/components/gcds-select/stories/overview.mdx
index cbec992b5..855c47505 100644
--- a/packages/web/src/components/gcds-select/stories/overview.mdx
+++ b/packages/web/src/components/gcds-select/stories/overview.mdx
@@ -43,6 +43,16 @@ A list of options with a single-option choice.
+### Native properties
+
+#### Autocomplete
+
+
+
+#### Form
+
+
+
## Resources
{/* prettier-ignore */}
diff --git a/packages/web/src/components/gcds-select/test/gcds-select.e2e.ts b/packages/web/src/components/gcds-select/test/gcds-select.e2e.ts
index a8235abe1..f52b04f09 100644
--- a/packages/web/src/components/gcds-select/test/gcds-select.e2e.ts
+++ b/packages/web/src/components/gcds-select/test/gcds-select.e2e.ts
@@ -134,6 +134,29 @@ test.describe('gcds-select', () => {
expect(errorMessage).toEqual('');
});
+
+ test('HTML validity', async ({ page }) => {
+ const element = await page.locator('gcds-select');
+
+ // Wait for element to attach and become visible, allowing up to 10s
+ await element.waitFor({ state: 'attached' });
+ await element.waitFor({ state: 'visible' });
+ await element.waitFor({ timeout: 10000 });
+
+ let validity = await element.evaluate(el =>
+ (el as HTMLGcdsSelectElement).checkValidity(),
+ );
+
+ expect(validity).toBe(false);
+
+ await element.locator('select').selectOption('2');
+
+ validity = await element.evaluate(el =>
+ (el as HTMLGcdsSelectElement).checkValidity(),
+ );
+
+ expect(validity).toBe(true);
+ });
});
/**
diff --git a/packages/web/src/components/gcds-select/test/gcds-select.spec.tsx b/packages/web/src/components/gcds-select/test/gcds-select.spec.tsx
index e15cb8ff7..88eb443bd 100644
--- a/packages/web/src/components/gcds-select/test/gcds-select.spec.tsx
+++ b/packages/web/src/components/gcds-select/test/gcds-select.spec.tsx
@@ -246,4 +246,172 @@ describe('gcds-select', () => {
`);
});
+
+ /**
+ * Select with autocomplete
+ */
+ it('renders with autocomplete', async () => {
+ const page = await newSpecPage({
+ components: [GcdsSelect],
+ html: ``,
+ });
+ expect(page.root).toEqualHtml(`
+
+
+
+
+
+
+
+
+ `);
+ });
+
+ /**
+ * Select with form attribute
+ */
+ it('renders with form attribute', async () => {
+ const page = await newSpecPage({
+ components: [GcdsSelect],
+ html: ``,
+ });
+ expect(page.root).toEqualHtml(`
+
+
+
+
+
+
+
+
+ `);
+ });
+
+ /**
+ * Select with autofocus
+ */
+ it('renders with autofocus', async () => {
+ const page = await newSpecPage({
+ components: [GcdsSelect],
+ html: ``,
+ });
+ expect(page.root).toEqualHtml(`
+
+
+
+
+
+
+
+
+ `);
+ });
+
+ /**
+ * Select with assigned value attribute
+ */
+ it('renders select with value attribute', async () => {
+ const page = await newSpecPage({
+ components: [GcdsSelect],
+ html: `
+
+
+
+
+
+ `,
+ });
+ expect(page.root).toEqualHtml(`
+
+
+
+
+
+
+
+
+
+
+
+ `);
+ ;
+ expect(page.root.value).toBe('2');
+ });
+
+ /**
+ * Select with selected option
+ */
+ it('renders select with selected option', async () => {
+ const page = await newSpecPage({
+ components: [GcdsSelect],
+ html: `
+
+
+
+
+
+ `,
+ });
+ expect(page.root).toEqualHtml(`
+
+
+
+
+
+
+
+
+
+
+
+ `);
+ ;
+ expect(page.root.value).toBe('2');
+ });
+
+ /**
+ * Select with invalid assigned value
+ */
+ it('renders select with invalid assigned value', async () => {
+ const page = await newSpecPage({
+ components: [GcdsSelect],
+ html: `
+
+
+
+
+
+ `,
+ });
+ expect(page.root).toEqualHtml(`
+
+
+
+
+
+
+
+
+
+
+
+ `);
+ ;
+ expect(page.root.value).toBeNull();
+ });
});