diff --git a/README.md b/README.md
index 1e11643..5d5e821 100644
--- a/README.md
+++ b/README.md
@@ -12,11 +12,10 @@
## Features
-- Hooks
+- Simplicity
- Focused on logic
- No UI restrictions
- Written in TypeScript
-- Documented, self explaining methods
## Installation
@@ -72,25 +71,26 @@ const Step1 = () => {
### Wizard
-`Wizard` is used to wrap your steps. Each child component will be treated as an individual step. You can pass a shared `footer` and `header` component that should always be in your steps.
+`Wizard` is used to wrap your steps. Each child component will be treated as an individual step. You can pass a shared `footer` and `header` component that should always be in your steps.
Example: pass a footer component that contains a "previous" and "next" button to the wizard.
#### Props
-| name | type | description | required | default |
-| ---------- | --------------- | ------------------------------------------------------------- | -------- | ------- |
-| startIndex | number | Indicate the wizard to start at the given step | ❌ | 0 |
-| header | React.ReactNode | Header that is shown above the active step | ❌ | |
-| footer | React.ReactNode | Footer that is shown below the active stepstep | ❌ | |
-| children | React.ReactNode | Each child component will be treated as an individual step | ✔️ |
+| name | type | description | required | default |
+| ---------- | --------------- | ---------------------------------------------------------- | -------- | ------- |
+| startIndex | number | Indicate the wizard to start at the given step | ❌ | 0 |
+| header | React.ReactNode | Header that is shown above the active step | ❌ | |
+| footer | React.ReactNode | Footer that is shown below the active stepstep | ❌ | |
+| children | React.ReactNode | Each child component will be treated as an individual step | ✔️ |
#### Example
```javascript
-// Example: show the active step in this component
+// Example: show the active step in the header
const Header = () =>
I am the header component
;
+// Example: show the "previous" and "next" buttons in the footer
const Footer = () => I am the footer component
;
const App = () => {
@@ -106,22 +106,24 @@ const App = () => {
### useWizard
-Used to retrieve all methods and properties related to your wizard. Make sure `Wizard` is wrapped around your component when calling `useWizard`.
+Used to retrieve all methods and properties related to your wizard. Make sure `Wizard` is wrapped around your component when calling `useWizard`.
+
+`handleStep` is used to attach a handler to the step, can either be `async` or a `sync` function. This function will be invoked when calling `nextStep`.
**Remark** - You can't use `useWizard` in the same component where `Wizard` is used.
#### Methods
-| name | type | description |
-| ----------------------------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------- |
-| nextStep | () => Promise | Go to the next step |
-| previousStep | () => void | Go to the previous step |
-| handleStep | (handler: Handler) => void | Attach a callback that will be called when calling `nextStep`. `handler` can be either sync or async |
-| isLoading | boolean | \* Will reflect the handler promise state: will be `true` if the handler promise is pending and `false` when the handler is either fulfilled or rejected |
-| activeStep | number | The current active step of the wizard |
-| isFirstStep | boolean | Indicate if the current step is the first step (aka no previous step) |
-| isLastStep | boolean | Indicate if the current step is the last step (aka no next step) |
-| |
+| name | type | description |
+| ------------ | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| nextStep | () => Promise | Go to the next step |
+| previousStep | () => void | Go to the previous step |
+| handleStep | (handler: Handler) => void | Attach a callback that will be called when calling `nextStep`. `handler` can be either sync or async |
+| isLoading | boolean | \* Will reflect the handler promise state: will be `true` if the handler promise is pending and `false` when the handler is either fulfilled or rejected |
+| activeStep | number | The current active step of the wizard |
+| isFirstStep | boolean | Indicate if the current step is the first step (aka no previous step) |
+| isLastStep | boolean | Indicate if the current step is the last step (aka no next step) |
+| |
#### Example
@@ -149,6 +151,7 @@ const Step1 = () => {
handleStep,
} = useWizard();
+ // This handler is optional
handleStep(() => {
alert('Going to step 2');
});
@@ -173,6 +176,7 @@ const Step1 = () => {
It's recommended to pass the shared components to the `header` or `footer` in the `Wizard` to avoid duplication.
## Examples
+
Go to [examples](https://github.com/devrnt/react-use-wiard/tree/master/examples) to check see some examples
## Async
@@ -200,14 +204,17 @@ const Step1 = () => {
```
### Errors
+
If no errors are thrown then the wizard will go to the next step, so no need to call `nextStep` by yourself.
-If an error is thrown in the conencted function the wizard will just stay at the same step and will rethrow the error. (So you can try-catch in your attached function).
+If an error is thrown in the attached function the wizard will just stay at the same step and will rethrow the error. (So you can try-catch in your attached function).
### IsLoading
+
If an async function is attached to `handleStep` the `isLoading` property will indicate the loading state of the function. In general `isLoading` will reflect the handler promise state: will be `true` if the handler promise is pending and `false` when the handler is either fulfilled or rejected.
## Animation
-Since `react-use-wizard` is focused to manage the logic of a wizard it doesn't mean you can't add some animation by your own. Add any animation library that you like. I highly suggest [framer-motion](https://www.framer.com/motion/) to add your animations.
-Checkout this [example](https://github.com/devrnt/react-use-wizard/blob/docs/readme/example/components/animatedStep.tsx) to see how a step can be animated with framer motion.
\ No newline at end of file
+Since `react-use-wizard` is focused to manage the logic of a wizard it doesn't mean you can't add some animation by your own. Add any animation library that you like. I highly suggest [framer-motion](https://www.framer.com/motion/) to add your animations.
+
+Checkout this [example](https://github.com/devrnt/react-use-wizard/blob/docs/readme/example/components/animatedStep.tsx) to see how a step can be animated with framer motion.
diff --git a/playground/components/asyncStep.tsx b/playground/components/asyncStep.tsx
index 4f7c668..37cc2ad 100644
--- a/playground/components/asyncStep.tsx
+++ b/playground/components/asyncStep.tsx
@@ -32,7 +32,7 @@ const Container = styled('div')`
`;
const P = styled('p')`
- color: white;
+ color: var(--text);
`;
const AsyncStep: React.FC = React.memo(({ number }) => {
diff --git a/playground/components/footer.tsx b/playground/components/footer.tsx
index fe654e6..0464cc7 100644
--- a/playground/components/footer.tsx
+++ b/playground/components/footer.tsx
@@ -5,17 +5,31 @@ import { useWizard } from '../../dist';
import { Button } from '../modules/common';
const Actions = styled('div')`
- display: grid;
+ display: flex;
justify-content: center;
margin: 1rem 0;
- grid-template-columns: min-content min-content;
gap: 1rem;
+ flex-direction: row;
`;
const Info = styled('div')`
display: flex;
justify-content: center;
- gap: 1rem;
+ flex-direction: column;
+ gap: 0;
+
+ & > p {
+ margin: 0.25rem 0;
+ }
+
+ @media screen and (min-width: 600px) {
+ flex-direction: row;
+ gap: 1rem;
+
+ & > p {
+ margin: initial;
+ }
+ }
`;
const Footer: React.FC = React.memo(() => {
diff --git a/playground/components/step.tsx b/playground/components/step.tsx
index 49d4934..70a7caf 100644
--- a/playground/components/step.tsx
+++ b/playground/components/step.tsx
@@ -21,7 +21,7 @@ const Container = styled('div')`
`;
const P = styled('p')`
- color: white;
+ color: var(--text);
`;
const Step: React.FC = React.memo(({ number, withCallback = true }) => {
diff --git a/playground/modules/common/button.tsx b/playground/modules/common/button.tsx
index 7201746..4d88c1b 100644
--- a/playground/modules/common/button.tsx
+++ b/playground/modules/common/button.tsx
@@ -12,7 +12,7 @@ const Container = styled('button')`
border: 1px solid var(--purple);
padding: 0.7rem 1.75rem;
border-radius: 6px;
- color: white;
+ color: var(--text);
font-size: 1.1rem;
font-weight: 700;
background-color: var(--dark);
@@ -27,6 +27,7 @@ const Container = styled('button')`
&:disabled {
opacity: 0.4;
background-image: initial;
+ cursor: initial;
}
`;
diff --git a/playground/modules/common/page.tsx b/playground/modules/common/page.tsx
index 154eb56..f2c06cc 100644
--- a/playground/modules/common/page.tsx
+++ b/playground/modules/common/page.tsx
@@ -14,6 +14,7 @@ const Container = styled('main')`
display: flex;
justify-content: center;
background: var(--dark);
+ overflow: hidden;
`;
const Wrapper = styled('div')`
@@ -27,14 +28,19 @@ const Body = styled('div')`
const Description = styled('div')`
font-size: 1.1rem;
font-weight: 200;
+ line-height: 1.5rem;
`;
const Divider = styled('div')`
height: 2px;
- width: 7%;
+ width: 15%;
background-image: linear-gradient(48.66deg, var(--purple), var(--blue));
- margin: 2.5rem 0;
+ margin: 2.5rem auto;
display: flex;
+
+ @media screen and (min-width: 800px) {
+ max-width: 7%;
+ }
`;
const TopBar = styled('header')`
@@ -42,14 +48,15 @@ const TopBar = styled('header')`
top: 0;
left: 0;
right: 0;
- padding: 1.5rem 1.75rem;
+ padding: 1.75rem 0;
display: flex;
justify-content: space-between;
align-items: center;
- margin-bottom: 4rem;
+ margin-bottom: 5rem;
background-color: var(--nav);
backdrop-filter: blur(20px);
z-index: 1000;
+ width: 100%;
`;
const Logo = styled('img')`
@@ -62,11 +69,19 @@ const GithubLogo = styled('img')`
`;
const MaxWidth = styled('div')`
- max-width: 53rem;
+ width: 100%;
padding: 0 2rem;
margin: 0 auto;
justify-content: space-between;
- width: 100%;
+
+ @media screen and (min-width: 800px) {
+ max-width: 53rem;
+ padding: 0 2rem;
+ }
+`;
+
+const H1 = styled('h1')`
+ font-size: 2.25rem;
`;
const Page = ({ title, description, children }: Props) => {
@@ -77,6 +92,7 @@ const Page = ({ title, description, children }: Props) => {
@@ -90,7 +106,7 @@ const Page = ({ title, description, children }: Props) => {
- {title}
+ {title}
{description}
{children}
diff --git a/playground/modules/common/style.tsx b/playground/modules/common/style.tsx
index cc387ea..5c08120 100644
--- a/playground/modules/common/style.tsx
+++ b/playground/modules/common/style.tsx
@@ -11,6 +11,11 @@ const GlobalStyle = createGlobalStyles`
--blue: #08D8F4;
--code:#260949;
--step:#170231;
+ --text: #cccccc;
+ }
+
+ * {
+ box-sizing: border-box;
}
html {
@@ -31,7 +36,7 @@ const GlobalStyle = createGlobalStyles`
body {
font-family: 'Inter', Helvetica, sans-serif;
text-rendering: optimizeLegibility;
- color: white;
+ color: var(--text);
}
i {
@@ -44,7 +49,7 @@ const GlobalStyle = createGlobalStyles`
border-radius: 2px;
font-family: 'Fira Code', monospace;
font-size: 0.95rem;
- padding: 0.75rem 0.35rem;
+ padding: 0.75rem 1rem;
}
`;
diff --git a/playground/modules/wizard/wizard.tsx b/playground/modules/wizard/wizard.tsx
index abb8295..51f3402 100644
--- a/playground/modules/wizard/wizard.tsx
+++ b/playground/modules/wizard/wizard.tsx
@@ -1,12 +1,12 @@
-import { styled } from 'goober';
+import { css, styled } from 'goober';
import * as React from 'react';
import { Wizard } from '../../../dist';
import { AnimatedStep, AsyncStep, Footer, Step } from '../../components';
-const Grid = styled('section')`
- display: grid;
- grid-template-columns: repeat(1, 1fr);
+const Container = styled('section')`
+ display: flex;
+ flex-direction: column;
width: 100%;
`;
@@ -21,27 +21,45 @@ const Title = styled('h2')`
}
`;
-const Item = styled('div')`
- display: grid;
- grid-template-rows: min-content;
+const Item = styled('div')<{ showDivider: boolean }>`
+ display: flex;
+ flex-direction: column;
&::after {
- content: '';
margin: 3rem 0 2rem;
+ content: '';
background-image: linear-gradient(48.66deg, var(--purple), var(--blue));
width: 100%;
position: relative;
- height: 1px;
+ height: ${({ showDivider }) => (showDivider ? '1px' : 0)};
}
+
+ ${({ showDivider }) =>
+ showDivider
+ ? `
+ &::after {
+ margin: 3rem 0 2rem;
+ content: '';
+ background-image: linear-gradient(
+ 48.66deg,
+ var(--purple),
+ var(--blue)
+ );
+ width: 100%;
+ position: relative;
+ height: 1px;
+ }
+ `
+ : ''}
`;
const WizardModule = () => {
return (
-
+
Simple wizard mix of async and sync steps
- -
+
-
}>
@@ -51,9 +69,9 @@ const WizardModule = () => {
- Animated wizard animations by framer motion
+ Animated wizard animation by framer motion
- -
+
-
}>
@@ -69,7 +87,7 @@ const WizardModule = () => {
-
+
);
};