@awsui/components-react
Version:
On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en
87 lines • 6.16 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useRef } from 'react';
import clsx from 'clsx';
import { useResizeObserver } from '@awsui/component-toolkit/internal';
import { getAnalyticsMetadataAttribute } from '@awsui/component-toolkit/internal/analytics-metadata';
import { useInternalI18n } from '../../i18n/context';
import InternalIcon from '../../icon/internal';
import { useSingleTabStopNavigation } from '../../internal/context/single-tab-stop-navigation-context';
import { useMergeRefs } from '../../internal/hooks/use-merge-refs';
import { useUniqueId } from '../../internal/hooks/use-unique-id';
import { KeyCode } from '../../internal/keycode';
import { Divider, Resizer } from '../resizer';
import { TableThElement } from './th-element';
import { getSortingIconName, getSortingStatus, isSorted } from './utils';
import analyticsSelectors from '../analytics-metadata/styles.css.js';
import styles from './styles.css.js';
export function TableHeaderCell({ tabIndex, column, activeSortingColumn, sortingDescending, sortingDisabled, wrapLines, focusedComponent, stuck, sticky, hidden, stripedRows, onClick, colIndex, updateColumn, resizableColumns, resizableStyle, onResizeFinish, isEditable, columnId, stickyState, cellRef, tableRole, resizerRoleDescription, isExpandable, hasDynamicContent, variant, }) {
var _a;
const i18n = useInternalI18n('table');
const sortable = !!column.sortingComparator || !!column.sortingField;
const sorted = !!activeSortingColumn && isSorted(column, activeSortingColumn);
const sortingStatus = getSortingStatus(sortable, sorted, !!sortingDescending, !!sortingDisabled);
const handleClick = () => onClick({
sortingColumn: column,
isDescending: sorted ? !sortingDescending : false,
});
// Elements with role="button" do not have the default behavior of <button>, where pressing
// Enter or Space will trigger a click event. Therefore we need to add this ourselves.
// The native <button> element cannot be used due to a misaligned implementation in Firefox:
// https://bugzilla.mozilla.org/show_bug.cgi?id=843003
const handleKeyPress = ({ nativeEvent: e }) => {
if (e.keyCode === KeyCode.enter || e.keyCode === KeyCode.space) {
e.preventDefault();
handleClick();
}
};
const headerId = useUniqueId('table-header-');
const clickableHeaderRef = useRef(null);
const { tabIndex: clickableHeaderTabIndex } = useSingleTabStopNavigation(clickableHeaderRef, { tabIndex });
const cellRefObject = useRef(null);
const cellRefCombined = useMergeRefs(cellRef, cellRefObject);
// Keep sticky and non-sticky headers in sync for dynamic cell
// content changes. This is only needed when:
// - Column has dynamic content
// - This is the non-sticky version of a sticky header (hidden === true)
// - Columns are not resizable
useResizeObserver(hasDynamicContent ? cellRefObject : () => null, entry => {
updateColumn(columnId, entry.borderBoxWidth);
});
return (React.createElement(TableThElement, Object.assign({ resizableStyle: resizableStyle, cellRef: cellRefCombined, sortingStatus: sortingStatus, sortingDisabled: sortingDisabled, focusedComponent: focusedComponent, stuck: stuck, sticky: sticky, hidden: hidden, stripedRows: stripedRows, colIndex: colIndex, columnId: columnId, stickyState: stickyState, tableRole: tableRole, variant: variant }, (sortingDisabled
? {}
: getAnalyticsMetadataAttribute({
action: 'sort',
detail: {
position: `${colIndex + 1}`,
columnId: column.id ? `${column.id}` : '',
label: `.${analyticsSelectors['header-cell-text']}`,
sortingDescending: `${!sortingDescending}`,
},
}))),
React.createElement("div", Object.assign({ ref: clickableHeaderRef, "data-focus-id": `sorting-control-${String(columnId)}`, className: clsx(styles['header-cell-content'], {
[styles['header-cell-fake-focus']]: focusedComponent === `sorting-control-${String(columnId)}`,
[styles['header-cell-content-expandable']]: isExpandable,
}), "aria-label": column.ariaLabel
? column.ariaLabel({
sorted: sorted,
descending: sorted && !!sortingDescending,
disabled: !!sortingDisabled,
})
: undefined }, (sortingStatus && !sortingDisabled
? {
onKeyPress: handleKeyPress,
tabIndex: clickableHeaderTabIndex,
role: 'button',
onClick: handleClick,
}
: {})),
React.createElement("div", { className: clsx(styles['header-cell-text'], analyticsSelectors['header-cell-text'], wrapLines && styles['header-cell-text-wrap']), id: headerId },
column.header,
isEditable ? (React.createElement("span", { className: styles['edit-icon'] },
React.createElement(InternalIcon, { name: "edit", ariaLabel: i18n('columnDefinitions.editConfig.editIconAriaLabel', (_a = column.editConfig) === null || _a === void 0 ? void 0 : _a.editIconAriaLabel) }))) : null),
sortingStatus && (React.createElement("span", { className: styles['sorting-icon'] },
React.createElement(InternalIcon, { name: getSortingIconName(sortingStatus) })))),
resizableColumns ? (React.createElement(Resizer, { tabIndex: tabIndex, focusId: `resize-control-${String(columnId)}`, showFocusRing: focusedComponent === `resize-control-${String(columnId)}`, onWidthUpdate: newWidth => updateColumn(columnId, newWidth), onWidthUpdateCommit: onResizeFinish, ariaLabelledby: headerId, minWidth: typeof column.minWidth === 'string' ? parseInt(column.minWidth) : column.minWidth, roleDescription: i18n('ariaLabels.resizerRoleDescription', resizerRoleDescription) })) : (React.createElement(Divider, { className: styles['resize-divider'] }))));
}
//# sourceMappingURL=index.js.map