mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Improve Table Editor design and accessibility (#50797)
## Problem Controls in the new table sheet's Columns section had inconsistent styling, alignment and focus states. Some icon-only actions were faint or lacked useful accessible names and tooltips, while related controls used different dropdown treatments. <img width="1428" height="250" alt="image" src="https://github.com/user-attachments/assets/9d1ad80d-2de0-4736-8ddb-0260e10ddacc" /> ## Solution - Align the column headers and fields on the same grid, and keep the foreign key action inside the name field in every state. - Give the drag, foreign key, suggestions, extra options and remove actions consistent button styling, sizing, hover and focus states, with accessible names and tooltips. - Move masking into Extra options and include it in the options count. Remove the separators around the former inline controls. - Use the design system's ComboboxTrigger for column types and align the Default value select's radius with it. Update the suggestions dropdown icon. - Tidy related field labels and update the affected table editor tests. The underlying column values and database behaviour are unchanged. | Original before | Original after | | --- | --- | | <img width="1498" height="392" alt="CleanShot 2026-09-24 at 13 33 40@2x" src="https://github.com/user-attachments/assets/56559e72-f289-44bc-999f-c1f3158c8f65" /> | <img width="1496" height="416" alt="CleanShot 2026-09-24 at 13 32 42@2x" src="https://github.com/user-attachments/assets/d05340fc-a460-4b5c-aaff-41127f692592" /> | ## Review instructions - Open **Table Editor → New table** and inspect the Columns section. Check that Name, Type and Default value headers align with their fields. - Tab through the row actions. Check their focus states, accessible names and tooltips, including the foreign key control with and without a relation. - Drag a column to reorder it, open Extra options and toggle masking. Check the options count and that the other settings still work. - Compare the closed Type and Default value dropdowns, including an enum default value. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Improvements** * Updated the column editor layout and controls for naming, sensitive-data settings, extra options, foreign-key editing, and column removal, with clearer tooltips and more consistent interactions. * Added accessible help tooltips for the Name and Default Value fields. * Updated column-type and suggested-value controls, including clearer guidance for choosing a suggested value. * Sensitive-data settings are now available in the extra-options menu. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
This commit is contained in:
1 parent
0d3b73794b
commit
ca28c945db
8 files changed
+371
-322
No files matched your search
@@ -58,8 +58,8 @@ test.describe('column editor complex types', () => {
|
||||
'Type dropdown should show the bare base type, not the raw _int4 pg format'
|
||||
).toBeVisible()
|
||||
await expect(
|
||||
columnEditor.getByRole('checkbox', { name: 'Define as Array' }),
|
||||
'Define as Array should be checked for an existing array column'
|
||||
columnEditor.getByRole('checkbox', { name: 'Define as array' }),
|
||||
'Define as array should be checked for an existing array column'
|
||||
).toBeChecked()
|
||||
|
||||
// Make an unrelated change and save - this must not corrupt the column's type.
|
||||
|
||||
@@ -263,10 +263,10 @@ testRunner('table editor', () => {
|
||||
await page.getByRole('button', { name: 'New table', exact: true }).click()
|
||||
await page.getByTestId('table-name-input').fill(tableNameEnum)
|
||||
await page.getByTestId('created_at-extra-options').click()
|
||||
await page.getByText('Is Nullable').click()
|
||||
await page.getByText('Is nullable').click()
|
||||
await page.getByTestId('created_at-extra-options').click()
|
||||
await page.getByRole('button', { name: 'Add column' }).click()
|
||||
await page.getByLabel('Column name').nth(2).fill(columnNameEnum)
|
||||
await page.getByLabel('Column name').nth(3).fill(columnNameEnum)
|
||||
await page.getByRole('combobox').filter({ hasText: 'Choose a column type...' }).click()
|
||||
await page.getByPlaceholder('Search types...').fill(enum_name)
|
||||
// wait for response, then click
|
||||
@@ -357,7 +357,7 @@ testRunner('table editor', () => {
|
||||
.click()
|
||||
await page.getByRole('menuitem', { name: 'Edit table' }).click()
|
||||
await page.getByTestId('table-name-input').fill(tableNameUpdated)
|
||||
await page.getByLabel('Column name').nth(2).fill(columnNameUpdated)
|
||||
await page.getByLabel('Column name').nth(3).fill(columnNameUpdated)
|
||||
const updateTablePromise = waitForApiResponse(page, 'pg-meta', ref, 'query?key=column-update', {
|
||||
method: 'POST',
|
||||
})
|
||||
@@ -948,7 +948,7 @@ testRunner('table editor', () => {
|
||||
|
||||
// Add boolean column
|
||||
await page.getByRole('button', { name: 'Add column' }).click()
|
||||
await page.getByLabel('Column name').nth(3).fill(boolColName)
|
||||
await page.getByLabel('Column name').nth(4).fill(boolColName)
|
||||
await page.getByText('Choose a column type...').click()
|
||||
await page.getByPlaceholder('Search types...').fill('bool')
|
||||
await page.getByRole('option', { name: 'bool' }).first().click()
|
||||
@@ -1064,7 +1064,7 @@ testRunner('table editor', () => {
|
||||
|
||||
// Add nullable boolean column
|
||||
await page.getByRole('button', { name: 'Add column' }).click()
|
||||
await page.getByLabel('Column name').nth(3).fill(boolColName)
|
||||
await page.getByLabel('Column name').nth(4).fill(boolColName)
|
||||
await page.getByText('Choose a column type...').click()
|
||||
await page.getByPlaceholder('Search types...').fill('bool')
|
||||
await page.getByRole('option', { name: 'bool' }).first().click()
|
||||
@@ -1985,14 +1985,14 @@ testRunner('table editor', () => {
|
||||
await page.getByRole('button', { name: 'New table' }).click()
|
||||
await page.getByLabel('Name', { exact: true }).fill(tableName)
|
||||
await page.getByRole('button', { name: 'Add column' }).click()
|
||||
await page.getByLabel('Column name').nth(2).fill('pw_column')
|
||||
await page.getByLabel('Column name').nth(3).fill('pw_column')
|
||||
await page.getByRole('combobox').filter({ hasText: 'Choose a column type...' }).click()
|
||||
await page.getByRole('option').filter({ hasText: 'int8' }).click()
|
||||
await page.getByLabel('Column default value').nth(2).fill('invalid')
|
||||
await page.getByLabel('Column default value').nth(3).fill('invalid')
|
||||
|
||||
await page.getByRole('button', { name: 'Save' }).click()
|
||||
await expect(page.getByText('invalid input syntax')).toBeVisible()
|
||||
await page.getByLabel('Column default value').nth(2).fill('10')
|
||||
await page.getByLabel('Column default value').nth(3).fill('10')
|
||||
await page.getByRole('button', { name: 'Save' }).click()
|
||||
await expect(page.getByText(`Table ${tableName} is good to go!`)).toBeVisible()
|
||||
await expect(page.getByRole('button', { name: `View ${tableName}`, exact: true })).toBeVisible()
|
||||
|
||||
Reference in new issue
Block a user