@contentful/field-editor-date 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),n=e(t),a=require("@contentful/f36-components"),r=e(require("@contentful/f36-tokens")),l=require("@contentful/field-editor-shared"),i=require("emotion"),u=e(require("moment"));function o(){return(o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e}).apply(this,arguments)}var s={root:i.css({maxWidth:"270px"})},m=function(e){var r,l=t.useMemo((function(){var e=new Date;e.setFullYear(e.getFullYear()-100);var t=new Date;return t.setFullYear(t.getFullYear()+100),[e,t]}),[]),i=l[0],o=l[1],m=null==(r=e.value)?void 0:r.toObject(),c=m?new Date(m.years,m.months,m.date):void 0;return n.createElement(a.Datepicker,{className:s.root,selected:c,onSelect:function(t){var n=t?u(t):void 0;e.onChange(n)},inputProps:{isDisabled:e.disabled,placeholder:""},fromDate:i,toDate:o})},c=["hh:mm a","hh:mm A","h:mm a","h:mm A","hh:mm","k:mm","kk:mm","h a","h A","h","hh","HH"],d=function(){return u("12:00 AM","hh:mm A")},f=function(e,t){return t.format(e?"hh:mm A":"HH:mm")},v=function(e){var r=e.disabled,l=e.uses12hClock,o=e.time,s=void 0===o?"12:00":o,m=e.ampm,v=void 0===m?"AM":m,h=e.onChange,p=t.useState((function(){return f(l,d())})),b=p[0],g=p[1];t.useEffect((function(){g(f(l,u(s+" "+v,"hh:mm A")))}),[s,v,l]);var C=t.useCallback((function(e){g(e.currentTarget.value)}),[]),D=t.useCallback((function(e){e.preventDefault(),e.target.select()}),[]);return n.createElement(a.Flex,{className:i.css({width:"145px"})},n.createElement(a.TextInput,{"aria-label":"Select time",placeholder:l?"12:00 AM":"00:00","date-time-type":l?"12":"24",testId:"time-input",value:b,isDisabled:r,onFocus:D,onBlur:function(){var e=function(e){for(var t=null,n=0;n<c.length;n++){var a=u(e,c[n]);if(a.isValid()){t=a;break}}return t}(b),t=null!=e?e:d();g(f(l,t)),h({time:t.format("hh:mm"),ampm:t.format("A")})},onChange:C}))},h=["-12:00","-11:00","-10:00","-09:30","-09:00","-08:00","-07:00","-06:00","-05:00","-04:30","-04:00","-03:30","-03:00","-02:00","-01:00","+00:00","+01:00","+02:00","+03:00","+03:30","+04:00","+04:30","+05:00","+05:30","+05:45","+06:00","+06:30","+07:00","+08:00","+08:45","+09:00","+09:30","+10:00","+10:30","+11:00","+11:30","+12:00","+12:45","+13:00","+14:00"],p=function(e){var t=e.onChange,r=e.value;return n.createElement(a.Select,{"aria-label":"Select timezone",testId:"timezone-input",value:void 0===r?"+00:00":r,isDisabled:e.disabled,onChange:function(e){t(e.currentTarget.value)}},h.map((function(e){return n.createElement(a.Select.Option,{key:e,value:e},"UTC",e)})))},b=/(Z|[+-]\d{2}[:+]?\d{2})$/;function g(){return u().set({hours:0,minutes:0}).format("Z")}var C={root:i.css({display:"flex",alignItems:"center"}),separator:i.css({marginLeft:r.spacingM})};function D(e){var n,r,l,i=e.initialValue,u=e.usesTime,s=e.usesTimezone,c=e.uses12hClock,d=e.disabled,f=e.hasClear,h=e.onChange,b=t.useState((function(){return i})),D=b[0],E=b[1];return n=function(){h(D)},r=[D],l=t.useRef(!0),t.useEffect((function(){l.current?l.current=!1:n()}),r),t.createElement("div",{"data-test-id":"date-editor",className:C.root},t.createElement(m,{disabled:d,value:D.date,onChange:function(e){E((function(t){return o({},t,{date:e})}))}}),u&&t.createElement(t.Fragment,null,t.createElement("div",{className:C.separator}),t.createElement(v,{disabled:d,time:D.time,ampm:D.ampm,onChange:function(e){var t=e.time,n=e.ampm;E((function(e){return o({},e,{time:t,ampm:n})}))},uses12hClock:c})),s&&t.createElement(t.Fragment,null,t.createElement("div",{className:C.separator}),t.createElement(p,{disabled:d,value:D.utcOffset,onChange:function(e){E((function(t){return o({},t,{utcOffset:e})}))}})),f&&t.createElement(t.Fragment,null,t.createElement("div",{className:C.separator}),t.createElement(a.TextLink,{as:"button",isDisabled:d,testId:"date-clear",onClick:function(){E({date:void 0,time:void 0,ampm:"AM",utcOffset:g()})}},"Clear")))}function E(e){var n,a,r,i,o=e.parameters,s=null!=(n=null==o||null==(a=o.instance)?void 0:a.format)?n:"timeZ",m=null!=(r=null==o||null==(i=o.instance)?void 0:i.ampm)?r:"24",c="dateonly"!==s,d="timeZ"===s,f="12"===m;return t.createElement(l.FieldConnector,{field:e.field,isInitiallyDisabled:e.isInitiallyDisabled,throttle:0},(function(n){var a,r=n.value,l=n.disabled,i=n.setValue,o=n.externalReset,s=function(e){var t=e.uses12hClock,n=function(e){if(!e)return null;var t=u(e);return b.test(e)&&t.utcOffset(e),t}(e.value);return n?{date:n,time:n.format(t?"hh:mm":"HH:mm"),ampm:n.format("A"),utcOffset:n.format("Z")}:{ampm:"AM",utcOffset:g()}}({value:r,uses12hClock:f});return t.createElement(D,{initialValue:s,uses12hClock:f,usesTimezone:d,usesTime:c,disabled:null!=(a=e.isDisabled)?a:l,hasClear:Boolean(r),onChange:function(e){var t=function(e){var t=e.usesTime,n=e.usesTimezone,a=function(e){if(!e.date)return{valid:null};var t=function(e){return u.utc((e.time||"00:00")+"!"+e.ampm,"HH:mm!A")}(e),n=u.parseZone(e.utcOffset,"Z").set(e.date.toObject()).set({hours:t.hours(),minutes:t.minutes()});return n.isValid()?{valid:n}:{invalid:!0,valid:null}}(e.data);return a.invalid?{invalid:!0}:{valid:null!=a&&a.valid?a.valid.format(n?"YYYY-MM-DDTHH:mmZ":t?"YYYY-MM-DDTHH:mm":"YYYY-MM-DD"):null,invalid:!1}}({data:e,usesTime:c,usesTimezone:d});t.invalid||(Boolean(r)||!r&&Boolean(t.valid))&&i(t.valid)},key:"date-container-"+o})}))}E.defaultProps={isInitiallyDisabled:!0},exports.DateEditor=E,exports.zoneOffsets=h;
1
+ "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),a=e(t),n=require("@contentful/f36-components"),l=e(require("@contentful/f36-tokens")),s=require("@contentful/field-editor-shared"),i=require("emotion"),r=e(require("moment"));const o={root:i.css({maxWidth:"270px"})},m=e=>{var l;const[s,i]=t.useMemo(()=>{const e=new Date;e.setFullYear(e.getFullYear()-100);const t=new Date;return t.setFullYear(t.getFullYear()+100),[e,t]},[]),m=null==(l=e.value)?void 0:l.toObject(),u=m?new Date(m.years,m.months,m.date):void 0;return a.createElement(n.Datepicker,{className:o.root,selected:u,onSelect:t=>{const a=t?r(t):void 0;e.onChange(a)},inputProps:{isDisabled:e.disabled,placeholder:""},fromDate:s,toDate:i})},u=["hh:mm a","hh:mm A","h:mm a","h:mm A","hh:mm","k:mm","kk:mm","h a","h A","h","hh","HH"],c=()=>r("12:00 AM","hh:mm A"),d=(e,t)=>t.format(e?"hh:mm A":"HH:mm"),f=({disabled:e,uses12hClock:l,time:s="12:00",ampm:o="AM",onChange:m})=>{const[f,h]=t.useState(()=>d(l,c()));t.useEffect(()=>{h(d(l,r(`${s} ${o}`,"hh:mm A")))},[s,o,l]);const v=t.useCallback(e=>{h(e.currentTarget.value)},[]),p=t.useCallback(e=>{e.preventDefault(),e.target.select()},[]);return a.createElement(n.Flex,{className:i.css({width:"145px"})},a.createElement(n.TextInput,{"aria-label":"Select time",placeholder:l?"12:00 AM":"00:00","date-time-type":l?"12":"24",testId:"time-input",value:f,isDisabled:e,onFocus:p,onBlur:()=>{const e=function(e){let t=null;for(let a=0;a<u.length;a++){const n=r(e,u[a]);if(n.isValid()){t=n;break}}return t}(f)??c();h(d(l,e)),m({time:e.format("hh:mm"),ampm:e.format("A")})},onChange:v}))},h=["-12:00","-11:00","-10:00","-09:30","-09:00","-08:00","-07:00","-06:00","-05:00","-04:30","-04:00","-03:30","-03:00","-02:00","-01:00","+00:00","+01:00","+02:00","+03:00","+03:30","+04:00","+04:30","+05:00","+05:30","+05:45","+06:00","+06:30","+07:00","+08:00","+08:45","+09:00","+09:30","+10:00","+10:30","+11:00","+11:30","+12:00","+12:45","+13:00","+14:00"],v=({disabled:e,onChange:t,value:l="+00:00"})=>a.createElement(n.Select,{"aria-label":"Select timezone",testId:"timezone-input",value:l,isDisabled:e,onChange:e=>{t(e.currentTarget.value)}},h.map(e=>a.createElement(n.Select.Option,{key:e,value:e},"UTC",e))),p=/(Z|[+-]\d{2}[:+]?\d{2})$/;function b(){return r().set({hours:0,minutes:0}).format("Z")}const C={root:i.css({display:"flex",alignItems:"center"}),separator:i.css({marginLeft:l.spacingM})};function D({initialValue:e,usesTime:a,usesTimezone:l,uses12hClock:s,disabled:i,hasClear:r,onChange:o}){const[u,c]=t.useState(()=>e);return function(e,a){const n=t.useRef(!0);t.useEffect(()=>{n.current?n.current=!1:o(u)},a)}(0,[u]),t.createElement("div",{"data-test-id":"date-editor",className:C.root},t.createElement(m,{disabled:i,value:u.date,onChange:e=>{c(t=>({...t,date:e}))}}),a&&t.createElement(t.Fragment,null,t.createElement("div",{className:C.separator}),t.createElement(f,{disabled:i,time:u.time,ampm:u.ampm,onChange:({time:e,ampm:t})=>{c(a=>({...a,time:e,ampm:t}))},uses12hClock:s})),l&&t.createElement(t.Fragment,null,t.createElement("div",{className:C.separator}),t.createElement(v,{disabled:i,value:u.utcOffset,onChange:e=>{c(t=>({...t,utcOffset:e}))}})),r&&t.createElement(t.Fragment,null,t.createElement("div",{className:C.separator}),t.createElement(n.TextLink,{as:"button",isDisabled:i,testId:"date-clear",onClick:()=>{c({date:void 0,time:void 0,ampm:"AM",utcOffset:b()})}},"Clear")))}function g(e){var a,n;const{field:l,parameters:i}=e,o=(null==i||null==(a=i.instance)?void 0:a.format)??"timeZ",m=(null==i||null==(n=i.instance)?void 0:n.ampm)??"24",u="dateonly"!==o,c="timeZ"===o,d="12"===m;return t.createElement(s.FieldConnector,{field:l,isInitiallyDisabled:e.isInitiallyDisabled,isDisabled:e.isDisabled,throttle:0},({value:e,disabled:a,setValue:n,externalReset:l})=>{const s=function({value:e,uses12hClock:t}){const a=function(e){if(!e)return null;const t=r(e);return p.test(e)&&t.utcOffset(e),t}(e);return a?{date:a,time:a.format(t?"hh:mm":"HH:mm"),ampm:a.format("A"),utcOffset:a.format("Z")}:{ampm:"AM",utcOffset:b()}}({value:e,uses12hClock:d});return t.createElement(D,{initialValue:s,uses12hClock:d,usesTimezone:c,usesTime:u,disabled:a,hasClear:Boolean(e),onChange:t=>{const a=function({data:e,usesTime:t,usesTimezone:a}){const n=function(e){if(!e.date)return{valid:null};const t=function(e){return r.utc((e.time||"00:00")+"!"+e.ampm,"HH:mm!A")}(e),a=r.parseZone(e.utcOffset,"Z").set(e.date.toObject()).set({hours:t.hours(),minutes:t.minutes()});return a.isValid()?{valid:a}:{invalid:!0,valid:null}}(e);if(n.invalid)return{invalid:!0};let l;return l=a?"YYYY-MM-DDTHH:mmZ":t?"YYYY-MM-DDTHH:mm":"YYYY-MM-DD",{valid:null!=n&&n.valid?n.valid.format(l):null,invalid:!1}}({data:t,usesTime:u,usesTimezone:c});a.invalid||(Boolean(e)||!e&&Boolean(a.valid))&&n(a.valid)},key:"date-container-"+l})})}g.defaultProps={isInitiallyDisabled:!0},exports.DateEditor=g,exports.zoneOffsets=h;
2
2
  //# sourceMappingURL=field-editor-date.cjs.production.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"field-editor-date.cjs.production.min.js","sources":["../src/DatepickerInput.tsx","../src/TimepickerInput.tsx","../src/utils/zoneOffsets.ts","../src/TimezonePickerInput.tsx","../src/utils/date.ts","../src/DateEditor.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\n\nimport { Datepicker } from '@contentful/f36-components';\nimport { css } from 'emotion';\n// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\n\nconst YEAR_RANGE = 100;\n\nconst styles = {\n root: css({\n maxWidth: '270px',\n }),\n};\n\nexport type DatePickerProps = {\n value?: moment.Moment;\n onChange: (val: moment.Moment | undefined) => void;\n disabled?: boolean;\n};\n\nexport const DatepickerInput = (props: DatePickerProps) => {\n const [fromDate, toDate] = useMemo(() => {\n const fromDate = new Date();\n fromDate.setFullYear(fromDate.getFullYear() - YEAR_RANGE);\n const toDate = new Date();\n toDate.setFullYear(toDate.getFullYear() + YEAR_RANGE);\n\n return [fromDate, toDate];\n }, []);\n\n // The DatepickerInput should be time and timezone agnostic,\n // thats why we don't use moment().toDate() to get Date object.\n // moment().toDate() takes into account time and timezone and converts it\n // based on your system timezone which can result in the date change.\n // e.g. if user has a timezone +02:00, moment('2022-09-16T00:00+04:00').toDate()\n // will return September 15 instead of September 16\n const dateObj = props.value?.toObject();\n const selectedDate = dateObj ? new Date(dateObj.years, dateObj.months, dateObj.date) : undefined;\n\n return (\n <Datepicker\n className={styles.root}\n selected={selectedDate}\n onSelect={(day) => {\n const momentDay = day ? moment(day) : undefined;\n props.onChange(momentDay);\n }}\n inputProps={{ isDisabled: props.disabled, placeholder: '' }}\n fromDate={fromDate}\n toDate={toDate}\n />\n );\n};\n","import React, { useState, useCallback, useEffect } from 'react';\n// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\nimport { css } from 'emotion';\n\nimport { TextInput, Flex } from '@contentful/f36-components';\n\nexport type TimepickerProps = {\n disabled: boolean;\n uses12hClock: boolean;\n onChange: (value: { time: string; ampm: string }) => void;\n time?: string;\n ampm?: string;\n};\n\nconst validInputFormats = [\n 'hh:mm a',\n 'hh:mm A',\n 'h:mm a',\n 'h:mm A',\n 'hh:mm',\n 'k:mm',\n 'kk:mm',\n 'h a',\n 'h A',\n 'h',\n 'hh',\n 'HH',\n];\n\nfunction parseRawInput(raw: string): moment.Moment | null {\n let time: moment.Moment | null = null;\n\n // eslint-disable-next-line -- TODO: refactor to use for of loop\n for (let i = 0; i < validInputFormats.length; i++) {\n const date = moment(raw, validInputFormats[i]);\n if (date.isValid()) {\n time = date;\n break;\n }\n }\n\n return time;\n}\n\nconst getDefaultTime = () => {\n return moment(`12:00 AM`, 'hh:mm A');\n};\n\nconst formatToString = (uses12hClock: boolean, value: moment.Moment): string => {\n return uses12hClock ? value.format('hh:mm A') : value.format('HH:mm');\n};\n\nexport const TimepickerInput = ({\n disabled,\n uses12hClock,\n time = '12:00',\n ampm = 'AM',\n onChange,\n}: TimepickerProps) => {\n const [selectedTime, setSelectedTime] = useState<string>(() => {\n return formatToString(uses12hClock, getDefaultTime());\n });\n\n useEffect(() => {\n setSelectedTime(formatToString(uses12hClock, moment(`${time} ${ampm}`, 'hh:mm A')));\n }, [time, ampm, uses12hClock]);\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n setSelectedTime(e.currentTarget.value);\n }, []);\n\n const handleFocus = useCallback((e) => {\n e.preventDefault();\n e.target.select();\n }, []);\n\n const handleBlur = () => {\n const parsedTime = parseRawInput(selectedTime);\n const value = parsedTime ?? getDefaultTime();\n setSelectedTime(formatToString(uses12hClock, value));\n onChange({ time: value.format('hh:mm'), ampm: value.format('A') });\n };\n\n return (\n <Flex className={css({ width: '145px' })}>\n <TextInput\n aria-label=\"Select time\"\n placeholder={uses12hClock ? '12:00 AM' : '00:00'}\n date-time-type={uses12hClock ? '12' : '24'}\n testId=\"time-input\"\n value={selectedTime}\n isDisabled={disabled}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n />\n </Flex>\n );\n};\n","export const defaultZoneOffset = '+00:00';\n\nexport const zoneOffsets = [\n '-12:00',\n '-11:00',\n '-10:00',\n '-09:30',\n '-09:00',\n '-08:00',\n '-07:00',\n '-06:00',\n '-05:00',\n '-04:30',\n '-04:00',\n '-03:30',\n '-03:00',\n '-02:00',\n '-01:00',\n '+00:00',\n '+01:00',\n '+02:00',\n '+03:00',\n '+03:30',\n '+04:00',\n '+04:30',\n '+05:00',\n '+05:30',\n '+05:45',\n '+06:00',\n '+06:30',\n '+07:00',\n '+08:00',\n '+08:45',\n '+09:00',\n '+09:30',\n '+10:00',\n '+10:30',\n '+11:00',\n '+11:30',\n '+12:00',\n '+12:45',\n '+13:00',\n '+14:00',\n];\n","import React, { ChangeEvent } from 'react';\nimport { zoneOffsets, defaultZoneOffset } from './utils/zoneOffsets';\n\nimport { Select } from '@contentful/f36-components';\n\nexport type TimezonepickerProps = {\n disabled: boolean;\n onChange: (value: string) => void;\n value?: string;\n};\nexport const TimezonepickerInput = ({\n disabled,\n onChange,\n value = defaultZoneOffset,\n}: TimezonepickerProps) => {\n return (\n <Select\n aria-label=\"Select timezone\"\n testId=\"timezone-input\"\n value={value}\n isDisabled={disabled}\n onChange={(e: ChangeEvent<HTMLSelectElement>) => {\n onChange(e.currentTarget.value);\n }}>\n {zoneOffsets.map((offset) => (\n <Select.Option key={offset} value={offset}>\n UTC{offset}\n </Select.Option>\n ))}\n </Select>\n );\n};\n","// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\nimport { TimeResult } from '../types';\n\nconst ZONE_RX = /(Z|[+-]\\d{2}[:+]?\\d{2})$/;\n\nfunction startOfToday(format: string) {\n return moment().set({ hours: 0, minutes: 0 }).format(format);\n}\n\nfunction fieldValueToMoment(datetimeString: string | null | undefined): moment.Moment | null {\n if (!datetimeString) {\n return null;\n }\n\n const datetime = moment(datetimeString);\n if (ZONE_RX.test(datetimeString)) {\n datetime.utcOffset(datetimeString);\n }\n return datetime;\n}\n\nfunction timeFromUserInput(input: TimeResult) {\n const timeInput = input.time || '00:00';\n return moment.utc(timeInput + '!' + input.ampm, 'HH:mm!A');\n}\n\n/**\n * Convert the user input object into either a 'moment' value or an\n * invalid symbol.\n *\n * Success is indicated by returning '{valid: value}' and failure is\n * indicated by returning '{invalid: true}'. If 'input.date' is\n * 'null' we return '{valid: null}'\n */\nfunction datetimeFromUserInput(input: TimeResult): {\n invalid?: boolean;\n valid: moment.Moment | null;\n} {\n if (!input.date) {\n return { valid: null };\n }\n\n const time = timeFromUserInput(input);\n\n const date = moment\n .parseZone(input.utcOffset, 'Z')\n .set(input.date.toObject())\n .set({ hours: time.hours(), minutes: time.minutes() });\n\n if (date.isValid()) {\n return { valid: date };\n } else {\n return { invalid: true, valid: null };\n }\n}\n\n/**\n * Parse user input into a string that is stored in the API.\n *\n * Returns a sum type with either the string as the `valid` property\n * or the `invalid` property set to `false`.\n */\nexport function buildFieldValue({\n data,\n usesTime,\n usesTimezone,\n}: {\n data: TimeResult;\n usesTime: boolean;\n usesTimezone: boolean;\n}) {\n const date = datetimeFromUserInput(data);\n if (date.invalid) {\n return {\n invalid: true,\n };\n }\n\n let format;\n if (usesTimezone) {\n format = 'YYYY-MM-DDTHH:mmZ';\n } else if (usesTime) {\n format = 'YYYY-MM-DDTHH:mm';\n } else {\n format = 'YYYY-MM-DD';\n }\n return { valid: date?.valid ? date.valid.format(format) : null, invalid: false };\n}\n\nexport function getDefaultAMPM() {\n return 'AM';\n}\n\nexport function getDefaultUtcOffset() {\n return startOfToday('Z');\n}\n\n/**\n * Create the user input object from the field value.\n */\nexport function userInputFromDatetime({\n value,\n uses12hClock,\n}: {\n value: string | undefined | null;\n uses12hClock: boolean;\n}): TimeResult {\n const datetime = fieldValueToMoment(value);\n\n if (datetime) {\n const timeFormat = uses12hClock ? 'hh:mm' : 'HH:mm';\n return {\n date: datetime,\n time: datetime.format(timeFormat),\n ampm: datetime.format('A'),\n utcOffset: datetime.format('Z'),\n };\n } else {\n return {\n ampm: getDefaultAMPM(),\n utcOffset: getDefaultUtcOffset(),\n };\n }\n}\n","import * as React from 'react';\n\nimport { TextLink } from '@contentful/f36-components';\nimport tokens from '@contentful/f36-tokens';\nimport { FieldAPI, FieldConnector, ParametersAPI } from '@contentful/field-editor-shared';\nimport { css } from 'emotion';\n\nimport { DatepickerInput } from './DatepickerInput';\nimport { TimepickerInput } from './TimepickerInput';\nimport { TimezonepickerInput } from './TimezonePickerInput';\nimport { TimeFormat, DateTimeFormat, TimeResult } from './types';\nimport {\n userInputFromDatetime,\n buildFieldValue,\n getDefaultAMPM,\n getDefaultUtcOffset,\n} from './utils/date';\n\n\nexport interface DateEditorProps {\n /**\n * is the field disabled initially\n */\n isInitiallyDisabled: boolean;\n\n /*\n * is the field manually disabled\n */\n isDisabled?: boolean;\n\n /**\n * sdk.field\n */\n field: FieldAPI;\n\n /**\n * sdk.parameters\n */\n parameters?: ParametersAPI & {\n instance?: {\n format?: DateTimeFormat;\n ampm?: TimeFormat;\n };\n };\n}\n\nconst styles = {\n root: css({\n display: 'flex',\n alignItems: 'center',\n }),\n separator: css({\n marginLeft: tokens.spacingM,\n }),\n};\n\nfunction useEffectWithoutFirstRender(callback: Function, deps: Array<any>) {\n const isFirstRun = React.useRef(true);\n React.useEffect(() => {\n if (isFirstRun.current) {\n isFirstRun.current = false;\n return;\n }\n callback();\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies\n }, deps);\n}\n\nfunction DateEditorContainer({\n initialValue,\n usesTime,\n usesTimezone,\n uses12hClock,\n disabled,\n hasClear,\n onChange,\n}: {\n initialValue: TimeResult;\n usesTime: boolean;\n usesTimezone: boolean;\n uses12hClock: boolean;\n disabled: boolean;\n hasClear: boolean;\n onChange: (value: TimeResult) => void;\n}) {\n const [value, setValue] = React.useState<TimeResult>(() => initialValue);\n\n useEffectWithoutFirstRender(() => {\n onChange(value);\n }, [value]);\n\n return (\n <div data-test-id=\"date-editor\" className={styles.root}>\n <DatepickerInput\n disabled={disabled}\n value={value.date}\n onChange={(date) => {\n setValue((value) => ({\n ...value,\n date,\n }));\n }}\n />\n {usesTime && (\n <>\n <div className={styles.separator} />\n <TimepickerInput\n disabled={disabled}\n time={value.time}\n ampm={value.ampm}\n onChange={({ time, ampm }) => {\n setValue((value) => ({\n ...value,\n time,\n ampm,\n }));\n }}\n uses12hClock={uses12hClock}\n />\n </>\n )}\n {usesTimezone && (\n <>\n <div className={styles.separator} />\n <TimezonepickerInput\n disabled={disabled}\n value={value.utcOffset}\n onChange={(utcOffset) => {\n setValue((value) => ({\n ...value,\n utcOffset,\n }));\n }}\n />\n </>\n )}\n {hasClear && (\n <>\n <div className={styles.separator} />\n <TextLink\n as=\"button\"\n isDisabled={disabled}\n testId=\"date-clear\"\n onClick={() => {\n setValue({\n date: undefined,\n time: undefined,\n ampm: getDefaultAMPM(),\n utcOffset: getDefaultUtcOffset(),\n });\n }}\n >\n Clear\n </TextLink>\n </>\n )}\n </div>\n );\n}\n\nexport function DateEditor(props: DateEditorProps) {\n const { field, parameters } = props;\n\n const formatParam = parameters?.instance?.format ?? 'timeZ';\n const ampmParam = parameters?.instance?.ampm ?? '24';\n\n const usesTime = formatParam !== 'dateonly';\n const usesTimezone = formatParam === 'timeZ';\n const uses12hClock = ampmParam === '12';\n\n return (\n <FieldConnector<string>\n field={field}\n isInitiallyDisabled={props.isInitiallyDisabled}\n throttle={0}\n >\n {({ value, disabled, setValue, externalReset }) => {\n const datetimeValue = userInputFromDatetime({\n value,\n uses12hClock,\n });\n return (\n <DateEditorContainer\n initialValue={datetimeValue}\n uses12hClock={uses12hClock}\n usesTimezone={usesTimezone}\n usesTime={usesTime}\n disabled={props.isDisabled ?? disabled}\n hasClear={Boolean(value)}\n onChange={(data) => {\n const fieldValue = buildFieldValue({ data, usesTime, usesTimezone });\n if (fieldValue.invalid) {\n return;\n }\n // if value is present - then override it with a new one\n // if value is not present - then set a new one if it's not nullable only\n if (Boolean(value) || (!value && Boolean(fieldValue.valid))) {\n setValue(fieldValue.valid);\n }\n }}\n key={`date-container-${externalReset}`}\n />\n );\n }}\n </FieldConnector>\n );\n}\n\nDateEditor.defaultProps = {\n isInitiallyDisabled: true,\n};\n"],"names":["styles","root","css","maxWidth","DatepickerInput","props","useMemo","fromDate","Date","setFullYear","getFullYear","toDate","dateObj","value","_props$value","toObject","selectedDate","years","months","date","undefined","React","Datepicker","className","selected","onSelect","day","momentDay","moment","onChange","inputProps","isDisabled","disabled","placeholder","validInputFormats","getDefaultTime","formatToString","uses12hClock","format","TimepickerInput","time","ampm","useState","selectedTime","setSelectedTime","useEffect","handleChange","useCallback","e","currentTarget","handleFocus","preventDefault","target","select","Flex","width","TextInput","testId","onFocus","onBlur","parsedTime","raw","i","length","isValid","parseRawInput","zoneOffsets","TimezonepickerInput","Select","map","offset","Option","key","ZONE_RX","getDefaultUtcOffset","set","hours","minutes","display","alignItems","separator","marginLeft","tokens","spacingM","DateEditorContainer","callback","deps","isFirstRun","initialValue","usesTime","usesTimezone","hasClear","setValue","current","utcOffset","TextLink","as","onClick","DateEditor","parameters","formatParam","instance","_parameters$instance","ampmParam","_parameters$instance2","FieldConnector","field","isInitiallyDisabled","throttle","externalReset","datetimeValue","datetime","datetimeString","test","fieldValueToMoment","userInputFromDatetime","Boolean","data","fieldValue","input","valid","utc","timeFromUserInput","parseZone","invalid","datetimeFromUserInput","buildFieldValue","defaultProps"],"mappings":"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"}
1
+ {"version":3,"file":"field-editor-date.cjs.production.min.js","sources":["../src/DatepickerInput.tsx","../src/TimepickerInput.tsx","../src/utils/zoneOffsets.ts","../src/TimezonePickerInput.tsx","../src/utils/date.ts","../src/DateEditor.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\n\nimport { Datepicker } from '@contentful/f36-components';\nimport { css } from 'emotion';\n// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\n\nconst YEAR_RANGE = 100;\n\nconst styles = {\n root: css({\n maxWidth: '270px',\n }),\n};\n\nexport type DatePickerProps = {\n value?: moment.Moment;\n onChange: (val: moment.Moment | undefined) => void;\n disabled?: boolean;\n};\n\nexport const DatepickerInput = (props: DatePickerProps) => {\n const [fromDate, toDate] = useMemo(() => {\n const fromDate = new Date();\n fromDate.setFullYear(fromDate.getFullYear() - YEAR_RANGE);\n const toDate = new Date();\n toDate.setFullYear(toDate.getFullYear() + YEAR_RANGE);\n\n return [fromDate, toDate];\n }, []);\n\n // The DatepickerInput should be time and timezone agnostic,\n // thats why we don't use moment().toDate() to get Date object.\n // moment().toDate() takes into account time and timezone and converts it\n // based on your system timezone which can result in the date change.\n // e.g. if user has a timezone +02:00, moment('2022-09-16T00:00+04:00').toDate()\n // will return September 15 instead of September 16\n const dateObj = props.value?.toObject();\n const selectedDate = dateObj ? new Date(dateObj.years, dateObj.months, dateObj.date) : undefined;\n\n return (\n <Datepicker\n className={styles.root}\n selected={selectedDate}\n onSelect={(day) => {\n const momentDay = day ? moment(day) : undefined;\n props.onChange(momentDay);\n }}\n inputProps={{ isDisabled: props.disabled, placeholder: '' }}\n fromDate={fromDate}\n toDate={toDate}\n />\n );\n};\n","import React, { useState, useCallback, useEffect } from 'react';\n\n// eslint-disable-next-line -- TODO: move to date-fns\nimport { TextInput, Flex } from '@contentful/f36-components';\nimport { css } from 'emotion';\n// eslint-disable-next-line no-restricted-imports -- will change\nimport moment from 'moment';\n\nexport type TimepickerProps = {\n disabled: boolean;\n uses12hClock: boolean;\n onChange: (value: { time: string; ampm: string }) => void;\n time?: string;\n ampm?: string;\n};\n\nconst validInputFormats = [\n 'hh:mm a',\n 'hh:mm A',\n 'h:mm a',\n 'h:mm A',\n 'hh:mm',\n 'k:mm',\n 'kk:mm',\n 'h a',\n 'h A',\n 'h',\n 'hh',\n 'HH',\n];\n\nfunction parseRawInput(raw: string): moment.Moment | null {\n let time: moment.Moment | null = null;\n\n // eslint-disable-next-line -- TODO: refactor to use for of loop\n for (let i = 0; i < validInputFormats.length; i++) {\n const date = moment(raw, validInputFormats[i]);\n if (date.isValid()) {\n time = date;\n break;\n }\n }\n\n return time;\n}\n\nconst getDefaultTime = () => {\n return moment(`12:00 AM`, 'hh:mm A');\n};\n\nconst formatToString = (uses12hClock: boolean, value: moment.Moment): string => {\n return uses12hClock ? value.format('hh:mm A') : value.format('HH:mm');\n};\n\nexport const TimepickerInput = ({\n disabled,\n uses12hClock,\n time = '12:00',\n ampm = 'AM',\n onChange,\n}: TimepickerProps) => {\n const [selectedTime, setSelectedTime] = useState<string>(() => {\n return formatToString(uses12hClock, getDefaultTime());\n });\n\n useEffect(() => {\n setSelectedTime(formatToString(uses12hClock, moment(`${time} ${ampm}`, 'hh:mm A')));\n }, [time, ampm, uses12hClock]);\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n setSelectedTime(e.currentTarget.value);\n }, []);\n\n const handleFocus = useCallback((e) => {\n e.preventDefault();\n e.target.select();\n }, []);\n\n const handleBlur = () => {\n const parsedTime = parseRawInput(selectedTime);\n const value = parsedTime ?? getDefaultTime();\n setSelectedTime(formatToString(uses12hClock, value));\n onChange({ time: value.format('hh:mm'), ampm: value.format('A') });\n };\n\n return (\n <Flex className={css({ width: '145px' })}>\n <TextInput\n aria-label=\"Select time\"\n placeholder={uses12hClock ? '12:00 AM' : '00:00'}\n date-time-type={uses12hClock ? '12' : '24'}\n testId=\"time-input\"\n value={selectedTime}\n isDisabled={disabled}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n />\n </Flex>\n );\n};\n","export const defaultZoneOffset = '+00:00';\n\nexport const zoneOffsets = [\n '-12:00',\n '-11:00',\n '-10:00',\n '-09:30',\n '-09:00',\n '-08:00',\n '-07:00',\n '-06:00',\n '-05:00',\n '-04:30',\n '-04:00',\n '-03:30',\n '-03:00',\n '-02:00',\n '-01:00',\n '+00:00',\n '+01:00',\n '+02:00',\n '+03:00',\n '+03:30',\n '+04:00',\n '+04:30',\n '+05:00',\n '+05:30',\n '+05:45',\n '+06:00',\n '+06:30',\n '+07:00',\n '+08:00',\n '+08:45',\n '+09:00',\n '+09:30',\n '+10:00',\n '+10:30',\n '+11:00',\n '+11:30',\n '+12:00',\n '+12:45',\n '+13:00',\n '+14:00',\n];\n","import React, { ChangeEvent } from 'react';\n\nimport { Select } from '@contentful/f36-components';\n\nimport { zoneOffsets, defaultZoneOffset } from './utils/zoneOffsets';\n\n\nexport type TimezonepickerProps = {\n disabled: boolean;\n onChange: (value: string) => void;\n value?: string;\n};\nexport const TimezonepickerInput = ({\n disabled,\n onChange,\n value = defaultZoneOffset,\n}: TimezonepickerProps) => {\n return (\n <Select\n aria-label=\"Select timezone\"\n testId=\"timezone-input\"\n value={value}\n isDisabled={disabled}\n onChange={(e: ChangeEvent<HTMLSelectElement>) => {\n onChange(e.currentTarget.value);\n }}>\n {zoneOffsets.map((offset) => (\n <Select.Option key={offset} value={offset}>\n UTC{offset}\n </Select.Option>\n ))}\n </Select>\n );\n};\n","// eslint-disable-next-line -- TODO: move to date-fns\nimport moment from 'moment';\nimport { TimeResult } from '../types';\n\nconst ZONE_RX = /(Z|[+-]\\d{2}[:+]?\\d{2})$/;\n\nfunction startOfToday(format: string) {\n return moment().set({ hours: 0, minutes: 0 }).format(format);\n}\n\nfunction fieldValueToMoment(datetimeString: string | null | undefined): moment.Moment | null {\n if (!datetimeString) {\n return null;\n }\n\n const datetime = moment(datetimeString);\n if (ZONE_RX.test(datetimeString)) {\n datetime.utcOffset(datetimeString);\n }\n return datetime;\n}\n\nfunction timeFromUserInput(input: TimeResult) {\n const timeInput = input.time || '00:00';\n return moment.utc(timeInput + '!' + input.ampm, 'HH:mm!A');\n}\n\n/**\n * Convert the user input object into either a 'moment' value or an\n * invalid symbol.\n *\n * Success is indicated by returning '{valid: value}' and failure is\n * indicated by returning '{invalid: true}'. If 'input.date' is\n * 'null' we return '{valid: null}'\n */\nfunction datetimeFromUserInput(input: TimeResult): {\n invalid?: boolean;\n valid: moment.Moment | null;\n} {\n if (!input.date) {\n return { valid: null };\n }\n\n const time = timeFromUserInput(input);\n\n const date = moment\n .parseZone(input.utcOffset, 'Z')\n .set(input.date.toObject())\n .set({ hours: time.hours(), minutes: time.minutes() });\n\n if (date.isValid()) {\n return { valid: date };\n } else {\n return { invalid: true, valid: null };\n }\n}\n\n/**\n * Parse user input into a string that is stored in the API.\n *\n * Returns a sum type with either the string as the `valid` property\n * or the `invalid` property set to `false`.\n */\nexport function buildFieldValue({\n data,\n usesTime,\n usesTimezone,\n}: {\n data: TimeResult;\n usesTime: boolean;\n usesTimezone: boolean;\n}) {\n const date = datetimeFromUserInput(data);\n if (date.invalid) {\n return {\n invalid: true,\n };\n }\n\n let format;\n if (usesTimezone) {\n format = 'YYYY-MM-DDTHH:mmZ';\n } else if (usesTime) {\n format = 'YYYY-MM-DDTHH:mm';\n } else {\n format = 'YYYY-MM-DD';\n }\n return { valid: date?.valid ? date.valid.format(format) : null, invalid: false };\n}\n\nexport function getDefaultAMPM() {\n return 'AM';\n}\n\nexport function getDefaultUtcOffset() {\n return startOfToday('Z');\n}\n\n/**\n * Create the user input object from the field value.\n */\nexport function userInputFromDatetime({\n value,\n uses12hClock,\n}: {\n value: string | undefined | null;\n uses12hClock: boolean;\n}): TimeResult {\n const datetime = fieldValueToMoment(value);\n\n if (datetime) {\n const timeFormat = uses12hClock ? 'hh:mm' : 'HH:mm';\n return {\n date: datetime,\n time: datetime.format(timeFormat),\n ampm: datetime.format('A'),\n utcOffset: datetime.format('Z'),\n };\n } else {\n return {\n ampm: getDefaultAMPM(),\n utcOffset: getDefaultUtcOffset(),\n };\n }\n}\n","import * as React from 'react';\n\nimport { TextLink } from '@contentful/f36-components';\nimport tokens from '@contentful/f36-tokens';\nimport { FieldAPI, FieldConnector, ParametersAPI } from '@contentful/field-editor-shared';\nimport { css } from 'emotion';\n\nimport { DatepickerInput } from './DatepickerInput';\nimport { TimepickerInput } from './TimepickerInput';\nimport { TimezonepickerInput } from './TimezonePickerInput';\nimport { TimeFormat, DateTimeFormat, TimeResult } from './types';\nimport {\n userInputFromDatetime,\n buildFieldValue,\n getDefaultAMPM,\n getDefaultUtcOffset,\n} from './utils/date';\n\nexport interface DateEditorProps {\n /**\n * is the field disabled initially\n */\n isInitiallyDisabled: boolean;\n\n /*\n * is the field manually disabled\n */\n isDisabled?: boolean;\n\n /**\n * sdk.field\n */\n field: FieldAPI;\n\n /**\n * sdk.parameters\n */\n parameters?: ParametersAPI & {\n instance?: {\n format?: DateTimeFormat;\n ampm?: TimeFormat;\n };\n };\n}\n\nconst styles = {\n root: css({\n display: 'flex',\n alignItems: 'center',\n }),\n separator: css({\n marginLeft: tokens.spacingM,\n }),\n};\n\nfunction useEffectWithoutFirstRender(callback: Function, deps: Array<any>) {\n const isFirstRun = React.useRef(true);\n React.useEffect(() => {\n if (isFirstRun.current) {\n isFirstRun.current = false;\n return;\n }\n callback();\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies\n }, deps);\n}\n\nfunction DateEditorContainer({\n initialValue,\n usesTime,\n usesTimezone,\n uses12hClock,\n disabled,\n hasClear,\n onChange,\n}: {\n initialValue: TimeResult;\n usesTime: boolean;\n usesTimezone: boolean;\n uses12hClock: boolean;\n disabled: boolean;\n hasClear: boolean;\n onChange: (value: TimeResult) => void;\n}) {\n const [value, setValue] = React.useState<TimeResult>(() => initialValue);\n\n useEffectWithoutFirstRender(() => {\n onChange(value);\n }, [value]);\n\n return (\n <div data-test-id=\"date-editor\" className={styles.root}>\n <DatepickerInput\n disabled={disabled}\n value={value.date}\n onChange={(date) => {\n setValue((value) => ({\n ...value,\n date,\n }));\n }}\n />\n {usesTime && (\n <>\n <div className={styles.separator} />\n <TimepickerInput\n disabled={disabled}\n time={value.time}\n ampm={value.ampm}\n onChange={({ time, ampm }) => {\n setValue((value) => ({\n ...value,\n time,\n ampm,\n }));\n }}\n uses12hClock={uses12hClock}\n />\n </>\n )}\n {usesTimezone && (\n <>\n <div className={styles.separator} />\n <TimezonepickerInput\n disabled={disabled}\n value={value.utcOffset}\n onChange={(utcOffset) => {\n setValue((value) => ({\n ...value,\n utcOffset,\n }));\n }}\n />\n </>\n )}\n {hasClear && (\n <>\n <div className={styles.separator} />\n <TextLink\n as=\"button\"\n isDisabled={disabled}\n testId=\"date-clear\"\n onClick={() => {\n setValue({\n date: undefined,\n time: undefined,\n ampm: getDefaultAMPM(),\n utcOffset: getDefaultUtcOffset(),\n });\n }}>\n Clear\n </TextLink>\n </>\n )}\n </div>\n );\n}\n\nexport function DateEditor(props: DateEditorProps) {\n const { field, parameters } = props;\n\n const formatParam = parameters?.instance?.format ?? 'timeZ';\n const ampmParam = parameters?.instance?.ampm ?? '24';\n\n const usesTime = formatParam !== 'dateonly';\n const usesTimezone = formatParam === 'timeZ';\n const uses12hClock = ampmParam === '12';\n\n return (\n <FieldConnector<string>\n field={field}\n isInitiallyDisabled={props.isInitiallyDisabled}\n isDisabled={props.isDisabled}\n throttle={0}>\n {({ value, disabled, setValue, externalReset }) => {\n const datetimeValue = userInputFromDatetime({\n value,\n uses12hClock,\n });\n return (\n <DateEditorContainer\n initialValue={datetimeValue}\n uses12hClock={uses12hClock}\n usesTimezone={usesTimezone}\n usesTime={usesTime}\n disabled={disabled}\n hasClear={Boolean(value)}\n onChange={(data) => {\n const fieldValue = buildFieldValue({ data, usesTime, usesTimezone });\n if (fieldValue.invalid) {\n return;\n }\n // if value is present - then override it with a new one\n // if value is not present - then set a new one if it's not nullable only\n if (Boolean(value) || (!value && Boolean(fieldValue.valid))) {\n setValue(fieldValue.valid);\n }\n }}\n key={`date-container-${externalReset}`}\n />\n );\n }}\n </FieldConnector>\n );\n}\n\nDateEditor.defaultProps = {\n isInitiallyDisabled: true,\n};\n"],"names":["styles","root","css","maxWidth","DatepickerInput","props","fromDate","toDate","useMemo","Date","setFullYear","getFullYear","dateObj","value","_props$value","toObject","selectedDate","years","months","date","undefined","React","Datepicker","className","selected","onSelect","day","momentDay","moment","onChange","inputProps","isDisabled","disabled","placeholder","validInputFormats","getDefaultTime","formatToString","uses12hClock","format","TimepickerInput","time","ampm","selectedTime","setSelectedTime","useState","useEffect","handleChange","useCallback","e","currentTarget","handleFocus","preventDefault","target","select","Flex","width","TextInput","testId","onFocus","onBlur","raw","i","length","isValid","parseRawInput","zoneOffsets","TimezonepickerInput","Select","map","offset","Option","key","ZONE_RX","getDefaultUtcOffset","set","hours","minutes","display","alignItems","separator","marginLeft","tokens","spacingM","DateEditorContainer","initialValue","usesTime","usesTimezone","hasClear","setValue","callback","deps","isFirstRun","current","useEffectWithoutFirstRender","utcOffset","TextLink","as","onClick","DateEditor","field","parameters","formatParam","instance","ampmParam","FieldConnector","isInitiallyDisabled","throttle","externalReset","datetimeValue","datetime","datetimeString","test","fieldValueToMoment","userInputFromDatetime","Boolean","data","fieldValue","input","valid","utc","timeFromUserInput","parseZone","invalid","datetimeFromUserInput","buildFieldValue","defaultProps"],"mappings":"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"}
@@ -5,56 +5,35 @@ import { FieldConnector } from '@contentful/field-editor-shared';
5
5
  import { css } from 'emotion';
6
6
  import moment from 'moment';
7
7
 
8
- function _extends() {
9
- _extends = Object.assign || function (target) {
10
- for (var i = 1; i < arguments.length; i++) {
11
- var source = arguments[i];
12
-
13
- for (var key in source) {
14
- if (Object.prototype.hasOwnProperty.call(source, key)) {
15
- target[key] = source[key];
16
- }
17
- }
18
- }
19
-
20
- return target;
21
- };
22
-
23
- return _extends.apply(this, arguments);
24
- }
25
-
26
- var YEAR_RANGE = 100;
27
- var styles = {
8
+ const YEAR_RANGE = 100;
9
+ const styles = {
28
10
  root: /*#__PURE__*/css({
29
11
  maxWidth: '270px'
30
12
  })
31
13
  };
32
- var DatepickerInput = function DatepickerInput(props) {
14
+ const DatepickerInput = props => {
33
15
  var _props$value;
34
16
 
35
- var _useMemo = useMemo(function () {
36
- var fromDate = new Date();
17
+ const [fromDate, toDate] = useMemo(() => {
18
+ const fromDate = new Date();
37
19
  fromDate.setFullYear(fromDate.getFullYear() - YEAR_RANGE);
38
- var toDate = new Date();
20
+ const toDate = new Date();
39
21
  toDate.setFullYear(toDate.getFullYear() + YEAR_RANGE);
40
22
  return [fromDate, toDate];
41
- }, []),
42
- fromDate = _useMemo[0],
43
- toDate = _useMemo[1]; // The DatepickerInput should be time and timezone agnostic,
23
+ }, []); // The DatepickerInput should be time and timezone agnostic,
44
24
  // thats why we don't use moment().toDate() to get Date object.
45
25
  // moment().toDate() takes into account time and timezone and converts it
46
26
  // based on your system timezone which can result in the date change.
47
27
  // e.g. if user has a timezone +02:00, moment('2022-09-16T00:00+04:00').toDate()
48
28
  // will return September 15 instead of September 16
49
29
 
50
-
51
- var dateObj = (_props$value = props.value) == null ? void 0 : _props$value.toObject();
52
- var selectedDate = dateObj ? new Date(dateObj.years, dateObj.months, dateObj.date) : undefined;
30
+ const dateObj = (_props$value = props.value) == null ? void 0 : _props$value.toObject();
31
+ const selectedDate = dateObj ? new Date(dateObj.years, dateObj.months, dateObj.date) : undefined;
53
32
  return React__default.createElement(Datepicker, {
54
33
  className: styles.root,
55
34
  selected: selectedDate,
56
- onSelect: function onSelect(day) {
57
- var momentDay = day ? moment(day) : undefined;
35
+ onSelect: day => {
36
+ const momentDay = day ? moment(day) : undefined;
58
37
  props.onChange(momentDay);
59
38
  },
60
39
  inputProps: {
@@ -66,13 +45,13 @@ var DatepickerInput = function DatepickerInput(props) {
66
45
  });
67
46
  };
68
47
 
69
- var validInputFormats = ['hh:mm a', 'hh:mm A', 'h:mm a', 'h:mm A', 'hh:mm', 'k:mm', 'kk:mm', 'h a', 'h A', 'h', 'hh', 'HH'];
48
+ const validInputFormats = ['hh:mm a', 'hh:mm A', 'h:mm a', 'h:mm A', 'hh:mm', 'k:mm', 'kk:mm', 'h a', 'h A', 'h', 'hh', 'HH'];
70
49
 
71
50
  function parseRawInput(raw) {
72
- var time = null; // eslint-disable-next-line -- TODO: refactor to use for of loop
51
+ let time = null; // eslint-disable-next-line -- TODO: refactor to use for of loop
73
52
 
74
- for (var i = 0; i < validInputFormats.length; i++) {
75
- var date = moment(raw, validInputFormats[i]);
53
+ for (let i = 0; i < validInputFormats.length; i++) {
54
+ const date = moment(raw, validInputFormats[i]);
76
55
 
77
56
  if (date.isValid()) {
78
57
  time = date;
@@ -83,43 +62,38 @@ function parseRawInput(raw) {
83
62
  return time;
84
63
  }
85
64
 
86
- var getDefaultTime = function getDefaultTime() {
87
- return moment("12:00 AM", 'hh:mm A');
65
+ const getDefaultTime = () => {
66
+ return moment(`12:00 AM`, 'hh:mm A');
88
67
  };
89
68
 
90
- var formatToString = function formatToString(uses12hClock, value) {
69
+ const formatToString = (uses12hClock, value) => {
91
70
  return uses12hClock ? value.format('hh:mm A') : value.format('HH:mm');
92
71
  };
93
72
 
94
- var TimepickerInput = function TimepickerInput(_ref) {
95
- var disabled = _ref.disabled,
96
- uses12hClock = _ref.uses12hClock,
97
- _ref$time = _ref.time,
98
- time = _ref$time === void 0 ? '12:00' : _ref$time,
99
- _ref$ampm = _ref.ampm,
100
- ampm = _ref$ampm === void 0 ? 'AM' : _ref$ampm,
101
- onChange = _ref.onChange;
102
-
103
- var _useState = useState(function () {
73
+ const TimepickerInput = ({
74
+ disabled,
75
+ uses12hClock,
76
+ time = '12:00',
77
+ ampm = 'AM',
78
+ onChange
79
+ }) => {
80
+ const [selectedTime, setSelectedTime] = useState(() => {
104
81
  return formatToString(uses12hClock, getDefaultTime());
105
- }),
106
- selectedTime = _useState[0],
107
- setSelectedTime = _useState[1];
108
-
109
- useEffect(function () {
110
- setSelectedTime(formatToString(uses12hClock, moment(time + " " + ampm, 'hh:mm A')));
82
+ });
83
+ useEffect(() => {
84
+ setSelectedTime(formatToString(uses12hClock, moment(`${time} ${ampm}`, 'hh:mm A')));
111
85
  }, [time, ampm, uses12hClock]);
112
- var handleChange = useCallback(function (e) {
86
+ const handleChange = useCallback(e => {
113
87
  setSelectedTime(e.currentTarget.value);
114
88
  }, []);
115
- var handleFocus = useCallback(function (e) {
89
+ const handleFocus = useCallback(e => {
116
90
  e.preventDefault();
117
91
  e.target.select();
118
92
  }, []);
119
93
 
120
- var handleBlur = function handleBlur() {
121
- var parsedTime = parseRawInput(selectedTime);
122
- var value = parsedTime != null ? parsedTime : getDefaultTime();
94
+ const handleBlur = () => {
95
+ const parsedTime = parseRawInput(selectedTime);
96
+ const value = parsedTime ?? getDefaultTime();
123
97
  setSelectedTime(formatToString(uses12hClock, value));
124
98
  onChange({
125
99
  time: value.format('hh:mm'),
@@ -144,32 +118,30 @@ var TimepickerInput = function TimepickerInput(_ref) {
144
118
  }));
145
119
  };
146
120
 
147
- var defaultZoneOffset = '+00:00';
148
- var zoneOffsets = ['-12:00', '-11:00', '-10:00', '-09:30', '-09:00', '-08:00', '-07:00', '-06:00', '-05:00', '-04:30', '-04:00', '-03:30', '-03:00', '-02:00', '-01:00', '+00:00', '+01:00', '+02:00', '+03:00', '+03:30', '+04:00', '+04:30', '+05:00', '+05:30', '+05:45', '+06:00', '+06:30', '+07:00', '+08:00', '+08:45', '+09:00', '+09:30', '+10:00', '+10:30', '+11:00', '+11:30', '+12:00', '+12:45', '+13:00', '+14:00'];
121
+ const defaultZoneOffset = '+00:00';
122
+ const zoneOffsets = ['-12:00', '-11:00', '-10:00', '-09:30', '-09:00', '-08:00', '-07:00', '-06:00', '-05:00', '-04:30', '-04:00', '-03:30', '-03:00', '-02:00', '-01:00', '+00:00', '+01:00', '+02:00', '+03:00', '+03:30', '+04:00', '+04:30', '+05:00', '+05:30', '+05:45', '+06:00', '+06:30', '+07:00', '+08:00', '+08:45', '+09:00', '+09:30', '+10:00', '+10:30', '+11:00', '+11:30', '+12:00', '+12:45', '+13:00', '+14:00'];
149
123
 
150
- var TimezonepickerInput = function TimezonepickerInput(_ref) {
151
- var disabled = _ref.disabled,
152
- _onChange = _ref.onChange,
153
- _ref$value = _ref.value,
154
- value = _ref$value === void 0 ? defaultZoneOffset : _ref$value;
124
+ const TimezonepickerInput = ({
125
+ disabled,
126
+ onChange,
127
+ value = defaultZoneOffset
128
+ }) => {
155
129
  return React__default.createElement(Select, {
156
130
  "aria-label": "Select timezone",
157
131
  testId: "timezone-input",
158
132
  value: value,
159
133
  isDisabled: disabled,
160
- onChange: function onChange(e) {
161
- _onChange(e.currentTarget.value);
134
+ onChange: e => {
135
+ onChange(e.currentTarget.value);
162
136
  }
163
- }, zoneOffsets.map(function (offset) {
164
- return React__default.createElement(Select.Option, {
165
- key: offset,
166
- value: offset
167
- }, "UTC", offset);
168
- }));
137
+ }, zoneOffsets.map(offset => React__default.createElement(Select.Option, {
138
+ key: offset,
139
+ value: offset
140
+ }, "UTC", offset)));
169
141
  };
170
142
 
171
143
  // eslint-disable-next-line -- TODO: move to date-fns
172
- var ZONE_RX = /(Z|[+-]\d{2}[:+]?\d{2})$/;
144
+ const ZONE_RX = /(Z|[+-]\d{2}[:+]?\d{2})$/;
173
145
 
174
146
  function startOfToday(format) {
175
147
  return moment().set({
@@ -183,7 +155,7 @@ function fieldValueToMoment(datetimeString) {
183
155
  return null;
184
156
  }
185
157
 
186
- var datetime = moment(datetimeString);
158
+ const datetime = moment(datetimeString);
187
159
 
188
160
  if (ZONE_RX.test(datetimeString)) {
189
161
  datetime.utcOffset(datetimeString);
@@ -193,7 +165,7 @@ function fieldValueToMoment(datetimeString) {
193
165
  }
194
166
 
195
167
  function timeFromUserInput(input) {
196
- var timeInput = input.time || '00:00';
168
+ const timeInput = input.time || '00:00';
197
169
  return moment.utc(timeInput + '!' + input.ampm, 'HH:mm!A');
198
170
  }
199
171
  /**
@@ -213,8 +185,8 @@ function datetimeFromUserInput(input) {
213
185
  };
214
186
  }
215
187
 
216
- var time = timeFromUserInput(input);
217
- var date = moment.parseZone(input.utcOffset, 'Z').set(input.date.toObject()).set({
188
+ const time = timeFromUserInput(input);
189
+ const date = moment.parseZone(input.utcOffset, 'Z').set(input.date.toObject()).set({
218
190
  hours: time.hours(),
219
191
  minutes: time.minutes()
220
192
  });
@@ -238,11 +210,12 @@ function datetimeFromUserInput(input) {
238
210
  */
239
211
 
240
212
 
241
- function buildFieldValue(_ref) {
242
- var data = _ref.data,
243
- usesTime = _ref.usesTime,
244
- usesTimezone = _ref.usesTimezone;
245
- var date = datetimeFromUserInput(data);
213
+ function buildFieldValue({
214
+ data,
215
+ usesTime,
216
+ usesTimezone
217
+ }) {
218
+ const date = datetimeFromUserInput(data);
246
219
 
247
220
  if (date.invalid) {
248
221
  return {
@@ -250,7 +223,7 @@ function buildFieldValue(_ref) {
250
223
  };
251
224
  }
252
225
 
253
- var format;
226
+ let format;
254
227
 
255
228
  if (usesTimezone) {
256
229
  format = 'YYYY-MM-DDTHH:mmZ';
@@ -275,13 +248,14 @@ function getDefaultUtcOffset() {
275
248
  * Create the user input object from the field value.
276
249
  */
277
250
 
278
- function userInputFromDatetime(_ref2) {
279
- var value = _ref2.value,
280
- uses12hClock = _ref2.uses12hClock;
281
- var datetime = fieldValueToMoment(value);
251
+ function userInputFromDatetime({
252
+ value,
253
+ uses12hClock
254
+ }) {
255
+ const datetime = fieldValueToMoment(value);
282
256
 
283
257
  if (datetime) {
284
- var timeFormat = uses12hClock ? 'hh:mm' : 'HH:mm';
258
+ const timeFormat = uses12hClock ? 'hh:mm' : 'HH:mm';
285
259
  return {
286
260
  date: datetime,
287
261
  time: datetime.format(timeFormat),
@@ -296,7 +270,7 @@ function userInputFromDatetime(_ref2) {
296
270
  }
297
271
  }
298
272
 
299
- var styles$1 = {
273
+ const styles$1 = {
300
274
  root: /*#__PURE__*/css({
301
275
  display: 'flex',
302
276
  alignItems: 'center'
@@ -307,8 +281,8 @@ var styles$1 = {
307
281
  };
308
282
 
309
283
  function useEffectWithoutFirstRender(callback, deps) {
310
- var isFirstRun = useRef(true);
311
- useEffect(function () {
284
+ const isFirstRun = useRef(true);
285
+ useEffect(() => {
312
286
  if (isFirstRun.current) {
313
287
  isFirstRun.current = false;
314
288
  return;
@@ -318,22 +292,17 @@ function useEffectWithoutFirstRender(callback, deps) {
318
292
  }, deps);
319
293
  }
320
294
 
321
- function DateEditorContainer(_ref) {
322
- var initialValue = _ref.initialValue,
323
- usesTime = _ref.usesTime,
324
- usesTimezone = _ref.usesTimezone,
325
- uses12hClock = _ref.uses12hClock,
326
- disabled = _ref.disabled,
327
- hasClear = _ref.hasClear,
328
- onChange = _ref.onChange;
329
-
330
- var _React$useState = useState(function () {
331
- return initialValue;
332
- }),
333
- value = _React$useState[0],
334
- setValue = _React$useState[1];
335
-
336
- useEffectWithoutFirstRender(function () {
295
+ function DateEditorContainer({
296
+ initialValue,
297
+ usesTime,
298
+ usesTimezone,
299
+ uses12hClock,
300
+ disabled,
301
+ hasClear,
302
+ onChange
303
+ }) {
304
+ const [value, setValue] = useState(() => initialValue);
305
+ useEffectWithoutFirstRender(() => {
337
306
  onChange(value);
338
307
  }, [value]);
339
308
  return createElement("div", {
@@ -342,12 +311,10 @@ function DateEditorContainer(_ref) {
342
311
  }, createElement(DatepickerInput, {
343
312
  disabled: disabled,
344
313
  value: value.date,
345
- onChange: function onChange(date) {
346
- setValue(function (value) {
347
- return _extends({}, value, {
348
- date: date
349
- });
350
- });
314
+ onChange: date => {
315
+ setValue(value => ({ ...value,
316
+ date
317
+ }));
351
318
  }
352
319
  }), usesTime && createElement(Fragment, null, createElement("div", {
353
320
  className: styles$1.separator
@@ -355,15 +322,14 @@ function DateEditorContainer(_ref) {
355
322
  disabled: disabled,
356
323
  time: value.time,
357
324
  ampm: value.ampm,
358
- onChange: function onChange(_ref2) {
359
- var time = _ref2.time,
360
- ampm = _ref2.ampm;
361
- setValue(function (value) {
362
- return _extends({}, value, {
363
- time: time,
364
- ampm: ampm
365
- });
366
- });
325
+ onChange: ({
326
+ time,
327
+ ampm
328
+ }) => {
329
+ setValue(value => ({ ...value,
330
+ time,
331
+ ampm
332
+ }));
367
333
  },
368
334
  uses12hClock: uses12hClock
369
335
  })), usesTimezone && createElement(Fragment, null, createElement("div", {
@@ -371,12 +337,10 @@ function DateEditorContainer(_ref) {
371
337
  }), createElement(TimezonepickerInput, {
372
338
  disabled: disabled,
373
339
  value: value.utcOffset,
374
- onChange: function onChange(utcOffset) {
375
- setValue(function (value) {
376
- return _extends({}, value, {
377
- utcOffset: utcOffset
378
- });
379
- });
340
+ onChange: utcOffset => {
341
+ setValue(value => ({ ...value,
342
+ utcOffset
343
+ }));
380
344
  }
381
345
  })), hasClear && createElement(Fragment, null, createElement("div", {
382
346
  className: styles$1.separator
@@ -384,7 +348,7 @@ function DateEditorContainer(_ref) {
384
348
  as: "button",
385
349
  isDisabled: disabled,
386
350
  testId: "date-clear",
387
- onClick: function onClick() {
351
+ onClick: () => {
388
352
  setValue({
389
353
  date: undefined,
390
354
  time: undefined,
@@ -396,42 +360,44 @@ function DateEditorContainer(_ref) {
396
360
  }
397
361
 
398
362
  function DateEditor(props) {
399
- var _parameters$instance$, _parameters$instance, _parameters$instance$2, _parameters$instance2;
400
-
401
- var field = props.field,
402
- parameters = props.parameters;
403
- var formatParam = (_parameters$instance$ = parameters == null ? void 0 : (_parameters$instance = parameters.instance) == null ? void 0 : _parameters$instance.format) != null ? _parameters$instance$ : 'timeZ';
404
- var ampmParam = (_parameters$instance$2 = parameters == null ? void 0 : (_parameters$instance2 = parameters.instance) == null ? void 0 : _parameters$instance2.ampm) != null ? _parameters$instance$2 : '24';
405
- var usesTime = formatParam !== 'dateonly';
406
- var usesTimezone = formatParam === 'timeZ';
407
- var uses12hClock = ampmParam === '12';
363
+ var _parameters$instance, _parameters$instance2;
364
+
365
+ const {
366
+ field,
367
+ parameters
368
+ } = props;
369
+ const formatParam = (parameters == null ? void 0 : (_parameters$instance = parameters.instance) == null ? void 0 : _parameters$instance.format) ?? 'timeZ';
370
+ const ampmParam = (parameters == null ? void 0 : (_parameters$instance2 = parameters.instance) == null ? void 0 : _parameters$instance2.ampm) ?? '24';
371
+ const usesTime = formatParam !== 'dateonly';
372
+ const usesTimezone = formatParam === 'timeZ';
373
+ const uses12hClock = ampmParam === '12';
408
374
  return createElement(FieldConnector, {
409
375
  field: field,
410
376
  isInitiallyDisabled: props.isInitiallyDisabled,
377
+ isDisabled: props.isDisabled,
411
378
  throttle: 0
412
- }, function (_ref3) {
413
- var _props$isDisabled;
414
-
415
- var value = _ref3.value,
416
- disabled = _ref3.disabled,
417
- setValue = _ref3.setValue,
418
- externalReset = _ref3.externalReset;
419
- var datetimeValue = userInputFromDatetime({
420
- value: value,
421
- uses12hClock: uses12hClock
379
+ }, ({
380
+ value,
381
+ disabled,
382
+ setValue,
383
+ externalReset
384
+ }) => {
385
+ const datetimeValue = userInputFromDatetime({
386
+ value,
387
+ uses12hClock
422
388
  });
423
389
  return createElement(DateEditorContainer, {
424
390
  initialValue: datetimeValue,
425
391
  uses12hClock: uses12hClock,
426
392
  usesTimezone: usesTimezone,
427
393
  usesTime: usesTime,
428
- disabled: (_props$isDisabled = props.isDisabled) != null ? _props$isDisabled : disabled,
394
+ disabled: disabled,
429
395
  hasClear: Boolean(value),
430
- onChange: function onChange(data) {
431
- var fieldValue = buildFieldValue({
432
- data: data,
433
- usesTime: usesTime,
434
- usesTimezone: usesTimezone
396
+ onChange: data => {
397
+ const fieldValue = buildFieldValue({
398
+ data,
399
+ usesTime,
400
+ usesTimezone
435
401
  });
436
402
 
437
403
  if (fieldValue.invalid) {
@@ -444,7 +410,7 @@ function DateEditor(props) {
444
410
  setValue(fieldValue.valid);
445
411
  }
446
412
  },
447
- key: "date-container-" + externalReset
413
+ key: `date-container-${externalReset}`
448
414
  });
449
415
  });
450
416
  }