diff --git a/package.json b/package.json index 79ec2b281..c36bb704c 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,6 @@ "@types/path-browserify": "^1.0.0", "@types/react": "^18.3.9", "@types/react-color": "^3.0.6", - "@types/react-datepicker": "^4.4.2", "@types/react-dom": "^18.3.0", "@types/react-helmet": "^6.1.5", "@types/react-motion": "^0.0.40", @@ -128,7 +127,6 @@ "qrcode.react": "^3.1.0", "react": "^18.3.1", "react-color": "^2.19.3", - "react-datepicker": "^4.8.0", "react-dom": "^18.3.1", "react-error-boundary": "^4.0.11", "react-helmet": "^6.1.0", diff --git a/src/components/birthday-input.tsx b/src/components/birthday-input.tsx index 209739278..0c4700d83 100644 --- a/src/components/birthday-input.tsx +++ b/src/components/birthday-input.tsx @@ -1,10 +1,10 @@ import React, { useMemo } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import IconButton from 'soapbox/components/icon-button'; -import { DatePicker } from 'soapbox/features/ui/util/async-components'; import { useInstance, useFeatures } from 'soapbox/hooks'; +import { Datetime } from './ui/datetime/datetime'; + const messages = defineMessages({ birthdayPlaceholder: { id: 'edit_profile.fields.birthday_placeholder', defaultMessage: 'Your birthday' }, previousMonth: { id: 'datepicker.previous_month', defaultMessage: 'Previous month' }, @@ -28,7 +28,7 @@ const BirthdayInput: React.FC = ({ value, onChange, required }) const minAge = instance.pleroma.metadata.birthday_min_age; const maxDate = useMemo(() => { - if (!supportsBirthdays) return null; + if (!supportsBirthdays) return; let maxDate = new Date(); maxDate = new Date(maxDate.getTime() - minAge * 1000 * 60 * 60 * 24 + maxDate.getTimezoneOffset() * 1000 * 60); @@ -36,7 +36,7 @@ const BirthdayInput: React.FC = ({ value, onChange, required }) }, [minAge]); const selected = useMemo(() => { - if (!supportsBirthdays || !value) return null; + if (!supportsBirthdays || !value) return; const date = new Date(value); return new Date(date.getTime() + (date.getTimezoneOffset() * 60000)); @@ -44,85 +44,17 @@ const BirthdayInput: React.FC = ({ value, onChange, required }) if (!supportsBirthdays) return null; - const renderCustomHeader = ({ - decreaseMonth, - increaseMonth, - prevMonthButtonDisabled, - nextMonthButtonDisabled, - decreaseYear, - increaseYear, - prevYearButtonDisabled, - nextYearButtonDisabled, - date, - }: { - decreaseMonth(): void; - increaseMonth(): void; - prevMonthButtonDisabled: boolean; - nextMonthButtonDisabled: boolean; - decreaseYear(): void; - increaseYear(): void; - prevYearButtonDisabled: boolean; - nextYearButtonDisabled: boolean; - date: Date; - }) => { - return ( -
-
- - {intl.formatDate(date, { month: 'long' })} - -
-
- - {intl.formatDate(date, { year: 'numeric' })} - -
-
- ); - }; - const handleChange = (date: Date) => onChange(date ? new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(0, 10) : ''); return (
-
); diff --git a/src/components/ui/datetime/datetime.tsx b/src/components/ui/datetime/datetime.tsx new file mode 100644 index 000000000..bdf676840 --- /dev/null +++ b/src/components/ui/datetime/datetime.tsx @@ -0,0 +1,39 @@ +import React from 'react'; + +import Input from '../input/input'; + +interface DatetimeProps { + value: Date; + onChange(date: Date): void; + min?: Date; + max?: Date; + placeholder?: string; + required?: boolean; +} + +/** + * Date input with time. + */ +export const Datetime: React.FC = ({ value, onChange, min, max, ...rest }) => { + return ( + onChange(new Date(e.target.value))} + value={formatDateLocal(value)} + min={min ? formatDateLocal(min) : undefined} + max={max ? formatDateLocal(max) : undefined} + {...rest} + /> + ); +}; + +/** Format a Date object to 'YYYY-MM-DDTHH:MM' format, used by `` elements. */ +function formatDateLocal(date: Date): string { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + + return `${year}-${month}-${day}T${hours}:${minutes}`; +} \ No newline at end of file diff --git a/src/components/ui/input/input.tsx b/src/components/ui/input/input.tsx index 8b855ab3d..94daf1dcb 100644 --- a/src/components/ui/input/input.tsx +++ b/src/components/ui/input/input.tsx @@ -17,7 +17,7 @@ const messages = defineMessages({ /** Possible theme names for an Input. */ type InputThemes = 'normal' | 'search' -interface IInput extends Pick, 'maxLength' | 'onChange' | 'onBlur' | 'type' | 'autoComplete' | 'autoCorrect' | 'autoCapitalize' | 'required' | 'disabled' | 'onClick' | 'readOnly' | 'min' | 'pattern' | 'onKeyDown' | 'onKeyUp' | 'onFocus' | 'style' | 'id'> { +interface IInput extends Pick, 'maxLength' | 'onChange' | 'onBlur' | 'type' | 'autoComplete' | 'autoCorrect' | 'autoCapitalize' | 'required' | 'disabled' | 'onClick' | 'readOnly' | 'min' | 'max' | 'pattern' | 'onKeyDown' | 'onKeyUp' | 'onFocus' | 'style' | 'id'> { /** Put the cursor into the input on mount. */ autoFocus?: boolean; /** The initial text in the input. */ diff --git a/src/features/birthdays/date-picker.ts b/src/features/birthdays/date-picker.ts deleted file mode 100644 index 1944067d7..000000000 --- a/src/features/birthdays/date-picker.ts +++ /dev/null @@ -1,4 +0,0 @@ -import DatePicker from 'react-datepicker'; -import 'react-datepicker/dist/react-datepicker.css'; - -export default DatePicker; diff --git a/src/features/compose/components/schedule-form.tsx b/src/features/compose/components/schedule-form.tsx index fa8a1cd3e..ab7a64f34 100644 --- a/src/features/compose/components/schedule-form.tsx +++ b/src/features/compose/components/schedule-form.tsx @@ -1,24 +1,12 @@ -import clsx from 'clsx'; -import React, { Suspense } from 'react'; +import React from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { setSchedule, removeSchedule } from 'soapbox/actions/compose'; import IconButton from 'soapbox/components/icon-button'; -import { HStack, Input, Stack, Text } from 'soapbox/components/ui'; -import { DatePicker } from 'soapbox/features/ui/util/async-components'; +import { HStack, Stack, Text } from 'soapbox/components/ui'; +import { Datetime } from 'soapbox/components/ui/datetime/datetime'; import { useAppDispatch, useCompose } from 'soapbox/hooks'; -export const isCurrentOrFutureDate = (date: Date) => { - return date && new Date().setHours(0, 0, 0, 0) <= new Date(date).setHours(0, 0, 0, 0); -}; - -const isFiveMinutesFromNow = (time: Date) => { - const fiveMinutesFromNow = new Date(new Date().getTime() + 300000); // now, plus five minutes (Pleroma won't schedule posts ) - const selectedDate = new Date(time); - - return fiveMinutesFromNow.getTime() < selectedDate.getTime(); -}; - const messages = defineMessages({ schedule: { id: 'schedule.post_time', defaultMessage: 'Post Date/Time' }, remove: { id: 'schedule.remove', defaultMessage: 'Remove schedule' }, @@ -35,6 +23,8 @@ const ScheduleForm: React.FC = ({ composeId }) => { const scheduledAt = useCompose(composeId).schedule; const active = !!scheduledAt; + const fiveMinutesFromNow = new Date(new Date().getTime() + 300_000); + const onSchedule = (date: Date) => { dispatch(setSchedule(composeId, date)); }; @@ -54,22 +44,11 @@ const ScheduleForm: React.FC = ({ composeId }) => { - }> - - + = ({ onClose }) => { } > - @@ -278,15 +273,10 @@ const ComposeEventModal: React.FC = ({ onClose }) => { } > - )} diff --git a/src/features/ui/components/modals/edit-announcement-modal.tsx b/src/features/ui/components/modals/edit-announcement-modal.tsx index 3188b4e2b..1a81df1ab 100644 --- a/src/features/ui/components/modals/edit-announcement-modal.tsx +++ b/src/features/ui/components/modals/edit-announcement-modal.tsx @@ -4,7 +4,7 @@ import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { closeModal } from 'soapbox/actions/modals'; import { useAnnouncements } from 'soapbox/api/hooks/admin/useAnnouncements'; import { Form, FormGroup, HStack, Modal, Stack, Text, Textarea, Toggle } from 'soapbox/components/ui'; -import { DatePicker } from 'soapbox/features/ui/util/async-components'; +import { Datetime } from 'soapbox/components/ui/datetime/datetime'; import { useAppDispatch } from 'soapbox/hooks'; import toast from 'soapbox/toast'; @@ -30,15 +30,15 @@ const EditAnnouncementModal: React.FC = ({ onClose, anno const intl = useIntl(); const [content, setContent] = useState(announcement?.content || ''); - const [startTime, setStartTime] = useState(announcement?.starts_at ? new Date(announcement.starts_at) : null); - const [endTime, setEndTime] = useState(announcement?.ends_at ? new Date(announcement.ends_at) : null); + const [startTime, setStartTime] = useState(announcement?.starts_at ? new Date(announcement.starts_at) : undefined); + const [endTime, setEndTime] = useState(announcement?.ends_at ? new Date(announcement.ends_at) : undefined); const [allDay, setAllDay] = useState(announcement?.all_day || false); const onChangeContent: React.ChangeEventHandler = ({ target }) => setContent(target.value); - const onChangeStartTime = (date: Date | null) => setStartTime(date); + const onChangeStartTime = (date: Date | undefined) => setStartTime(date); - const onChangeEndTime = (date: Date | null) => setEndTime(date); + const onChangeEndTime = (date: Date | undefined) => setEndTime(date); const onChangeAllDay: React.ChangeEventHandler = ({ target }) => setAllDay(target.checked); @@ -94,29 +94,19 @@ const EditAnnouncementModal: React.FC = ({ onClose, anno } > - } > - diff --git a/src/features/ui/util/async-components.ts b/src/features/ui/util/async-components.ts index 91af34395..8a78471c7 100644 --- a/src/features/ui/util/async-components.ts +++ b/src/features/ui/util/async-components.ts @@ -120,7 +120,6 @@ export const CreateApp = lazy(() => import('soapbox/features/developers/apps/cre export const SettingsStore = lazy(() => import('soapbox/features/developers/settings-store')); export const TestTimeline = lazy(() => import('soapbox/features/test-timeline')); export const ServiceWorkerInfo = lazy(() => import('soapbox/features/developers/service-worker-info')); -export const DatePicker = lazy(() => import('soapbox/features/birthdays/date-picker')); export const CompareHistoryModal = lazy(() => import('soapbox/features/ui/components/modals/compare-history-modal')); export const AuthTokenList = lazy(() => import('soapbox/features/auth-token-list')); export const FamiliarFollowersModal = lazy(() => import('soapbox/features/ui/components/modals/familiar-followers-modal')); diff --git a/src/main.tsx b/src/main.tsx index 78555853e..c0f99b85c 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -14,7 +14,6 @@ import '@fontsource/inter/700.css'; import '@fontsource/inter/900.css'; import '@fontsource/roboto-mono/400.css'; import 'line-awesome/dist/font-awesome-line-awesome/css/all.css'; -import 'react-datepicker/dist/react-datepicker.css'; import 'soapbox/features/nostr/keys'; import './iframe'; diff --git a/src/styles/application.scss b/src/styles/application.scss index f0a17c975..5e29bcde8 100644 --- a/src/styles/application.scss +++ b/src/styles/application.scss @@ -28,4 +28,3 @@ @import 'components/icon'; @import 'forms'; @import 'utilities'; -@import 'components/datepicker'; diff --git a/src/styles/components/datepicker.scss b/src/styles/components/datepicker.scss deleted file mode 100644 index 13bc71585..000000000 --- a/src/styles/components/datepicker.scss +++ /dev/null @@ -1,150 +0,0 @@ -.react-datepicker { - @apply black:bg-black dark:bg-gray-900 dark:border-gray-700 p-4 font-sans text-xs text-gray-900 dark:text-gray-300 border border-solid border-gray-200 rounded-lg; -} - -.react-datepicker__input-container > input { - @apply black:bg-black dark:bg-gray-900 dark:text-gray-100 block w-full sm:text-sm border-gray-400 dark:border-gray-800 rounded-md focus:ring-primary-500 focus:border-primary-500; - - &.has-error { - @apply text-red-600 border-red-600; - } -} - -.react-datepicker-popper[data-placement^='bottom'] .react-datepicker__triangle::before, -.react-datepicker-popper[data-placement^='bottom'] .react-datepicker__triangle::after { - @apply border-b-white dark:border-b-gray-900 black:border-b-black; -} - -.react-datepicker-popper[data-placement^='bottom'] .react-datepicker__triangle::before { - @apply border-b-gray-200 dark:border-b-gray-700; -} - -.react-datepicker__header:not(.react-datepicker__header--has-time-select) { - @apply rounded-tr-lg; -} - -.react-datepicker__header { - @apply bg-white black:bg-black dark:bg-gray-900 border-b-0 py-1 px-0; -} - -.react-datepicker__current-month, -.react-datepicker-time__header, -.react-datepicker-year-header { - @apply text-gray-900 dark:text-gray-300 font-bold text-sm; -} - -.react-datepicker__current-month { - margin-top: 2px; -} - -.react-datepicker__navigation { - @apply top-4 h-8 w-8 rounded hover:bg-gray-50 dark:hover:bg-gray-900/50; -} - -.react-datepicker__navigation-icon { - margin-top: -3px; -} - -.react-datepicker__navigation-icon--previous::before { - right: -5px; -} - -.react-datepicker__navigation-icon--next::before { - left: -5px; -} - -.react-datepicker__navigation--previous { - left: 16px; -} - -.react-datepicker__navigation--next { - right: 16px; - - &--with-time:not(.react-datepicker__navigation--next--with-today-button) { - right: 100px; - } -} - -.react-datepicker__year-read-view--down-arrow, -.react-datepicker__month-read-view--down-arrow, -.react-datepicker__month-year-read-view--down-arrow, -.react-datepicker__navigation-icon::before { - border-width: 2px 2px 0 0; - height: 7px; - width: 7px; - top: 8px; -} - -.react-datepicker__header__dropdown { - @apply py-4; -} - -.react-datepicker__day-names, -.react-datepicker__week { - @apply flex justify-between; -} - -.react-datepicker__time { - &-container & { - @apply dark:bg-gray-900 black:bg-black; - } -} - -.react-datepicker__time-container { - @apply dark:border-gray-700 black:border-gray-800; -} - -.react-datepicker__day-name, -.react-datepicker__day, -.react-datepicker__time-name { - @apply text-gray-900 dark:text-gray-300; - width: 30px; - height: 30px; - line-height: 30px; -} - -.react-datepicker__time-list-item--disabled, -.react-datepicker__day--disabled { - @apply text-gray-400 dark:text-gray-500; -} - -.react-datepicker__day:hover, -.react-datepicker__month-text:hover, -.react-datepicker__quarter-text:hover, -.react-datepicker__year-text:hover, -.react-datepicker__time-list-item:hover { - @apply bg-gray-100 dark:bg-gray-700 rounded; -} - -.react-datepicker__day--selected, -.react-datepicker__day--in-selecting-range, -.react-datepicker__day--in-range, -.react-datepicker__month-text--selected, -.react-datepicker__month-text--in-selecting-range, -.react-datepicker__month-text--in-range, -.react-datepicker__quarter-text--selected, -.react-datepicker__quarter-text--in-selecting-range, -.react-datepicker__quarter-text--in-range, -.react-datepicker__year-text--selected, -.react-datepicker__year-text--in-selecting-range, -.react-datepicker__year-text--in-range { - @apply bg-primary-600 hover:bg-primary-700 dark:bg-gray-300 dark:hover:bg-gray-200 text-white dark:text-black rounded; -} - -.react-datepicker__day--keyboard-selected, -.react-datepicker__month-text--keyboard-selected, -.react-datepicker__quarter-text--keyboard-selected, -.react-datepicker__year-text--keyboard-selected { - @apply bg-primary-50 hover:bg-primary-100 dark:bg-gray-700 dark:hover:bg-gray-600 text-primary-600 dark:text-primary-400; -} - -.react-datepicker__close-icon { - @apply rtl:left-0 rtl:right-auto rtl:pr-0 rtl:pl-[6px]; -} - -.react-datepicker__close-icon::after { - @apply bg-transparent text-gray-600 dark:text-gray-400 text-base; - font-family: 'Font Awesome 5 Free'; - content: ''; - font-weight: 900; -} diff --git a/yarn.lock b/yarn.lock index 16d273518..3318d8cbd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1948,11 +1948,6 @@ "@parcel/watcher-win32-ia32" "2.4.1" "@parcel/watcher-win32-x64" "2.4.1" -"@popperjs/core@^2.9.2": - version "2.11.5" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" - integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw== - "@reach/auto-id@0.18.0": version "0.18.0" resolved "https://registry.yarnpkg.com/@reach/auto-id/-/auto-id-0.18.0.tgz#4b97085cd1cf1360a9bedc6e9c78e97824014f0d" @@ -2648,16 +2643,6 @@ "@types/react" "*" "@types/reactcss" "*" -"@types/react-datepicker@^4.4.2": - version "4.4.2" - resolved "https://registry.yarnpkg.com/@types/react-datepicker/-/react-datepicker-4.4.2.tgz#13ab25a5fff7f3da4c5380c471efd8b38f53010e" - integrity sha512-g8DhWvYmaIMLzVrIEVLXncylyImyBaoPsEUr3yR13JDaaHoebhDorqnVv4tLkNGa8SjBB8SAOQvxD5jaPNBX8A== - dependencies: - "@popperjs/core" "^2.9.2" - "@types/react" "*" - date-fns "^2.0.1" - react-popper "^2.2.5" - "@types/react-dom@^18.0.0", "@types/react-dom@^18.3.0": version "18.3.0" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0" @@ -3705,7 +3690,7 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== -classnames@^2.2.5, classnames@^2.2.6: +classnames@^2.2.5: version "2.3.1" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== @@ -4057,11 +4042,6 @@ data-urls@^5.0.0: whatwg-mimetype "^4.0.0" whatwg-url "^14.0.0" -date-fns@^2.0.1, date-fns@^2.24.0: - version "2.28.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" - integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== - debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.6, debug@^4.3.7: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" @@ -7232,18 +7212,6 @@ react-color@^2.19.3: reactcss "^1.2.0" tinycolor2 "^1.4.1" -react-datepicker@^4.8.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-4.8.0.tgz#11b8918d085a1ce4781eee4c8e4641b3cd592010" - integrity sha512-u69zXGHMpxAa4LeYR83vucQoUCJQ6m/WBsSxmUMu/M8ahTSVMMyiyQzauHgZA2NUr9y0FUgOAix71hGYUb6tvg== - dependencies: - "@popperjs/core" "^2.9.2" - classnames "^2.2.6" - date-fns "^2.24.0" - prop-types "^15.7.2" - react-onclickoutside "^6.12.0" - react-popper "^2.2.5" - react-dom@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" @@ -7275,7 +7243,7 @@ react-event-listener@^0.6.0: prop-types "^15.6.0" warning "^4.0.1" -react-fast-compare@^3.0.1, react-fast-compare@^3.1.1: +react-fast-compare@^3.1.1: version "3.2.0" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== @@ -7349,11 +7317,6 @@ react-motion@^0.5.2: prop-types "^15.5.8" raf "^3.1.0" -react-onclickoutside@^6.12.0: - version "6.12.1" - resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.12.1.tgz#92dddd28f55e483a1838c5c2930e051168c1e96b" - integrity sha512-a5Q7CkWznBRUWPmocCvE8b6lEYw1s6+opp/60dCunhO+G6E4tDTO2Sd2jKE+leEnnrLAE2Wj5DlDHNqj5wPv1Q== - react-overlays@^0.9.0: version "0.9.3" resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.9.3.tgz#5bac8c1e9e7e057a125181dee2d784864dd62902" @@ -7366,14 +7329,6 @@ react-overlays@^0.9.0: react-transition-group "^2.2.1" warning "^3.0.0" -react-popper@^2.2.5: - version "2.3.0" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba" - integrity sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q== - dependencies: - react-fast-compare "^3.0.1" - warning "^4.0.2" - react-property@2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/react-property/-/react-property-2.0.2.tgz#d5ac9e244cef564880a610bc8d868bd6f60fdda6" @@ -8938,7 +8893,7 @@ warning@^3.0.0: dependencies: loose-envify "^1.0.0" -warning@^4.0.0, warning@^4.0.1, warning@^4.0.2: +warning@^4.0.0, warning@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==