Skip to content

Commit

Permalink
Merge branch 'main' into media-container-iframe
Browse files Browse the repository at this point in the history
  • Loading branch information
avinashbot authored Aug 28, 2023
2 parents f4ae284 + fb4b027 commit 34de379
Show file tree
Hide file tree
Showing 38 changed files with 539 additions and 211 deletions.
20 changes: 16 additions & 4 deletions pages/table-fragments/grid-navigation-custom.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import {
Input,
Link,
SegmentedControl,
Select,
} from '~components';
import styles from './styles.scss';
import { id as generateId, generateItems, Instance } from '../table/generate-data';
import AppContext, { AppContextType } from '../app/app-context';
import {
TableRole,
getTableCellRoleProps,
getTableColHeaderRoleProps,
getTableHeaderRowRoleProps,
Expand All @@ -34,6 +36,7 @@ import appLayoutLabels from '../app-layout/utils/labels';
type PageContext = React.Context<
AppContextType<{
pageSize: number;
tableRole: TableRole;
}>
>;

Expand Down Expand Up @@ -94,10 +97,13 @@ const createColumnDefinitions = ({
{ key: 'type', label: 'Type', render: (item: Instance) => item.type },
];

const tableRoleOptions = [{ value: 'table' }, { value: 'grid' }, { value: 'grid-default' }];

export default function Page() {
const [toolsOpen, setToolsOpen] = useState(false);
const { urlParams, setUrlParams } = useContext(AppContext as PageContext);
const pageSize = urlParams.pageSize ?? 10;
const tableRole = urlParams.tableRole ?? 'grid';

const [items, setItems] = useState(generateItems(25));
const columnDefinitions = useMemo(
Expand All @@ -117,7 +123,6 @@ export default function Page() {

const tableRef = useRef<HTMLTableElement>(null);

const tableRole = 'grid';
useGridNavigation({ tableRole, pageSize, getTable: () => tableRef.current });

const sortedItems = useMemo(() => {
Expand Down Expand Up @@ -149,6 +154,14 @@ export default function Page() {
onChange={event => setUrlParams({ pageSize: parseInt(event.detail.value) })}
/>
</FormField>

<FormField label="Table role">
<Select
options={tableRoleOptions}
selectedOption={tableRoleOptions.find(option => option.value === tableRole) ?? null}
onChange={event => setUrlParams({ tableRole: event.detail.selectedOption.value as TableRole })}
/>
</FormField>
</ColumnLayout>

<Link onFollow={() => setToolsOpen(true)} data-testid="link-before">
Expand Down Expand Up @@ -178,7 +191,7 @@ export default function Page() {
<th
key={column.key}
className={styles['custom-table-cell']}
{...getTableColHeaderRoleProps({ tableRole, colIndex })}
{...getTableColHeaderRoleProps({ tableRole, colIndex, isWidget: true })}
>
<div style={{ display: 'flex', gap: '8px', flexWrap: 'nowrap' }}>
<button
Expand Down Expand Up @@ -208,8 +221,7 @@ export default function Page() {
<td
key={column.key}
className={styles['custom-table-cell']}
{...getTableCellRoleProps({ tableRole, colIndex })}
data-widget-cell={column.isWidget}
{...getTableCellRoleProps({ tableRole, colIndex, isWidget: column.isWidget })}
>
{column.render(item)}
</td>
Expand Down
8 changes: 7 additions & 1 deletion src/app-layout/__tests__/common.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,12 @@ describeEachAppLayout(size => {
});

test('Renders aria-expanded only on toggle', () => {
const { wrapper } = renderComponent(<AppLayout />);
const props = {
[openProp]: false,
[handler]: () => {},
};

const { wrapper } = renderComponent(<AppLayout {...props} />);
expect(findToggle(wrapper).getElement()).toHaveAttribute('aria-expanded', 'false');
expect(findToggle(wrapper).getElement()).toHaveAttribute('aria-haspopup', 'true');
expect(findClose(wrapper).getElement()).not.toHaveAttribute('aria-expanded');
Expand Down Expand Up @@ -294,6 +299,7 @@ describeEachAppLayout(size => {
expect(wrapper.findDrawersTriggers()![0].getElement()).toHaveAttribute('aria-expanded', 'false');
expect(wrapper.findDrawersTriggers()![0].getElement()).toHaveAttribute('aria-haspopup', 'true');
wrapper.findDrawersTriggers()![0].click();
expect(wrapper.findDrawersTriggers()![0].getElement()).toHaveAttribute('aria-expanded', 'true');
expect(wrapper.findActiveDrawerCloseButton()!.getElement()).not.toHaveAttribute('aria-expanded');
expect(wrapper.findActiveDrawerCloseButton()!.getElement()).not.toHaveAttribute('aria-haspopup');
});
Expand Down
7 changes: 7 additions & 0 deletions src/app-layout/__tests__/desktop.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,13 @@ describeEachThemeAppLayout(false, () => {

expect(wrapper.findDrawersTriggers()!.length).toBeLessThan(100);
});

test('Renders aria-controls on toggle only when active', () => {
const { wrapper } = renderComponent(<AppLayout contentType="form" {...singleDrawer} />);
expect(wrapper.findDrawersTriggers()![0].getElement()).not.toHaveAttribute('aria-controls');
act(() => wrapper.findDrawersTriggers()![0].click());
expect(wrapper.findDrawersTriggers()![0].getElement()).toHaveAttribute('aria-controls', 'security');
});
});

// In VR we use a custom CSS property so we cannot test the style declaration.
Expand Down
22 changes: 19 additions & 3 deletions src/app-layout/drawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,14 @@ export const Drawer = React.forwardRef(
iconName={iconName}
ariaLabel={openLabel}
onClick={() => onToggle(true)}
ariaExpanded={false}
ariaExpanded={isOpen ? undefined : false}
/>
</TagName>
);

return (
<div
id={drawers?.activeDrawerId}
ref={ref}
className={clsx(styles.drawer, {
[styles['drawer-closed']]: !isOpen,
Expand Down Expand Up @@ -132,6 +133,7 @@ interface DrawerTriggerProps {
testUtilsClassName?: string;
ariaLabel: string | undefined;
ariaExpanded: boolean;
ariaControls?: string;
badge: boolean | undefined;
itemId?: string;
isActive: boolean;
Expand All @@ -141,7 +143,17 @@ interface DrawerTriggerProps {

const DrawerTrigger = React.forwardRef(
(
{ testUtilsClassName, ariaLabel, ariaExpanded, badge, itemId, isActive, trigger, onClick }: DrawerTriggerProps,
{
testUtilsClassName,
ariaLabel,
ariaExpanded,
ariaControls,
badge,
itemId,
isActive,
trigger,
onClick,
}: DrawerTriggerProps,
ref: React.Ref<{ focus: () => void }>
) => (
<div className={clsx(styles['drawer-trigger'], isActive && styles['drawer-trigger-active'])} onClick={onClick}>
Expand All @@ -152,6 +164,7 @@ const DrawerTrigger = React.forwardRef(
iconSvg={trigger.iconSvg}
ariaLabel={ariaLabel}
ariaExpanded={ariaExpanded}
ariaControls={ariaControls}
badge={badge}
testId={itemId && `awsui-app-layout-trigger-${itemId}`}
/>
Expand Down Expand Up @@ -189,6 +202,8 @@ export const DrawerTriggersBar = ({ isMobile, topOffset, bottomOffset, drawers }
ref={triggersContainerRef}
style={{ top: topOffset, bottom: bottomOffset }}
className={clsx(styles['drawer-content'])}
role="toolbar"
aria-orientation="vertical"
>
{!isMobile && (
<aside
Expand All @@ -201,8 +216,9 @@ export const DrawerTriggersBar = ({ isMobile, topOffset, bottomOffset, drawers }
<DrawerTrigger
key={index}
testUtilsClassName={testutilStyles['drawers-trigger']}
ariaExpanded={drawers?.activeDrawerId !== undefined}
ariaExpanded={drawers?.activeDrawerId === item.id}
ariaLabel={item.ariaLabels?.triggerButton}
ariaControls={drawers?.activeDrawerId === item.id ? item.id : undefined}
trigger={item.trigger}
badge={item.badge}
itemId={item.id}
Expand Down
4 changes: 2 additions & 2 deletions src/app-layout/mobile-toolbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export function MobileToolbar({
aria-label={drawers.ariaLabel}
className={clsx(styles['drawers-container'], testutilStyles['drawers-mobile-triggers-container'])}
>
{visibleItems.map((item: DrawerItem, index: number) => (
{visibleItems.map((item, index) => (
<div
className={clsx(styles['mobile-toggle'], styles['mobile-toggle-type-drawer'])}
key={index}
Expand All @@ -141,7 +141,7 @@ export function MobileToolbar({
iconSvg={item.trigger.iconSvg}
badge={item.badge}
ariaLabel={item.ariaLabels?.triggerButton}
ariaExpanded={drawers.activeDrawerId !== undefined}
ariaExpanded={drawers.activeDrawerId === item.id}
testId={`awsui-app-layout-trigger-${item.id}`}
/>
</div>
Expand Down
16 changes: 14 additions & 2 deletions src/app-layout/toggles/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,18 @@ export const togglesConfig = {

export const ToggleButton = React.forwardRef(
(
{ className, ariaLabel, ariaExpanded, iconName, iconSvg, disabled, testId, onClick, badge }: AppLayoutButtonProps,
{
className,
ariaLabel,
ariaExpanded,
ariaControls,
iconName,
iconSvg,
disabled,
testId,
onClick,
badge,
}: AppLayoutButtonProps,
ref: React.Ref<{ focus(): void }>
) => {
return (
Expand All @@ -43,8 +54,9 @@ export const ToggleButton = React.forwardRef(
type="button"
onClick={onClick}
disabled={disabled}
aria-expanded={ariaExpanded ? undefined : false}
aria-expanded={ariaExpanded}
aria-haspopup={ariaExpanded ? undefined : true}
aria-controls={ariaControls}
data-testid={testId}
>
<InternalIcon svg={iconSvg} name={iconName} badge={badge} />
Expand Down
1 change: 1 addition & 0 deletions src/app-layout/toggles/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface AppLayoutButtonProps {
className?: string;
ariaLabel: string | undefined;
ariaExpanded?: boolean;
ariaControls?: string;
iconName?: IconProps.Name;
iconSvg?: React.ReactNode;
onClick?: () => void;
Expand Down
7 changes: 7 additions & 0 deletions src/app-layout/visual-refresh/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import styles from './styles.css.js';
import { useContainerQuery } from '@cloudscape-design/component-toolkit';
import useBackgroundOverlap from './use-background-overlap';
import { useDrawers } from '../utils/use-drawers';
import { useUniqueId } from '../../internal/hooks/use-unique-id';

interface AppLayoutInternals extends AppLayoutProps {
activeDrawerId: string | undefined;
Expand Down Expand Up @@ -77,6 +78,7 @@ interface AppLayoutInternals extends AppLayoutProps {
setSplitPanelReportedHeaderHeight: (value: number) => void;
headerHeight: number;
footerHeight: number;
splitPanelControlId: string;
splitPanelMaxWidth: number;
splitPanelMinWidth: number;
splitPanelPosition: AppLayoutProps.SplitPanelPosition;
Expand All @@ -86,6 +88,7 @@ interface AppLayoutInternals extends AppLayoutProps {
setSplitPanelToggle: (toggle: SplitPanelSideToggleProps) => void;
splitPanelDisplayed: boolean;
splitPanelRefs: SplitPanelFocusControlRefs;
toolsControlId: string;
toolsRefs: FocusControlRefs;
}

Expand Down Expand Up @@ -376,6 +379,8 @@ export const AppLayoutInternalsProvider = React.forwardRef(
ariaLabel: undefined,
});
const splitPanelDisplayed = !!(splitPanelToggle.displayed || isSplitPanelOpen);
const splitPanelControlId = useUniqueId('split-panel-');
const toolsControlId = useUniqueId('tools-');

const [splitPanelSize, setSplitPanelSize] = useControllable(
props.splitPanelSize,
Expand Down Expand Up @@ -637,6 +642,7 @@ export const AppLayoutInternalsProvider = React.forwardRef(
setSplitPanelReportedSize,
setSplitPanelReportedHeaderHeight,
splitPanel,
splitPanelControlId,
splitPanelDisplayed,
splitPanelMaxWidth,
splitPanelMinWidth,
Expand All @@ -648,6 +654,7 @@ export const AppLayoutInternalsProvider = React.forwardRef(
splitPanelToggle,
setSplitPanelToggle,
splitPanelRefs,
toolsControlId,
toolsHide,
toolsOpen: isToolsOpen,
toolsWidth,
Expand Down
36 changes: 18 additions & 18 deletions src/app-layout/visual-refresh/drawers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ function ActiveDrawer() {

return (
<aside
id={activeDrawerId}
aria-hidden={isHidden}
aria-label={computedAriaLabels.content}
className={clsx(styles.drawer, sharedStyles['with-motion'], {
Expand Down Expand Up @@ -158,6 +159,7 @@ function DesktopTriggers() {
isSplitPanelOpen,
isToolsOpen,
splitPanel,
splitPanelControlId,
splitPanelDisplayed,
splitPanelPosition,
splitPanelRefs,
Expand Down Expand Up @@ -220,11 +222,15 @@ function DesktopTriggers() {
[styles['has-multiple-triggers']]: hasMultipleTriggers,
[styles['has-open-drawer']]: hasOpenDrawer,
})}
role="toolbar"
aria-orientation="vertical"
>
{visibleItems.map(item => {
return (
<TriggerButton
ariaLabel={item.ariaLabels?.triggerButton}
ariaExpanded={item.id === activeDrawerId}
ariaControls={activeDrawerId === item.id ? item.id : undefined}
className={clsx(styles['drawers-trigger'], testutilStyles['drawers-trigger'])}
iconName={item.trigger.iconName}
iconSvg={item.trigger.iconSvg}
Expand All @@ -245,24 +251,16 @@ function DesktopTriggers() {
<OverflowMenu
items={overflowItems}
ariaLabel={drawersOverflowAriaLabel}
customTriggerBuilder={({ onClick, triggerRef, ariaLabel, testUtilsClass }) => (
<div className={clsx(styles['trigger-wrapper'])}>
<TriggerButton
ref={triggerRef}
ariaLabel={ariaLabel}
className={clsx(
styles['drawers-trigger'],
{
[styles.badge]: overflowMenuHasBadge,
},
testutilStyles['drawers-trigger'],
testUtilsClass
)}
iconName="ellipsis"
onClick={onClick}
/>
{overflowMenuHasBadge && <div className={clsx(styles.dot)} />}
</div>
customTriggerBuilder={({ onClick, triggerRef, ariaLabel, ariaExpanded, testUtilsClass }) => (
<TriggerButton
ref={triggerRef}
ariaLabel={ariaLabel}
ariaExpanded={ariaExpanded}
badge={overflowMenuHasBadge}
className={clsx(styles['drawers-trigger'], testutilStyles['drawers-trigger'], testUtilsClass)}
iconName="ellipsis"
onClick={onClick}
/>
)}
onItemClick={({ detail }) => {
handleDrawersClick(detail.id);
Expand All @@ -272,6 +270,8 @@ function DesktopTriggers() {
{hasSplitPanel && splitPanelToggle.displayed && (
<TriggerButton
ariaLabel={splitPanelToggle.ariaLabel}
ariaControls={splitPanelControlId}
ariaExpanded={!!isSplitPanelOpen}
className={clsx(styles['drawers-trigger'], splitPanelStyles['open-button'])}
iconName="view-vertical"
onClick={() => handleSplitPanelClick()}
Expand Down
1 change: 1 addition & 0 deletions src/app-layout/visual-refresh/navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export default function Navigation() {
>
<TriggerButton
ariaLabel={ariaLabels?.navigationToggle}
ariaExpanded={isNavigationOpen ? undefined : false}
iconName="menu"
className={testutilStyles['navigation-toggle']}
onClick={() => handleNavigationClick(true)}
Expand Down
2 changes: 2 additions & 0 deletions src/app-layout/visual-refresh/split-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ function SplitPanelSide() {
splitPanelMaxWidth,
splitPanelMinWidth,
splitPanelReportedSize,
splitPanelControlId,
} = useAppLayoutInternals();

if (!splitPanel) {
Expand All @@ -130,6 +131,7 @@ function SplitPanelSide() {
<Transition in={isSplitPanelOpen ?? false} exit={false}>
{(state, transitionEventsRef) => (
<section
id={splitPanelControlId}
aria-hidden={!isSplitPanelOpen || splitPanelPosition === 'bottom' ? true : false}
className={clsx(styles['split-panel-side'], styles[`position-${splitPanelPosition}`], {
[styles.animating]: state === 'entering',
Expand Down
Loading

0 comments on commit 34de379

Please sign in to comment.