From 4a31721a5621b1c29d318b88af6ea65c7b1a7bc9 Mon Sep 17 00:00:00 2001 From: AssisrMatheus Date: Tue, 11 Apr 2023 13:53:26 -0400 Subject: [PATCH 1/5] feat: adds time picker --- CHANGELOG.md | 2 + .../DatePickerInput.stories.tsx | 62 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0991b96..d01443a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added examples for time picker on `DatePickerInput` + ### Fixed ## [9.4.0] 2023-04-11 diff --git a/src/components/DatePickerInput/DatePickerInput.stories.tsx b/src/components/DatePickerInput/DatePickerInput.stories.tsx index dade0f0..97b57d8 100644 --- a/src/components/DatePickerInput/DatePickerInput.stories.tsx +++ b/src/components/DatePickerInput/DatePickerInput.stories.tsx @@ -1,5 +1,6 @@ // also exported from '@storybook/react' if you can deal with breaking changes in 6.1 import { Meta, Story } from '@storybook/react/types-6-0'; +import { now, getLocalTimeZone } from '@internationalized/date'; import React from 'react'; import classnames from 'classnames'; import { DatePickerInput, DatePickerProps } from '.'; @@ -81,3 +82,64 @@ export const WithError = Template.bind({}); WithError.args = { error: 'Input is required' }; + +export const Time = Template.bind({}); +Time.args = { + granularity: 'minute' +}; + +export const Time24Hours = Template.bind({}); +Time24Hours.args = { + granularity: 'minute', + hourCycle: 24 +}; + +/** + * A story that displays a DatePickerInput example + * + * @param props the story props + * @param props.color the color property set on controls + * @param props.className The input className + */ +const LocalTimezoneTemplate: Story = ({ color, className, ...props }) => { + return ( + + ); +}; + +export const LocalTimezone = LocalTimezoneTemplate.bind({}); + +/** + * A story that displays a DatePickerInput example + * + * @param props the story props + * @param props.color the color property set on controls + * @param props.className The input className + */ +const OtherTimezoneTemplate: Story = ({ color, className, ...props }) => { + return ( + + ); +}; + +export const OtherTimezone = OtherTimezoneTemplate.bind({}); From b81fe302e6b05672a13216d12981edea9656e89e Mon Sep 17 00:00:00 2001 From: AssisrMatheus Date: Tue, 11 Apr 2023 14:09:39 -0400 Subject: [PATCH 2/5] chore: reorganize component folders --- src/components/BaseCard/BaseCard.stories.tsx | 2 +- src/components/Button/Button.stories.tsx | 2 +- src/components/ButtonStack/ButtonStack.stories.tsx | 2 +- src/components/EventCard/EventCard.stories.tsx | 2 +- src/components/ExpertCard/ExpertCard.stories.tsx | 2 +- src/components/ExpertImage/ExpertImage.stories.tsx | 2 +- src/components/ImageLoader/ImageLoader.stories.tsx | 2 +- src/components/ModuleCard/ModuleCard.stories.tsx | 2 +- src/components/ProgramCard/ProgramCard.stories.tsx | 2 +- src/components/ResourcesCard/ResourcesCard.stories.tsx | 2 +- src/components/Skeleton/Skeleton.stories.tsx | 2 +- src/components/Spinner/Spinner.stories.tsx | 2 +- src/components/WorkSessionCard/WorkSessionCard.stories.tsx | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/components/BaseCard/BaseCard.stories.tsx b/src/components/BaseCard/BaseCard.stories.tsx index 012dc02..e3d417e 100644 --- a/src/components/BaseCard/BaseCard.stories.tsx +++ b/src/components/BaseCard/BaseCard.stories.tsx @@ -4,7 +4,7 @@ import { Story, Meta } from '@storybook/react/types-6-0'; import { BaseCard, BaseCardProps } from '.'; export default { - title: 'Components/BaseCard', + title: 'Components/qadense/BaseCard', component: BaseCard, argTypes: { className: { diff --git a/src/components/Button/Button.stories.tsx b/src/components/Button/Button.stories.tsx index 018f09e..1ae5b09 100644 --- a/src/components/Button/Button.stories.tsx +++ b/src/components/Button/Button.stories.tsx @@ -8,7 +8,7 @@ import { BellIcon, MenuIcon } from '../Icons'; import { puiColorClassnameMap, borderStyleClassnameMap } from '../../storybookMappers'; export default { - title: 'Components/Button', + title: 'Components/Buttons/Default', component: Button, argTypes: { border: { diff --git a/src/components/ButtonStack/ButtonStack.stories.tsx b/src/components/ButtonStack/ButtonStack.stories.tsx index 3dcaa1e..2ea572c 100644 --- a/src/components/ButtonStack/ButtonStack.stories.tsx +++ b/src/components/ButtonStack/ButtonStack.stories.tsx @@ -9,7 +9,7 @@ import { puiColorClassnameMap } from '../../storybookMappers'; import { BellIcon } from '../Icons'; export default { - title: 'Components/ButtonStack', + title: 'Components/Buttons/Stack', component: ButtonStack, argTypes: { color: { diff --git a/src/components/EventCard/EventCard.stories.tsx b/src/components/EventCard/EventCard.stories.tsx index 971cb4e..91521d6 100644 --- a/src/components/EventCard/EventCard.stories.tsx +++ b/src/components/EventCard/EventCard.stories.tsx @@ -5,7 +5,7 @@ import { EventCard, EventCardProps } from '.'; import { gradientFromClassNameMap, gradientToClassNameMap, gradientViaClassNameMap } from '../../storybookMappers'; export default { - title: 'Components/EventCard', + title: 'Components/qadense/EventCard', component: EventCard, argTypes: { className: { diff --git a/src/components/ExpertCard/ExpertCard.stories.tsx b/src/components/ExpertCard/ExpertCard.stories.tsx index f64f5de..aba9136 100644 --- a/src/components/ExpertCard/ExpertCard.stories.tsx +++ b/src/components/ExpertCard/ExpertCard.stories.tsx @@ -5,7 +5,7 @@ import { ExpertCard, ExpertCardProps } from '.'; import { gradientFromClassNameMap, gradientToClassNameMap, gradientViaClassNameMap } from '../../storybookMappers'; export default { - title: 'Components/ExpertCard', + title: 'Components/qadense/ExpertCard', component: ExpertCard, argTypes: { className: { diff --git a/src/components/ExpertImage/ExpertImage.stories.tsx b/src/components/ExpertImage/ExpertImage.stories.tsx index 54b027a..9bb8a58 100644 --- a/src/components/ExpertImage/ExpertImage.stories.tsx +++ b/src/components/ExpertImage/ExpertImage.stories.tsx @@ -5,7 +5,7 @@ import classnames from 'classnames'; import { gradientFromClassNameMap, gradientToClassNameMap, gradientViaClassNameMap } from '../../storybookMappers'; export default { - title: 'Components/ExpertImage', + title: 'Components/qadense/ExpertImage', argTypes: { gradientInitialColor: { defaultValue: 'from-pui-primary', diff --git a/src/components/ImageLoader/ImageLoader.stories.tsx b/src/components/ImageLoader/ImageLoader.stories.tsx index b21c333..770d576 100644 --- a/src/components/ImageLoader/ImageLoader.stories.tsx +++ b/src/components/ImageLoader/ImageLoader.stories.tsx @@ -4,7 +4,7 @@ import React from 'react'; import { ImageLoader, ImageLoaderProps } from '.'; export default { - title: 'Components/ImageLoader', + title: 'Components/Loaders/ImageLoader', component: ImageLoader, argTypes: { src: { defaultValue: 'https://cataas.com/cat' }, diff --git a/src/components/ModuleCard/ModuleCard.stories.tsx b/src/components/ModuleCard/ModuleCard.stories.tsx index b8718a1..7c28378 100644 --- a/src/components/ModuleCard/ModuleCard.stories.tsx +++ b/src/components/ModuleCard/ModuleCard.stories.tsx @@ -5,7 +5,7 @@ import { colorOptions } from '../../prebuiltTailwindTheme'; import { ModuleCard, ModuleCardProps } from '.'; export default { - title: 'Components/ModuleCard', + title: 'Components/qadense/ModuleCard', component: ModuleCard, argTypes: { color: { diff --git a/src/components/ProgramCard/ProgramCard.stories.tsx b/src/components/ProgramCard/ProgramCard.stories.tsx index 8e0b5cb..e24e574 100644 --- a/src/components/ProgramCard/ProgramCard.stories.tsx +++ b/src/components/ProgramCard/ProgramCard.stories.tsx @@ -5,7 +5,7 @@ import { colorOptions } from '../../prebuiltTailwindTheme'; import { ProgramCard, ProgramCardProps } from '..'; export default { - title: 'Components/ProgramCard', + title: 'Components/qadense/ProgramCard', component: ProgramCard, argTypes: { color: { diff --git a/src/components/ResourcesCard/ResourcesCard.stories.tsx b/src/components/ResourcesCard/ResourcesCard.stories.tsx index cd0ec9c..e891aa4 100644 --- a/src/components/ResourcesCard/ResourcesCard.stories.tsx +++ b/src/components/ResourcesCard/ResourcesCard.stories.tsx @@ -4,7 +4,7 @@ import { Story, Meta } from '@storybook/react/types-6-0'; import { ResourcesCard, ResourcesCardProps } from '.'; export default { - title: 'Components/ResourcesCard', + title: 'Components/qadense/ResourcesCard', component: ResourcesCard, argTypes: { className: { diff --git a/src/components/Skeleton/Skeleton.stories.tsx b/src/components/Skeleton/Skeleton.stories.tsx index 19c413a..e39acec 100644 --- a/src/components/Skeleton/Skeleton.stories.tsx +++ b/src/components/Skeleton/Skeleton.stories.tsx @@ -6,7 +6,7 @@ import classnames from 'classnames'; import { heightClassnameMap, widthClassnameMap } from '../../storybookMappers'; export default { - title: 'Components/Skeleton', + title: 'Components/Loaders/Skeleton', argTypes: { width: { defaultValue: '3/4', diff --git a/src/components/Spinner/Spinner.stories.tsx b/src/components/Spinner/Spinner.stories.tsx index 02bb97c..a79b0e0 100644 --- a/src/components/Spinner/Spinner.stories.tsx +++ b/src/components/Spinner/Spinner.stories.tsx @@ -6,7 +6,7 @@ import classnames from 'classnames'; import { heightClassnameMap, puiColorClassnameMap, widthClassnameMap } from '../../storybookMappers'; export default { - title: 'Components/Spinner', + title: 'Components/Loaders/Spinner', argTypes: { size: { defaultValue: '4', diff --git a/src/components/WorkSessionCard/WorkSessionCard.stories.tsx b/src/components/WorkSessionCard/WorkSessionCard.stories.tsx index 88aa0d3..dce7d3f 100644 --- a/src/components/WorkSessionCard/WorkSessionCard.stories.tsx +++ b/src/components/WorkSessionCard/WorkSessionCard.stories.tsx @@ -5,7 +5,7 @@ import { WorkSessionCard, WorkSessionCardProps } from '.'; import { gradientFromClassNameMap, gradientToClassNameMap, gradientViaClassNameMap } from '../../storybookMappers'; export default { - title: 'Components/WorkSessionCard', + title: 'Components/qadense/WorkSessionCard', component: WorkSessionCard, argTypes: { className: { From 6c2af9a034672ed152c3bdb40375a493e6762681 Mon Sep 17 00:00:00 2001 From: AssisrMatheus Date: Tue, 11 Apr 2023 15:22:43 -0400 Subject: [PATCH 3/5] feat: adds toggle input --- CHANGELOG.md | 1 + .../ToggleInput/ToggleInput.stories.tsx | 82 +++++++++++++++++++ src/components/ToggleInput/index.tsx | 64 +++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 src/components/ToggleInput/ToggleInput.stories.tsx create mode 100644 src/components/ToggleInput/index.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index d01443a..a772066 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added examples for time picker on `DatePickerInput` +- Added `ToggleInput` component ### Fixed diff --git a/src/components/ToggleInput/ToggleInput.stories.tsx b/src/components/ToggleInput/ToggleInput.stories.tsx new file mode 100644 index 0000000..a12279b --- /dev/null +++ b/src/components/ToggleInput/ToggleInput.stories.tsx @@ -0,0 +1,82 @@ +// also exported from '@storybook/react' if you can deal with breaking changes in 6.1 +import { Meta, Story } from '@storybook/react/types-6-0'; +import React, { useState } from 'react'; +import { ToggleInput, ToggleInputProps } from '.'; +import { colorOptions } from '../../prebuiltTailwindTheme'; + +export default { + title: 'Components/Inputs/Toggle', + component: ToggleInput, + argTypes: { + label: { defaultValue: 'Input' }, + color: { + defaultValue: 'pui-primary', + control: { + type: 'select', + options: colorOptions + } + }, + defaultChecked: { + control: { + type: 'boolean' + } + }, + placeholder: { + defaultValue: 'Type here...', + control: { + type: 'text' + } + }, + defaultValue: { + control: { + type: 'boolean' + } + }, + disabled: { + control: { + type: 'boolean' + } + }, + readOnly: { + control: { + type: 'boolean' + } + }, + className: { + control: { + type: 'text' + } + }, + onChange: { action: 'onChange' }, + onBlur: { action: 'onBlur' }, + onFocus: { action: 'onFocus' } + } +} as Meta; + +/** + * A story that displays a ToggleInput example + * + * @param props the story props + */ +const Template: Story = (props) => { + const [checked, setChecked] = useState(false); + + return setChecked(e.target.checked)} />; +}; + +export const WithLabel = Template.bind({}); + +export const NoLabel = Template.bind({}); +NoLabel.args = { + label: undefined +}; + +export const WithHelp = Template.bind({}); +WithHelp.args = { + help: 'You can also have a help text' +}; + +export const WithError = Template.bind({}); +WithError.args = { + error: 'Input is required' +}; diff --git a/src/components/ToggleInput/index.tsx b/src/components/ToggleInput/index.tsx new file mode 100644 index 0000000..261f9b0 --- /dev/null +++ b/src/components/ToggleInput/index.tsx @@ -0,0 +1,64 @@ +import classnames from 'classnames'; +import { motion } from 'framer-motion'; +import React from 'react'; +import { HTMLParsedContent } from '../HTMLParsedContent'; + +const spring = { + type: 'spring', + stiffness: 700, + damping: 30 +}; + +export type ToggleInputProps = Omit< + React.DetailedHTMLProps, HTMLInputElement>, + 'children' | 'type' +> & { + label?: string | React.ReactNode; + error?: string; + help?: string; +}; + +/** + * A toggle input component + * + * @param props the component props + * @param props.label the label of the input + * @param props.error the error message + * @param props.help help message if any + */ +export const ToggleInput: React.FC = ({ label, error, help, ...props }) => ( +
+ +
+ {help && !error &&

{help}

} + {error &&

{error}

} +
+
+); From 36ab4175866267b8b7132559bba0f389b6f3dd54 Mon Sep 17 00:00:00 2001 From: AssisrMatheus Date: Wed, 12 Apr 2023 10:40:12 -0400 Subject: [PATCH 4/5] feat: adds toggle button component --- package-lock.json | 140 +++--------------- package.json | 2 +- .../ToggleButton/ToggleButton.stories.tsx | 68 +++++++++ src/components/ToggleButton/index.tsx | 71 +++++++++ .../ToggleInput/ToggleInput.stories.tsx | 32 ++-- 5 files changed, 181 insertions(+), 132 deletions(-) create mode 100644 src/components/ToggleButton/ToggleButton.stories.tsx create mode 100644 src/components/ToggleButton/index.tsx diff --git a/package-lock.json b/package-lock.json index 384de73..6834978 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@perimetre/ui", - "version": "9.3.2", + "version": "9.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@perimetre/ui", - "version": "9.3.2", + "version": "9.4.0", "license": "MIT", "dependencies": { "@babel/core": "^7.12.13", @@ -45,7 +45,7 @@ "draft-js": "^0.11.7", "draftjs-to-html": "^0.9.1", "draftjs-utils": "^0.10.2", - "framer-motion": "^3.3.0", + "framer-motion": "^10.11.6", "hammerjs": "^2.0.8", "html-react-parser": "^1.2.4", "html-to-draftjs": "^1.5.0", @@ -18985,34 +18985,28 @@ } }, "node_modules/framer-motion": { - "version": "3.10.6", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-3.10.6.tgz", - "integrity": "sha512-OxOtKgQS4km9a8dm0IMBtNNp4f0DiHfQ/IzxKs818+Kg9V/Ve/pRUJ2dtWBb6+W4lIPNLgRSpbOwOACVj15XcQ==", - "dependencies": { - "framesync": "5.2.0", - "hey-listen": "^1.0.8", - "popmotion": "9.3.1", - "style-value-types": "4.1.1", - "tslib": "^1.10.0" + "version": "10.11.6", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.11.6.tgz", + "integrity": "sha512-QXfnUzPQqbJEnWpmtPaRB4OCuyH44uCys5Agg44LEQvItKTg0bou57WuhsNVuEyVCnMoAhrtRYiKeG/vAz6bFw==", + "dependencies": { + "tslib": "^2.4.0" }, "optionalDependencies": { "@emotion/is-prop-valid": "^0.8.2" }, "peerDependencies": { - "react": ">=16.8 || ^17.0.0", - "react-dom": ">=16.8 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } } }, - "node_modules/framer-motion/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/framesync": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/framesync/-/framesync-5.2.0.tgz", - "integrity": "sha512-dcl92w5SHc0o6pRK3//VBVNvu6WkYkiXmHG6ZIXrVzmgh0aDYMDAaoA3p3LH71JIdN5qmhDcfONFA4Lmq22tNA==" - }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -19941,11 +19935,6 @@ "he": "bin/he" } }, - "node_modules/hey-listen": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", - "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" - }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -24612,22 +24601,6 @@ "node": ">=10" } }, - "node_modules/popmotion": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-9.3.1.tgz", - "integrity": "sha512-Qozvg8rz2OGeZwWuIjqlSXqqgWto/+QL24ll8sAAc0n71KY/wvN1W4sAASxTuHv8YWdDnk9u9IdadyPo2DGvDA==", - "dependencies": { - "framesync": "5.2.0", - "hey-listen": "^1.0.8", - "style-value-types": "4.1.1", - "tslib": "^1.10.0" - } - }, - "node_modules/popmotion/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/portfinder": { "version": "1.0.32", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", @@ -29879,20 +29852,6 @@ "inline-style-parser": "0.1.1" } }, - "node_modules/style-value-types": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-4.1.1.tgz", - "integrity": "sha512-cNLrl6jk+I1T18ZI2KIp/fcqKVuykcNELDrOz7y+TYZR97xmNdN0ewupURvVFnQxVrRJv98TMBq92VMsggq3kw==", - "dependencies": { - "hey-listen": "^1.0.8", - "tslib": "^1.10.0" - } - }, - "node_modules/style-value-types/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/styled-components": { "version": "5.3.6", "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.6.tgz", @@ -47231,30 +47190,14 @@ } }, "framer-motion": { - "version": "3.10.6", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-3.10.6.tgz", - "integrity": "sha512-OxOtKgQS4km9a8dm0IMBtNNp4f0DiHfQ/IzxKs818+Kg9V/Ve/pRUJ2dtWBb6+W4lIPNLgRSpbOwOACVj15XcQ==", + "version": "10.11.6", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.11.6.tgz", + "integrity": "sha512-QXfnUzPQqbJEnWpmtPaRB4OCuyH44uCys5Agg44LEQvItKTg0bou57WuhsNVuEyVCnMoAhrtRYiKeG/vAz6bFw==", "requires": { "@emotion/is-prop-valid": "^0.8.2", - "framesync": "5.2.0", - "hey-listen": "^1.0.8", - "popmotion": "9.3.1", - "style-value-types": "4.1.1", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } + "tslib": "^2.4.0" } }, - "framesync": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/framesync/-/framesync-5.2.0.tgz", - "integrity": "sha512-dcl92w5SHc0o6pRK3//VBVNvu6WkYkiXmHG6ZIXrVzmgh0aDYMDAaoA3p3LH71JIdN5qmhDcfONFA4Lmq22tNA==" - }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -47960,11 +47903,6 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, - "hey-listen": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", - "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" - }, "highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -51486,24 +51424,6 @@ "@babel/runtime": "^7.17.8" } }, - "popmotion": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-9.3.1.tgz", - "integrity": "sha512-Qozvg8rz2OGeZwWuIjqlSXqqgWto/+QL24ll8sAAc0n71KY/wvN1W4sAASxTuHv8YWdDnk9u9IdadyPo2DGvDA==", - "requires": { - "framesync": "5.2.0", - "hey-listen": "^1.0.8", - "style-value-types": "4.1.1", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, "portfinder": { "version": "1.0.32", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", @@ -55350,22 +55270,6 @@ "inline-style-parser": "0.1.1" } }, - "style-value-types": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-4.1.1.tgz", - "integrity": "sha512-cNLrl6jk+I1T18ZI2KIp/fcqKVuykcNELDrOz7y+TYZR97xmNdN0ewupURvVFnQxVrRJv98TMBq92VMsggq3kw==", - "requires": { - "hey-listen": "^1.0.8", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, "styled-components": { "version": "5.3.6", "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.6.tgz", diff --git a/package.json b/package.json index 12de3a5..9c89604 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "draft-js": "^0.11.7", "draftjs-to-html": "^0.9.1", "draftjs-utils": "^0.10.2", - "framer-motion": "^3.3.0", + "framer-motion": "^10.11.6", "hammerjs": "^2.0.8", "html-react-parser": "^1.2.4", "html-to-draftjs": "^1.5.0", diff --git a/src/components/ToggleButton/ToggleButton.stories.tsx b/src/components/ToggleButton/ToggleButton.stories.tsx new file mode 100644 index 0000000..a6477d6 --- /dev/null +++ b/src/components/ToggleButton/ToggleButton.stories.tsx @@ -0,0 +1,68 @@ +// also exported from '@storybook/react' if you can deal with breaking changes in 6.1 +import { Meta, Story } from '@storybook/react/types-6-0'; +import React, { useState } from 'react'; +import { ToggleButton, ToggleButtonProps } from '.'; +import { colorOptions } from '../../prebuiltTailwindTheme'; +import classnames from 'classnames'; +import { puiColorClassnameMap } from '../../storybookMappers'; + +export default { + title: 'Components/Inputs/ToggleButton', + component: ToggleButton, + argTypes: { + offLabel: { defaultValue: 'Off' }, + onLabel: { defaultValue: 'On' }, + color: { + defaultValue: 'pui-primary', + control: { + type: 'select', + options: colorOptions + } + }, + defaultChecked: { + control: { + type: 'boolean' + } + }, + disabled: { + control: { + type: 'boolean' + } + }, + className: { + control: { + type: 'text' + } + }, + onChange: { action: 'onChange' }, + onBlur: { action: 'onBlur' }, + onFocus: { action: 'onFocus' } + } +} as Meta; + +/** + * A story that displays a ToggleButton example + * + * @param props the story props + * @param props.color User selected color + */ +const Template: Story = ({ color, ...props }) => { + const [checked, setChecked] = useState(false); + + return ( + { + setChecked(e.target.checked); + if (props.onChange) props.onChange(e); + }} + /> + ); +}; + +export const Default = Template.bind({}); diff --git a/src/components/ToggleButton/index.tsx b/src/components/ToggleButton/index.tsx new file mode 100644 index 0000000..0eb00e7 --- /dev/null +++ b/src/components/ToggleButton/index.tsx @@ -0,0 +1,71 @@ +import classnames from 'classnames'; +import { motion } from 'framer-motion'; +import React from 'react'; + +const spring = { + type: 'spring', + stiffness: 700, + damping: 36 +}; + +export type ToggleButtonProps = Omit< + React.DetailedHTMLProps, HTMLInputElement>, + 'children' | 'type' +> & { + /** + * Label text for the button's off state + */ + offLabel: string; + /** + * Label text for the button's on state + */ + onLabel: string; +}; + +/** + * A toggle input component + * + * @param props the component props + * @param props.offLabel Label text for the button's off state + * @param props.onLabel Label text for the button's on state + */ +export const ToggleButton: React.FC = ({ offLabel, onLabel, ...props }) => ( + + {/* Hidden input so it fakes as a real html input and can be used with forms, it also gives us the full range of event inputs to listen to */} + + + {[offLabel, onLabel].map((label, index) => { + const selected = (!props.checked && index === 0) || (props.checked && index === 1); + return ( + // This defines the sizing that the background will copy from +
+ {/* Label text */} +

+ {label} +

+ + {/* This is the background that will get animated on toggle */} + {selected ? ( + + ) : null} +
+ ); + })} +
+); diff --git a/src/components/ToggleInput/ToggleInput.stories.tsx b/src/components/ToggleInput/ToggleInput.stories.tsx index a12279b..1335f22 100644 --- a/src/components/ToggleInput/ToggleInput.stories.tsx +++ b/src/components/ToggleInput/ToggleInput.stories.tsx @@ -3,9 +3,11 @@ import { Meta, Story } from '@storybook/react/types-6-0'; import React, { useState } from 'react'; import { ToggleInput, ToggleInputProps } from '.'; import { colorOptions } from '../../prebuiltTailwindTheme'; +import classnames from 'classnames'; +import { puiColorClassnameMap } from '../../storybookMappers'; export default { - title: 'Components/Inputs/Toggle', + title: 'Components/Inputs/ToggleInput', component: ToggleInput, argTypes: { label: { defaultValue: 'Input' }, @@ -27,21 +29,11 @@ export default { type: 'text' } }, - defaultValue: { - control: { - type: 'boolean' - } - }, disabled: { control: { type: 'boolean' } }, - readOnly: { - control: { - type: 'boolean' - } - }, className: { control: { type: 'text' @@ -57,11 +49,25 @@ export default { * A story that displays a ToggleInput example * * @param props the story props + * @param props.color User selected color */ -const Template: Story = (props) => { +const Template: Story = ({ color, ...props }) => { const [checked, setChecked] = useState(false); - return setChecked(e.target.checked)} />; + return ( + { + setChecked(e.target.checked); + if (props.onChange) props.onChange(e); + }} + /> + ); }; export const WithLabel = Template.bind({}); From 8949cb9a760db7b16b648a683521baf5158f1cf1 Mon Sep 17 00:00:00 2001 From: AssisrMatheus Date: Wed, 12 Apr 2023 10:42:26 -0400 Subject: [PATCH 5/5] build: version 9.5.0 --- CHANGELOG.md | 9 +++++++-- package.json | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a772066..c169a0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,10 +23,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +### Fixed + +## [9.5.0] 2023-04-12 + +### Added + - Added examples for time picker on `DatePickerInput` - Added `ToggleInput` component - -### Fixed +- Added `ToggleButton` component ## [9.4.0] 2023-04-11 diff --git a/package.json b/package.json index 9c89604..fdc0d11 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@perimetre/ui", "description": "A component library made by @perimetre", - "version": "9.4.0", + "version": "9.5.0", "repository": { "type": "git", "url": "git+https://github.com/perimetre/ui.git"