Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Components): Pass data-, aria- and id props to rendered component #263

Merged
merged 2 commits into from
Jan 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions packages/base/src/hooks/usePassThroughHtmlProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useMemo } from 'react';

const PROP_WHITELIST = /^(aria-|data-|id$)/;

export const usePassThroughHtmlProps = (props) => {
const passThroughPropNames = Object.keys(props).filter((name) => PROP_WHITELIST.test(name));

return useMemo(
() => {
return passThroughPropNames.reduce(
(acc, val) => ({
...acc,
[val]: props[val]
}),
{}
);
},
passThroughPropNames.map((name) => props[name])
);
};
4 changes: 3 additions & 1 deletion packages/base/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import * as sap_fiori_3 from './lib/sap_fiori_3';
import * as spacing from './lib/spacing';
import { StyleClassHelper } from './lib/StyleClassHelper';
import { useConsolidatedRef } from './lib/useConsolidatedRef';
import { usePassThroughHtmlProps } from './lib/usePassThroughHtmlProps';
import { deprecationNotice, getScrollBarWidth } from './lib/Utils';

export {
Expand All @@ -28,5 +29,6 @@ export {
HSLColor,
sap_fiori_3,
createGenerateClassName,
useConsolidatedRef
useConsolidatedRef,
usePassThroughHtmlProps
};
3 changes: 3 additions & 0 deletions packages/base/src/lib/usePassThroughHtmlProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { usePassThroughHtmlProps } from '../hooks/usePassThroughHtmlProps';

export { usePassThroughHtmlProps };
8 changes: 5 additions & 3 deletions packages/main/src/components/ActionSheet/ActionSheet.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { mountThemedComponent } from '@shared/tests/utils';
import React, { createRef, RefObject } from 'react';
import { Ui5PopoverDomRef } from '../../interfaces/Ui5PopoverDomRef';
import { createPassThroughPropsTest, mountThemedComponent } from '@shared/tests/utils';
import { ActionSheet } from '@ui5/webcomponents-react/lib/ActionSheet';
import { Button } from '@ui5/webcomponents-react/lib/Button';
import React, { createRef, RefObject } from 'react';
import { Ui5PopoverDomRef } from '../../interfaces/Ui5PopoverDomRef';

describe('ActionSheet', () => {
test('Render without Crashing', () => {
Expand All @@ -28,4 +28,6 @@ describe('ActionSheet', () => {
mountThemedComponent(<ActionSheet ref={ref} openBy={button} />);
expect((ref.current as any).tagName).toEqual('UI5-POPOVER');
});

createPassThroughPropsTest(ActionSheet);
});
12 changes: 11 additions & 1 deletion packages/main/src/components/ActionSheet/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Device } from '@ui5/webcomponents-react-base/lib/Device';
import { StyleClassHelper } from '@ui5/webcomponents-react-base/lib/StyleClassHelper';
import { usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/usePassThroughHtmlProps';
import { useConsolidatedRef } from '@ui5/webcomponents-react-base/lib/useConsolidatedRef';
import React, { Children, cloneElement, forwardRef, ReactElement, ReactNode, RefObject, FC } from 'react';
import { CommonProps } from '../../interfaces/CommonProps';
Expand Down Expand Up @@ -55,8 +56,17 @@ const ActionSheet: FC<ActionSheetPropTypes> = forwardRef(
}
};

const passThroughProps = usePassThroughHtmlProps(props);

return (
<Popover ref={popoverRef} openBy={openBy} placementType={placement} style={style} slot={slot}>
<Popover
ref={popoverRef}
openBy={openBy}
placementType={placement}
style={style}
slot={slot}
{...passThroughProps}
>
<ul className={actionSheetClasses.valueOf()}>{Children.map(children, renderActionSheetButton)}</ul>
</Popover>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mountThemedComponent } from '@shared/tests/utils';
import { createPassThroughPropsTest, mountThemedComponent } from '@shared/tests/utils';
import React from 'react';
import { AnalyticalCard } from '@ui5/webcomponents-react/lib/AnalyticalCard';
import { AnalyticalCardHeader } from '@ui5/webcomponents-react/lib/AnalyticalCardHeader';
Expand Down Expand Up @@ -32,4 +32,6 @@ describe('Analytical Card', () => {
);
expect(wrapper.render()).toMatchSnapshot();
});

createPassThroughPropsTest(AnalyticalCard);
});
12 changes: 11 additions & 1 deletion packages/main/src/components/AnalyticalCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/usePassThroughHtmlProps';
import { StyleClassHelper } from '@ui5/webcomponents-react-base/lib/StyleClassHelper';
import React, { CSSProperties, FC, forwardRef, ReactNode, ReactNodeArray, Ref, useMemo } from 'react';
import { createUseStyles } from 'react-jss';
Expand Down Expand Up @@ -35,8 +36,17 @@ export const AnalyticalCard: FC<AnalyticalCardTypes> = forwardRef(
...style
};
}, [style, width]);

const passThroughProps = usePassThroughHtmlProps(props);

return (
<div ref={ref} className={classNameString.toString()} style={analyticalCardStyles} title={tooltip}>
<div
ref={ref}
className={classNameString.toString()}
style={analyticalCardStyles}
title={tooltip}
{...passThroughProps}
>
{header}
<div className={classes.content}>{children}</div>
</div>
Expand Down
25 changes: 18 additions & 7 deletions packages/main/src/components/AnalyticalCardHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { Event } from '@ui5/webcomponents-react-base/lib/Event';
import { StyleClassHelper } from '@ui5/webcomponents-react-base/lib/StyleClassHelper';
import React, { FC, forwardRef, Ref, useCallback, useMemo } from 'react';
import { CommonProps } from '../../interfaces/CommonProps';
import { usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/usePassThroughHtmlProps';
import { DeviationIndicator } from '@ui5/webcomponents-react/lib/DeviationIndicator';
import { ObjectStatus } from '@ui5/webcomponents-react/lib/ObjectStatus';
import { ValueState } from '@ui5/webcomponents-react/lib/ValueState';
import { FlexBox } from '@ui5/webcomponents-react/lib/FlexBox';
import { FlexBoxAlignItems } from '@ui5/webcomponents-react/lib/FlexBoxAlignItems';
import { FlexBoxDirection } from '@ui5/webcomponents-react/lib/FlexBoxDirection';
import { FlexBoxJustifyContent } from '@ui5/webcomponents-react/lib/FlexBoxJustifyContent';
import { FlexBoxWrap } from '@ui5/webcomponents-react/lib/FlexBoxWrap';
import styles from './AnalyticalCardHeader.jss';
import { JSSTheme } from '../../interfaces/JSSTheme';
import { ObjectStatus } from '@ui5/webcomponents-react/lib/ObjectStatus';
import { ValueState } from '@ui5/webcomponents-react/lib/ValueState';
import React, { FC, forwardRef, Ref, useCallback, useMemo } from 'react';
import { createUseStyles } from 'react-jss';
import { CommonProps } from '../../interfaces/CommonProps';
import { JSSTheme } from '../../interfaces/JSSTheme';
import styles from './AnalyticalCardHeader.jss';

export interface AnalyticalCardHeaderPropTypes extends CommonProps {
title?: string;
Expand Down Expand Up @@ -119,8 +120,18 @@ export const AnalyticalCardHeader: FC<AnalyticalCardHeaderPropTypes> = forwardRe
headerClasses.put(className);
}
const shouldRenderContent = [value, unit, deviation, target].some((v) => v !== null);

const passThroughProps = usePassThroughHtmlProps(props);

return (
<div ref={ref} onClick={onClick} className={headerClasses.valueOf()} title={tooltip} style={style}>
<div
ref={ref}
onClick={onClick}
className={headerClasses.valueOf()}
title={tooltip}
style={style}
{...passThroughProps}
>
<div className={classes.headerContent}>
<div className={classes.headerTitles}>
<FlexBox justifyContent={FlexBoxJustifyContent.SpaceBetween} wrap={FlexBoxWrap.NoWrap}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mountThemedComponent } from '@shared/tests/utils';
import { createPassThroughPropsTest, mountThemedComponent } from '@shared/tests/utils';
import { AnalyticalTable } from '@ui5/webcomponents-react/lib/AnalyticalTable';
import { TableSelectionMode } from '@ui5/webcomponents-react/lib/TableSelectionMode';
import React from 'react';
Expand Down Expand Up @@ -259,4 +259,6 @@ describe('AnalyticalTable', () => {

expect(wrapper.render()).toMatchSnapshot();
});

createPassThroughPropsTest(AnalyticalTable);
});
5 changes: 4 additions & 1 deletion packages/main/src/components/AnalyticalTable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Device } from '@ui5/webcomponents-react-base/lib/Device';
import { Event } from '@ui5/webcomponents-react-base/lib/Event';
import { StyleClassHelper } from '@ui5/webcomponents-react-base/lib/StyleClassHelper';
import { usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/usePassThroughHtmlProps';
import { ContentDensity } from '@ui5/webcomponents-react/lib/ContentDensity';
import { TableSelectionMode } from '@ui5/webcomponents-react/lib/TableSelectionMode';
import { TextAlign } from '@ui5/webcomponents-react/lib/TextAlign';
Expand Down Expand Up @@ -309,8 +310,10 @@ const AnalyticalTable: FC<TableProps> = forwardRef((props: TableProps, ref: Ref<
tableState.columnResizing
);

const passThroughProps = usePassThroughHtmlProps(props);

return (
<div className={className} style={style} title={tooltip} ref={analyticalTableRef}>
<div className={className} style={style} title={tooltip} ref={analyticalTableRef} {...passThroughProps}>
{title && <TitleBar>{title}</TitleBar>}
{typeof renderExtension === 'function' && <div>{renderExtension()}</div>}
<div className={tableContainerClasses.valueOf()} ref={tableRef}>
Expand Down
4 changes: 3 additions & 1 deletion packages/main/src/components/Avatar/Avatar.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mountThemedComponent } from '@shared/tests/utils';
import { createPassThroughPropsTest, mountThemedComponent } from '@shared/tests/utils';
import React from 'react';
import sinon from 'sinon';
import { Avatar } from '@ui5/webcomponents-react/lib/Avatar';
Expand Down Expand Up @@ -72,4 +72,6 @@ describe('Avatar', () => {
wrapper.find(Avatar).simulate('keyDown', { key: 'ArrowLeft' });
expect(callback.called).toBe(false);
});

createPassThroughPropsTest(Avatar);
});
4 changes: 4 additions & 0 deletions packages/main/src/components/Avatar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Event } from '@ui5/webcomponents-react-base/lib/Event';
import { usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/usePassThroughHtmlProps';
import { AvatarShape } from '@ui5/webcomponents-react/lib/AvatarShape';
import { AvatarSize } from '@ui5/webcomponents-react/lib/AvatarSize';
import React, { CSSProperties, FC, forwardRef, Ref, useCallback } from 'react';
Expand Down Expand Up @@ -86,6 +87,8 @@ const Avatar: FC<AvatarPropTypes> = forwardRef((props: AvatarPropTypes, ref: Ref
[onClick]
);

const passThroughProps = usePassThroughHtmlProps(props);

return (
<span
ref={ref}
Expand All @@ -96,6 +99,7 @@ const Avatar: FC<AvatarPropTypes> = forwardRef((props: AvatarPropTypes, ref: Ref
onKeyDown={handleKeyDown}
title={tooltip}
slot={slot}
{...passThroughProps}
>
{initials ? initials : children}
</span>
Expand Down
4 changes: 3 additions & 1 deletion packages/main/src/components/Bar/Bar.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mountThemedComponent, renderThemedComponent } from '@shared/tests/utils';
import { createPassThroughPropsTest, mountThemedComponent, renderThemedComponent } from '@shared/tests/utils';
import React from 'react';
import { Bar } from '@ui5/webcomponents-react/lib/Bar';

Expand Down Expand Up @@ -48,4 +48,6 @@ describe('Bar', () => {
const node = wrapper.getDOMNode();
expect(window.getComputedStyle(node).paddingLeft).toEqual('0.5rem');
});

createPassThroughPropsTest(Bar);
});
13 changes: 12 additions & 1 deletion packages/main/src/components/Bar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { StyleClassHelper } from '@ui5/webcomponents-react-base/lib/StyleClassHelper';
import { usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/usePassThroughHtmlProps';
import { ContentDensity } from '@ui5/webcomponents-react/lib/ContentDensity';
import React, { FC, forwardRef, Ref } from 'react';
import { createUseStyles, useTheme } from 'react-jss';
Expand Down Expand Up @@ -29,8 +30,18 @@ const Bar: FC<BarPropTypes> = forwardRef((props: BarPropTypes, ref: Ref<HTMLDivE
cssClasses.put(classes.compact);
}

const passThroughProps = usePassThroughHtmlProps(props);

return (
<div data-bar-part="Root" className={cssClasses.toString()} style={style} title={tooltip} slot={slot} ref={ref}>
<div
data-bar-part="Root"
className={cssClasses.toString()}
style={style}
title={tooltip}
slot={slot}
ref={ref}
{...passThroughProps}
>
<div data-bar-part="Left" className={classes.left}>
{renderContentLeft()}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mountThemedComponent } from '@shared/tests/utils';
import { createPassThroughPropsTest, mountThemedComponent } from '@shared/tests/utils';
import { Breadcrumbs } from '@ui5/webcomponents-react/lib/Breadcrumbs';
import { BreadcrumbsSeparatorStyle } from '@ui5/webcomponents-react/lib/BreadcrumbsSeparatorStyle';
import { Link } from '@ui5/webcomponents-react/lib/Link';
Expand Down Expand Up @@ -28,4 +28,6 @@ describe('Breadcrumbs', () => {
);
expect(wrapper.render()).toMatchSnapshot();
});

createPassThroughPropsTest(Breadcrumbs);
});
5 changes: 4 additions & 1 deletion packages/main/src/components/Breadcrumbs/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/usePassThroughHtmlProps';
import { BreadcrumbsSeparatorStyle } from '@ui5/webcomponents-react/lib/BreadcrumbsSeparatorStyle';
import { Label } from '@ui5/webcomponents-react/lib/Label';
import React, { Children, FC, forwardRef, Fragment, ReactNode, ReactNodeArray, Ref } from 'react';
Expand Down Expand Up @@ -33,8 +34,10 @@ const Breadcrumbs: FC<BreadcrumbsPropTypes> = forwardRef((props: BreadcrumbsProp
const { children, separatorStyle, currentLocationText, tooltip, style, className, slot } = props;
const childrenArray = Children.toArray(children).filter(Boolean);

const passThroughProps = usePassThroughHtmlProps(props);

return (
<div ref={ref} title={tooltip} style={style} className={className} slot={slot}>
<div ref={ref} title={tooltip} style={style} className={className} slot={slot} {...passThroughProps}>
{childrenArray.map((item, index) => {
if (index === childrenArray.length - 1) {
return item;
Expand Down
4 changes: 3 additions & 1 deletion packages/main/src/components/Carousel/Carousel.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getEventFromCallback, mountThemedComponent } from '@shared/tests/utils';
import { createPassThroughPropsTest, getEventFromCallback, mountThemedComponent } from '@shared/tests/utils';
import React, { cloneElement } from 'react';
import * as sinon from 'sinon';
import { Carousel } from '@ui5/webcomponents-react/lib/Carousel';
Expand Down Expand Up @@ -166,4 +166,6 @@ describe('Carousel', () => {
.simulate('keydown', { key: 'ArrowLeft' });
expect(getEventFromCallback(callback).getParameter('selectedIndex')).toEqual(0);
});

createPassThroughPropsTest(Carousel);
});
9 changes: 7 additions & 2 deletions packages/main/src/components/Carousel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Event } from '@ui5/webcomponents-react-base/lib/Event';
import { StyleClassHelper } from '@ui5/webcomponents-react-base/lib/StyleClassHelper';
import { usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/usePassThroughHtmlProps';
import { CarouselArrowsPlacement } from '@ui5/webcomponents-react/lib/CarouselArrowsPlacement';
import { PlacementType } from '@ui5/webcomponents-react/lib/PlacementType';
import React, {
Children,
CSSProperties,
Expand All @@ -15,8 +18,6 @@ import React, {
import { createUseStyles } from 'react-jss';
import { CommonProps } from '../../interfaces/CommonProps';
import { JSSTheme } from '../../interfaces/JSSTheme';
import { CarouselArrowsPlacement } from '@ui5/webcomponents-react/lib/CarouselArrowsPlacement';
import { PlacementType } from '@ui5/webcomponents-react/lib/PlacementType';
import styles from './Carousel.jss';
import { CarouselPagination, CarouselPaginationPropTypes } from './CarouselPagination';

Expand Down Expand Up @@ -155,6 +156,9 @@ const Carousel: FC<CarouselPropTypes> = forwardRef((props: CarouselPropTypes, re
);

const translateXPrefix = document.dir === 'rtl' ? '' : '-';

const passThroughProps = usePassThroughHtmlProps(props);

return (
<div
className={classNameString.toString()}
Expand All @@ -165,6 +169,7 @@ const Carousel: FC<CarouselPropTypes> = forwardRef((props: CarouselPropTypes, re
role="list"
tabIndex={0}
onKeyDown={onKeyDown}
{...passThroughProps}
>
{childElementCount > 1 && pageIndicatorPlacement === PlacementType.Top && (
<CarouselPagination
Expand Down
14 changes: 11 additions & 3 deletions packages/main/src/components/FilterBar/FilterBar.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mountThemedComponent } from '@shared/tests/utils';
import { createPassThroughPropsTest, mountThemedComponent } from '@shared/tests/utils';
import React from 'react';
import { FilterBar } from '@ui5/webcomponents-react/lib/FilterBar';
import { FilterItem } from '@ui5/webcomponents-react/lib/FilterItem';
Expand All @@ -7,8 +7,14 @@ import { Input } from '@ui5/webcomponents-react/lib/Input';
import { Switch } from '@ui5/webcomponents-react/lib/Switch';
import { VariantManagement } from '@ui5/webcomponents-react/lib/VariantManagement';

const variantItems = [{ label: 'Variant 1', key: '1' }, { label: 'Variant 2', key: '2' }];
const filterItems = [{ text: 'Text 1', key: '1' }, { text: 'Text 2', key: '2' }];
const variantItems = [
{ label: 'Variant 1', key: '1' },
{ label: 'Variant 2', key: '2' }
];
const filterItems = [
{ text: 'Text 1', key: '1' },
{ text: 'Text 2', key: '2' }
];

const renderVariants = () => <VariantManagement variantItems={variantItems} />;
const renderSearch = () => <Input placeholder={'Search'} />;
Expand Down Expand Up @@ -120,4 +126,6 @@ describe('FilterBar', () => {

expect(wrapper.render()).toMatchSnapshot();
});

createPassThroughPropsTest(FilterBar);
});
Loading