uikit-react-public 0.28.0 → 0.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/BreadcrumbsNew/BaseBreadcrumbsItem.d.ts +12 -0
- package/dist/components/BreadcrumbsNew/Breadcrumbs.d.ts +18 -0
- package/dist/components/BreadcrumbsNew/BreadcrumbsCurrent.d.ts +8 -0
- package/dist/components/BreadcrumbsNew/BreadcrumbsLink.d.ts +7 -0
- package/dist/components/BreadcrumbsNew/__tests__/Breadcrumbs.test.d.ts +1 -0
- package/dist/components/BreadcrumbsNew/index.d.ts +2 -0
- package/dist/components/Link/BaseLink.d.ts +3 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/index.js +5524 -5329
- package/lib/components/BreadcrumbsNew/BaseBreadcrumbsItem.tsx +69 -0
- package/lib/components/BreadcrumbsNew/Breadcrumbs.tsx +118 -0
- package/lib/components/BreadcrumbsNew/BreadcrumbsCurrent.tsx +54 -0
- package/lib/components/BreadcrumbsNew/BreadcrumbsLink.tsx +67 -0
- package/lib/components/BreadcrumbsNew/__tests__/Breadcrumbs.test.tsx +53 -0
- package/lib/components/BreadcrumbsNew/index.ts +8 -0
- package/lib/components/Link/BaseLink.tsx +40 -2
- package/lib/components/Link/__tests__/link.test.tsx +58 -1
- package/lib/components/index.ts +9 -0
- package/package.json +1 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { LiHTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { css, cx } from '@emotion/css';
|
|
3
|
+
import Icon from '../Icon';
|
|
4
|
+
import { useTheme } from '../../theme';
|
|
5
|
+
import type { BreadcrumbsSize } from './Breadcrumbs';
|
|
6
|
+
|
|
7
|
+
export const NAME = 'ucl-uikit-breadcrumbs__item';
|
|
8
|
+
|
|
9
|
+
export interface BaseBreadcrumbsItemProps extends LiHTMLAttributes<HTMLLIElement> {
|
|
10
|
+
separator?: boolean;
|
|
11
|
+
back?: boolean;
|
|
12
|
+
size?: BreadcrumbsSize;
|
|
13
|
+
testId?: string;
|
|
14
|
+
children?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const BaseBreadcrumbsItem = ({
|
|
18
|
+
separator = false,
|
|
19
|
+
back = false,
|
|
20
|
+
size = 'medium',
|
|
21
|
+
testId = NAME,
|
|
22
|
+
className,
|
|
23
|
+
children,
|
|
24
|
+
...props
|
|
25
|
+
}: BaseBreadcrumbsItemProps) => {
|
|
26
|
+
const [theme] = useTheme();
|
|
27
|
+
|
|
28
|
+
const style = cx(
|
|
29
|
+
NAME,
|
|
30
|
+
css`
|
|
31
|
+
display: inline-flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
gap: ${theme.margin.m8};
|
|
34
|
+
min-width: 0;
|
|
35
|
+
`,
|
|
36
|
+
className
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const iconStyle = css`
|
|
40
|
+
flex: 0 0 auto;
|
|
41
|
+
color: ${theme.colour.icon.brandPrimary};
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<li
|
|
46
|
+
className={style}
|
|
47
|
+
data-testid={testId}
|
|
48
|
+
{...props}
|
|
49
|
+
>
|
|
50
|
+
{back && (
|
|
51
|
+
<Icon.ArrowLeft
|
|
52
|
+
aria-hidden
|
|
53
|
+
className={iconStyle}
|
|
54
|
+
size={size === 'small' ? 16 : 20}
|
|
55
|
+
/>
|
|
56
|
+
)}
|
|
57
|
+
{children}
|
|
58
|
+
{separator && (
|
|
59
|
+
<Icon.ChevronRight
|
|
60
|
+
aria-hidden
|
|
61
|
+
className={iconStyle}
|
|
62
|
+
size={size === 'small' ? 12 : 16}
|
|
63
|
+
/>
|
|
64
|
+
)}
|
|
65
|
+
</li>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default BaseBreadcrumbsItem;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Children,
|
|
3
|
+
HTMLAttributes,
|
|
4
|
+
NamedExoticComponent,
|
|
5
|
+
ReactElement,
|
|
6
|
+
cloneElement,
|
|
7
|
+
isValidElement,
|
|
8
|
+
memo,
|
|
9
|
+
} from 'react';
|
|
10
|
+
import { css, cx } from '@emotion/css';
|
|
11
|
+
import { useTheme } from '../../theme';
|
|
12
|
+
import BaseBreadcrumbsItem, {
|
|
13
|
+
BaseBreadcrumbsItemProps,
|
|
14
|
+
} from './BaseBreadcrumbsItem';
|
|
15
|
+
import BreadcrumbsCurrent, {
|
|
16
|
+
BreadcrumbsCurrentProps,
|
|
17
|
+
} from './BreadcrumbsCurrent';
|
|
18
|
+
import BreadcrumbsLink, { BreadcrumbsLinkProps } from './BreadcrumbsLink';
|
|
19
|
+
|
|
20
|
+
export const NAME = 'ucl-uikit-breadcrumbs';
|
|
21
|
+
|
|
22
|
+
export type BreadcrumbsSize = 'small' | 'medium';
|
|
23
|
+
|
|
24
|
+
export interface BreadcrumbsProps extends HTMLAttributes<HTMLElement> {
|
|
25
|
+
size?: BreadcrumbsSize;
|
|
26
|
+
testId?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type BreadcrumbChild = ReactElement<{
|
|
30
|
+
separator?: boolean;
|
|
31
|
+
back?: boolean;
|
|
32
|
+
size?: BreadcrumbsSize;
|
|
33
|
+
}>;
|
|
34
|
+
|
|
35
|
+
const Breadcrumbs = ({
|
|
36
|
+
size = 'medium',
|
|
37
|
+
testId = NAME,
|
|
38
|
+
className,
|
|
39
|
+
children,
|
|
40
|
+
'aria-label': ariaLabel = 'Breadcrumb',
|
|
41
|
+
...props
|
|
42
|
+
}: BreadcrumbsProps) => {
|
|
43
|
+
const [theme] = useTheme();
|
|
44
|
+
const items = Children.toArray(children).filter(isValidElement);
|
|
45
|
+
const parentItem = items[items.length - 2] as BreadcrumbChild | undefined;
|
|
46
|
+
|
|
47
|
+
const listStyle = css`
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
gap: ${theme.margin.m8};
|
|
51
|
+
margin: 0;
|
|
52
|
+
padding: 0;
|
|
53
|
+
list-style: none;
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
const desktopStyle = css`
|
|
57
|
+
display: none;
|
|
58
|
+
|
|
59
|
+
@media screen and (min-width: ${theme.breakpoints.tablet}px) {
|
|
60
|
+
display: flex;
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
const mobileStyle = css`
|
|
65
|
+
@media screen and (min-width: ${theme.breakpoints.tablet}px) {
|
|
66
|
+
display: none;
|
|
67
|
+
}
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
const style = cx(NAME, className);
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<nav
|
|
74
|
+
aria-label={ariaLabel}
|
|
75
|
+
className={style}
|
|
76
|
+
data-testid={testId}
|
|
77
|
+
{...props}
|
|
78
|
+
>
|
|
79
|
+
<ol className={cx(listStyle, desktopStyle)}>
|
|
80
|
+
{items.map((item, index) =>
|
|
81
|
+
cloneElement(item as BreadcrumbChild, {
|
|
82
|
+
separator: index < items.length - 1,
|
|
83
|
+
size,
|
|
84
|
+
})
|
|
85
|
+
)}
|
|
86
|
+
</ol>
|
|
87
|
+
{parentItem && (
|
|
88
|
+
<ol className={cx(listStyle, mobileStyle)}>
|
|
89
|
+
{cloneElement(parentItem, {
|
|
90
|
+
back: true,
|
|
91
|
+
separator: false,
|
|
92
|
+
size,
|
|
93
|
+
})}
|
|
94
|
+
</ol>
|
|
95
|
+
)}
|
|
96
|
+
</nav>
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
interface BreadcrumbsComponent extends NamedExoticComponent<BreadcrumbsProps> {
|
|
101
|
+
BaseItem: typeof BaseBreadcrumbsItem;
|
|
102
|
+
Link: typeof BreadcrumbsLink;
|
|
103
|
+
Current: typeof BreadcrumbsCurrent;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const MemoBreadcrumbs: BreadcrumbsComponent = Object.assign(memo(Breadcrumbs), {
|
|
107
|
+
BaseItem: BaseBreadcrumbsItem,
|
|
108
|
+
Link: BreadcrumbsLink,
|
|
109
|
+
Current: BreadcrumbsCurrent,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export type {
|
|
113
|
+
BaseBreadcrumbsItemProps,
|
|
114
|
+
BreadcrumbsCurrentProps,
|
|
115
|
+
BreadcrumbsLinkProps,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export default MemoBreadcrumbs;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
import { css, cx } from '@emotion/css';
|
|
3
|
+
import Text from '../Text';
|
|
4
|
+
import { useTheme } from '../../theme';
|
|
5
|
+
import BaseBreadcrumbsItem, {
|
|
6
|
+
BaseBreadcrumbsItemProps,
|
|
7
|
+
} from './BaseBreadcrumbsItem';
|
|
8
|
+
|
|
9
|
+
export const NAME = 'ucl-uikit-breadcrumbs__current';
|
|
10
|
+
|
|
11
|
+
export interface BreadcrumbsCurrentProps
|
|
12
|
+
extends
|
|
13
|
+
HTMLAttributes<HTMLSpanElement>,
|
|
14
|
+
Pick<BaseBreadcrumbsItemProps, 'separator' | 'size'> {
|
|
15
|
+
testId?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const BreadcrumbsCurrent = ({
|
|
19
|
+
separator,
|
|
20
|
+
size = 'medium',
|
|
21
|
+
testId = NAME,
|
|
22
|
+
className,
|
|
23
|
+
children,
|
|
24
|
+
...props
|
|
25
|
+
}: BreadcrumbsCurrentProps) => {
|
|
26
|
+
const [theme] = useTheme();
|
|
27
|
+
|
|
28
|
+
const style = cx(
|
|
29
|
+
NAME,
|
|
30
|
+
css`
|
|
31
|
+
color: ${theme.colour.text.secondary};
|
|
32
|
+
`,
|
|
33
|
+
className
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<BaseBreadcrumbsItem
|
|
38
|
+
separator={separator}
|
|
39
|
+
size={size}
|
|
40
|
+
>
|
|
41
|
+
<Text
|
|
42
|
+
aria-current='page'
|
|
43
|
+
className={style}
|
|
44
|
+
data-testid={testId}
|
|
45
|
+
level={size === 'small' ? 'sm-semibold' : 'md-semibold'}
|
|
46
|
+
{...props}
|
|
47
|
+
>
|
|
48
|
+
{children}
|
|
49
|
+
</Text>
|
|
50
|
+
</BaseBreadcrumbsItem>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default BreadcrumbsCurrent;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { css, cx } from '@emotion/css';
|
|
2
|
+
import Link, { LinkProps } from '../Link';
|
|
3
|
+
import { useTheme } from '../../theme';
|
|
4
|
+
import BaseBreadcrumbsItem, {
|
|
5
|
+
BaseBreadcrumbsItemProps,
|
|
6
|
+
} from './BaseBreadcrumbsItem';
|
|
7
|
+
|
|
8
|
+
export const NAME = 'ucl-uikit-breadcrumbs__link';
|
|
9
|
+
|
|
10
|
+
type BreadcrumbsLinkOwnProps = Pick<
|
|
11
|
+
BaseBreadcrumbsItemProps,
|
|
12
|
+
'separator' | 'back' | 'size'
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
export type BreadcrumbsLinkProps = BreadcrumbsLinkOwnProps &
|
|
16
|
+
Omit<LinkProps, 'size'>;
|
|
17
|
+
|
|
18
|
+
const BreadcrumbsLink = ({
|
|
19
|
+
separator,
|
|
20
|
+
back,
|
|
21
|
+
size = 'medium',
|
|
22
|
+
className,
|
|
23
|
+
children,
|
|
24
|
+
...props
|
|
25
|
+
}: BreadcrumbsLinkProps) => {
|
|
26
|
+
const [theme] = useTheme();
|
|
27
|
+
|
|
28
|
+
const linkStyle = cx(
|
|
29
|
+
NAME,
|
|
30
|
+
css`
|
|
31
|
+
color: ${theme.colour.link.primary};
|
|
32
|
+
text-decoration: none;
|
|
33
|
+
|
|
34
|
+
&:visited {
|
|
35
|
+
color: ${theme.colour.link.primary};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&:hover {
|
|
39
|
+
text-decoration: underline;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&:active {
|
|
43
|
+
color: ${theme.colour.link.primaryHover};
|
|
44
|
+
}
|
|
45
|
+
`,
|
|
46
|
+
className
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<BaseBreadcrumbsItem
|
|
51
|
+
separator={separator}
|
|
52
|
+
back={back}
|
|
53
|
+
size={size}
|
|
54
|
+
>
|
|
55
|
+
<Link
|
|
56
|
+
className={linkStyle}
|
|
57
|
+
noVisited
|
|
58
|
+
size={size === 'small' ? 'small' : 'default'}
|
|
59
|
+
{...props}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
</Link>
|
|
63
|
+
</BaseBreadcrumbsItem>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default BreadcrumbsLink;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { render, screen, within } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, test } from 'vitest';
|
|
3
|
+
import { ThemeContextProvider } from '../../../theme/useTheme';
|
|
4
|
+
import Breadcrumbs from '../Breadcrumbs';
|
|
5
|
+
|
|
6
|
+
describe('BreadcrumbsNew', () => {
|
|
7
|
+
test('renders the full trail and a mobile parent link', () => {
|
|
8
|
+
render(
|
|
9
|
+
<ThemeContextProvider>
|
|
10
|
+
<Breadcrumbs>
|
|
11
|
+
<Breadcrumbs.Link asChild>
|
|
12
|
+
<a href='/'>Home</a>
|
|
13
|
+
</Breadcrumbs.Link>
|
|
14
|
+
<Breadcrumbs.Link asChild>
|
|
15
|
+
<a href='/parent'>Parent</a>
|
|
16
|
+
</Breadcrumbs.Link>
|
|
17
|
+
<Breadcrumbs.Current>Current page</Breadcrumbs.Current>
|
|
18
|
+
</Breadcrumbs>
|
|
19
|
+
</ThemeContextProvider>
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const lists = screen.getAllByRole('list', { hidden: true });
|
|
23
|
+
|
|
24
|
+
expect(
|
|
25
|
+
within(lists[0]).getAllByRole('listitem', { hidden: true })
|
|
26
|
+
).toHaveLength(3);
|
|
27
|
+
expect(
|
|
28
|
+
within(lists[1]).getAllByRole('listitem', { hidden: true })
|
|
29
|
+
).toHaveLength(1);
|
|
30
|
+
expect(
|
|
31
|
+
within(lists[1]).getByRole('link', { hidden: true })
|
|
32
|
+
).toHaveAttribute('href', '/parent');
|
|
33
|
+
expect(screen.getByText('Current page')).toHaveAttribute(
|
|
34
|
+
'aria-current',
|
|
35
|
+
'page'
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('supports small breadcrumbs', () => {
|
|
40
|
+
render(
|
|
41
|
+
<ThemeContextProvider>
|
|
42
|
+
<Breadcrumbs size='small'>
|
|
43
|
+
<Breadcrumbs.Link asChild>
|
|
44
|
+
<a href='/parent'>Parent</a>
|
|
45
|
+
</Breadcrumbs.Link>
|
|
46
|
+
<Breadcrumbs.Current>Current page</Breadcrumbs.Current>
|
|
47
|
+
</Breadcrumbs>
|
|
48
|
+
</ThemeContextProvider>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
expect(screen.getByText('Current page')).toHaveClass('ucl-uikit-text');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import React, {
|
|
2
|
+
Children,
|
|
3
|
+
cloneElement,
|
|
2
4
|
ComponentPropsWithoutRef,
|
|
3
5
|
ElementType,
|
|
4
6
|
forwardRef,
|
|
7
|
+
isValidElement,
|
|
8
|
+
ReactElement,
|
|
5
9
|
useCallback,
|
|
6
10
|
} from 'react';
|
|
7
11
|
import { css, cx } from '@emotion/css';
|
|
@@ -30,13 +34,16 @@ type BaseLinkOwnProps = {
|
|
|
30
34
|
testId?: string;
|
|
31
35
|
className?: string;
|
|
32
36
|
children?: React.ReactNode;
|
|
37
|
+
/** @deprecated Prefer `asChild` with a routing link child. */
|
|
33
38
|
to?: string;
|
|
39
|
+
asChild?: boolean;
|
|
34
40
|
};
|
|
35
41
|
|
|
36
42
|
type PolymorphicRef<C extends ElementType> =
|
|
37
43
|
React.ComponentPropsWithRef<C>['ref'];
|
|
38
44
|
|
|
39
45
|
export type BaseLinkProps<C extends ElementType = 'a'> = BaseLinkOwnProps & {
|
|
46
|
+
/** @deprecated Prefer `asChild` with a custom link child. */
|
|
40
47
|
component?: C;
|
|
41
48
|
} & Omit<
|
|
42
49
|
ComponentPropsWithoutRef<C>,
|
|
@@ -58,6 +65,7 @@ const BaseLink = forwardRef(function BaseLinkInner(
|
|
|
58
65
|
disabled = false,
|
|
59
66
|
component,
|
|
60
67
|
to,
|
|
68
|
+
asChild = false,
|
|
61
69
|
...props
|
|
62
70
|
}: BaseLinkProps<ElementType>,
|
|
63
71
|
ref: React.Ref<Element>
|
|
@@ -110,6 +118,31 @@ const BaseLink = forwardRef(function BaseLinkInner(
|
|
|
110
118
|
className
|
|
111
119
|
);
|
|
112
120
|
|
|
121
|
+
if (asChild) {
|
|
122
|
+
const child = Children.only(children) as ReactElement<
|
|
123
|
+
Record<string, unknown> & {
|
|
124
|
+
className?: string;
|
|
125
|
+
onClick?: React.MouseEventHandler;
|
|
126
|
+
tabIndex?: number;
|
|
127
|
+
}
|
|
128
|
+
>;
|
|
129
|
+
|
|
130
|
+
if (isValidElement(child)) {
|
|
131
|
+
return cloneElement(child, {
|
|
132
|
+
...props,
|
|
133
|
+
ref,
|
|
134
|
+
className: cx(style, child.props.className),
|
|
135
|
+
'data-testid': testId,
|
|
136
|
+
'aria-disabled': disabled || undefined,
|
|
137
|
+
tabIndex: disabled ? -1 : (props.tabIndex ?? child.props.tabIndex),
|
|
138
|
+
...(to ? { to } : {}),
|
|
139
|
+
onClick: disabled
|
|
140
|
+
? disabledHandleClick
|
|
141
|
+
: (props.onClick ?? child.props.onClick),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
113
146
|
return (
|
|
114
147
|
<Component
|
|
115
148
|
ref={ref}
|
|
@@ -117,9 +150,14 @@ const BaseLink = forwardRef(function BaseLinkInner(
|
|
|
117
150
|
data-testid={testId}
|
|
118
151
|
aria-disabled={disabled || undefined}
|
|
119
152
|
tabIndex={disabled ? -1 : props.tabIndex}
|
|
120
|
-
href={isAnchor ? (disabled ? undefined : (href ?? to)) : undefined}
|
|
121
153
|
onClick={disabled ? disabledHandleClick : onClick}
|
|
122
|
-
{...(isAnchor
|
|
154
|
+
{...(isAnchor
|
|
155
|
+
? { href: disabled ? undefined : (href ?? to) }
|
|
156
|
+
: to
|
|
157
|
+
? { to }
|
|
158
|
+
: href
|
|
159
|
+
? { href }
|
|
160
|
+
: {})}
|
|
123
161
|
{...rest}
|
|
124
162
|
>
|
|
125
163
|
{children}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, expect, test } from 'vitest';
|
|
1
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
2
2
|
import { render, screen } from '@testing-library/react';
|
|
3
3
|
import Link from '../Link';
|
|
4
4
|
import { ThemeContextProvider } from '../../../theme/useTheme';
|
|
@@ -57,4 +57,61 @@ describe('Link', () => {
|
|
|
57
57
|
expect(link.textContent).toBe('linktext');
|
|
58
58
|
expect(link.href).toBe('http://localhost:3000/testlink');
|
|
59
59
|
});
|
|
60
|
+
|
|
61
|
+
test('renders a custom link child with asChild', () => {
|
|
62
|
+
const handleClick = vi.fn((event: React.MouseEvent) =>
|
|
63
|
+
event.preventDefault()
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
render(
|
|
67
|
+
<ThemeContextProvider>
|
|
68
|
+
<Link asChild>
|
|
69
|
+
<a
|
|
70
|
+
href='/custom'
|
|
71
|
+
onClick={handleClick}
|
|
72
|
+
>
|
|
73
|
+
Custom link
|
|
74
|
+
</a>
|
|
75
|
+
</Link>
|
|
76
|
+
</ThemeContextProvider>
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const link = screen.getByRole('link', { name: 'Custom link' });
|
|
80
|
+
link.click();
|
|
81
|
+
|
|
82
|
+
expect(link).toHaveAttribute('href', '/custom');
|
|
83
|
+
expect(link).toHaveAttribute('data-testid', 'ucl-uikit-link');
|
|
84
|
+
expect(handleClick).toHaveBeenCalledOnce();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('continues to support the deprecated component and to props', () => {
|
|
88
|
+
const CustomLink = ({
|
|
89
|
+
to,
|
|
90
|
+
children,
|
|
91
|
+
...props
|
|
92
|
+
}: React.AnchorHTMLAttributes<HTMLAnchorElement> & { to?: string }) => (
|
|
93
|
+
<a
|
|
94
|
+
href={to}
|
|
95
|
+
{...props}
|
|
96
|
+
>
|
|
97
|
+
{children}
|
|
98
|
+
</a>
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
render(
|
|
102
|
+
<ThemeContextProvider>
|
|
103
|
+
<Link
|
|
104
|
+
component={CustomLink}
|
|
105
|
+
to='/legacy'
|
|
106
|
+
>
|
|
107
|
+
Legacy link
|
|
108
|
+
</Link>
|
|
109
|
+
</ThemeContextProvider>
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
expect(screen.getByRole('link', { name: 'Legacy link' })).toHaveAttribute(
|
|
113
|
+
'href',
|
|
114
|
+
'/legacy'
|
|
115
|
+
);
|
|
116
|
+
});
|
|
60
117
|
});
|
package/lib/components/index.ts
CHANGED
|
@@ -79,6 +79,15 @@ export type { AppHeaderProps } from './AppHeader';
|
|
|
79
79
|
export { default as Breadcrumbs } from './Breadcrumbs';
|
|
80
80
|
export type { BreadcrumbsProps } from './Breadcrumbs';
|
|
81
81
|
|
|
82
|
+
export { default as BreadcrumbsNew } from './BreadcrumbsNew';
|
|
83
|
+
export type {
|
|
84
|
+
BaseBreadcrumbsItemProps,
|
|
85
|
+
BreadcrumbsCurrentProps,
|
|
86
|
+
BreadcrumbsLinkProps,
|
|
87
|
+
BreadcrumbsProps as BreadcrumbsNewProps,
|
|
88
|
+
BreadcrumbsSize,
|
|
89
|
+
} from './BreadcrumbsNew';
|
|
90
|
+
|
|
82
91
|
export { default as Checkbox, LabelledCheckbox } from './Checkbox';
|
|
83
92
|
export type { CheckboxProps, LabelledCheckboxProps } from './Checkbox';
|
|
84
93
|
|