diff --git a/.babelrc b/.babelrc index cfc2312..f8b5a6c 100644 --- a/.babelrc +++ b/.babelrc @@ -1,16 +1,8 @@ { - "presets": [ - "@babel/env", - "@babel/react" - ], + "presets": ["@babel/env", "@babel/react"], "env": { "production": { - "plugins": [ - ["transform-react-remove-prop-types", { - "mode": "remove", - "removeImport": true - }] - ] + "plugins": [] } }, "plugins": ["@babel/plugin-proposal-class-properties"] diff --git a/.eslintrc b/.eslintrc index 8c4864c..e9827fe 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,22 +1,24 @@ { "env": { + "node": true, "browser": true, "jest": true }, "extends": [ - "airbnb-base", - "plugin:react/recommended" + "eslint:recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended" ], "settings": { "react": { - "version": "16.0" + "version": "16.0" } }, - "parser": "babel-eslint", - "plugins": ["babel"], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], "rules": { "arrow-parens": 0, - "indent": [ "error", 4 ], + "indent": ["error", 4], "no-console": ["error", { "allow": ["error"] }], "no-continue": 0, "operator-linebreak": 0, diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index cf013dc..883afc4 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -21,6 +21,8 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v4 + with: + version: latest - name: Install dependencies run: pnpm install --frozen-lockfile diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 9355f46..61ab004 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -2,6 +2,7 @@ name: Pull Request on: pull_request: + types: [opened, synchronize, reopened] branches: - '**' # This triggers the workflow on pull requests to any branch @@ -17,6 +18,11 @@ jobs: with: node-version: 20.13.1 + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: latest + - name: Install dependencies run: pnpm install --frozen-lockfile diff --git a/.gitignore b/.gitignore index b990381..c2fb502 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ dist !app/dist/ react-step-wizard-*.tgz coverage/ +app/next diff --git a/.npmignore b/.npmignore index 37eb3c6..f114e0c 100644 --- a/.npmignore +++ b/.npmignore @@ -8,8 +8,10 @@ _config.yml .eslintrc .gitignore .nvmrc +.prettierrc .vscode/ app/ +docs/ CHANGELOG.md coverage/ example.gif @@ -17,10 +19,12 @@ example/ .github/ index.html jest.config.json +jest.config.js react-step-wizard-*.tgz rollup.config.js scripts/ src/ +tsconfig.json webpack.config.js yarn.lock yarn*.log diff --git a/.nvmrc b/.nvmrc index d9617ea..297d47b 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.5.0 \ No newline at end of file +20.13.1 \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..c7905a9 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "tabWidth": 4, + "semi": true, + "singleQuote": true +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f28e539..3831796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Changelog All notable changes to this project will be documented in this file. +### [5.4.0-beta.2] +• Generate `main: cjs`, `browser: umd`, and `module: esm` bundles for better import compatibility - like with Next.js +• Generate accurate types thanks to TypeScript + +> Dev Changes +• Refactor codebase in Typescript +• Update packages to address security vulnerabilities + ### [5.3.11] • Add missing transition type - intro - Thanks [bundit](https://github.com/bundit) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5f62159..7f3f50f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,10 +3,11 @@ Steps to develop locally: • `nvm use` -• `npm install` +• `pnpm install` • `npm start` ### Testing + Once your changes look good, test it intensely! • `npm test` - runs existing unit tests. If your changes require a new unit test, please add it to `src/index.test.js` @@ -20,6 +21,7 @@ Create a production build of the example app and test in Chrome, Safari, Firefox Open `app/index.html` in all the browsers listed above and ensure there are no console errors. Also, make sure hashKeys still work as expected. ### Create Pull Request + If you feel confidence in your changes, open a PR for me to review. I'll most likely have you merge into a dev branch before going straight to master. From there I will handle the versioning and publish your changes! I'm working on automating publishing straight to NPM when a new release is created. To up the version use `npm version` for semantic versioning. diff --git a/app/App.js b/app/App.js index a98ed63..1d42366 100644 --- a/app/App.js +++ b/app/App.js @@ -1,17 +1,15 @@ import React from 'react'; -import ReactDOM from 'react-dom'; -import { hot } from 'react-hot-loader'; +import { createRoot } from 'react-dom/client'; import Wizard from './components/wizard'; -import 'bootstrap/dist/css/bootstrap.min.css'; import './less/app.less'; const App = () => ( ); -/** HMR */ -hot(module)(App); +const domNode = document.getElementById('app'); +const root = createRoot(domNode); -ReactDOM.render(, document.getElementById('app')); +root.render(); \ No newline at end of file diff --git a/app/components/nav.less b/app/components/nav.css similarity index 89% rename from app/components/nav.less rename to app/components/nav.css index 6727ba5..d87c050 100644 --- a/app/components/nav.less +++ b/app/components/nav.css @@ -1,6 +1,7 @@ -.nav { +.wizard-nav { margin-bottom: 15px; text-align: center; + justify-content: center; } .dot { diff --git a/app/components/nav.js b/app/components/nav.js index addb61e..9e44644 100644 --- a/app/components/nav.js +++ b/app/components/nav.js @@ -1,6 +1,5 @@ import React from 'react'; -/* eslint react/prop-types: 0 */ -import styles from './nav.less'; +import styles from './nav.css'; const Nav = (props) => { const dots = []; @@ -16,7 +15,7 @@ const Nav = (props) => { } return ( -
{dots}
+
{dots}
); }; diff --git a/app/components/transitions.less b/app/components/transitions.css similarity index 100% rename from app/components/transitions.less rename to app/components/transitions.css diff --git a/app/components/wizard.less b/app/components/wizard.css similarity index 69% rename from app/components/wizard.less rename to app/components/wizard.css index fafd639..3cb5dd2 100644 --- a/app/components/wizard.less +++ b/app/components/wizard.css @@ -3,8 +3,10 @@ } /** Progress Bar */ -@progress-height: 5px; -@duration: 3s; +:root { + --progress-height: 5px; + --duration: 3s; +} @keyframes stripes { from { background-position: 1rem 0 } @@ -30,17 +32,17 @@ } .progress { - height: @progress-height; + height: var(progress-height); overflow: hidden; } .progress-bar { - height: @progress-height; + height: var(--progress-height); width: 100%; - - .loaded & { - animation: grow @duration ease, - stripes 1s linear infinite, - rainbow @duration ease infinite; - } } + +.loaded .progress-bar { + animation: grow var(--duration) ease, + stripes 1s linear infinite, + rainbow var(--duration) ease infinite; +} \ No newline at end of file diff --git a/app/components/wizard.js b/app/components/wizard.js index 3d8d2bf..c490a51 100644 --- a/app/components/wizard.js +++ b/app/components/wizard.js @@ -1,12 +1,12 @@ import React, { Fragment, useState, useEffect } from 'react'; -import StepWizard from '../../dist/react-step-wizard.min'; +import StepWizard from '../../'; import Nav from './nav'; import Plugs from './Plugs'; -import styles from './wizard.less'; -import transitions from './transitions.less'; -/* eslint react/prop-types: 0 */ +import styles from './wizard.css'; +import transitions from './transitions.css'; +import 'bootstrap/dist/css/bootstrap.min.css'; /** * A basic demonstration of how to use the step wizard @@ -64,11 +64,12 @@ const Wizard = () => { {null /* will be ignored */} + - { (demo && SW) && } + {(demo && SW) && } ); }; @@ -103,10 +104,10 @@ const Stats = ({ }) => (

- { step > 1 && + {step > 1 && } - { step < totalSteps ? + {step < totalSteps ? : @@ -151,7 +152,7 @@ const Second = props => { return (
- { props.form.firstname &&

Hey {props.form.firstname}! 👋

} + {props.form.firstname &&

Hey {props.form.firstname}! 👋

} I've added validation to the previous button.
diff --git a/app/dist/app.bundle.js b/app/dist/app.bundle.js index 9db05fb..170dd60 100644 --- a/app/dist/app.bundle.js +++ b/app/dist/app.bundle.js @@ -1 +1 @@ -!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=11)}([function(e,t,r){"use strict";e.exports=r(13)},function(e,t,r){var n=r(21);"string"==typeof n&&(n=[[e.i,n,""]]);var o={singleton:!0,transform:void 0},a=r(4)(n,o);n.locals&&(e.exports=n.locals),e.exports.__universal__=a.__universal__},function(e,t,r){var n=r(20);"string"==typeof n&&(n=[[e.i,n,""]]);var o={singleton:!0,transform:void 0},a=r(4)(n,o);n.locals&&(e.exports=n.locals),e.exports.__universal__=a.__universal__},function(e,t,r){"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var r=function(e,t){var r=e[1]||"",n=e[3];if(!n)return r;if(t&&"function"==typeof btoa){var o=(i=n,l=btoa(unescape(encodeURIComponent(JSON.stringify(i)))),s="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(l),"/*# ".concat(s," */")),a=n.sources.map((function(e){return"/*# sourceURL=".concat(n.sourceRoot||"").concat(e," */")}));return[r].concat(a).concat([o]).join("\n")}var i,l,s;return[r].join("\n")}(t,e);return t[2]?"@media ".concat(t[2]," {").concat(r,"}"):r})).join("")},t.i=function(e,r,n){"string"==typeof e&&(e=[[null,e,""]]);var o={};if(n)for(var a=0;a=0&&u.splice(t,1)}function v(e){var t=document.createElement("style");return e.attrs.type="text/css",w(t,e.attrs),h(e,t),t}function w(e,t){Object.keys(t).forEach((function(r){e.setAttribute(r,t[r])}))}function y(e,t){var r,n,o,a;if(t.transform&&e.css){if(!(a=t.transform(e.css)))return function(){};e.css=a}if(t.singleton){var i=m++;r=d||(d=v(t)),n=E.bind(null,r,i,!1),o=E.bind(null,r,i,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(r=function(e){var t=document.createElement("link");return e.attrs.type="text/css",e.attrs.rel="stylesheet",w(t,e.attrs),h(e,t),t}(t),n=_.bind(null,r,t),o=function(){x(r),r.href&&URL.revokeObjectURL(r.href)}):(r=v(t),n=T.bind(null,r),o=function(){x(r)});return n(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;n(e=t)}else o()}}e.exports=function(e,t){(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{};var u,h,x=g(e,t);return p.__universal__=void 0,"object"==typeof window&&window.document?(n=l((function(){return window&&document&&document.all&&!window.atob})),t.singleton||(t.singleton=n()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom"),a=r(19),u=function(e){return document.querySelector(e)},h={},o=function(e){if(void 0===h[e]){var t=u.call(this,e);if(t instanceof window.HTMLIFrameElement)try{t=t.contentDocument.head}catch(e){t=null}h[e]=t}return h[e]},b(x,t),setTimeout(f,16),function(e){for(var r=[],n=0;n=t.totalSteps})),a(c(t),"setActiveStep",(function(e){var r,n,o=t.state.activeStep;o!==e&&(t.isInvalidStep(e)?console.error("".concat(e+1," is an invalid step")):(r=t.state.classes,n=t.getTransitions(),oe.length)&&(t=e.length);for(var r=0,n=new Array(t);r1&&o.a.createElement("button",{className:"btn btn-default btn-block",onClick:l},"Go Back"),cN.length&&N.push(e)}function M(e,t,r){return null==e?0:function e(t,r,n,o){var l=typeof t;"undefined"!==l&&"boolean"!==l||(t=null);var s=!1;if(null===t)s=!0;else switch(l){case"string":case"number":s=!0;break;case"object":switch(t.$$typeof){case a:case i:s=!0}}if(s)return n(o,t,""===r?"."+R(t,0):r),1;if(s=0,r=""===r?".":r+":",Array.isArray(t))for(var c=0;c