diff --git a/packages/oc-docs/e2e/components/environments/env-editor.component.ts b/packages/oc-docs/e2e/components/environments/env-editor.component.ts index fedb0222..25d4342b 100644 --- a/packages/oc-docs/e2e/components/environments/env-editor.component.ts +++ b/packages/oc-docs/e2e/components/environments/env-editor.component.ts @@ -1,7 +1,19 @@ +import type { Locator } from '@playwright/test'; import { BaseComponent } from '../base.component'; export class EnvEditorComponent extends BaseComponent { readonly cards = this.page.getByTestId('env-var-cards'); + readonly cardItems = this.cards.locator('.env-card'); readonly nameInputs = this.cards.getByPlaceholder('Name'); readonly valueInputs = this.cards.getByPlaceholder('Value'); + + /** The per-variable enable/disable checkbox, addressed by the variable name via its aria-label. */ + enableToggle(name: string): Locator { + return this.cards.getByRole('checkbox', { name: `Enable ${name}` }); + } + + /** The card that owns the named variable, matched via its enable checkbox. */ + cardFor(name: string): Locator { + return this.cardItems.filter({ has: this.page.getByRole('checkbox', { name: `Enable ${name}` }) }); + } } diff --git a/packages/oc-docs/e2e/components/key-value-table/key-value-table.component.ts b/packages/oc-docs/e2e/components/key-value-table/key-value-table.component.ts index 41b671db..ab45e001 100644 --- a/packages/oc-docs/e2e/components/key-value-table/key-value-table.component.ts +++ b/packages/oc-docs/e2e/components/key-value-table/key-value-table.component.ts @@ -19,4 +19,9 @@ export class KeyValueTableComponent extends BaseComponent { this.cellErrors = page.getByTestId(`${testId}-error`); this.autocomplete = page.getByTestId('variable-autocomplete'); } + + /** The per-row enable/disable checkbox, addressed by the row name via its aria-label. */ + enableToggle(name: string): Locator { + return this.table.getByRole('checkbox', { name: `Enable ${name}` }); + } } diff --git a/packages/oc-docs/e2e/tests/playground/env-add-variable.spec.ts b/packages/oc-docs/e2e/tests/playground/env-add-variable.spec.ts index 50e5938d..cdaea6bc 100644 --- a/packages/oc-docs/e2e/tests/playground/env-add-variable.spec.ts +++ b/packages/oc-docs/e2e/tests/playground/env-add-variable.spec.ts @@ -18,4 +18,24 @@ test.describe('Environment variables — adding rows (card view)', () => { await expect(envEditor.nameInputs.nth(before - 1)).toHaveValue('newVariable'); await expect(envEditor.valueInputs.nth(before - 1)).toHaveValue('newValue'); }); + + test('toggling a variable checkbox enables/disables its card', async ({ playground, envEditor }) => { + await playground.open('inline'); + await playground.openEnvironments(); + + const toggle = envEditor.enableToggle('host'); + const card = envEditor.cardFor('host'); + const disabled = /(^|\s)disabled(\s|$)/; + + await expect(toggle).toBeChecked(); + await expect(card).not.toHaveClass(disabled); + + await toggle.uncheck(); + await expect(toggle).not.toBeChecked(); + await expect(card).toHaveClass(disabled); + + await toggle.check(); + await expect(toggle).toBeChecked(); + await expect(card).not.toHaveClass(disabled); + }); }); diff --git a/packages/oc-docs/e2e/tests/playground/keyvalue-table.spec.ts b/packages/oc-docs/e2e/tests/playground/keyvalue-table.spec.ts index ecf07b77..fa98c474 100644 --- a/packages/oc-docs/e2e/tests/playground/keyvalue-table.spec.ts +++ b/packages/oc-docs/e2e/tests/playground/keyvalue-table.spec.ts @@ -56,4 +56,19 @@ test.describe('KeyValueTable — tooltips & mobile scroll', () => { await expect(error).toBeVisible(); await expect(error).toHaveAttribute('aria-label', 'Header name cannot contain spaces or newlines'); }); + + test('a named row can be enabled and disabled via its checkbox', async ({ playground }) => { + const { keyValueTable } = playground; + // The trailing blank row has no checkbox; naming a row promotes it to a real row with one. + await keyValueTable.nameInputs.last().fill('X-Custom'); + + const toggle = keyValueTable.enableToggle('X-Custom'); + await expect(toggle).toBeChecked(); + + await toggle.uncheck(); + await expect(toggle).not.toBeChecked(); + + await toggle.check(); + await expect(toggle).toBeChecked(); + }); }); diff --git a/packages/oc-docs/src/assets/icons/CheckIcon.tsx b/packages/oc-docs/src/assets/icons/CheckIcon.tsx new file mode 100644 index 00000000..20bad838 --- /dev/null +++ b/packages/oc-docs/src/assets/icons/CheckIcon.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { baseIconProps } from './baseIconProps'; + +interface CheckIconProps { + className?: string; + width?: number; + height?: number; +} + +export const CheckIcon: React.FC = ({ className, width=24, height=24 }) => ( + + + +); diff --git a/packages/oc-docs/src/assets/icons/index.ts b/packages/oc-docs/src/assets/icons/index.ts index a54d4b20..b72c9aec 100644 --- a/packages/oc-docs/src/assets/icons/index.ts +++ b/packages/oc-docs/src/assets/icons/index.ts @@ -27,3 +27,4 @@ export * from './SidebarToggleIcon'; export * from './SettingsIcon'; export * from './TrashIcon'; export * from './ExampleIcon'; +export * from './CheckIcon'; \ No newline at end of file diff --git a/packages/oc-docs/src/components/Docs/Sidebar/SidebarNavLink/SidebarNavLink.spec.tsx b/packages/oc-docs/src/components/Docs/Sidebar/SidebarNavLink/SidebarNavLink.spec.tsx index c2e05b3a..1f45e760 100644 --- a/packages/oc-docs/src/components/Docs/Sidebar/SidebarNavLink/SidebarNavLink.spec.tsx +++ b/packages/oc-docs/src/components/Docs/Sidebar/SidebarNavLink/SidebarNavLink.spec.tsx @@ -54,9 +54,9 @@ describe('SidebarNavLink', () => { it('indents by level via margin (chevron + gap step of 19px) with a uniform 8px inner pad', () => { const html = renderToStaticMarkup(); - // level*19 + 4 = 42px -> 42/16 = 2.625rem margin; the 8px (0.5rem) pad is uniform + // level*19 = 38px -> 38/16 = 2.375rem margin; the 8px (0.5rem) pad is uniform // across folders and leaves so glyphs line up under their parent. - expect(html).toContain('margin-left:2.625rem'); + expect(html).toContain('margin-left:2.375rem'); expect(html).toContain('padding-left:0.5rem'); }); }); diff --git a/packages/oc-docs/src/components/InitialsAvatar/StyledWrapper.ts b/packages/oc-docs/src/components/InitialsAvatar/StyledWrapper.ts index b3eda359..dfe28bc0 100644 --- a/packages/oc-docs/src/components/InitialsAvatar/StyledWrapper.ts +++ b/packages/oc-docs/src/components/InitialsAvatar/StyledWrapper.ts @@ -9,7 +9,7 @@ export const StyledWrapper = styled.span` flex: none; border-radius: var(--oc-radius); background: linear-gradient(135deg, #d37f17 0%, #dc9741 100%); - color: #fff; + color: var(--oc-background-base); font-family: var(--font-mono); font-size: var(--oc-font-size-xs); font-weight: 700; diff --git a/packages/oc-docs/src/components/KeyValueTable/KeyValueTable.css b/packages/oc-docs/src/components/KeyValueTable/KeyValueTable.css index 79c8b08c..7b7a522b 100644 --- a/packages/oc-docs/src/components/KeyValueTable/KeyValueTable.css +++ b/packages/oc-docs/src/components/KeyValueTable/KeyValueTable.css @@ -109,7 +109,6 @@ .key-value-table .checkbox-slot { flex: none; display: inline-flex; - align-items: center; width: 1rem; height: 1rem; } @@ -140,26 +139,6 @@ vertical-align: middle; } -.key-value-table .checkbox-input { - appearance: none; - -webkit-appearance: none; - margin: 0; - width: 1rem; - height: 1rem; - border: 0.0625rem solid var(--oc-table-border); - border-radius: 0.1875rem; - background-color: transparent; - background-repeat: no-repeat; - background-position: center; - cursor: pointer; -} - -.key-value-table .checkbox-input:checked { - background-color: var(--primary-color); - border-color: var(--primary-color); - background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='12'%20height='12'%20viewBox='0%200%2012%2012'%3E%3Cpath%20fill='none'%20stroke='%23fff'%20stroke-width='1.67'%20stroke-linecap='round'%20stroke-linejoin='round'%20d='M3%206.2%205%208.4%209%203.8'/%3E%3C/svg%3E"); -} - .key-value-table .text-input { width: 100%; border: 0.0625rem solid transparent; diff --git a/packages/oc-docs/src/components/KeyValueTable/KeyValueTable.tsx b/packages/oc-docs/src/components/KeyValueTable/KeyValueTable.tsx index 237807e3..dea08e61 100644 --- a/packages/oc-docs/src/components/KeyValueTable/KeyValueTable.tsx +++ b/packages/oc-docs/src/components/KeyValueTable/KeyValueTable.tsx @@ -6,6 +6,7 @@ import { WarningIcon } from '../../assets/icons'; import HighlightedInput from '../HighlightedInput/HighlightedInput'; import { SecretValue } from '../../ui/SecretValue/SecretValue'; import './KeyValueTable.css'; +import Checkbox from '../../ui/Checkbox/Checkbox'; export interface KeyValueRow { id: string; @@ -179,11 +180,9 @@ const KeyValueTable: React.FC = ({ {showEnabled && ( {!isLastEmptyRow && ( - updateField(index, 'enabled', e.target.checked)} /> )} diff --git a/packages/oc-docs/src/components/Playground/Content/Views/Common/HeadersTab/HeadersTab.spec.tsx b/packages/oc-docs/src/components/Playground/Content/Views/Common/HeadersTab/HeadersTab.spec.tsx index 232580be..aad27adf 100644 --- a/packages/oc-docs/src/components/Playground/Content/Views/Common/HeadersTab/HeadersTab.spec.tsx +++ b/packages/oc-docs/src/components/Playground/Content/Views/Common/HeadersTab/HeadersTab.spec.tsx @@ -24,9 +24,14 @@ describe('HeadersTab', () => { expect(values).toContain('text/html'); }); - it('renders the default title and a provided description', () => { + it('renders a provided title and description', () => { const root = useRenderToDom( - + ); expect(query(root, '.title').text.trim()).toBe('Headers'); expect(query(root, '.description').text.trim()).toBe('Request headers sent with the call'); diff --git a/packages/oc-docs/src/components/Playground/Content/Views/Common/ScriptsTab/ScriptsTab.spec.tsx b/packages/oc-docs/src/components/Playground/Content/Views/Common/ScriptsTab/ScriptsTab.spec.tsx index 8e38a97e..7d0d56f1 100644 --- a/packages/oc-docs/src/components/Playground/Content/Views/Common/ScriptsTab/ScriptsTab.spec.tsx +++ b/packages/oc-docs/src/components/Playground/Content/Views/Common/ScriptsTab/ScriptsTab.spec.tsx @@ -18,9 +18,8 @@ describe('ScriptsTab', () => { expect(query(root, '[data-testid="scripts-tabs-tab-post-response"]').text.trim()).toBe('Post response'); }); - it('renders the default title and the Tests section', () => { + it('renders the Tests section by default', () => { const root = useRenderToDom(); - expect(query(root, '.title').text.trim()).toBe('Scripts'); expect(query(root, '.label').text.trim()).toBe('Tests'); }); diff --git a/packages/oc-docs/src/components/Playground/Content/Views/EnvironmentsView/EnvVarCards/EnvVarCards.tsx b/packages/oc-docs/src/components/Playground/Content/Views/EnvironmentsView/EnvVarCards/EnvVarCards.tsx index d6af0b14..b0a5534a 100644 --- a/packages/oc-docs/src/components/Playground/Content/Views/EnvironmentsView/EnvVarCards/EnvVarCards.tsx +++ b/packages/oc-docs/src/components/Playground/Content/Views/EnvironmentsView/EnvVarCards/EnvVarCards.tsx @@ -7,6 +7,7 @@ import { cx } from '../../../../../../utils/cx'; import { toDataType } from '../../../../../../utils/variableDataType'; import { VariableTypeControl } from '../../Common/VariableTypeControl/VariableTypeControl'; import { StyledWrapper } from './StyledWrapper'; +import Checkbox from '../../../../../../ui/Checkbox/Checkbox'; interface EnvVarCardsProps { rows: KeyValueRow[]; @@ -38,11 +39,10 @@ const EnvVarCards: React.FC = ({ return (
{!isBlankRow && ( - updateRow(index, { enabled: e.target.checked })} /> )} @@ -69,7 +69,14 @@ const EnvVarCards: React.FC = ({
{row.secret ? ( - updateRow(index, { value: v })} className="value-secret" /> + updateRow(index, { value: v })} + className="value-secret" + /> ) : (