From ad3e547b2269907e8b6dd25acb6ee76e5d368727 Mon Sep 17 00:00:00 2001 From: Justin Bennett Date: Thu, 21 Jul 2022 18:14:19 +0100 Subject: [PATCH 1/2] Remove formik Field components from UI layer --- app/components/form/fields/CheckboxField.tsx | 13 ++ app/components/form/fields/ListboxField.tsx | 4 +- app/components/form/fields/RadioField.tsx | 4 +- app/components/form/fields/TagsField.tsx | 4 +- app/components/form/fields/TextField.tsx | 28 ++-- app/components/form/fields/index.ts | 1 + app/forms/firewall-rules-create.tsx | 139 +++++++----------- app/forms/instance-create.tsx | 18 +-- .../project/networking/VpcPage/VpcPage.e2e.ts | 10 +- libs/ui/index.ts | 2 +- libs/ui/lib/checkbox/Checkbox.tsx | 10 -- libs/ui/lib/radio/Radio.tsx | 5 +- .../TextInput.stories.tsx} | 8 +- .../TextInput.tsx} | 30 ++-- 14 files changed, 121 insertions(+), 155 deletions(-) create mode 100644 app/components/form/fields/CheckboxField.tsx rename libs/ui/lib/{text-field/TextField.stories.tsx => text-input/TextInput.stories.tsx} (64%) rename libs/ui/lib/{text-field/TextField.tsx => text-input/TextInput.tsx} (78%) diff --git a/app/components/form/fields/CheckboxField.tsx b/app/components/form/fields/CheckboxField.tsx new file mode 100644 index 0000000000..0ace09912d --- /dev/null +++ b/app/components/form/fields/CheckboxField.tsx @@ -0,0 +1,13 @@ +import type { FieldAttributes } from 'formik' +import { Field } from 'formik' + +import type { CheckboxProps } from '@oxide/ui' +import { Checkbox } from '@oxide/ui' + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type CheckboxFieldProps = CheckboxProps & Omit, 'type'> + +/** Formik Field version of Checkbox */ +export const CheckboxField = (props: CheckboxFieldProps) => ( + +) diff --git a/app/components/form/fields/ListboxField.tsx b/app/components/form/fields/ListboxField.tsx index dbcdaf3839..c2651c4fe4 100644 --- a/app/components/form/fields/ListboxField.tsx +++ b/app/components/form/fields/ListboxField.tsx @@ -1,7 +1,7 @@ import cn from 'classnames' import { useField } from 'formik' -import { FieldLabel, Listbox, TextFieldHint } from '@oxide/ui' +import { FieldLabel, Listbox, TextInputHint } from '@oxide/ui' export type ListboxFieldProps = { name: string @@ -35,7 +35,7 @@ export function ListboxField({ {label} - {helpText && {helpText}} + {helpText && {helpText}} { @@ -48,7 +48,7 @@ export function RadioField({ )} {/* TODO: Figure out where this hint field def should live */} - {helpText && {helpText}} + {helpText && {helpText}} {/* TODO: Should TextFieldHint be grouped with FieldLabel? */} - {hint && {hint}} + {hint && {hint}} - - + +
+ +
diff --git a/app/forms/instance-create.tsx b/app/forms/instance-create.tsx index 843cf7542a..3257aaad10 100644 --- a/app/forms/instance-create.tsx +++ b/app/forms/instance-create.tsx @@ -17,7 +17,7 @@ import { Success16Icon, Tab, Tabs, - TextFieldHint, + TextInputHint, } from '@oxide/ui' import { GiB } from '@oxide/util' @@ -182,10 +182,10 @@ export default function CreateInstanceForm({ General Purpose - + General purpose instances provide a good balance of CPU, memory, and high performance storage; well suited for a wide range of use cases. - + {renderLargeRadioCards('general')} @@ -193,9 +193,9 @@ export default function CreateInstanceForm({ CPU Optimized - + CPU optimized instances provide a good balance of... - + {renderLargeRadioCards('cpuOptimized')} @@ -203,9 +203,9 @@ export default function CreateInstanceForm({ Memory optimized - + CPU optimized instances provide a good balance of... - + {renderLargeRadioCards('memoryOptimized')} @@ -213,9 +213,9 @@ export default function CreateInstanceForm({ Custom - + Custom instances... - + {renderLargeRadioCards('custom')} diff --git a/app/pages/project/networking/VpcPage/VpcPage.e2e.ts b/app/pages/project/networking/VpcPage/VpcPage.e2e.ts index cd2f06f736..267e3bd984 100644 --- a/app/pages/project/networking/VpcPage/VpcPage.e2e.ts +++ b/app/pages/project/networking/VpcPage/VpcPage.e2e.ts @@ -57,12 +57,12 @@ test.describe('VpcPage', () => { await page.fill('input[name=name]', 'my-new-rule') await page.locator('text=Outgoing').click() - await page.fill('text="Priority"', '5') + await page.fill('role=spinbutton[name="Priority"]', '5') // add target VPC "my-target-vpc" await page.locator('role=button[name="Target type"]').click() await page.locator('role=option[name="VPC"]').click() - await page.fill('text="Target name"', 'my-target-vpc') + await page.fill('role=textbox[name="Target name"]', 'my-target-vpc') await page.locator('text="Add target"').click() // target is added to targets table @@ -71,14 +71,14 @@ test.describe('VpcPage', () => { // add host filter instance "host-filter-instance" await page.locator('role=button[name="Host type"]').click() await page.locator('role=option[name="Instance"]').click() - await page.fill('text="Value"', 'host-filter-instance') + await page.fill('role=textbox[name="Value"]', 'host-filter-instance') await page.locator('text="Add host filter"').click() // host is added to hosts table await expect(page.locator('td:has-text("host-filter-instance")')).toBeVisible() // TODO: test invalid port range once I put an error message in there - await page.fill('text="Port filter"', '123-456') + await page.fill('role=textbox[name="Port filter"]', '123-456') await page.locator('text="Add port filter"').click() // port range is added to port ranges table @@ -158,7 +158,7 @@ test.describe('VpcPage', () => { // add host filter await page.locator('role=button[name="Host type"]').click() await page.locator('role=option[name="Instance"]').click() - await page.fill('text="Value"', 'edit-filter-instance') + await page.fill('role=textbox[name="Value"]', 'edit-filter-instance') await page.locator('text="Add host filter"').click() // new host is added to hosts table diff --git a/libs/ui/index.ts b/libs/ui/index.ts index e0326edf78..25f6dd938d 100644 --- a/libs/ui/index.ts +++ b/libs/ui/index.ts @@ -24,6 +24,6 @@ export * from './lib/skip-link/SkipLink' export * from './lib/spinner/Spinner' export * from './lib/table/Table' export * from './lib/tabs/Tabs' -export * from './lib/text-field/TextField' +export * from './lib/text-input/TextInput' export * from './lib/toast/Toast' export * from './lib/tooltip/Tooltip' diff --git a/libs/ui/lib/checkbox/Checkbox.tsx b/libs/ui/lib/checkbox/Checkbox.tsx index b7b1631f6a..81de8b1847 100644 --- a/libs/ui/lib/checkbox/Checkbox.tsx +++ b/libs/ui/lib/checkbox/Checkbox.tsx @@ -1,6 +1,4 @@ import cn from 'classnames' -import type { FieldAttributes } from 'formik' -import { Field } from 'formik' import { Checkmark12Icon } from '@oxide/ui' import { classed } from '@oxide/util' @@ -54,11 +52,3 @@ export const Checkbox = ({ {children && {children}} ) - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type CheckboxFieldProps = CheckboxProps & Omit, 'type'> - -/** Formik Field version of Checkbox */ -export const CheckboxField = (props: CheckboxFieldProps) => ( - -) diff --git a/libs/ui/lib/radio/Radio.tsx b/libs/ui/lib/radio/Radio.tsx index c57eec14e3..35a0193847 100644 --- a/libs/ui/lib/radio/Radio.tsx +++ b/libs/ui/lib/radio/Radio.tsx @@ -6,7 +6,6 @@ * difference is that label content is handled through children. */ import cn from 'classnames' -import { Field } from 'formik' import type { ComponentProps } from 'react' // input type is fixed to "radio" @@ -24,7 +23,7 @@ const fieldStyles = ` export const Radio = ({ children, className, ...inputProps }: RadioProps) => (