From 8caea2c6e4c58474fe76749fdad38c490981de44 Mon Sep 17 00:00:00 2001 From: Dawn Carrasco Date: Fri, 1 Mar 2024 16:44:14 +0800 Subject: [PATCH 01/10] chore: add new datepicker component --- package.json | 2 + .../Datepicker/ComponentSummary.mdx | 4 + .../Datepicker/Datepicker.stories.tsx | 31 +++ .../Datepicker/Datepicker.styles.ts | 10 + src/components/Datepicker/Datepicker.test.tsx | 10 + src/components/Datepicker/Datepicker.tsx | 51 +++++ src/components/Datepicker/index.ts | 1 + src/components/index.ts | 1 + yarn.lock | 192 +++++++++++++++++- 9 files changed, 299 insertions(+), 3 deletions(-) create mode 100644 src/components/Datepicker/ComponentSummary.mdx create mode 100755 src/components/Datepicker/Datepicker.stories.tsx create mode 100644 src/components/Datepicker/Datepicker.styles.ts create mode 100644 src/components/Datepicker/Datepicker.test.tsx create mode 100644 src/components/Datepicker/Datepicker.tsx create mode 100644 src/components/Datepicker/index.ts diff --git a/package.json b/package.json index 709af3b..263cdca 100644 --- a/package.json +++ b/package.json @@ -119,6 +119,8 @@ "@fortawesome/react-fontawesome": "^0.2.0", "@popperjs/core": "^2.11.6", "classnames": "^2.3.2", + "date-fns": "^2.11.0", + "react-datepicker": "^2.14.0", "react-helmet": "^6.1.0", "react-popper": "^2.3.0", "react-table": "^7.8.0", diff --git a/src/components/Datepicker/ComponentSummary.mdx b/src/components/Datepicker/ComponentSummary.mdx new file mode 100644 index 0000000..3345c63 --- /dev/null +++ b/src/components/Datepicker/ComponentSummary.mdx @@ -0,0 +1,4 @@ +A datepicker is a graphical user interface (GUI) element that allows users to easily select a date from a calendar. It is commonly used in web forms and applications to streamline the process of entering dates. A typical datepicker consists of an input field, where users can manually enter a date, and a graphical calendar interface that pops up when users interact with the input field. + +##Figma Link +Figma link not available diff --git a/src/components/Datepicker/Datepicker.stories.tsx b/src/components/Datepicker/Datepicker.stories.tsx new file mode 100755 index 0000000..8102ec9 --- /dev/null +++ b/src/components/Datepicker/Datepicker.stories.tsx @@ -0,0 +1,31 @@ +import React from "react"; +import { ComponentStory, ComponentMeta } from "@storybook/react"; +import Datepicker from "./Datepicker"; +import { withDesign } from 'storybook-addon-designs'; +import ComponentSummary from "./ComponentSummary.mdx"; +import ReactDOMServer from "react-dom/server"; + +// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export +export default { + title: "Components/Datepicker", + component: Datepicker, + decorators: [withDesign], + parameters: { + docs: { + description: { + component: ReactDOMServer.renderToString(), + }, + }, + }, +} as ComponentMeta; + +// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +const Template: ComponentStory = (args) => ; + +export const Basic = Template.bind({}); + +export const WithDefaultDate = Template.bind({}); +// More on args: https://storybook.js.org/docs/react/writing-stories/args +WithDefaultDate.args = { + defaultValue: new Date("2022-01-02") +}; diff --git a/src/components/Datepicker/Datepicker.styles.ts b/src/components/Datepicker/Datepicker.styles.ts new file mode 100644 index 0000000..873851d --- /dev/null +++ b/src/components/Datepicker/Datepicker.styles.ts @@ -0,0 +1,10 @@ +import styled from "styled-components"; +import 'react-datepicker/dist/react-datepicker.css'; + +const StyledDatepickerWrapper = styled.div` +.react-datepicker-time__input { + width: 120px !important; + } +`; + +export default StyledDatepickerWrapper; \ No newline at end of file diff --git a/src/components/Datepicker/Datepicker.test.tsx b/src/components/Datepicker/Datepicker.test.tsx new file mode 100644 index 0000000..896e2ca --- /dev/null +++ b/src/components/Datepicker/Datepicker.test.tsx @@ -0,0 +1,10 @@ +import React from "react"; +import { render } from "../test-utils"; + +import Datepicker from "./Datepicker"; + +describe("Datepicker", () => { + test("renders the Datepicker component", () => { + render(); + }); +}); \ No newline at end of file diff --git a/src/components/Datepicker/Datepicker.tsx b/src/components/Datepicker/Datepicker.tsx new file mode 100644 index 0000000..17d5479 --- /dev/null +++ b/src/components/Datepicker/Datepicker.tsx @@ -0,0 +1,51 @@ +import React, { useState, useEffect } from "react"; +//@ts-ignore +import DatePicker, { registerLocale } from "react-datepicker"; +import enGB from 'date-fns/locale/en-GB'; +import StyledDatepickerWrapper from './Datepicker.styles'; + + +export interface DatepickerProps { + defaultValue?: Date | null + /** + * Callback fired when the date changes + */ + onChange?: (date: Date | null) => void; +}; + +/** + * `Datepicker` Describe what it does + * + * Component Demo: [Datepicker](https://ui.govconnex.com/?path=/story/components-Datepicker--example) + * + */ +const Datepicker = (props: DatepickerProps) => { + const [selectedDate, setSelectedDate] = useState(props.defaultValue || null); + + useEffect(() => { + registerLocale('es', enGB) + }, []); + + const handleDateChange = (date: Date | null) => { + setSelectedDate(date); + if (props.onChange) { + props.onChange(date); + } + }; + + return ( + + + + ); +}; + +export default Datepicker; diff --git a/src/components/Datepicker/index.ts b/src/components/Datepicker/index.ts new file mode 100644 index 0000000..5fd3902 --- /dev/null +++ b/src/components/Datepicker/index.ts @@ -0,0 +1 @@ +export { default } from "./Datepicker"; diff --git a/src/components/index.ts b/src/components/index.ts index 2b8e229..5ade22d 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,4 +1,5 @@ export {default as ThemeProvider} from "./ThemeProvider"; +export { default as Datepicker } from "./Datepicker"; export {default as Toggle} from "./Toggle"; export {default as PopIn} from "./PopIn"; export {default as Snackbar, PopinSnackbar as PopinSnackbar} from "./Snackbar"; diff --git a/yarn.lock b/yarn.lock index b703514..d853de3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1295,6 +1295,13 @@ dependencies: regenerator-runtime "^0.13.11" +"@babel/runtime@^7.1.2", "@babel/runtime@^7.21.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e" + integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.8", "@babel/runtime@^7.5.0", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" @@ -1878,6 +1885,14 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@hypnosphi/create-react-context@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6" + integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A== + dependencies: + gud "^1.0.0" + warning "^4.0.3" + "@icons/material@^0.2.4": version "0.2.4" resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8" @@ -5695,6 +5710,17 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-bind@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + call-me-maybe@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa" @@ -5965,6 +5991,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +classnames@^2.2.6: + version "2.5.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" + integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== + classnames@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" @@ -6714,6 +6745,13 @@ data-urls@^3.0.2: whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" +date-fns@^2.0.1, date-fns@^2.11.0: + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" + debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -6755,6 +6793,18 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +deep-equal@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.2.tgz#78a561b7830eef3134c7f6f3a3d6af272a678761" + integrity sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg== + dependencies: + is-arguments "^1.1.1" + is-date-object "^1.0.5" + is-regex "^1.1.4" + object-is "^1.1.5" + object-keys "^1.1.1" + regexp.prototype.flags "^1.5.1" + deep-equal@^2.0.2, deep-equal@^2.0.5: version "2.2.0" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.0.tgz#5caeace9c781028b9ff459f33b779346637c43e6" @@ -6804,6 +6854,15 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +define-data-property@^1.0.1, define-data-property@^1.1.2, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" @@ -6817,6 +6876,15 @@ define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -7235,6 +7303,18 @@ es-array-method-boxes-properly@^1.0.0: resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + es-get-iterator@^1.0.2, es-get-iterator@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" @@ -8270,6 +8350,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + function.prototype.name@^1.1.0, function.prototype.name@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" @@ -8280,7 +8365,7 @@ function.prototype.name@^1.1.0, function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" -functions-have-names@^1.2.2: +functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== @@ -8326,6 +8411,17 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ has "^1.0.3" has-symbols "^1.0.3" +get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -8556,6 +8652,11 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +gud@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" + integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== + handlebars@^4.4.3, handlebars@^4.7.7: version "4.7.7" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" @@ -8604,6 +8705,13 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-property-descriptors@^1.0.1, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + has-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" @@ -8681,6 +8789,13 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hasown@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.1.tgz#26f48f039de2c0f8d3356c223fb8d50253519faa" + integrity sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA== + dependencies: + function-bind "^1.1.2" + hast-to-hyperscript@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" @@ -12168,6 +12283,11 @@ polished@^4.2.2: dependencies: "@babel/runtime" "^7.17.8" +popper.js@^1.14.4: + version "1.16.1" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" + integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -12651,7 +12771,7 @@ prompts@^2.0.1, prompts@^2.4.0: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -12899,6 +13019,17 @@ react-color@^2.18.0: reactcss "^1.2.0" tinycolor2 "^1.4.1" +react-datepicker@^2.14.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-2.16.0.tgz#6bd68de94f5fb38c8f6a4370f3c612837c700e4e" + integrity sha512-TvcmSY27rn0JKvuJuIXNNS+niGQNdgtuG/CsBttVYhPOA9KmSw7c2PvQBPVEvzkyV+QPNJ8jN/KVJNj9uvopqA== + dependencies: + classnames "^2.2.6" + date-fns "^2.0.1" + prop-types "^15.7.2" + react-onclickoutside "^6.9.0" + react-popper "^1.3.4" + react-docgen-typescript-plugin@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.5.tgz#015d8350b06a450d98000080d8ae5eac475e9f79" @@ -12999,6 +13130,24 @@ react-merge-refs@^1.0.0: resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06" integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ== +react-onclickoutside@^6.9.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.13.0.tgz#e165ea4e5157f3da94f4376a3ab3e22a565f4ffc" + integrity sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A== + +react-popper@^1.3.4: + version "1.3.11" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd" + integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg== + dependencies: + "@babel/runtime" "^7.1.2" + "@hypnosphi/create-react-context" "^0.3.1" + deep-equal "^1.1.1" + popper.js "^1.14.4" + prop-types "^15.6.1" + typed-styles "^0.0.7" + warning "^4.0.2" + react-popper@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba" @@ -13204,6 +13353,16 @@ regexp.prototype.flags@^1.4.3: define-properties "^1.1.3" functions-have-names "^1.2.2" +regexp.prototype.flags@^1.5.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" + integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== + dependencies: + call-bind "^1.0.6" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.1" + regexpu-core@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.1.tgz#66900860f88def39a5cb79ebd9490e84f17bcdfb" @@ -13842,6 +14001,28 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +set-function-length@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.1.tgz#47cc5945f2c771e2cf261c6737cf9684a2a5e425" + integrity sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g== + dependencies: + define-data-property "^1.1.2" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.1" + +set-function-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.2" + set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -14901,6 +15082,11 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" +typed-styles@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" + integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -15319,7 +15505,7 @@ walker@^1.0.7, walker@^1.0.8, walker@~1.0.5: dependencies: makeerror "1.0.12" -warning@^4.0.2: +warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== From 1c8f93208a31801ca87a3a3c8f273eb814f4a812 Mon Sep 17 00:00:00 2001 From: Dawn Carrasco Date: Tue, 5 Mar 2024 12:35:42 +0800 Subject: [PATCH 02/10] chore: updated datepicker --- .../Datepicker/Datepicker.stories.tsx | 7 +- .../Datepicker/Datepicker.styles.ts | 8 +- src/components/Datepicker/Datepicker.test.tsx | 6 +- src/components/Datepicker/Datepicker.tsx | 155 +++++++++++++++--- src/components/Datepicker/index.ts | 2 +- src/components/index.ts | 2 +- 6 files changed, 146 insertions(+), 34 deletions(-) diff --git a/src/components/Datepicker/Datepicker.stories.tsx b/src/components/Datepicker/Datepicker.stories.tsx index 8102ec9..3625a02 100755 --- a/src/components/Datepicker/Datepicker.stories.tsx +++ b/src/components/Datepicker/Datepicker.stories.tsx @@ -1,7 +1,7 @@ import React from "react"; -import { ComponentStory, ComponentMeta } from "@storybook/react"; +import {ComponentStory, ComponentMeta} from "@storybook/react"; import Datepicker from "./Datepicker"; -import { withDesign } from 'storybook-addon-designs'; +import {withDesign} from "storybook-addon-designs"; import ComponentSummary from "./ComponentSummary.mdx"; import ReactDOMServer from "react-dom/server"; @@ -27,5 +27,6 @@ export const Basic = Template.bind({}); export const WithDefaultDate = Template.bind({}); // More on args: https://storybook.js.org/docs/react/writing-stories/args WithDefaultDate.args = { - defaultValue: new Date("2022-01-02") + defaultDate: new Date("2022-01-02"), + defaultTime: "10:35", }; diff --git a/src/components/Datepicker/Datepicker.styles.ts b/src/components/Datepicker/Datepicker.styles.ts index 873851d..86d5de6 100644 --- a/src/components/Datepicker/Datepicker.styles.ts +++ b/src/components/Datepicker/Datepicker.styles.ts @@ -1,10 +1,10 @@ +import "react-datepicker/dist/react-datepicker.css"; import styled from "styled-components"; -import 'react-datepicker/dist/react-datepicker.css'; const StyledDatepickerWrapper = styled.div` -.react-datepicker-time__input { - width: 120px !important; + .react-datepicker { + border: none; } `; -export default StyledDatepickerWrapper; \ No newline at end of file +export default StyledDatepickerWrapper; diff --git a/src/components/Datepicker/Datepicker.test.tsx b/src/components/Datepicker/Datepicker.test.tsx index 896e2ca..fccff21 100644 --- a/src/components/Datepicker/Datepicker.test.tsx +++ b/src/components/Datepicker/Datepicker.test.tsx @@ -1,10 +1,12 @@ import React from "react"; -import { render } from "../test-utils"; +import {render} from "../test-utils"; import Datepicker from "./Datepicker"; +jest.mock('react-datepicker/dist/react-datepicker.css', () => '') + describe("Datepicker", () => { test("renders the Datepicker component", () => { render(); }); -}); \ No newline at end of file +}); diff --git a/src/components/Datepicker/Datepicker.tsx b/src/components/Datepicker/Datepicker.tsx index 17d5479..9b0cc47 100644 --- a/src/components/Datepicker/Datepicker.tsx +++ b/src/components/Datepicker/Datepicker.tsx @@ -1,49 +1,158 @@ -import React, { useState, useEffect } from "react"; +import React, {useState, useEffect} from "react"; //@ts-ignore -import DatePicker, { registerLocale } from "react-datepicker"; -import enGB from 'date-fns/locale/en-GB'; -import StyledDatepickerWrapper from './Datepicker.styles'; - +import DatePicker, {registerLocale} from "react-datepicker"; +import enGB from "date-fns/locale/en-GB"; +import StyledDatepickerWrapper from "./Datepicker.styles"; +import Popover from "../Popover"; +import Button from "../Button"; +import Box from "../Box"; +import Typography from "../Typography"; +import {customStyles} from "../../core/styleFunctions"; +import {Modifier} from "react-popper"; +import {Placement} from "@popperjs/core"; export interface DatepickerProps { - defaultValue?: Date | null + defaultDate?: Date | null; + defaultTime?: any; /** - * Callback fired when the date changes - */ + * Callback fired when the date changes + */ onChange?: (date: Date | null) => void; + onTimeChange?: (time: any) => void; + popoverCs?: customStyles; + isBlock?: boolean; + modifiers?: ReadonlyArray>; + placement?: Placement; + anchorEl?: React.RefObject; +} + +interface TimePickerProps { + selectedTime: any; // Assuming selectedTime is a string in the format "HH:mm" + onTimeChange: (time: string) => void; +} + +const TimePicker: React.FC = ({selectedTime, onTimeChange}) => { + const [inputValue, setInputValue] = useState(selectedTime); + + useEffect(() => { + setInputValue(selectedTime); + }, [selectedTime]); + + const handleInputChange = (event: React.ChangeEvent) => { + const newTime = event.target.value; + setInputValue(newTime); + + if (onTimeChange) { + onTimeChange(newTime); + } + }; + + return ( + + + Time: + + + + ); }; /** * `Datepicker` Describe what it does * * Component Demo: [Datepicker](https://ui.govconnex.com/?path=/story/components-Datepicker--example) - * + * */ -const Datepicker = (props: DatepickerProps) => { - const [selectedDate, setSelectedDate] = useState(props.defaultValue || null); +const Datepicker = ({ + defaultDate, + defaultTime, + onChange, + onTimeChange, + popoverCs, + isBlock = true, + modifiers, + placement = "bottom-start", + anchorEl, +}: DatepickerProps) => { + const [selectedDate, setSelectedDate] = useState(defaultDate || null); + const [selectedTime, setSelectedTime] = useState(defaultTime); useEffect(() => { - registerLocale('es', enGB) + registerLocale("es", enGB); }, []); const handleDateChange = (date: Date | null) => { setSelectedDate(date); - if (props.onChange) { - props.onChange(date); + if (onChange) { + onChange(date); + } + }; + + const handleClear = () => { + setSelectedDate(null); + if (onChange) { + onChange(null); + } + }; + + const handleToday = () => { + const todaysDate = new Date(); + setSelectedDate(todaysDate); + setSelectedTime("21:28"); + + if (onChange) { + onChange(todaysDate); } }; return ( - + + + + + + + + + + + + + + ); }; diff --git a/src/components/Datepicker/index.ts b/src/components/Datepicker/index.ts index 5fd3902..e4b7fce 100644 --- a/src/components/Datepicker/index.ts +++ b/src/components/Datepicker/index.ts @@ -1 +1 @@ -export { default } from "./Datepicker"; +export {default} from "./Datepicker"; diff --git a/src/components/index.ts b/src/components/index.ts index 5ade22d..923dc61 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,5 +1,5 @@ export {default as ThemeProvider} from "./ThemeProvider"; -export { default as Datepicker } from "./Datepicker"; +export {default as Datepicker} from "./Datepicker"; export {default as Toggle} from "./Toggle"; export {default as PopIn} from "./PopIn"; export {default as Snackbar, PopinSnackbar as PopinSnackbar} from "./Snackbar"; From 4ae2622119e5157e3c47921b7ffbbbda8bcbbaf7 Mon Sep 17 00:00:00 2001 From: Dawn Carrasco Date: Tue, 5 Mar 2024 15:00:05 +0800 Subject: [PATCH 03/10] chore: update datepicker --- .../Datepicker/Datepicker.stories.tsx | 36 +++++- src/components/Datepicker/Datepicker.test.tsx | 2 +- src/components/Datepicker/Datepicker.tsx | 115 ++++++++++++------ 3 files changed, 114 insertions(+), 39 deletions(-) diff --git a/src/components/Datepicker/Datepicker.stories.tsx b/src/components/Datepicker/Datepicker.stories.tsx index 3625a02..dcd1264 100755 --- a/src/components/Datepicker/Datepicker.stories.tsx +++ b/src/components/Datepicker/Datepicker.stories.tsx @@ -1,6 +1,7 @@ import React from "react"; import {ComponentStory, ComponentMeta} from "@storybook/react"; import Datepicker from "./Datepicker"; +import Button from "../Button"; import {withDesign} from "storybook-addon-designs"; import ComponentSummary from "./ComponentSummary.mdx"; import ReactDOMServer from "react-dom/server"; @@ -19,8 +20,32 @@ export default { }, } as ComponentMeta; -// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args -const Template: ComponentStory = (args) => ; +const Template: ComponentStory = (args) => { + const [shown, setShown] = React.useState(false); + const buttonRef = React.useRef(null); + + // override on close + const overriddenArgs = { + ...args, + onClose: () => { + setShown(false); + }, + }; + + return ( + <> + + {shown && } + + ); +}; export const Basic = Template.bind({}); @@ -29,4 +54,11 @@ export const WithDefaultDate = Template.bind({}); WithDefaultDate.args = { defaultDate: new Date("2022-01-02"), defaultTime: "10:35", + hasTime: true, + onChange: (value) => { + console.log("date: ", value); + }, + onTimeChange: (value) => { + console.log("time: ", value); + }, }; diff --git a/src/components/Datepicker/Datepicker.test.tsx b/src/components/Datepicker/Datepicker.test.tsx index fccff21..a99ec60 100644 --- a/src/components/Datepicker/Datepicker.test.tsx +++ b/src/components/Datepicker/Datepicker.test.tsx @@ -3,7 +3,7 @@ import {render} from "../test-utils"; import Datepicker from "./Datepicker"; -jest.mock('react-datepicker/dist/react-datepicker.css', () => '') +jest.mock("react-datepicker/dist/react-datepicker.css", () => ""); describe("Datepicker", () => { test("renders the Datepicker component", () => { diff --git a/src/components/Datepicker/Datepicker.tsx b/src/components/Datepicker/Datepicker.tsx index 9b0cc47..78a00a7 100644 --- a/src/components/Datepicker/Datepicker.tsx +++ b/src/components/Datepicker/Datepicker.tsx @@ -6,6 +6,7 @@ import StyledDatepickerWrapper from "./Datepicker.styles"; import Popover from "../Popover"; import Button from "../Button"; import Box from "../Box"; +import ClickAwayListener from "../ClickAwayListener"; import Typography from "../Typography"; import {customStyles} from "../../core/styleFunctions"; import {Modifier} from "react-popper"; @@ -13,14 +14,16 @@ import {Placement} from "@popperjs/core"; export interface DatepickerProps { defaultDate?: Date | null; - defaultTime?: any; + defaultTime?: string; /** * Callback fired when the date changes */ onChange?: (date: Date | null) => void; - onTimeChange?: (time: any) => void; + onTimeChange?: (time: string) => void; + onClose?: () => void; popoverCs?: customStyles; isBlock?: boolean; + hasTime?: boolean; modifiers?: ReadonlyArray>; placement?: Placement; anchorEl?: React.RefObject; @@ -35,7 +38,11 @@ const TimePicker: React.FC = ({selectedTime, onTimeChange}) => const [inputValue, setInputValue] = useState(selectedTime); useEffect(() => { - setInputValue(selectedTime); + if (selectedTime && selectedTime.includes("NA")) { + setInputValue(""); + } else { + setInputValue(selectedTime.substring(0, 5)); + } }, [selectedTime]); const handleInputChange = (event: React.ChangeEvent) => { @@ -82,8 +89,10 @@ const Datepicker = ({ defaultTime, onChange, onTimeChange, + onClose, popoverCs, isBlock = true, + hasTime = false, modifiers, placement = "bottom-start", anchorEl, @@ -107,53 +116,87 @@ const Datepicker = ({ if (onChange) { onChange(null); } + + if (hasTime) { + // need seconds to update time element in the component and trigger useeffect + const seconds = new Date().getSeconds(); + const todaysTime = `NA:${seconds.toString().padStart(2, "0")}`; + setSelectedTime(todaysTime); + if (onTimeChange) { + onTimeChange(""); + } + } }; const handleToday = () => { const todaysDate = new Date(); setSelectedDate(todaysDate); - setSelectedTime("21:28"); + + const hours = todaysDate.getHours(); + const minutes = todaysDate.getMinutes(); + const seconds = todaysDate.getSeconds(); + + // need seconds to update time element in the component and trigger useeffect + const todaysTime = `${hours.toString().padStart(2, "0")}:${minutes + .toString() + .padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`; + setSelectedTime(todaysTime); if (onChange) { onChange(todaysDate); } + + if (onTimeChange && hasTime) { + onTimeChange(todaysTime.substring(0, 5)); + } + }; + + const handleClickaway = () => { + onClose && onClose(); }; return ( - - - - - - - - - + + + + + + {hasTime && ( + {})} + /> + )} - - + + + + + + + - - - + + + ); }; From 420833c8760fab564b75eab6fea8f2559a946b8a Mon Sep 17 00:00:00 2001 From: Dawn Carrasco Date: Tue, 5 Mar 2024 15:47:09 +0800 Subject: [PATCH 04/10] chore: updated styling --- .../Datepicker/Datepicker.styles.ts | 106 +++++++++++++++++- src/components/Datepicker/Datepicker.test.tsx | 2 - src/components/Datepicker/Datepicker.tsx | 3 +- 3 files changed, 106 insertions(+), 5 deletions(-) diff --git a/src/components/Datepicker/Datepicker.styles.ts b/src/components/Datepicker/Datepicker.styles.ts index 86d5de6..0e6c01a 100644 --- a/src/components/Datepicker/Datepicker.styles.ts +++ b/src/components/Datepicker/Datepicker.styles.ts @@ -1,10 +1,114 @@ -import "react-datepicker/dist/react-datepicker.css"; import styled from "styled-components"; const StyledDatepickerWrapper = styled.div` .react-datepicker { border: none; } + + .react-datepicker { + font-family: sans-serif; + border-radius: 4px; + } + + .react-datepicker__header { + background-color: #ffffff; + color: #000000; + border: none; + padding: 10px; + text-align: center; + border-bottom: 1px solid #ccc; + } + + .react-datepicker__navigation { + margin-left: 20px; + margin-right: 20px; + background: none; + line-height: 1.7rem; + text-align: center; + cursor: pointer; + position: absolute; + top: 30px; + width: 0; + padding: 0; + border: 0.45rem solid transparent; + z-index: 1; + height: 10px; + width: 10px; + text-indent: -999em; + overflow: hidden; + } + + .react-datepicker__navigation--previous { + left: 10px; + border-right-color: #ccc; + } + + .react-datepicker__navigation--previous:hover { + border-right-color: #b3b3b3; + } + + .react-datepicker__navigation--previous--disabled, + .react-datepicker__navigation--previous--disabled:hover { + border-right-color: #e6e6e6; + cursor: default; + } + + .react-datepicker__navigation--next { + right: 10px; + border-left-color: #ccc; + } + + .react-datepicker__navigation--next--with-time:not( + .react-datepicker__navigation--next--with-today-button + ) { + right: 80px; + } + + .react-datepicker__navigation--next:hover { + border-left-color: #b3b3b3; + } + + .react-datepicker__day-names { + display: flex; + justify-content: space-around; + margin-top: 10px; + } + + .react-datepicker__week { + display: flex; + justify-content: space-around; + margin-bottom: 10px; + } + + .react-datepicker__day { + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s; + + &:hover { + background-color: #f0f0f0; + } + } + + .react-datepicker__month { + padding: 10px; + } + + .react-datepicker__day--selected { + background-color: #3498db; + color: #ffffff; + } + + .react-datepicker__day--keyboard-selected { + background-color: #2980b9; + color: #ffffff; + } `; export default StyledDatepickerWrapper; diff --git a/src/components/Datepicker/Datepicker.test.tsx b/src/components/Datepicker/Datepicker.test.tsx index a99ec60..8204ba6 100644 --- a/src/components/Datepicker/Datepicker.test.tsx +++ b/src/components/Datepicker/Datepicker.test.tsx @@ -3,8 +3,6 @@ import {render} from "../test-utils"; import Datepicker from "./Datepicker"; -jest.mock("react-datepicker/dist/react-datepicker.css", () => ""); - describe("Datepicker", () => { test("renders the Datepicker component", () => { render(); diff --git a/src/components/Datepicker/Datepicker.tsx b/src/components/Datepicker/Datepicker.tsx index 78a00a7..4630fad 100644 --- a/src/components/Datepicker/Datepicker.tsx +++ b/src/components/Datepicker/Datepicker.tsx @@ -58,7 +58,6 @@ const TimePicker: React.FC = ({selectedTime, onTimeChange}) => = ({selectedTime, onTimeChange}) => Time: Date: Tue, 5 Mar 2024 16:59:27 +0800 Subject: [PATCH 05/10] chore: updated styling --- src/components/Datepicker/Datepicker.styles.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/Datepicker/Datepicker.styles.ts b/src/components/Datepicker/Datepicker.styles.ts index 0e6c01a..8bdea62 100644 --- a/src/components/Datepicker/Datepicker.styles.ts +++ b/src/components/Datepicker/Datepicker.styles.ts @@ -19,6 +19,19 @@ const StyledDatepickerWrapper = styled.div` border-bottom: 1px solid #ccc; } + .react-datepicker__portal .react-datepicker__current-month, + .react-datepicker__portal .react-datepicker-time__header { + font-size: 1.44rem; + } + + .react-datepicker__current-month, + .react-datepicker-time__header, + .react-datepicker-year-header { + margin-top: 1px; + color: #000; + font-size: 0.944rem; + } + .react-datepicker__navigation { margin-left: 20px; margin-right: 20px; @@ -92,7 +105,8 @@ const StyledDatepickerWrapper = styled.div` transition: background-color 0.3s; &:hover { - background-color: #f0f0f0; + background-color: rgb(74 131 169); + color: #ffffff; } } @@ -106,7 +120,7 @@ const StyledDatepickerWrapper = styled.div` } .react-datepicker__day--keyboard-selected { - background-color: #2980b9; + background-color: #3498db; color: #ffffff; } `; From ba7cee8afab121166fa5b1c7fbcdf51c41046c34 Mon Sep 17 00:00:00 2001 From: Dawn Carrasco Date: Wed, 6 Mar 2024 15:22:17 +0800 Subject: [PATCH 06/10] chore: update on datepicker --- src/components/Datepicker/Datepicker.tsx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/Datepicker/Datepicker.tsx b/src/components/Datepicker/Datepicker.tsx index 4630fad..1a31720 100644 --- a/src/components/Datepicker/Datepicker.tsx +++ b/src/components/Datepicker/Datepicker.tsx @@ -19,7 +19,7 @@ export interface DatepickerProps { * Callback fired when the date changes */ onChange?: (date: Date | null) => void; - onTimeChange?: (time: string) => void; + onTimeChange?: (time: string, date: Date | null) => void; onClose?: () => void; popoverCs?: customStyles; isBlock?: boolean; @@ -30,11 +30,12 @@ export interface DatepickerProps { } interface TimePickerProps { - selectedTime: any; // Assuming selectedTime is a string in the format "HH:mm" - onTimeChange: (time: string) => void; + selectedTime: string; // Assuming selectedTime is a string in the format "HH:mm" + selectedDate?: Date | null; + onTimeChange: (time: string, date: Date | null) => void; } -const TimePicker: React.FC = ({selectedTime, onTimeChange}) => { +const TimePicker: React.FC = ({selectedTime, selectedDate = null, onTimeChange}) => { const [inputValue, setInputValue] = useState(selectedTime); useEffect(() => { @@ -50,7 +51,7 @@ const TimePicker: React.FC = ({selectedTime, onTimeChange}) => setInputValue(newTime); if (onTimeChange) { - onTimeChange(newTime); + onTimeChange(newTime, selectedDate); } }; @@ -84,8 +85,8 @@ const TimePicker: React.FC = ({selectedTime, onTimeChange}) => * */ const Datepicker = ({ - defaultDate, - defaultTime, + defaultDate = null, + defaultTime = "", onChange, onTimeChange, onClose, @@ -122,7 +123,7 @@ const Datepicker = ({ const todaysTime = `NA:${seconds.toString().padStart(2, "0")}`; setSelectedTime(todaysTime); if (onTimeChange) { - onTimeChange(""); + onTimeChange("", null); } } }; @@ -146,7 +147,7 @@ const Datepicker = ({ } if (onTimeChange && hasTime) { - onTimeChange(todaysTime.substring(0, 5)); + onTimeChange(todaysTime.substring(0, 5), todaysDate); } }; @@ -177,6 +178,7 @@ const Datepicker = ({ {hasTime && ( {})} /> )} From b356154609d04c7002cb92ffa67f386256d97de0 Mon Sep 17 00:00:00 2001 From: Dawn Carrasco Date: Wed, 6 Mar 2024 15:23:08 +0800 Subject: [PATCH 07/10] chore: change in format --- src/components/Datepicker/Datepicker.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/Datepicker/Datepicker.tsx b/src/components/Datepicker/Datepicker.tsx index 1a31720..c725c4d 100644 --- a/src/components/Datepicker/Datepicker.tsx +++ b/src/components/Datepicker/Datepicker.tsx @@ -35,7 +35,11 @@ interface TimePickerProps { onTimeChange: (time: string, date: Date | null) => void; } -const TimePicker: React.FC = ({selectedTime, selectedDate = null, onTimeChange}) => { +const TimePicker: React.FC = ({ + selectedTime, + selectedDate = null, + onTimeChange, +}) => { const [inputValue, setInputValue] = useState(selectedTime); useEffect(() => { From 88070cfe1f442ad8de1a211b03d08bd64e8f7607 Mon Sep 17 00:00:00 2001 From: Dawn Carrasco Date: Wed, 6 Mar 2024 15:40:15 +0800 Subject: [PATCH 08/10] chore: version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 263cdca..c1f595a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@govconnex/ui", - "version": "0.0.169", + "version": "0.0.170", "description": "GovConnex UI - React Component Library", "scripts": { "build:tokens": "./tokens-build.sh", From 9fe84a61cac0a104479447550561dc502b1f3fdc Mon Sep 17 00:00:00 2001 From: Dawn Carrasco Date: Thu, 7 Mar 2024 10:33:57 +0800 Subject: [PATCH 09/10] chore: change datepicker case --- package.json | 2 +- .../Datepicker/Datepicker.stories.tsx | 17 ++++++---- .../Datepicker/Datepicker.styles.ts | 4 +-- src/components/Datepicker/Datepicker.test.tsx | 8 ++--- src/components/Datepicker/Datepicker.tsx | 33 +++++++++++-------- src/components/Datepicker/index.ts | 2 +- src/components/index.ts | 2 +- 7 files changed, 39 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index c1f595a..8887399 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@govconnex/ui", - "version": "0.0.170", + "version": "0.0.171", "description": "GovConnex UI - React Component Library", "scripts": { "build:tokens": "./tokens-build.sh", diff --git a/src/components/Datepicker/Datepicker.stories.tsx b/src/components/Datepicker/Datepicker.stories.tsx index dcd1264..5d70546 100755 --- a/src/components/Datepicker/Datepicker.stories.tsx +++ b/src/components/Datepicker/Datepicker.stories.tsx @@ -1,6 +1,6 @@ import React from "react"; import {ComponentStory, ComponentMeta} from "@storybook/react"; -import Datepicker from "./Datepicker"; +import DatePicker from "./DatePicker"; import Button from "../Button"; import {withDesign} from "storybook-addon-designs"; import ComponentSummary from "./ComponentSummary.mdx"; @@ -8,8 +8,8 @@ import ReactDOMServer from "react-dom/server"; // More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export export default { - title: "Components/Datepicker", - component: Datepicker, + title: "Components/DatePicker", + component: DatePicker, decorators: [withDesign], parameters: { docs: { @@ -18,9 +18,9 @@ export default { }, }, }, -} as ComponentMeta; +} as ComponentMeta; -const Template: ComponentStory = (args) => { +const Template: ComponentStory = (args) => { const [shown, setShown] = React.useState(false); const buttonRef = React.useRef(null); @@ -40,9 +40,9 @@ const Template: ComponentStory = (args) => { setShown(true); }} > - Show Datepicker + Show Date Picker - {shown && } + {shown && } ); }; @@ -61,4 +61,7 @@ WithDefaultDate.args = { onTimeChange: (value) => { console.log("time: ", value); }, + "data-cy": "popover", + "data-cy-clear": "clear", + "data-cy-today": "today", }; diff --git a/src/components/Datepicker/Datepicker.styles.ts b/src/components/Datepicker/Datepicker.styles.ts index 8bdea62..0d214c6 100644 --- a/src/components/Datepicker/Datepicker.styles.ts +++ b/src/components/Datepicker/Datepicker.styles.ts @@ -1,6 +1,6 @@ import styled from "styled-components"; -const StyledDatepickerWrapper = styled.div` +const StyledDatePickerWrapper = styled.div` .react-datepicker { border: none; } @@ -125,4 +125,4 @@ const StyledDatepickerWrapper = styled.div` } `; -export default StyledDatepickerWrapper; +export default StyledDatePickerWrapper; diff --git a/src/components/Datepicker/Datepicker.test.tsx b/src/components/Datepicker/Datepicker.test.tsx index 8204ba6..77b4364 100644 --- a/src/components/Datepicker/Datepicker.test.tsx +++ b/src/components/Datepicker/Datepicker.test.tsx @@ -1,10 +1,10 @@ import React from "react"; import {render} from "../test-utils"; -import Datepicker from "./Datepicker"; +import DatePicker from "./DatePicker"; -describe("Datepicker", () => { - test("renders the Datepicker component", () => { - render(); +describe("DatePicker", () => { + test("renders the DatePicker component", () => { + render(); }); }); diff --git a/src/components/Datepicker/Datepicker.tsx b/src/components/Datepicker/Datepicker.tsx index c725c4d..29c383d 100644 --- a/src/components/Datepicker/Datepicker.tsx +++ b/src/components/Datepicker/Datepicker.tsx @@ -1,8 +1,8 @@ import React, {useState, useEffect} from "react"; //@ts-ignore -import DatePicker, {registerLocale} from "react-datepicker"; +import {default as ReactDatePicker, registerLocale} from "react-datepicker"; import enGB from "date-fns/locale/en-GB"; -import StyledDatepickerWrapper from "./Datepicker.styles"; +import StyledDatePickerWrapper from "./DatePicker.styles"; import Popover from "../Popover"; import Button from "../Button"; import Box from "../Box"; @@ -12,7 +12,7 @@ import {customStyles} from "../../core/styleFunctions"; import {Modifier} from "react-popper"; import {Placement} from "@popperjs/core"; -export interface DatepickerProps { +export interface DatePickerProps { defaultDate?: Date | null; defaultTime?: string; /** @@ -27,6 +27,9 @@ export interface DatepickerProps { modifiers?: ReadonlyArray>; placement?: Placement; anchorEl?: React.RefObject; + "data-cy"?: string; + "data-cy-today"?: string; + "data-cy-clear"?: string; } interface TimePickerProps { @@ -83,12 +86,12 @@ const TimePicker: React.FC = ({ }; /** - * `Datepicker` Describe what it does + * `DatePicker` Describe what it does * - * Component Demo: [Datepicker](https://ui.govconnex.com/?path=/story/components-Datepicker--example) + * Component Demo: [DatePicker](https://ui.govconnex.com/?path=/story/components-DatePicker--example) * */ -const Datepicker = ({ +const DatePicker = ({ defaultDate = null, defaultTime = "", onChange, @@ -100,7 +103,10 @@ const Datepicker = ({ modifiers, placement = "bottom-start", anchorEl, -}: DatepickerProps) => { + "data-cy": dataCy = "date-picker-popover", + "data-cy-clear": dataCyClear = "date-picker-clear-button", + "data-cy-today": dataCyToday = "date-picker-today-button", +}: DatePickerProps) => { const [selectedDate, setSelectedDate] = useState(defaultDate || null); const [selectedTime, setSelectedTime] = useState(defaultTime); @@ -161,7 +167,7 @@ const Datepicker = ({ return ( - + - - - - + ); }; -export default Datepicker; +export default DatePicker; diff --git a/src/components/Datepicker/index.ts b/src/components/Datepicker/index.ts index e4b7fce..11c7f84 100644 --- a/src/components/Datepicker/index.ts +++ b/src/components/Datepicker/index.ts @@ -1 +1 @@ -export {default} from "./Datepicker"; +export {default} from "./DatePicker"; diff --git a/src/components/index.ts b/src/components/index.ts index 923dc61..9e126b4 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,5 +1,5 @@ export {default as ThemeProvider} from "./ThemeProvider"; -export {default as Datepicker} from "./Datepicker"; +export {default as DatePicker} from "./DatePicker"; export {default as Toggle} from "./Toggle"; export {default as PopIn} from "./PopIn"; export {default as Snackbar, PopinSnackbar as PopinSnackbar} from "./Snackbar"; From 224c22b2e618cef152e2a2516f5aee240780d902 Mon Sep 17 00:00:00 2001 From: Dawn Carrasco Date: Thu, 7 Mar 2024 15:28:14 +0800 Subject: [PATCH 10/10] chore: updated lib --- package.json | 1 - src/components/Datepicker/Datepicker.tsx | 7 ------- yarn.lock | 2 +- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/package.json b/package.json index 8887399..c8d0987 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,6 @@ "@fortawesome/react-fontawesome": "^0.2.0", "@popperjs/core": "^2.11.6", "classnames": "^2.3.2", - "date-fns": "^2.11.0", "react-datepicker": "^2.14.0", "react-helmet": "^6.1.0", "react-popper": "^2.3.0", diff --git a/src/components/Datepicker/Datepicker.tsx b/src/components/Datepicker/Datepicker.tsx index 29c383d..7920b78 100644 --- a/src/components/Datepicker/Datepicker.tsx +++ b/src/components/Datepicker/Datepicker.tsx @@ -9,7 +9,6 @@ import Box from "../Box"; import ClickAwayListener from "../ClickAwayListener"; import Typography from "../Typography"; import {customStyles} from "../../core/styleFunctions"; -import {Modifier} from "react-popper"; import {Placement} from "@popperjs/core"; export interface DatePickerProps { @@ -22,9 +21,7 @@ export interface DatePickerProps { onTimeChange?: (time: string, date: Date | null) => void; onClose?: () => void; popoverCs?: customStyles; - isBlock?: boolean; hasTime?: boolean; - modifiers?: ReadonlyArray>; placement?: Placement; anchorEl?: React.RefObject; "data-cy"?: string; @@ -98,9 +95,7 @@ const DatePicker = ({ onTimeChange, onClose, popoverCs, - isBlock = true, hasTime = false, - modifiers, placement = "bottom-start", anchorEl, "data-cy": dataCy = "date-picker-popover", @@ -169,8 +164,6 @@ const DatePicker = ({