@openedx/paragon 23.18.2 → 23.19.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/README.md
CHANGED
|
@@ -514,10 +514,34 @@ Paragon components can have different behavior in the MFE environment. `example`
|
|
|
514
514
|
|
|
515
515
|
Steps to install the `example` app.
|
|
516
516
|
|
|
517
|
+
To set up the example app with a local Tutor installation, you'll need to configure a Tutor plugin to handle CORS settings
|
|
518
|
+
|
|
519
|
+
Prerequisites.
|
|
520
|
+
|
|
521
|
+
Before running the example app, ensure you have a local Tutor installation configured.
|
|
522
|
+
1. Create a new file (i.e. `paragon-example-app.py`) in your tutor plugins folder (`tutor plugins printroot` to get the path).
|
|
523
|
+
2. Add the following content to the paragon-example-app.py file:
|
|
524
|
+
```
|
|
525
|
+
from tutor import hooks
|
|
526
|
+
|
|
527
|
+
hooks.Filters.ENV_PATCHES.add_item(
|
|
528
|
+
(
|
|
529
|
+
"openedx-lms-development-settings",
|
|
530
|
+
"""
|
|
531
|
+
CORS_ORIGIN_WHITELIST.append("http://localhost:8080")
|
|
532
|
+
LOGIN_REDIRECT_WHITELIST.append("http://localhost:8080")
|
|
533
|
+
CSRF_TRUSTED_ORIGINS.append("http://localhost:8080")
|
|
534
|
+
"""
|
|
535
|
+
)
|
|
536
|
+
)
|
|
537
|
+
```
|
|
538
|
+
3. Enable the plugin: `tutor plugins enable paragon-example-app`
|
|
539
|
+
4. Apply configuration changes: `tutor config save` && `tutor dev restart`
|
|
540
|
+
|
|
541
|
+
Running the Example App:
|
|
517
542
|
1. `npm install` to install dependencies.
|
|
518
|
-
2.
|
|
519
|
-
3.
|
|
520
|
-
4. Go to the `example/src/MyComponent.jsx` and use Paragon components inside the MFE environment.
|
|
543
|
+
2. `npm run example:start` to start the app.
|
|
544
|
+
3. Go to the `example/src/MyComponent.jsx` and use Paragon components inside the MFE environment.
|
|
521
545
|
|
|
522
546
|
## Semantic Release
|
|
523
547
|
|
|
@@ -16,7 +16,7 @@ interface BreadcrumbProps {
|
|
|
16
16
|
spacer?: React.ReactElement;
|
|
17
17
|
/** allows to add a custom function to be called `onClick` of a breadcrumb link.
|
|
18
18
|
* The use case for this is for adding custom analytics to the component. */
|
|
19
|
-
clickHandler?: (event: React.MouseEvent
|
|
19
|
+
clickHandler?: (event: React.MouseEvent<HTMLAnchorElement>, link: any) => void;
|
|
20
20
|
/** The `Breadcrumbs` style variant to use. */
|
|
21
21
|
variant?: 'light' | 'dark';
|
|
22
22
|
/** The `Breadcrumbs` mobile variant view. */
|
|
@@ -25,6 +25,8 @@ interface BreadcrumbProps {
|
|
|
25
25
|
* [react-router's Link](https://reactrouter.com/en/main/components/link).
|
|
26
26
|
*/
|
|
27
27
|
linkAs?: React.ElementType;
|
|
28
|
+
/** Optional class name(s) to append to the base `<nav>` element. */
|
|
29
|
+
className?: string;
|
|
28
30
|
}
|
|
29
|
-
declare function Breadcrumb({ links, activeLabel, spacer, clickHandler, variant, isMobile, ariaLabel, linkAs,
|
|
31
|
+
declare function Breadcrumb({ links, activeLabel, spacer, clickHandler, className, variant, isMobile, ariaLabel, linkAs, }: BreadcrumbProps): import("react/jsx-runtime").JSX.Element;
|
|
30
32
|
export default Breadcrumb;
|
package/dist/Breadcrumb/index.js
CHANGED
|
@@ -8,18 +8,17 @@ function Breadcrumb({
|
|
|
8
8
|
activeLabel,
|
|
9
9
|
spacer,
|
|
10
10
|
clickHandler,
|
|
11
|
+
className,
|
|
11
12
|
variant = 'light',
|
|
12
13
|
isMobile = false,
|
|
13
14
|
ariaLabel = 'breadcrumb',
|
|
14
|
-
linkAs = 'a'
|
|
15
|
-
...props
|
|
15
|
+
linkAs = 'a'
|
|
16
16
|
}) {
|
|
17
17
|
const linkCount = links.length;
|
|
18
18
|
const displayLinks = isMobile ? [links[linkCount - 1]] : links;
|
|
19
19
|
return /*#__PURE__*/React.createElement("nav", {
|
|
20
20
|
"aria-label": ariaLabel,
|
|
21
|
-
className: classNames('pgn__breadcrumb', `pgn__breadcrumb-${variant}
|
|
22
|
-
...props
|
|
21
|
+
className: classNames('pgn__breadcrumb', `pgn__breadcrumb-${variant}`, className)
|
|
23
22
|
}, /*#__PURE__*/React.createElement("ol", {
|
|
24
23
|
className: classNames('list-inline', {
|
|
25
24
|
'is-mobile': isMobile
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["React","classNames","BreadcrumbLink","ChevronRight","Icon","Breadcrumb","links","activeLabel","spacer","clickHandler","variant","isMobile","ariaLabel","linkAs","
|
|
1
|
+
{"version":3,"file":"index.js","names":["React","classNames","BreadcrumbLink","ChevronRight","Icon","Breadcrumb","links","activeLabel","spacer","clickHandler","className","variant","isMobile","ariaLabel","linkAs","linkCount","length","displayLinks","createElement","map","link","i","Fragment","key","label","as","linkProps","role","src","id"],"sources":["../../src/Breadcrumb/index.tsx"],"sourcesContent":["import React from 'react';\nimport classNames from 'classnames';\n\nimport BreadcrumbLink from './BreadcrumbLink';\nimport { ChevronRight } from '../../icons';\nimport Icon from '../Icon';\n\ninterface BreadcrumbProps {\n /** An array of objects describing links to be rendered. The contents of an object depend on the value of `linkAs`\n * prop as these objects will get passed down as props to the underlying component defined by `linkAs` prop.\n */\n links: Array<{ label: string, [key: string]: any }>;\n /** allows to add a label that is not a link to the end of the breadcrumb. */\n activeLabel?: string;\n /** label of the element */\n ariaLabel?: string;\n /** allows to add a custom element between the breadcrumb items.\n * Defaults to `>` rendered using the `Icon` component. */\n spacer?: React.ReactElement;\n /** allows to add a custom function to be called `onClick` of a breadcrumb link.\n * The use case for this is for adding custom analytics to the component. */\n clickHandler?: (event: React.MouseEvent<HTMLAnchorElement>, link: any) => void;\n /** The `Breadcrumbs` style variant to use. */\n variant?: 'light' | 'dark';\n /** The `Breadcrumbs` mobile variant view. */\n isMobile?: boolean;\n /** Specifies the base element to use when rendering links, you should generally use either plain 'a' or\n * [react-router's Link](https://reactrouter.com/en/main/components/link).\n */\n linkAs?: React.ElementType;\n /** Optional class name(s) to append to the base `<nav>` element. */\n className?: string;\n}\n\nfunction Breadcrumb({\n links, activeLabel, spacer, clickHandler, className,\n variant = 'light', isMobile = false, ariaLabel = 'breadcrumb', linkAs = 'a',\n}: BreadcrumbProps) {\n const linkCount = links.length;\n const displayLinks = isMobile ? [links[linkCount - 1]] : links;\n\n return (\n <nav\n aria-label={ariaLabel}\n className={classNames('pgn__breadcrumb', `pgn__breadcrumb-${variant}`, className)}\n >\n <ol className={classNames('list-inline', { 'is-mobile': isMobile })}>\n {displayLinks.map((link, i) => (\n <React.Fragment key={link.label}>\n <li className={classNames('list-inline-item')}>\n <BreadcrumbLink as={linkAs} clickHandler={clickHandler} linkProps={link} />\n </li>\n {(activeLabel || ((i + 1) < linkCount))\n && (\n <li className=\"list-inline-item\" role=\"presentation\">\n {spacer || <Icon src={ChevronRight} id={`spacer-${i}`} />}\n </li>\n )}\n </React.Fragment>\n ))}\n {!isMobile && activeLabel && <li className=\"list-inline-item active\" key=\"active\" aria-current=\"page\">{activeLabel}</li>}\n </ol>\n </nav>\n );\n}\n\nexport default Breadcrumb;\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,OAAOC,UAAU,MAAM,YAAY;AAEnC,OAAOC,cAAc,MAAM,kBAAkB;AAC7C,SAASC,YAAY,QAAQ,aAAa;AAC1C,OAAOC,IAAI,MAAM,SAAS;AA6B1B,SAASC,UAAUA,CAAC;EAClBC,KAAK;EAAEC,WAAW;EAAEC,MAAM;EAAEC,YAAY;EAAEC,SAAS;EACnDC,OAAO,GAAG,OAAO;EAAEC,QAAQ,GAAG,KAAK;EAAEC,SAAS,GAAG,YAAY;EAAEC,MAAM,GAAG;AACzD,CAAC,EAAE;EAClB,MAAMC,SAAS,GAAGT,KAAK,CAACU,MAAM;EAC9B,MAAMC,YAAY,GAAGL,QAAQ,GAAG,CAACN,KAAK,CAACS,SAAS,GAAG,CAAC,CAAC,CAAC,GAAGT,KAAK;EAE9D,oBACEN,KAAA,CAAAkB,aAAA;IACE,cAAYL,SAAU;IACtBH,SAAS,EAAET,UAAU,CAAC,iBAAiB,EAAE,mBAAmBU,OAAO,EAAE,EAAED,SAAS;EAAE,gBAElFV,KAAA,CAAAkB,aAAA;IAAIR,SAAS,EAAET,UAAU,CAAC,aAAa,EAAE;MAAE,WAAW,EAAEW;IAAS,CAAC;EAAE,GACjEK,YAAY,CAACE,GAAG,CAAC,CAACC,IAAI,EAAEC,CAAC,kBACxBrB,KAAA,CAAAkB,aAAA,CAAClB,KAAK,CAACsB,QAAQ;IAACC,GAAG,EAAEH,IAAI,CAACI;EAAM,gBAC9BxB,KAAA,CAAAkB,aAAA;IAAIR,SAAS,EAAET,UAAU,CAAC,kBAAkB;EAAE,gBAC5CD,KAAA,CAAAkB,aAAA,CAAChB,cAAc;IAACuB,EAAE,EAAEX,MAAO;IAACL,YAAY,EAAEA,YAAa;IAACiB,SAAS,EAAEN;EAAK,CAAE,CACxE,CAAC,EACJ,CAACb,WAAW,IAAMc,CAAC,GAAG,CAAC,GAAIN,SAAU,kBAEpCf,KAAA,CAAAkB,aAAA;IAAIR,SAAS,EAAC,kBAAkB;IAACiB,IAAI,EAAC;EAAc,GACjDnB,MAAM,iBAAIR,KAAA,CAAAkB,aAAA,CAACd,IAAI;IAACwB,GAAG,EAAEzB,YAAa;IAAC0B,EAAE,EAAE,UAAUR,CAAC;EAAG,CAAE,CACtD,CAEQ,CACjB,CAAC,EACD,CAACT,QAAQ,IAAIL,WAAW,iBAAIP,KAAA,CAAAkB,aAAA;IAAIR,SAAS,EAAC,yBAAyB;IAACa,GAAG,EAAC,QAAQ;IAAC,gBAAa;EAAM,GAAEhB,WAAgB,CACrH,CACD,CAAC;AAEV;AAEA,eAAeF,UAAU","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -95,4 +95,29 @@ describe('<Breadcrumb />', () => {
|
|
|
95
95
|
expect(links.getAttribute('target')).toBe('_blank');
|
|
96
96
|
expect(links.getAttribute('href')).toBe('/link-1');
|
|
97
97
|
});
|
|
98
|
+
|
|
99
|
+
it('renders with a custom CSS class', () => {
|
|
100
|
+
render(<Breadcrumb {...baseProps} ariaLabel="Breadcrumbs" className="foobar" />);
|
|
101
|
+
const nav = screen.getByLabelText('Breadcrumbs');
|
|
102
|
+
expect(nav.classList).toContain('foobar');
|
|
103
|
+
expect(nav.classList).toContain('pgn__breadcrumb');
|
|
104
|
+
expect(nav.classList).toContain('pgn__breadcrumb-light');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('can access data-xxxxx attributes on the links in clickHandler', async () => {
|
|
108
|
+
const user = userEvent.setup();
|
|
109
|
+
const clickHandler = jest.fn();
|
|
110
|
+
render(
|
|
111
|
+
<Breadcrumb
|
|
112
|
+
ariaLabel="Location"
|
|
113
|
+
links={[
|
|
114
|
+
{ label: 'Link1', href: '/link1', 'data-parent-index': 17 },
|
|
115
|
+
]}
|
|
116
|
+
clickHandler={({ currentTarget }) => clickHandler(currentTarget.dataset.parentIndex)}
|
|
117
|
+
/>,
|
|
118
|
+
);
|
|
119
|
+
const link = screen.getByRole('link', { name: 'Link1' });
|
|
120
|
+
await user.click(link);
|
|
121
|
+
expect(clickHandler).toHaveBeenCalledWith('17');
|
|
122
|
+
});
|
|
98
123
|
});
|
package/src/Breadcrumb/index.tsx
CHANGED
|
@@ -19,7 +19,7 @@ interface BreadcrumbProps {
|
|
|
19
19
|
spacer?: React.ReactElement;
|
|
20
20
|
/** allows to add a custom function to be called `onClick` of a breadcrumb link.
|
|
21
21
|
* The use case for this is for adding custom analytics to the component. */
|
|
22
|
-
clickHandler?: (event: React.MouseEvent
|
|
22
|
+
clickHandler?: (event: React.MouseEvent<HTMLAnchorElement>, link: any) => void;
|
|
23
23
|
/** The `Breadcrumbs` style variant to use. */
|
|
24
24
|
variant?: 'light' | 'dark';
|
|
25
25
|
/** The `Breadcrumbs` mobile variant view. */
|
|
@@ -28,11 +28,13 @@ interface BreadcrumbProps {
|
|
|
28
28
|
* [react-router's Link](https://reactrouter.com/en/main/components/link).
|
|
29
29
|
*/
|
|
30
30
|
linkAs?: React.ElementType;
|
|
31
|
+
/** Optional class name(s) to append to the base `<nav>` element. */
|
|
32
|
+
className?: string;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
function Breadcrumb({
|
|
34
|
-
links, activeLabel, spacer, clickHandler,
|
|
35
|
-
variant = 'light', isMobile = false, ariaLabel = 'breadcrumb', linkAs = 'a',
|
|
36
|
+
links, activeLabel, spacer, clickHandler, className,
|
|
37
|
+
variant = 'light', isMobile = false, ariaLabel = 'breadcrumb', linkAs = 'a',
|
|
36
38
|
}: BreadcrumbProps) {
|
|
37
39
|
const linkCount = links.length;
|
|
38
40
|
const displayLinks = isMobile ? [links[linkCount - 1]] : links;
|
|
@@ -40,8 +42,7 @@ function Breadcrumb({
|
|
|
40
42
|
return (
|
|
41
43
|
<nav
|
|
42
44
|
aria-label={ariaLabel}
|
|
43
|
-
className={classNames('pgn__breadcrumb', `pgn__breadcrumb-${variant}
|
|
44
|
-
{...props}
|
|
45
|
+
className={classNames('pgn__breadcrumb', `pgn__breadcrumb-${variant}`, className)}
|
|
45
46
|
>
|
|
46
47
|
<ol className={classNames('list-inline', { 'is-mobile': isMobile })}>
|
|
47
48
|
{displayLinks.map((link, i) => (
|