diff --git a/__tests__/PaginationBoxView-test.js b/__tests__/PaginationBoxView-test.js index ad979b5..a8eafd9 100755 --- a/__tests__/PaginationBoxView-test.js +++ b/__tests__/PaginationBoxView-test.js @@ -2151,21 +2151,25 @@ describe('Test custom props', () => { ReactDOM.findDOMNode(pagination).querySelectorAll('.selected a').length ).toBe(1); expect( - ReactDOM.findDOMNode(pagination).querySelector('.selected a').textContent + ReactDOM.findDOMNode(pagination).querySelector('.selected a') + .textContent ).toBe('2'); // Click to go to page 8. for (let i = 1; i < 7; i++) { ReactTestUtils.Simulate.click(next); expect( - ReactDOM.findDOMNode(pagination).querySelectorAll('.selected a').length + ReactDOM.findDOMNode(pagination).querySelectorAll('.selected a') + .length ).toBe(1); expect( - ReactDOM.findDOMNode(pagination).querySelector('.selected a').textContent - ).toBe(`${2+i}`); + ReactDOM.findDOMNode(pagination).querySelector('.selected a') + .textContent + ).toBe(`${2 + i}`); } expect( - ReactDOM.findDOMNode(pagination).querySelector('.selected a').textContent + ReactDOM.findDOMNode(pagination).querySelector('.selected a') + .textContent ).toBe('8'); ReactTestUtils.Simulate.click(previous); @@ -2174,7 +2178,8 @@ describe('Test custom props', () => { ReactDOM.findDOMNode(pagination).querySelectorAll('.selected a').length ).toBe(1); expect( - ReactDOM.findDOMNode(pagination).querySelector('.selected a').textContent + ReactDOM.findDOMNode(pagination).querySelector('.selected a') + .textContent ).toBe('7'); }); }); diff --git a/demo/index.html b/demo/index.html index 598c99b..c05cf81 100644 --- a/demo/index.html +++ b/demo/index.html @@ -6,10 +6,11 @@ <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>React-Paginate</title> <link - href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" + href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" - /> - <link href="styles/style.css" rel="stylesheet" /> + integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" + crossorigin="anonymous" + > <style type="text/css"> body { margin-top: 60px; @@ -17,33 +18,22 @@ </style> </head> <body> - <nav class="navbar navbar-inverse navbar-fixed-top"> + <nav class="navbar navbar-expand-lg bg-light mb-5"> <div class="container"> - <div class="navbar-header"> - <button - type="button" - class="navbar-toggle collapsed" - data-toggle="collapse" - data-target="#navbar" - aria-expanded="false" - aria-controls="navbar" - > - <span class="sr-only">Toggle navigation</span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="#">React-Paginate</a> - </div> - <div id="navbar" class="collapse navbar-collapse"> - <ul class="nav navbar-nav"> - <li><a href="#">Home</a></li> - </ul> + <a class="navbar-brand" href="#">React Paginate</a> + <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbarSupportedContent"> + <ul class="navbar-nav me-auto mb-2 mb-lg-0"> + <li class="nav-item"> + <a class="nav-link active" aria-current="page" href="#">Home</a> + </li> </div> </div> </nav> <div class="container"> - <p> + <p class="mb-5"> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea diff --git a/demo/js/demo.js b/demo/js/demo.js index 8efd34b..a1b1efb 100644 --- a/demo/js/demo.js +++ b/demo/js/demo.js @@ -2,9 +2,48 @@ import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import ReactPaginate from 'react-paginate'; +import styled from 'styled-components'; import $ from 'jquery'; -window.React = React; +// You can style your pagination component +// thanks to styled-components. +// Use inner class names to style the controls. +const MyPaginate = styled(ReactPaginate).attrs({ + // You can redifine classes here, if you want. + activeClassName: 'active', // default to "disabled" +})` + margin-bottom: 2rem; + display: flex; + flex-direction: row; + justify-content: space-between; + list-style-type: none; + padding: 0 5rem; + + li a { + border-radius: 7px; + padding: 0.1rem 1rem; + border: gray 1px solid; + cursor: pointer; + } + li.previous a, + li.next a, + li.break a { + border-color: transparent; + } + li.active a { + background-color: #0366d6; + border-color: transparent; + color: white; + min-width: 32px; + } + li.disabled a { + color: grey; + } + li.disable, + li.disabled a { + cursor: default; + } +`; export class CommentList extends Component { static propTypes = { @@ -14,15 +53,18 @@ export class CommentList extends Component { render() { let commentNodes = this.props.data.map(function (comment, index) { return ( - <div key={index}> - {comment.comment} and {comment.username} - </div> + <li key={index} className="list-group-item"> + <div className="d-flex w-100 justify-content-between"> + <h5 className="mb-1">{comment.comment}</h5> + </div> + <small>From {comment.username}.</small> + </li> ); }); return ( <div id="project-comments" className="commentList"> - <ul>{commentNodes}</ul> + <ul className="list-group">{commentNodes}</ul> </div> ); } @@ -78,32 +120,50 @@ export class App extends Component { }; render() { + const currentPage = Math.round(this.state.offset / this.props.perPage); return ( <div className="commentBox"> - <CommentList data={this.state.data} /> - <ReactPaginate - previousLabel="previous" - nextLabel="next" - breakLabel="..." - breakClassName="break-me" + <MyPaginate pageCount={20} - marginPagesDisplayed={2} - pageRangeDisplayed={5} onPageChange={this.handlePageClick} - containerClassName="pagination" - activeClassName="active" - // eslint-disable-next-line no-unused-vars - hrefBuilder={(page, pageCount, selected) => - page >= 1 && page <= pageCount ? `/page/${page}` : '#' - } - hrefAllControls + forcePage={currentPage} /> + <CommentList data={this.state.data} /> + {/* Here the pagination component is styled thanks to Boostrap + classes. See https://getbootstrap.com/docs/5.1/components/pagination */} + <nav aria-label="Page navigation comments" className="mt-4"> + <ReactPaginate + previousLabel="previous" + nextLabel="next" + breakLabel="..." + breakClassName="page-item" + breakLinkClassName="page-link" + pageCount={20} + marginPagesDisplayed={2} + pageRangeDisplayed={5} + onPageChange={this.handlePageClick} + containerClassName="pagination justify-content-center" + pageClassName="page-item" + pageLinkClassName="page-link" + previousClassName="page-item" + previousLinkClassName="page-link" + nextClassName="page-item" + nextLinkClassName="page-link" + activeClassName="active" + // eslint-disable-next-line no-unused-vars + hrefBuilder={(page, pageCount, selected) => + page >= 1 && page <= pageCount ? `/page/${page}` : '#' + } + hrefAllControls + forcePage={currentPage} + /> + </nav> </div> ); } } ReactDOM.render( - <App url={'http://localhost:3000/comments'} author={'adele'} perPage={10} />, + <App url={'http://localhost:3000/comments'} author={'adele'} perPage={6} />, document.getElementById('react-paginate') ); diff --git a/demo/server.js b/demo/server.js index 67ef834..ec3a950 100644 --- a/demo/server.js +++ b/demo/server.js @@ -17,7 +17,6 @@ const STYLES_DIR = path.join(__dirname, 'styles'); const DATA = path.join(__dirname, 'data', 'data.json'); const NODE_PORT = process.env.NODE_PORT || 3000; const NODE_ENV = process.env.NODE_ENV || 'development'; -const PER_PAGE = 10; app.use(serveStatic(ROOT_DIR)); app.use(serveStatic(STYLES_DIR)); @@ -31,27 +30,29 @@ app.use( }) ); -function getPaginatedItems(items, offset) { - return items.slice(offset, offset + PER_PAGE); +const ITEMS = JSON.parse(fs.readFileSync(DATA)); + +function getPaginatedItems(items, offset, limit) { + return items.slice(offset, offset + limit); } app.get('/comments', function (req, res) { - const items = JSON.parse(fs.readFileSync(DATA)); - const offset = req.query.offset ? parseInt(req.query.offset, 10) : 0; - const nextOffset = offset + PER_PAGE; - const previousOffset = offset - PER_PAGE < 1 ? 0 : offset - PER_PAGE; + const offset = req.query.offset ? parseInt(req.query.offset) : 0; + const limit = req.query.limit ? parseInt(req.query.limit) : 10; + const nextOffset = offset + limit; + const previousOffset = offset - limit < 1 ? 0 : offset - limit; const meta = { - limit: PER_PAGE, - next: util.format('?limit=%s&offset=%s', PER_PAGE, nextOffset), + limit: limit, + next: util.format('?limit=%d&offset=%d', limit, nextOffset), offset: req.query.offset, - previous: util.format('?limit=%s&offset=%s', PER_PAGE, previousOffset), - total_count: items.length, + previous: util.format('?limit=%d&offset=%', limit, previousOffset), + total_count: ITEMS.length, }; const json = { meta: meta, - comments: getPaginatedItems(items, offset), + comments: getPaginatedItems(ITEMS, offset, limit), }; return res.json(json); diff --git a/demo/styles/style.css b/demo/styles/style.css deleted file mode 100644 index cb2383e..0000000 --- a/demo/styles/style.css +++ /dev/null @@ -1,9 +0,0 @@ -#react-paginate ul { - display: inline-block; - padding-left: 18px; - padding-right: 18px; -} - -#react-paginate li { - display: inline-block; -} diff --git a/index.d.ts b/index.d.ts index 010a9bb..c587257 100644 --- a/index.d.ts +++ b/index.d.ts @@ -37,9 +37,9 @@ export interface ReactPaginateProps { prevPageRel?: string | null | undefined; /** - * The `rel` property on the `a` tag for the prev page control. - * Default value `prev`. Set to `null` to disable. - */ + * The `rel` property on the `a` tag for the prev page control. + * Default value `prev`. Set to `null` to disable. + */ prevRel?: string | null | undefined; /** @@ -59,9 +59,9 @@ export interface ReactPaginateProps { nextPageRel?: string | null | undefined; /** - * The `rel` property on the `a` tag for the next page control. - * Default value `next`. Set to `null` to disable. - */ + * The `rel` property on the `a` tag for the next page control. + * Default value `next`. Set to `null` to disable. + */ nextRel?: string | null | undefined; /** @@ -171,7 +171,11 @@ export interface ReactPaginateProps { /** * The method is called to generate the href attribute value on tag a of each page element. */ - hrefBuilder?(pageIndex: number, pageCount: number, selectedPage: number): void; + hrefBuilder?( + pageIndex: number, + pageCount: number, + selectedPage: number + ): void; /** * By default the `hrefBuilder` add `href` only to active controls. @@ -179,7 +183,7 @@ export interface ReactPaginateProps { * ([see](https://github.com/AdeleD/react-paginate/issues/242)) * Default to `false` */ - hrefAllControls?: boolean | undefined; + hrefAllControls?: boolean | undefined; /** * Extra context to add to the aria-label HTML attribute. @@ -206,7 +210,7 @@ export interface ReactPaginateProps { * The `rel` propery on the `a` tag for the selected page. * Default value `canonical`. Set to `null` to disable. */ - selectedPageRel?: string | null | undefined; + selectedPageRel?: string | null | undefined; } declare const ReactPaginate: React.ComponentClass<ReactPaginateProps>; diff --git a/package-lock.json b/package-lock.json index 6aa10c6..a055cc2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "react-dom": "^17.0.2", "react-hot-loader": "^4.13.0", "serve-static": "^1.14.1", + "styled-components": "^5.3.3", "webpack": "^5.60.0", "webpack-cli": "^4.9.1", "webpack-dev-middleware": "^5.2.1" @@ -139,12 +140,12 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", - "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", + "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -322,12 +323,12 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", + "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -1762,12 +1763,12 @@ "dev": true }, "node_modules/@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-validator-identifier": "^7.15.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1789,6 +1790,33 @@ "node": ">=10.0.0" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "dev": true, + "dependencies": { + "@emotion/memoize": "0.7.4" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "dev": true + }, + "node_modules/@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==", + "dev": true + }, + "node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", + "dev": true + }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -3655,6 +3683,27 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/babel-plugin-styled-components": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.1.tgz", + "integrity": "sha512-U3wmORxerYBiqcRCo6thItIosEIga3F+ph0jJPkiOZJjyhpZyUZFQV9XvrZ2CbBIihJ3rDBC/itQ+Wx3VHMauw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.11" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, + "node_modules/babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", + "dev": true + }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -3824,6 +3873,12 @@ "node": ">=6" } }, + "node_modules/camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=", + "dev": true + }, "node_modules/caniuse-lite": { "version": "1.0.30001271", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001271.tgz", @@ -4060,6 +4115,26 @@ "node": ">= 8" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", + "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", + "dev": true, + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -8707,6 +8782,12 @@ "node": ">=8" } }, + "node_modules/postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -9564,6 +9645,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/styled-components": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz", + "integrity": "sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^0.8.8", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0", + "react-is": ">= 16.8.0" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -10558,12 +10669,12 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", - "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", + "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { @@ -10693,12 +10804,12 @@ } }, "@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", + "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-module-transforms": { @@ -11681,12 +11792,12 @@ } }, "@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-validator-identifier": "^7.15.7", "to-fast-properties": "^2.0.0" } }, @@ -11702,6 +11813,33 @@ "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", "dev": true }, + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "dev": true, + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "dev": true + }, + "@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==", + "dev": true + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", + "dev": true + }, "@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -13177,6 +13315,24 @@ "@babel/helper-define-polyfill-provider": "^0.2.2" } }, + "babel-plugin-styled-components": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.1.tgz", + "integrity": "sha512-U3wmORxerYBiqcRCo6thItIosEIga3F+ph0jJPkiOZJjyhpZyUZFQV9XvrZ2CbBIihJ3rDBC/itQ+Wx3VHMauw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.11" + } + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", + "dev": true + }, "babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -13309,6 +13465,12 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=", + "dev": true + }, "caniuse-lite": { "version": "1.0.30001271", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001271.tgz", @@ -13500,6 +13662,23 @@ "which": "^2.0.1" } }, + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", + "dev": true + }, + "css-to-react-native": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", + "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", + "dev": true, + "requires": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -16991,6 +17170,12 @@ "find-up": "^4.0.0" } }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -17655,6 +17840,24 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "styled-components": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz", + "integrity": "sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^0.8.8", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/package.json b/package.json index efb0134..ba28974 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "react-dom": "^17.0.2", "react-hot-loader": "^4.13.0", "serve-static": "^1.14.1", + "styled-components": "^5.3.3", "webpack": "^5.60.0", "webpack-cli": "^4.9.1", "webpack-dev-middleware": "^5.2.1"