Skip to content
Open
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
4 changes: 2 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,13 @@ module.exports = {
},
'./packages/clay-pagination/src/': {
branches: 86,
functions: 76,
functions: 70,
lines: 92,
statements: 98,
},
'./packages/clay-pagination-bar/src/': {
branches: 92,
functions: 69,
functions: 65,
lines: 94,
statements: 95,
},
Expand Down
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@
"@types/d3": "^5.7.2",
"@types/geojson": "^7946.0.7",
"@types/jest": "^26.0.0",
"@types/react": "16.9.9",
"@types/react-dom": "16.9.9",
"@types/react": "18.3.26",
"@types/react-dom": "18.3.7",
"@types/react-test-renderer": "^16.8.0",
"@types/react-transition-group": "^4.4.0",
"@types/react-transition-group": "^4.4.12",
"@types/storybook__addon-a11y": "5.1.2",
"@types/storybook__addon-knobs": "^5.2.1",
"@types/storybook__react": "^5.2.1",
Expand Down Expand Up @@ -120,8 +120,6 @@
},
"resolutions": {
"@pmmmwh/react-refresh-webpack-plugin": "0.5.1",
"@types/react": "16.9.9",
"@types/react-dom": "16.9.9",
"js-beautify": "1.7.5",
"event-stream": "3.3.4",
"graceful-fs": "^4.2.4"
Expand Down
10 changes: 6 additions & 4 deletions packages/clay-autocomplete/src/LegacyAutocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ AutocompleteMarkup.displayName = 'ClayAutocompleteMarkup';
* Temporary helper function to determine which version of autocomplete
* is being used.
*/
const hasItems = (children?: React.ReactNode) => {
if (!children) {
const hasItems = (children?: React.ReactNode | Function) => {
if (!children || typeof children === 'function') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What required this change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because React.Children.map no longer accepts the function type, so we have to guard against that.

Additionally we have to add Function as a suspected type to hasItems because in ClayAutocomplete the children prop can be a function

Essentially there were gaps in the previous types, so I think it just got more strict.

return [];
}

return React.Children.map(children, (child) => {
const mappedChildren = React.Children.map(children, (child) => {
if (
React.isValidElement(child) &&
// @ts-ignore
Expand All @@ -46,7 +46,9 @@ const hasItems = (children?: React.ReactNode) => {
}

return false;
}).filter(Boolean);
});

return (mappedChildren || []).filter(Boolean);
};

export interface IProps<T> extends IAutocompleteProps<T> {
Expand Down
22 changes: 8 additions & 14 deletions packages/clay-button/src/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,7 @@ export interface IProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
translucent?: boolean;
}

export interface IForwardRef<T, P = {}>
extends React.ForwardRefExoticComponent<P & React.RefAttributes<T>> {
Group: typeof Group;
}

function forwardRef<T, P = {}>(component: React.RefForwardingComponent<T, P>) {
return React.forwardRef<T, P>(component) as IForwardRef<T, P>;
}

const Button = forwardRef(
const ButtonComponent = React.forwardRef<HTMLButtonElement, IProps>(
(
{
alert,
Expand All @@ -117,8 +108,8 @@ const Button = forwardRef(
translucent,
type = 'button',
...otherProps
}: IProps,
ref: React.Ref<HTMLButtonElement>
},
ref
) => {
const childArray = React.Children.toArray(children);

Expand Down Expand Up @@ -174,7 +165,10 @@ const Button = forwardRef(
}
);

Button.Group = Group;
Button.displayName = 'ClayButton';
ButtonComponent.displayName = 'ClayButton';

const Button = Object.assign(ButtonComponent, {
Group,
});

export default Button;
21 changes: 4 additions & 17 deletions packages/clay-button/src/ButtonWithIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,14 @@ import React from 'react';

import ClayButton from './Button';

type ButtonAria =
| {
/**
* Define a value that labels the button.
*/
'aria-label': string;
'aria-labelledby'?: never;
}
| {
/**
* Define a value that labels the button.
*/
'aria-label'?: never;
'aria-labelledby': string;
};

interface ICommonProps
extends Omit<
React.ComponentProps<typeof ClayButton>,
'aria-label' | 'aria-labelledby'
> {
'aria-label'?: string;

'aria-labelledby'?: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old type looked like it was requiring either aria-labelledby or aria-label to be included while also not allowing both to be added at the same time. This doesn't look like this will have the same behavior.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason with the updated type libraries, it no longer allowed them to be mutually exclusive. I'm not exactly why or what type changed in the react definitions, but I figured it might just be simpler to make them both optional types instead.

/**
* Path to the location of the spritemap resource.
*/
Expand All @@ -40,7 +27,7 @@ interface ICommonProps
symbol: string;
}

export type Props = ICommonProps & ButtonAria;
export type Props = ICommonProps;

const ClayButtonWithIcon = React.forwardRef<HTMLButtonElement, Props>(
({monospaced = true, spritemap, symbol, ...otherProps}: Props, ref) => (
Expand Down
2 changes: 1 addition & 1 deletion packages/clay-charts/src/Predictive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interface IProps {
* Predictive Chart component.
*/
const PredictiveChart = React.forwardRef<HTMLDivElement, IProps>(
({data, predictionDate, ...otherProps}: IProps, ref) => {
({data, predictionDate, ...otherProps}, ref) => {
let columns = data.columns;

if (columns) {
Expand Down
46 changes: 25 additions & 21 deletions packages/clay-core/src/collection/useCollection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import {useId} from '@clayui/shared';
import React, {
ReactNode,
useCallback,
useContext,
useEffect,
Expand Down Expand Up @@ -241,7 +242,7 @@ export function useCollection<

registerItem(key, child, index);
}
} else {
} else if (typeof children !== 'function') {
React.Children.forEach(children, (child, index) => {
if (!React.isValidElement(child)) {
return;
Expand Down Expand Up @@ -351,27 +352,30 @@ export function useCollection<
});
}

return React.Children.map(children, (child, index) => {
if (!React.isValidElement(child)) {
return null;
}
return React.Children.map(
children as Iterable<ReactNode>,
(child, index) => {
if (!React.isValidElement(child)) {
return null;
}

const key = getKey(index, child.key, parentKey);
const key = getKey(index, child.key, parentKey);

if (
visibleKeys &&
((Array.isArray(visibleKeys) &&
visibleKeys.length > 0 &&
!visibleKeys.includes(index)) ||
(visibleKeys instanceof Set &&
visibleKeys.size > 0 &&
!visibleKeys.has(key)))
) {
return null;
}
if (
visibleKeys &&
((Array.isArray(visibleKeys) &&
visibleKeys.length > 0 &&
!visibleKeys.includes(index)) ||
(visibleKeys instanceof Set &&
visibleKeys.size > 0 &&
!visibleKeys.has(key)))
) {
return null;
}

return performItemRender(child as ChildElement, key, index);
});
return performItemRender(child as ChildElement, key, index);
}
);
},
[
performItemRender,
Expand All @@ -391,7 +395,7 @@ export function useCollection<
}, []);

const getFirstItem = useCallback(() => {
const key = layout.current.keys().next().value;
const key = layout.current.keys().next().value!;

return {
key,
Expand Down Expand Up @@ -443,7 +447,7 @@ export function useCollection<
// - Data: We get the data of the item to consume later
// - Rendering: We render each element in memory
const rendered = useMemo(() => {
const list = performCollectionRender({children, items});
const list = performCollectionRender({children, items})!;

if (list.length === 0 && notFound) {
return notFound;
Expand Down
9 changes: 6 additions & 3 deletions packages/clay-core/src/nav/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {LinkOrButton} from '@clayui/shared';
import classNames from 'classnames';
import React from 'react';

interface IProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
export interface IPropsLink
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
/**
* Flag to indicate if `active` class should be applied.
*/
Expand All @@ -35,9 +36,9 @@ interface IProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
spritemap?: string;
}

export const Link = React.forwardRef<
const Link = React.forwardRef<
HTMLButtonElement | HTMLAnchorElement | HTMLDivElement,
IProps
IPropsLink
>(
(
{
Expand Down Expand Up @@ -94,3 +95,5 @@ export const Link = React.forwardRef<
);

Link.displayName = 'NavLink';

export {Link};
22 changes: 8 additions & 14 deletions packages/clay-core/src/nav/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import React from 'react';
import {Item} from './Item';
import {Link} from './Link';

interface IProps extends React.HTMLAttributes<HTMLUListElement> {
export interface IPropsNav extends React.HTMLAttributes<HTMLUListElement> {
/**
* Flag to indicate if `nav-nested` class should be applied. Adds padding to indent each nested navigation.
*/
Expand All @@ -26,17 +26,7 @@ interface IProps extends React.HTMLAttributes<HTMLUListElement> {
stacked?: boolean;
}

interface IForwardRef<T, P = {}>
extends React.ForwardRefExoticComponent<P & React.RefAttributes<T>> {
Item: typeof Item;
Link: typeof Link;
}

function forwardRef<T, P = {}>(component: React.RefForwardingComponent<T, P>) {
return React.forwardRef<T, P>(component) as IForwardRef<T, P>;
}

export const Nav = forwardRef<HTMLUListElement, IProps>(function Nav(
const NavComponent = React.forwardRef<HTMLUListElement, IPropsNav>(function Nav(
{children, className, nestMargins, nested, stacked, ...otherProps},
ref
) {
Expand All @@ -55,5 +45,9 @@ export const Nav = forwardRef<HTMLUListElement, IProps>(function Nav(
);
});

Nav.Item = Item;
Nav.Link = Link;
NavComponent.displayName = 'Nav';

export const Nav = Object.assign(NavComponent, {
Item,
Link,
});
13 changes: 7 additions & 6 deletions packages/clay-core/src/overlay-mask/OverlayMask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ type Props<T> = {
onBoundsChange?: InternalDispatch<Bounds>;
};

export function OverlayMask<T>({
export function OverlayMask<T extends HTMLElement>({
defaultBounds = initialBounds,
bounds,
children,
Expand All @@ -172,7 +172,7 @@ export function OverlayMask<T>({
value: bounds,
});

const childrenRef = useRef<HTMLElement | null>(null);
const childrenRef = useRef<T | null>(null);

useIsomorphicLayoutEffect(() => {
if (childrenRef.current) {
Expand All @@ -181,13 +181,14 @@ export function OverlayMask<T>({
return;
}

const {height, width, x, y} =
childrenRef.current.getBoundingClientRect();
const {height, width, x, y} = (
childrenRef.current as HTMLElement
).getBoundingClientRect();

setBounds({height, width, x, y});
};

return observeRect(childrenRef.current, updater);
return observeRect(childrenRef.current as HTMLElement, updater);
}
}, [setBounds]);

Expand All @@ -196,7 +197,7 @@ export function OverlayMask<T>({
{children &&
typeof children !== 'function' &&
React.cloneElement(children as React.ReactElement, {
ref: (node: HTMLElement) => {
ref: (node: T) => {
childrenRef.current = node;

// @ts-ignore
Expand Down
2 changes: 1 addition & 1 deletion packages/clay-core/src/picker/Option.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export function Option({
{...otherProps}
aria-describedby={ariaDescribedby}
disabled={disabled}
value={keyValue}
value={keyValue ? String(keyValue) : undefined}
>
{typeof children === 'string' ? children : textValue}
</option>
Expand Down
2 changes: 1 addition & 1 deletion packages/clay-core/src/picker/Picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ export function Picker<T extends Record<string, any> | string | number>({
className
)}
onChange={(event) => setSelectedKey(event.target.value)}
value={selectedKey}
value={selectedKey ? String(selectedKey) : undefined}
>
<PickerContext.Provider value={context}>
<Collection<T> collection={collection} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type Panel = {
};

type Panels = {
[key: React.Key]: Panel;
[key: string | number | symbol]: Panel;
};

export function SidePanelWithDrilldown({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {SidePanelWithDrilldown} from '../SidePanelWithDrilldown';

function Component({
selectedPanelKey = 'x1',
}: {selectedPanelKey?: React.Key} = {}) {
const [panelKey, setPanelKey] = useState<React.Key>(selectedPanelKey);
}: {selectedPanelKey?: string} = {}) {
const [panelKey, setPanelKey] = useState(selectedPanelKey);

const ref = useRef<HTMLDivElement | null>(null);

Expand Down
Loading
Loading