Skip to content

Commit b4f0b2f

Browse files
authored
feat: Add directional resize buttons to code editor's resize control (#3311)
1 parent 1803277 commit b4f0b2f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1408
-124
lines changed

pages/code-editor/base-props.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,7 @@ export const i18nStrings: CodeEditorProps.I18nStrings = {
3535
preferencesModalThemeFilteringAriaLabel: 'Filter themes',
3636
preferencesModalThemeFilteringClearAriaLabel: 'Clear',
3737
preferencesModalThemeFilteringPlaceholder: 'Filter themes',
38+
39+
resizeHandleAriaLabel: 'Resize handle',
40+
resizeHandleTooltipText: 'Drag or select to resize',
3841
};

src/__integ__/__snapshots__/themes.test.ts.snap

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "compact" 1`] =
7171
"color-background-control-checked": "#0073bb",
7272
"color-background-control-default": "#ffffff",
7373
"color-background-control-disabled": "#d5dbdb",
74+
"color-background-direction-button-active": "#2a2e33",
75+
"color-background-direction-button-default": "#545b64",
76+
"color-background-direction-button-disabled": "#eaeded",
77+
"color-background-direction-button-hover": "#414750",
7478
"color-background-dropdown-item-default": "#ffffff",
7579
"color-background-dropdown-item-dimmed": "transparent",
7680
"color-background-dropdown-item-filter-match": "#f1faff",
@@ -382,6 +386,8 @@ exports[`CSS Custom Properties match previous snapshot for mode "compact" 1`] =
382386
"color-text-column-sorting-icon": "#687078",
383387
"color-text-control-disabled": "#aab7b8",
384388
"color-text-counter": "#687078",
389+
"color-text-direction-button-default": "#ffffff",
390+
"color-text-direction-button-disabled": "#aab7b8",
385391
"color-text-disabled": "#aab7b8",
386392
"color-text-disabled-inline-edit": "#545b64",
387393
"color-text-dropdown-footer": "#687078",
@@ -730,6 +736,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "dark" 1`] = `
730736
"color-background-control-checked": "#00a1c9",
731737
"color-background-control-default": "#1a2029",
732738
"color-background-control-disabled": "#414750",
739+
"color-background-direction-button-active": "#2a2e33",
740+
"color-background-direction-button-default": "#545b64",
741+
"color-background-direction-button-disabled": "#2a2e33",
742+
"color-background-direction-button-hover": "#414750",
733743
"color-background-dropdown-item-default": "#2a2e33",
734744
"color-background-dropdown-item-dimmed": "transparent",
735745
"color-background-dropdown-item-filter-match": "#12293b",
@@ -1041,6 +1051,8 @@ exports[`CSS Custom Properties match previous snapshot for mode "dark" 1`] = `
10411051
"color-text-column-sorting-icon": "#95a5a6",
10421052
"color-text-control-disabled": "#687078",
10431053
"color-text-counter": "#95a5a6",
1054+
"color-text-direction-button-default": "#ffffff",
1055+
"color-text-direction-button-disabled": "#687078",
10441056
"color-text-disabled": "#687078",
10451057
"color-text-disabled-inline-edit": "#95a5a6",
10461058
"color-text-dropdown-footer": "#95a5a6",
@@ -1389,6 +1401,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "light" 1`] = `
13891401
"color-background-control-checked": "#0073bb",
13901402
"color-background-control-default": "#ffffff",
13911403
"color-background-control-disabled": "#d5dbdb",
1404+
"color-background-direction-button-active": "#2a2e33",
1405+
"color-background-direction-button-default": "#545b64",
1406+
"color-background-direction-button-disabled": "#eaeded",
1407+
"color-background-direction-button-hover": "#414750",
13921408
"color-background-dropdown-item-default": "#ffffff",
13931409
"color-background-dropdown-item-dimmed": "transparent",
13941410
"color-background-dropdown-item-filter-match": "#f1faff",
@@ -1700,6 +1716,8 @@ exports[`CSS Custom Properties match previous snapshot for mode "light" 1`] = `
17001716
"color-text-column-sorting-icon": "#687078",
17011717
"color-text-control-disabled": "#aab7b8",
17021718
"color-text-counter": "#687078",
1719+
"color-text-direction-button-default": "#ffffff",
1720+
"color-text-direction-button-disabled": "#aab7b8",
17031721
"color-text-disabled": "#aab7b8",
17041722
"color-text-disabled-inline-edit": "#545b64",
17051723
"color-text-dropdown-footer": "#687078",
@@ -2048,6 +2066,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "reduced-motion"
20482066
"color-background-control-checked": "#0073bb",
20492067
"color-background-control-default": "#ffffff",
20502068
"color-background-control-disabled": "#d5dbdb",
2069+
"color-background-direction-button-active": "#2a2e33",
2070+
"color-background-direction-button-default": "#545b64",
2071+
"color-background-direction-button-disabled": "#eaeded",
2072+
"color-background-direction-button-hover": "#414750",
20512073
"color-background-dropdown-item-default": "#ffffff",
20522074
"color-background-dropdown-item-dimmed": "transparent",
20532075
"color-background-dropdown-item-filter-match": "#f1faff",
@@ -2359,6 +2381,8 @@ exports[`CSS Custom Properties match previous snapshot for mode "reduced-motion"
23592381
"color-text-column-sorting-icon": "#687078",
23602382
"color-text-control-disabled": "#aab7b8",
23612383
"color-text-counter": "#687078",
2384+
"color-text-direction-button-default": "#ffffff",
2385+
"color-text-direction-button-disabled": "#aab7b8",
23622386
"color-text-disabled": "#aab7b8",
23632387
"color-text-disabled-inline-edit": "#545b64",
23642388
"color-text-dropdown-footer": "#687078",
@@ -2707,6 +2731,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh"
27072731
"color-background-control-checked": "#006ce0",
27082732
"color-background-control-default": "#ffffff",
27092733
"color-background-control-disabled": "#dedee3",
2734+
"color-background-direction-button-active": "#232b37",
2735+
"color-background-direction-button-default": "#424650",
2736+
"color-background-direction-button-disabled": "#ebebf0",
2737+
"color-background-direction-button-hover": "#333843",
27102738
"color-background-dropdown-item-default": "#ffffff",
27112739
"color-background-dropdown-item-dimmed": "transparent",
27122740
"color-background-dropdown-item-filter-match": "#f0fbff",
@@ -3018,6 +3046,8 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh"
30183046
"color-text-column-sorting-icon": "#424650",
30193047
"color-text-control-disabled": "#b4b4bb",
30203048
"color-text-counter": "#656871",
3049+
"color-text-direction-button-default": "#ffffff",
3050+
"color-text-direction-button-disabled": "#b4b4bb",
30213051
"color-text-disabled": "#b4b4bb",
30223052
"color-text-disabled-inline-edit": "#424650",
30233053
"color-text-dropdown-footer": "#656871",
@@ -3366,6 +3396,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh-
33663396
"color-background-control-checked": "#006ce0",
33673397
"color-background-control-default": "#ffffff",
33683398
"color-background-control-disabled": "#dedee3",
3399+
"color-background-direction-button-active": "#232b37",
3400+
"color-background-direction-button-default": "#424650",
3401+
"color-background-direction-button-disabled": "#ebebf0",
3402+
"color-background-direction-button-hover": "#333843",
33693403
"color-background-dropdown-item-default": "#ffffff",
33703404
"color-background-dropdown-item-dimmed": "transparent",
33713405
"color-background-dropdown-item-filter-match": "#f0fbff",
@@ -3677,6 +3711,8 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh-
36773711
"color-text-column-sorting-icon": "#424650",
36783712
"color-text-control-disabled": "#b4b4bb",
36793713
"color-text-counter": "#656871",
3714+
"color-text-direction-button-default": "#ffffff",
3715+
"color-text-direction-button-disabled": "#b4b4bb",
36803716
"color-text-disabled": "#b4b4bb",
36813717
"color-text-disabled-inline-edit": "#424650",
36823718
"color-text-dropdown-footer": "#656871",
@@ -4025,6 +4061,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh-
40254061
"color-background-control-checked": "#42b4ff",
40264062
"color-background-control-default": "#0f141a",
40274063
"color-background-control-disabled": "#333843",
4064+
"color-background-direction-button-active": "#232b37",
4065+
"color-background-direction-button-default": "#424650",
4066+
"color-background-direction-button-disabled": "#232b37",
4067+
"color-background-direction-button-hover": "#333843",
40284068
"color-background-dropdown-item-default": "#1b232d",
40294069
"color-background-dropdown-item-dimmed": "transparent",
40304070
"color-background-dropdown-item-filter-match": "#333843",
@@ -4336,6 +4376,8 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh-
43364376
"color-text-column-sorting-icon": "#b4b4bb",
43374377
"color-text-control-disabled": "#656871",
43384378
"color-text-counter": "#a4a4ad",
4379+
"color-text-direction-button-default": "#ffffff",
4380+
"color-text-direction-button-disabled": "#656871",
43394381
"color-text-disabled": "#656871",
43404382
"color-text-disabled-inline-edit": "#b4b4bb",
43414383
"color-text-dropdown-footer": "#a4a4ad",
@@ -4684,6 +4726,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh-
46844726
"color-background-control-checked": "#42b4ff",
46854727
"color-background-control-default": "#161d26",
46864728
"color-background-control-disabled": "#333843",
4729+
"color-background-direction-button-active": "#232b37",
4730+
"color-background-direction-button-default": "#424650",
4731+
"color-background-direction-button-disabled": "#232b37",
4732+
"color-background-direction-button-hover": "#333843",
46874733
"color-background-dropdown-item-default": "#1b232d",
46884734
"color-background-dropdown-item-dimmed": "transparent",
46894735
"color-background-dropdown-item-filter-match": "#333843",
@@ -4995,6 +5041,8 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh-
49955041
"color-text-column-sorting-icon": "#b4b4bb",
49965042
"color-text-control-disabled": "#656871",
49975043
"color-text-counter": "#a4a4ad",
5044+
"color-text-direction-button-default": "#ffffff",
5045+
"color-text-direction-button-disabled": "#656871",
49985046
"color-text-disabled": "#656871",
49995047
"color-text-disabled-inline-edit": "#b4b4bb",
50005048
"color-text-dropdown-footer": "#a4a4ad",

src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5690,6 +5690,16 @@ The object should contain, among others:
56905690
"optional": true,
56915691
"type": "string",
56925692
},
5693+
{
5694+
"name": "resizeHandleAriaLabel",
5695+
"optional": true,
5696+
"type": "string",
5697+
},
5698+
{
5699+
"name": "resizeHandleTooltipText",
5700+
"optional": true,
5701+
"type": "string",
5702+
},
56935703
{
56945704
"name": "statusBarGroupAriaLabel",
56955705
"optional": true,

src/code-editor/__integ__/code-editor.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ test(
142142

143143
await page.keys('Tab'); // Tab into gutter
144144
await page.keys('Tab'); // Tab into editor area
145+
await page.keys('Tab'); // Tab into drag handle
145146
await page.keys('Tab');
146147
await expect(page.isFocused(codeEditorWrapper.findSettingsButton().toSelector())).resolves.toBe(true);
147148

src/code-editor/__tests__/code-editor.test.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { createWrapper } from '@cloudscape-design/test-utils-core/dom';
1010
import '../../__a11y__/to-validate-a11y';
1111
import CodeEditor, { CodeEditorProps } from '../../../lib/components/code-editor';
1212
import TestI18nProvider from '../../../lib/components/i18n/testing';
13+
import { PointerEventMock } from '../../../lib/components/internal/utils/pointer-events-mock.js';
1314
import { CodeEditorWrapper, ElementWrapper } from '../../../lib/components/test-utils/dom';
1415
import { KeyCode } from '../../internal/keycode';
1516
import {
@@ -22,13 +23,18 @@ import {
2223

2324
import resizableStyles from '../../../lib/components/code-editor/resizable-box/styles.css.js';
2425
import styles from '../../../lib/components/code-editor/styles.css.js';
26+
import dragHandleStyles from '../../../lib/components/internal/components/drag-handle/styles.css.js';
2527
import liveRegionStyles from '../../../lib/components/live-region/test-classes/styles.css.js';
2628

2729
jest.mock('@cloudscape-design/component-toolkit/internal', () => ({
2830
...jest.requireActual('@cloudscape-design/component-toolkit/internal'),
2931
warnOnce: jest.fn(),
3032
}));
3133

34+
beforeAll(() => {
35+
(window as any).PointerEvent ??= PointerEventMock;
36+
});
37+
3238
afterEach(() => {
3339
(warnOnce as jest.Mock).mockReset();
3440
});
@@ -512,8 +518,8 @@ describe('Code editor component', () => {
512518
it('updates size when resize handle is dragged', () => {
513519
const { wrapper } = renderCodeEditor({ editorContentHeight: 10 });
514520
editorMock.resize.mockClear();
515-
fireEvent.mouseDown(wrapper.findByClassName(resizableStyles['resizable-box-handle'])!.getElement());
516-
fireEvent.mouseMove(document.body, { clientY: 100 });
521+
fireEvent.pointerDown(wrapper.findByClassName(dragHandleStyles.handle)!.getElement());
522+
fireEvent.pointerMove(document, { clientY: 100 });
517523
expect(editorMock.resize).toHaveBeenCalledTimes(1);
518524
});
519525

@@ -637,6 +643,7 @@ describe('Code editor component', () => {
637643
messages={{
638644
'code-editor': {
639645
'i18nStrings.paneCloseButtonAriaLabel': 'Custom close',
646+
'i18nStrings.resizeHandleAriaLabel': 'Custom resize handle',
640647
},
641648
}}
642649
>
@@ -647,6 +654,10 @@ describe('Code editor component', () => {
647654
act(() => emulateAceAnnotationEvent!());
648655
wrapper.findErrorsTab()!.click();
649656
expect(wrapper.findPane()!.findButton()!.getElement()).toHaveAttribute('aria-label', 'Custom close');
657+
expect(wrapper.findPane()!.find('[role=slider]')!.getElement()).toHaveAttribute(
658+
'aria-label',
659+
'Custom resize handle'
660+
);
650661
});
651662

652663
test('supports using preferences modal strings from i18n provider', () => {

src/code-editor/__tests__/common.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@ export const i18nStrings: CodeEditorProps.I18nStrings = {
2828
preferencesModalThemeFilteringAriaLabel: 'Filter themes aria',
2929
preferencesModalThemeFilteringClearAriaLabel: 'Clear',
3030
preferencesModalThemeFilteringPlaceholder: 'Filter themes',
31+
32+
resizeHandleAriaLabel: 'Resize handle',
33+
resizeHandleTooltipText: 'Drag or select to resize',
3134
};

src/code-editor/assets/resize-handler.svg

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/code-editor/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ const CodeEditor = forwardRef((props: CodeEditorProps, ref: React.Ref<CodeEditor
221221
onResize();
222222
fireNonCancelableEvent(onEditorContentResize, { height });
223223
}}
224+
handleAriaLabel={i18n('i18nStrings.resizeHandleAriaLabel', i18nStrings?.resizeHandleAriaLabel)}
225+
handleTooltipText={i18n('i18nStrings.resizeHandleTooltipText', i18nStrings?.resizeHandleTooltipText)}
224226
>
225227
<div
226228
ref={editorRef}
@@ -272,6 +274,8 @@ const CodeEditor = forwardRef((props: CodeEditorProps, ref: React.Ref<CodeEditor
272274
format => (row, column) => format({ row, column })
273275
)}
274276
closeButtonAriaLabel={i18n('i18nStrings.paneCloseButtonAriaLabel', i18nStrings?.paneCloseButtonAriaLabel)}
277+
handleAriaLabel={i18n('i18nStrings.resizeHandleAriaLabel', i18nStrings?.resizeHandleAriaLabel)}
278+
handleTooltipText={i18n('i18nStrings.resizeHandleTooltipText', i18nStrings?.resizeHandleTooltipText)}
275279
/>
276280
</div>
277281
{isPreferencesModalVisible && (

src/code-editor/interfaces.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ export namespace CodeEditorProps {
167167
preferencesModalThemeFilteringPlaceholder?: string;
168168
preferencesModalThemeFilteringAriaLabel?: string;
169169
preferencesModalThemeFilteringClearAriaLabel?: string;
170+
171+
resizeHandleAriaLabel?: string;
172+
resizeHandleTooltipText?: string;
170173
}
171174
export interface ResizeDetail {
172175
height: number;

src/code-editor/pane.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ interface PaneProps {
2626

2727
cursorPositionLabel?: (row: number, column: number) => string;
2828
closeButtonAriaLabel?: string;
29+
handleAriaLabel?: string;
30+
handleTooltipText?: string;
2931

3032
onClose: () => void;
3133
onAnnotationClick: (annotation: Ace.Annotation) => void;
@@ -43,6 +45,8 @@ export const Pane = ({
4345
onAnnotationClear,
4446
cursorPositionLabel,
4547
closeButtonAriaLabel,
48+
handleAriaLabel,
49+
handleTooltipText,
4650
}: PaneProps) => {
4751
const [paneHeight, setPaneHeight] = useState(MIN_HEIGHT);
4852
const listRef = useRef<HTMLTableSectionElement>(null);
@@ -88,7 +92,13 @@ export const Pane = ({
8892

8993
return (
9094
<div id={id} className={styles.pane} onKeyDown={onEscKeyDown} role="tabpanel" aria-labelledby={ariaLabelledBy}>
91-
<ResizableBox height={paneHeight} minHeight={MIN_HEIGHT} onResize={newHeight => setPaneHeight(newHeight)}>
95+
<ResizableBox
96+
height={paneHeight}
97+
minHeight={MIN_HEIGHT}
98+
onResize={newHeight => setPaneHeight(newHeight)}
99+
handleAriaLabel={handleAriaLabel}
100+
handleTooltipText={handleTooltipText}
101+
>
92102
<FocusLock className={styles['focus-lock']} autoFocus={true} restoreFocus={true}>
93103
<div className={styles.pane__list} tabIndex={-1}>
94104
<table className={styles.pane__table} role="presentation">

0 commit comments

Comments
 (0)