Skip to content

Commit

Permalink
Merge branch 'release-22.x' into sync-22-23-react18
Browse files Browse the repository at this point in the history
  • Loading branch information
brian-smith-tcril committed Jan 23, 2025
2 parents 2117eb6 + c5c48aa commit f43480b
Show file tree
Hide file tree
Showing 86 changed files with 624 additions and 544 deletions.
7 changes: 7 additions & 0 deletions .stylelintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
}],
"alpha-value-notation": "number",
"color-function-notation": "legacy",
"import-notation": "string",
"at-rule-empty-line-before": ["always", {
"except": ["blockless-after-same-name-blockless", "first-nested"],
"ignore": ["after-comment"],
"ignoreAtRules": ["import"]
}],
"declaration-block-no-redundant-longhand-properties": null,
"value-keyword-case": ["lower", {
"ignoreProperties": ["/font-family/"]
}],
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -802,8 +802,8 @@ The following subcomponents have been added / reworked:

* fix: update image sizing according to figma design

Co-authored-by: vlasovmichael <[email protected]>
Co-authored-by: vzadorozhnii <[email protected]>
Co-authored-by: vlasovmichael \<[email protected]\>
Co-authored-by: vzadorozhnii \<[email protected]\>



Expand Down
6 changes: 6 additions & 0 deletions example/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: [
'@edx/eslint-config',
],
root: true, // Don't also import the paragon eslint config in the parent directory.
};
10 changes: 3 additions & 7 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,10 @@
"license": "ISC",
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
"@edx/frontend-platform": "^4.2.0",
"@edx/frontend-build": "^13.0.14",
"@edx/frontend-platform": "^8",
"@faker-js/faker": "^7.6.0",
"core-js": "^3.22.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"regenerator-runtime": "^0.13.9"
},
"devDependencies": {
"@edx/frontend-build": "^12.8.10"
"react-dom": "^17.0.2"
}
}
4 changes: 2 additions & 2 deletions example/src/MyComponent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { Button, Form, Icon, Bubble, Stack, Container } from '@openedx/paragon'; // eslint-disable-line
import { FavoriteBorder } from '@openedx/paragon/icons'; // eslint-disable-line

const MyComponent = () => {
function MyComponent() {
const [value, setValue] = useState('');
const handleChange = (e) => setValue(e.target.value);
const handleClick = () => alert('Form is submitted!'); // eslint-disable-line no-alert
Expand All @@ -26,6 +26,6 @@ const MyComponent = () => {
</Form>
</Container>
);
};
}

export default MyComponent;
3 changes: 0 additions & 3 deletions example/src/index.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import 'core-js/stable';
import 'regenerator-runtime/runtime';

import React from 'react';
import ReactDOM from 'react-dom';
import {
Expand Down
2 changes: 1 addition & 1 deletion icons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"bootstrap-icons": "^1.11.3"
},
"peerDependencies": {
"react": "^16.8.6 || ^17.0.2"
"react": "^16.8.6 || ^17 || ^18"
},
"exports": {
".": {
Expand Down
4 changes: 4 additions & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@
environment = { SEGMENT_KEY = "", NODE_VERSION = "18.16.0" }
[functions]
directory = "www/netlify/functions"
[[headers]]
for = "/*"
[headers.values]
Content-Security-Policy = "frame-ancestors *;"
27 changes: 10 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@
"uuid": "^9.0.0"
},
"peerDependencies": {
"react": "^16.8.6 || ^17.0.0",
"react-dom": "^16.8.6 || ^17.0.0",
"react": "^16.8.6 || ^17 || ^18",
"react-dom": "^16.8.6 || ^17 || ^18",
"react-intl": "^5.25.1 || ^6.4.0"
},
"devDependencies": {
Expand All @@ -121,13 +121,12 @@
"@formatjs/cli": "^5.0.2",
"@semantic-release/changelog": "^6.0.1",
"@semantic-release/git": "^10.0.1",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^12.1.4",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^13.5.0",
"@testing-library/jest-dom": "^6.6",
"@testing-library/react": "^16.1",
"@testing-library/user-event": "^14.5",
"@types/jest": "^29.5.10",
"@types/react": "^17.0.80",
"@types/react-dom": "^17.0.11",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/react-responsive": "^8.0.8",
"@types/react-table": "^7.7.19",
"@types/react-test-renderer": "^18.0.0",
Expand All @@ -140,25 +139,19 @@
"babel-loader": "^8.2.4",
"commander": "^9.3.0",
"eslint": "8.18.0",
"eslint-config-airbnb": "19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-jsx-a11y": "6.7.1",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-react-hooks": "4.6.0",
"husky": "^9.0.11",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.7.0",
"jest-cli": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"lint-staged": "^15.2.0",
"markdown-loader-jest": "^0.1.1",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-test-renderer": "^17.0.0",
"react": "^18",
"react-test-renderer": "^18",
"regenerator-runtime": "^0.13.9",
"semantic-release": "^20.1.3",
"stylelint": "^14.7.1",
"stylelint": "^15.11.0",
"stylelint-config-standard-scss": "^4.0.0",
"ts-jest": "^29.1.2",
"typescript": "^4.7.4"
Expand Down
5 changes: 3 additions & 2 deletions src/Breadcrumb/Breadcrumb.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,16 @@ describe('<Breadcrumb />', () => {
expect(screen.getAllByRole('presentation').length).toBe(2);
});

it('fires the passed in click handler', () => {
it('fires the passed in click handler', async () => {
const user = userEvent.setup();
const clickHandler = jest.fn();
render(<Breadcrumb {...baseProps} clickHandler={clickHandler} />);

const listItems = screen.queryAllByRole('listitem');
const links = screen.queryAllByRole('link');
expect(listItems.length).toBe(baseProps.links.length);

userEvent.click(links[0]);
await user.click(links[0]);
expect(clickHandler).toHaveBeenCalled();
});

Expand Down
1 change: 1 addition & 0 deletions src/Bubble/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const Bubble = React.forwardRef<HTMLDivElement, BubbleProps>(({

Bubble.propTypes = {
/** Specifies contents of the component. */
// @ts-ignore
children: PropTypes.node,
/** The `Bubble` style variant to use. */
variant: PropTypes.oneOf(STYLE_VARIANTS),
Expand Down
10 changes: 6 additions & 4 deletions src/Card/CardCarousel/tests/CardCarouselControls.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,29 @@ describe('<CardCarouselControls />', () => {
expect(tree).toMatchSnapshot();
});

it('handles scroll to previous click', () => {
it('handles scroll to previous click', async () => {
const user = userEvent.setup();
const contextValue = {
...defaultCardCarouselContextValue,
isScrolledToStart: false,
};
render((
<CardCarouselControlsWrapper cardCarouselContextValue={contextValue} />
));
userEvent.click(screen.getByLabelText('Scroll to previous'));
await user.click(screen.getByLabelText('Scroll to previous'));
expect(mockScrollToPrevious).toHaveBeenCalledTimes(1);
});

it('handles scroll to next click', () => {
it('handles scroll to next click', async () => {
const user = userEvent.setup();
const contextValue = {
...defaultCardCarouselContextValue,
isScrolledToEnd: false,
};
render((
<CardCarouselControlsWrapper cardCarouselContextValue={contextValue} />
));
userEvent.click(screen.getByLabelText('Scroll to next'));
await user.click(screen.getByLabelText('Scroll to next'));
expect(mockScrollToNext).toHaveBeenCalledTimes(1);
});
});
1 change: 1 addition & 0 deletions src/Chip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const Chip = React.forwardRef(({

Chip.propTypes = {
/** Specifies the content of the `Chip`. */
// @ts-ignore
children: PropTypes.node.isRequired,
/** Specifies an additional `className` to add to the base element. */
className: PropTypes.string,
Expand Down
22 changes: 15 additions & 7 deletions src/Collapsible/Collapsible.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { render, screen, waitFor } from '@testing-library/react';
import renderer from 'react-test-renderer';
import userEvent from '@testing-library/user-event';

Expand Down Expand Up @@ -75,17 +75,23 @@ describe('<Collapsible />', () => {
<Collapsible.Advanced ref={ref}>{collapsibleContent}</Collapsible.Advanced>,
);
});
it('opens on .open()', () => {
it('opens on .open()', async () => {
expect(screen.queryByText(EXAMPLE_CONTENT)).not.toBeInTheDocument();
ref.current.open();
expect(screen.getByText(EXAMPLE_CONTENT)).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByText(EXAMPLE_CONTENT)).toBeInTheDocument();
});
});

it('closes on .close()', () => {
it('closes on .close()', async () => {
ref.current.open();
expect(screen.getByText(EXAMPLE_CONTENT)).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByText(EXAMPLE_CONTENT)).toBeInTheDocument();
});
ref.current.close();
expect(screen.queryByText(EXAMPLE_CONTENT)).not.toBeInTheDocument();
await waitFor(() => {
expect(screen.queryByText(EXAMPLE_CONTENT)).not.toBeInTheDocument();
});
});

it('correct behavior with unmountOnExit', () => {
Expand Down Expand Up @@ -127,7 +133,9 @@ describe('<Collapsible />', () => {

it('closes on trigger click', async () => {
collapsible.open();
expect(screen.getByText(EXAMPLE_CONTENT)).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByText(EXAMPLE_CONTENT)).toBeInTheDocument();
});
await userEvent.click(screen.getAllByRole('button')[0]); // Close
expect(screen.queryByText(EXAMPLE_CONTENT)).not.toBeInTheDocument();
});
Expand Down
25 changes: 9 additions & 16 deletions src/ColorPicker/ColorPicker.test.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import renderer from 'react-test-renderer';
import userEvent from '@testing-library/user-event';
import { render, screen, act } from '@testing-library/react';
import { render, screen } from '@testing-library/react';

import ColorPicker from '.';

Expand Down Expand Up @@ -29,33 +29,26 @@ describe('picker works as expected', () => {
const color = 'wassap';
const setColor = jest.fn();
it('validates hex color', async () => {
const user = userEvent.setup();
render(<ColorPicker color={color} setColor={setColor} />);

await act(async () => {
await userEvent.click(screen.getByRole('button'));
});
await user.click(screen.getByRole('button'));
expect(screen.queryByTestId('hex-input').value).toEqual('#wassap');
expect(screen.queryByText('Colors must be in hexadecimal format.')).toBeInTheDocument();

await act(async () => {
await userEvent.clear(screen.getByTestId('hex-input'));
await userEvent.paste(screen.getByTestId('hex-input'), '32116c');
});
await user.clear(screen.getByTestId('hex-input')); // clear() will keep focus on the element, so we can paste
await user.paste('32116c');
expect(screen.queryByTestId('hex-input').value).toEqual('#32116c');
expect(screen.queryByText('Colors must be in hexadecimal format.')).not.toBeInTheDocument();

await act(async () => {
await userEvent.clear(screen.getByTestId('hex-input'));
await userEvent.paste(screen.getByTestId('hex-input'), 'yuk');
});
await user.clear(screen.getByTestId('hex-input'));
await user.paste('yuk');

expect(screen.queryByTestId('hex-input').value).toEqual('#yuk');
expect(screen.queryByText('Colors must be in hexadecimal format.')).toBeInTheDocument();

await act(async () => {
await userEvent.clear(screen.getByTestId('hex-input'));
await userEvent.paste(screen.getByTestId('hex-input'), '#fad');
});
await user.clear(screen.getByTestId('hex-input'));
await user.paste('#fad');

expect(screen.queryByTestId('hex-input').value).toEqual('#fad');
expect(screen.queryByText('Colors must be in hexadecimal format.')).not.toBeInTheDocument();
Expand Down
2 changes: 1 addition & 1 deletion src/ColorPicker/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Form from '../Form';
import ModalPopup from '../Modal/ModalPopup';
import { OverlayTrigger } from '../Overlay';
import Tooltip from '../Tooltip';
import useToggle from '../hooks/useToggle';
import useToggle from '../hooks/useToggleHook';

function ColorPicker({
color, setColor, className, size,
Expand Down
4 changes: 2 additions & 2 deletions src/DataTable/CollapsibleButtonGroup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React, { useContext, useMemo, useState } from 'react';
import PropTypes from 'prop-types';

import { MoreVert } from '../../icons';
import useToggle from '../hooks/useToggle';
import useWindowSize from '../hooks/useWindowSize';
import useToggle from '../hooks/useToggleHook';
import useWindowSize from '../hooks/useWindowSizeHook';
import DataTableContext from './DataTableContext';
import Icon from '../Icon';
import IconButton from '../IconButton';
Expand Down
2 changes: 1 addition & 1 deletion src/DataTable/DropdownFilters.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useContext, useMemo } from 'react';
import DataTableContext from './DataTableContext';
import { DropdownButton } from '../Dropdown';
import useWindowSize from '../hooks/useWindowSize';
import useWindowSize from '../hooks/useWindowSizeHook';
import breakpoints from '../utils/breakpoints';

/** The first filter will be as an input, additional filters will be available in a dropdown. */
Expand Down
9 changes: 1 addition & 8 deletions src/DataTable/dataviews.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,11 @@ It displays the data provided by the `DataTableContext` as an html table.
</DataTable>
```

<PropsTable displayName="Table" content='The DataTable.Table component expects to receive a react-table instance from the DataTableContext.' />

## Table Subcomponents

Subcomponents of `DataTable.Table` can be used independently of the main component. They are designed for use with a `react-table` instance.

<PropsTable displayName="TableRow" />
<PropsTable displayName="TableCell" />
<PropsTable displayName="TableHeaderCell" />
<PropsTable displayName="TableHeaderRow" />
See the available props of `<TableRow>`, `<TableCell>`, `<TableHeaderCell>`, and `<TableHeaderRow>` below.

## CardView and alternate table components

Expand Down Expand Up @@ -337,8 +332,6 @@ a responsive grid of cards.
The `CardComponent` prop on `CardView` represents a table row, and will receive the row that `react-table`
provides as props.

<PropsTable displayName="CardView" />

```jsx
const MiyazakiCard = ({ className, original }) => {
const { title, director, release_date } = original;
Expand Down
Loading

0 comments on commit f43480b

Please sign in to comment.