@sanity/rich-date-input
4.1.54.1.6
dist/index.js.map~
dist/index.js.mapModified+1−1
Index: package/dist/index.js.map
===================================================================
--- package/dist/index.js.map
+++ package/dist/index.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","names":["tz","TZDate","format","NormalizedTimeZone","formatInTimeZone","date","Date","timeZone","formatStr","in","shiftWallClockToTimeZone","fromTimeZone","toTimeZone","wallClock","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getMilliseconds","getConstructedUTCDate","utc","offset","currentOffset","getTimezoneOffset","diff","fakeUTCDate","getTime","toISOString","TimeZoneInfo","abbreviation","alternativeName","timeZoneInfoCache","Map","getTimeZoneInfo","cached","get","now","longFormatter","Intl","DateTimeFormat","undefined","timeZoneName","shortFormatter","rawOffset","replace","info","formatToParts","find","type","value","set","getTimeZoneAbbreviation","resolveCanonicalTimeZone","resolvedOptions","offsetToMinutes","multiplier","startsWith","includes","Number","hours","minutes","split","map","allTimezonesCache","getAllTimezones","supportedValuesOf","flatMap","name","segments","city","length","at","replaceAll","namePretty","sort","a","b","tzOffset","ReactNode","useCallback","DateTimeInput","FieldProps","FormPatch","PatchEvent","set","unset","RichDate","formatInTimeZone","getConstructedUTCDate","shiftWallClockToTimeZone","RelativeDateTimePickerProps","Omit","dateValue","RelativeDateTimePicker","props","$","_c","value","inputProps","t0","onChange","t1","offset","timezone","patch","formatter","Intl","DateTimeFormat","resolvedOptions","timeZone","Array","isArray","type","newDatetime","newUtcDateObject","Date","newOffset","localDate","patches","push","toISOString","handleDateChange","t2","utc","displayOffset","t3","dateToDisplay","t4","id","EarthAmericasIcon","Button","ReactNode","getTimeZoneAbbreviation","TimezoneButtonProps","onClick","timezone","TimezoneButton","props","$","_c","t0","formatter","Intl","DateTimeFormat","currentTimezone","resolvedOptions","timeZone","label","t1","Symbol","for","width","t2","t3","tzOffset","SearchIcon","Box","Card","Text","Autocomplete","ReactNode","useCallback","useMemo","ObjectInputProps","set","RichDate","formatInTimeZone","getAllTimezones","resolveCanonicalTimeZone","shiftWallClockToTimeZone","TimezoneSelectorProps","onChange","Pick","value","TimezoneSelector","props","$","_c","t0","Symbol","for","allTimezones","t1","timezone","undefined","canonicalStoredTz","t2","find","tz_0","tz","name","currentTz","t3","formatter","Intl","DateTimeFormat","userTzName","resolvedOptions","timeZone","tz_2","_temp","userTz","t4","selectedTz","newTimezone","tz_3","timezonePatch","patches","utc","newUtcDateObject","Date","newOffset","newLocalDate","push","toISOString","handleTimezoneChange","t5","floatingBoundary","document","body","referenceBoundary","constrainSize","placement","t6","t7","_temp2","_temp3","tz_1","abbreviation","option","offset","fontWeight","marginLeft","alternativeName","city","_","option_0","namePretty","Box","Dialog","Flex","ReactNode","useCallback","useState","ObjectInputMember","ObjectInputProps","RichDate","RelativeDateTimePicker","TimezoneButton","TimezoneSelector","isRichDate","value","_type","RichDateInput","props","$","_c","onChange","members","schemaType","options","t0","find","_temp","localMember","t1","_temp2","timezoneMember","timezoneSelectorOpen","setTimezoneSelectorOpen","t2","Symbol","for","onClose","t3","onOpen","richDateValue","undefined","t4","t5","renderFieldProps","inputProps","t6","t7","t8","t9","timezone","t10","t11","t12","t13","member","kind","name","member_0","DatetimeDefinition","defineField","defineType","ObjectDefinition","ObjectSchemaType","RichDateInput","richDateTypeName","const","RichDateSchemaType","Omit","options","RichDateDefinition","type","IntrinsicDefinitions","richDate","richDateSchema","name","title","fields","components","input","definePlugin","RichDateDefinition","richDateSchema","RichDateSchemaType","RichDate","richDate","name","schema","types"],"sources":["../src/utils/index.ts","../src/components/RelativeDateTimePicker.tsx","../src/components/TimezoneButton.tsx","../src/components/TimezoneSelector.tsx","../src/components/RichDateInput.tsx","../src/schema.ts","../src/index.ts"],"sourcesContent":["import {tz, TZDate} from '@date-fns/tz'\nimport {format} from 'date-fns/format'\n\nimport type {NormalizedTimeZone} from '../types'\n\n/**\n * Formats `date` as seen in `timeZone`, using date-fns v4's `in` context\n * option with the official `@date-fns/tz` package (the replacement for\n * `date-fns-tz`'s `formatInTimeZone`).\n */\nexport const formatInTimeZone = (date: Date, timeZone: string, formatStr: string): string => {\n return format(date, formatStr, {in: tz(timeZone)})\n}\n\n/**\n * Returns the UTC instant whose wall-clock time in `toTimeZone` matches the\n * wall-clock time that `date` has in `fromTimeZone`. Reads the date components\n * in the source time zone and constructs a `TZDate` from them in the target\n * time zone, the same way sanity core re-interprets dates across time zones.\n * Replaces the `zonedTimeToUtc(formatInTimeZone(...))` round-trip previously\n * performed with `date-fns-tz`.\n */\nexport const shiftWallClockToTimeZone = (\n date: Date,\n fromTimeZone: string,\n toTimeZone: string,\n): Date => {\n const wallClock = new TZDate(date, fromTimeZone)\n return new Date(\n +new TZDate(\n wallClock.getFullYear(),\n wallClock.getMonth(),\n wallClock.getDate(),\n wallClock.getHours(),\n wallClock.getMinutes(),\n wallClock.getSeconds(),\n wallClock.getMilliseconds(),\n toTimeZone,\n ),\n )\n}\n\n/* We have to \"fake\" a UTC date to make the datepicker look \"right\"\n * to the user. For example, if someone sets 7:00AM PST, which is 3PM UTC\n * and I am on the east coast, I want to have 12:00PM UTC, which will look like 7:00AM to me\n * In other words, UTC minus 3 hours, or (UTC(my offset - their offset))\n * this is purely cosmetic and should not be saved at all\n */\nexport const getConstructedUTCDate = (utc: string, offset: number): string => {\n const date = new Date(utc)\n const currentOffset = date.getTimezoneOffset() * -1\n const diff = currentOffset - offset\n const fakeUTCDate = new Date(date.getTime() - diff * 60 * 1000)\n return fakeUTCDate.toISOString()\n}\n\ninterface TimeZoneInfo {\n abbreviation: string\n alternativeName: string\n offset: string\n}\n\nconst timeZoneInfoCache = new Map<string, TimeZoneInfo>()\n\nconst getTimeZoneInfo = (timeZone: string): TimeZoneInfo => {\n const cached = timeZoneInfoCache.get(timeZone)\n if (cached) return cached\n\n const now = new Date()\n const longFormatter = new Intl.DateTimeFormat(undefined, {timeZone, timeZoneName: 'long'})\n const shortFormatter = new Intl.DateTimeFormat(undefined, {timeZone, timeZoneName: 'short'})\n const rawOffset = format(now, 'xxx', {in: tz(timeZone)})\n // If the offset is +02:00 then we can just show +2, if it has +13:45 then we\n // should show +13:45; remove the leading zero and the trailing :00, and drop\n // +0 entirely so UTC renders as plain \"GMT\"\n const offset = rawOffset\n .replace(/([+-])0(\\d)/, '$1$2')\n .replace(/([+-])0$/, '$1')\n .replace(/:00$/, '')\n .replace(/[+]0$/, '')\n\n const info: TimeZoneInfo = {\n abbreviation:\n shortFormatter.formatToParts(now).find(({type}) => type === 'timeZoneName')?.value ?? '',\n alternativeName:\n longFormatter.formatToParts(now).find(({type}) => type === 'timeZoneName')?.value ?? '',\n offset,\n }\n timeZoneInfoCache.set(timeZone, info)\n return info\n}\n\n/**\n * Returns the localized abbreviation (e.g. `PST`, `GMT+2`) for any valid IANA\n * time zone name, or `undefined` when the name is not recognized by the\n * runtime.\n */\nexport const getTimeZoneAbbreviation = (timeZone: string): string | undefined => {\n try {\n return getTimeZoneInfo(timeZone).abbreviation\n } catch {\n return undefined\n }\n}\n\n/**\n * Resolves any valid IANA time zone name to the runtime's canonical\n * identifier, e.g. `Europe/Kyiv` to `Europe/Kiev` when the runtime lists the\n * latter. Documents written with older plugin versions may store alias\n * spellings that are absent from `Intl.supportedValuesOf('timeZone')`.\n * Returns `undefined` when the name is not recognized.\n */\nexport const resolveCanonicalTimeZone = (timeZone: string): string | undefined => {\n try {\n return new Intl.DateTimeFormat(undefined, {timeZone}).resolvedOptions().timeZone\n } catch {\n return undefined\n }\n}\n\nconst offsetToMinutes = (offset: string): number => {\n if (!offset) return 0\n const multiplier = offset.startsWith('-') ? -1 : 1\n if (!offset.includes(':')) return multiplier * Number(offset.replace(/[+-]/, '')) * 60\n\n const [hours = 0, minutes = 0] = offset.replace(/[+-]/, '').split(':').map(Number)\n return multiplier * (hours * 60 + minutes)\n}\n\nlet allTimezonesCache: NormalizedTimeZone[] | undefined\n\n/**\n * Lists the IANA time zones known to the runtime, normalized for the timezone\n * selector. Mirrors how sanity core builds its time zone list from\n * `Intl.supportedValuesOf` instead of shipping a static time zone database.\n * Computed lazily and cached, as enumerating the time zones is expensive.\n */\nexport const getAllTimezones = (): NormalizedTimeZone[] => {\n if (allTimezonesCache) return allTimezonesCache\n\n allTimezonesCache = Intl.supportedValuesOf('timeZone')\n .flatMap((name): NormalizedTimeZone[] => {\n // Skip time zones without a city component (e.g. plain 'UTC'). The city\n // is the last segment: 'America/Indiana/Indianapolis' -> 'Indianapolis'\n const segments = name.split('/')\n const city = segments.length > 1 ? segments.at(-1) : undefined\n if (!city) return []\n\n const {abbreviation, alternativeName, offset} = getTimeZoneInfo(name)\n return [\n {\n abbreviation,\n alternativeName,\n city: city.replaceAll('_', ' '),\n // Main time zone name 'Africa/Dar_es_Salaam'\n name,\n // Time zone name with underscores removed\n namePretty: name.replaceAll('_', ' '),\n offset,\n // all searchable text - this is transformed before being rendered in `<AutoComplete>`\n value: `${offset} ${abbreviation} ${name} ${alternativeName}`,\n },\n ]\n })\n .sort((a, b) => offsetToMinutes(a.offset) - offsetToMinutes(b.offset))\n\n return allTimezonesCache\n}\n","import {tzOffset} from '@date-fns/tz'\nimport {type ReactNode, useCallback} from 'react'\nimport {DateTimeInput, type FieldProps, type FormPatch, type PatchEvent, set, unset} from 'sanity'\n\nimport type {RichDate} from '../types'\nimport {formatInTimeZone, getConstructedUTCDate, shiftWallClockToTimeZone} from '../utils'\n\ninterface RelativeDateTimePickerProps extends Omit<FieldProps, 'renderDefault'> {\n dateValue?: RichDate\n}\nexport const RelativeDateTimePicker = (props: RelativeDateTimePickerProps): ReactNode => {\n const {\n dateValue: value,\n inputProps: {onChange},\n } = props\n\n const handleDateChange = useCallback(\n (patch: FormPatch | PatchEvent | FormPatch[]) => {\n const formatter = new Intl.DateTimeFormat()\n const timezone = value?.timezone ?? formatter.resolvedOptions().timeZone\n\n // Type guard to check if patch is a set patch with a value\n if (\n !patch ||\n Array.isArray(patch) ||\n !('type' in patch) ||\n patch.type !== 'set' ||\n !('value' in patch) ||\n typeof patch.value !== 'string'\n ) {\n onChange(unset())\n return\n }\n\n const newDatetime = patch.value\n\n /* get what time the user \"meant\" to set without tz info\n * right now, newDatetime is the time the user set plus\n * their current offset, not the timezone offset\n */\n const newUtcDateObject = shiftWallClockToTimeZone(\n new Date(newDatetime),\n formatter.resolvedOptions().timeZone,\n timezone,\n )\n // offset may have changed based on DST, capture that\n const newOffset = tzOffset(timezone, newUtcDateObject)\n const localDate = formatInTimeZone(newUtcDateObject, timezone, \"yyyy-MM-dd'T'HH:mm:ssXXX\")\n\n const patches = []\n\n patches.push(set(newUtcDateObject.toISOString(), ['utc']))\n patches.push(set(localDate, ['local']))\n\n if (!value?.timezone) {\n patches.push(set(timezone, ['timezone']))\n }\n\n if (value?.offset !== newOffset) {\n patches.push(set(newOffset, ['offset']))\n }\n\n onChange(patches)\n },\n [onChange, value],\n )\n\n // Dynamically calculate the offset for the actual event date to handle DST correctly\n const displayOffset =\n value?.utc && value?.timezone\n ? tzOffset(value.timezone, new Date(value.utc))\n : (value?.offset ?? 0)\n\n const dateToDisplay = value?.utc ? getConstructedUTCDate(value.utc, displayOffset) : ''\n return (\n // @ts-expect-error -- slight mismatch in elementProps and renderDefault, but should line up in practice\n <DateTimeInput\n {...props}\n id={props.inputProps.id}\n onChange={handleDateChange}\n value={dateToDisplay}\n />\n )\n}\n","import {EarthAmericasIcon} from '@sanity/icons/EarthAmericas'\nimport {Button} from '@sanity/ui'\nimport {type ReactNode} from 'react'\n\nimport {getTimeZoneAbbreviation} from '../utils'\n\ninterface TimezoneButtonProps {\n onClick: () => void\n timezone: string\n}\n\nexport const TimezoneButton = (props: TimezoneButtonProps): ReactNode => {\n const {onClick, timezone} = props\n const formatter = new Intl.DateTimeFormat()\n const currentTimezone = formatter.resolvedOptions().timeZone\n\n const label = getTimeZoneAbbreviation(timezone) ?? getTimeZoneAbbreviation(currentTimezone)\n\n return (\n <Button\n fontSize={1}\n style={{width: '100%'}}\n justify={'flex-start'}\n icon={EarthAmericasIcon}\n mode=\"ghost\"\n onClick={onClick}\n text={label ?? timezone}\n aria-label=\"Select a timezone\"\n />\n )\n}\n","import {tzOffset} from '@date-fns/tz'\nimport {SearchIcon} from '@sanity/icons/Search'\nimport {Box, Card, Text} from '@sanity/ui'\nimport {Autocomplete} from '@sanity/ui/autocomplete'\nimport {type ReactNode, useCallback, useMemo} from 'react'\nimport {type ObjectInputProps, set} from 'sanity'\n\nimport type {RichDate} from '../types'\nimport {\n formatInTimeZone,\n getAllTimezones,\n resolveCanonicalTimeZone,\n shiftWallClockToTimeZone,\n} from '../utils'\n\ninterface TimezoneSelectorProps {\n onChange: Pick<ObjectInputProps, 'onChange'>['onChange']\n value?: RichDate\n}\n\nexport const TimezoneSelector = (props: TimezoneSelectorProps): ReactNode => {\n const {onChange, value} = props\n const allTimezones = useMemo(() => getAllTimezones(), [])\n // Stored names may be aliases the runtime does not list (e.g. 'Europe/Kyiv'\n // vs 'Europe/Kiev'), so fall back to matching on the canonical identifier\n const canonicalStoredTz = value?.timezone ? resolveCanonicalTimeZone(value.timezone) : undefined\n const currentTz =\n allTimezones.find((tz) => tz.name === value?.timezone) ??\n allTimezones.find((tz) => tz.name === canonicalStoredTz)\n const formatter = new Intl.DateTimeFormat()\n const userTzName = formatter.resolvedOptions().timeZone\n const userTz = (allTimezones.find((tz) => tz.name === userTzName) ??\n allTimezones.find((tz) => tz.abbreviation === 'GMT') ??\n allTimezones[0])!\n\n const handleTimezoneChange = useCallback(\n (selectedTz: string) => {\n const newTimezone = allTimezones.find((tz) => tz.value === selectedTz) ?? userTz\n\n const timezonePatch = set(newTimezone.name, ['timezone'])\n const patches = [timezonePatch]\n\n // then, recalculate UTC and local from \"old\" time with the new offset\n if (value?.utc) {\n const newUtcDateObject = shiftWallClockToTimeZone(\n new Date(value.utc),\n value.timezone,\n newTimezone.name,\n )\n const newOffset = tzOffset(newTimezone.name, newUtcDateObject)\n const newLocalDate = formatInTimeZone(\n newUtcDateObject,\n newTimezone.name,\n \"yyyy-MM-dd'T'HH:mm:ssXXX\",\n )\n patches.push(set(newUtcDateObject.toISOString(), ['utc']))\n patches.push(set(newLocalDate, ['local']))\n patches.push(set(newOffset, ['offset']))\n }\n onChange(patches)\n },\n [allTimezones, onChange, userTz, value],\n )\n\n return (\n // taken from Scheduled Publishing, again!\n // https://github.com/sanity-io/sanity-plugin-scheduled-publishing/blob/bb282e3df9a8a73df37fab8ee1fdd0e2430745be/src/components/dialogs/DialogTimeZone.tsx#L100\n <Box padding={4}>\n <Autocomplete\n fontSize={2}\n icon={SearchIcon}\n id=\"timezone\"\n onChange={handleTimezoneChange}\n openButton\n options={allTimezones}\n padding={4}\n placeholder=\"Search for a city or time zone\"\n popover={{\n floatingBoundary: document.body,\n referenceBoundary: document.body,\n constrainSize: true,\n placement: 'bottom-start',\n }}\n renderOption={(option) => {\n return (\n <Card as=\"button\" padding={3}>\n <Text size={1} textOverflow=\"ellipsis\">\n <span>GMT{option.offset}</span>\n <span style={{fontWeight: 500, marginLeft: '1em'}}>{option.alternativeName}</span>\n <span style={{marginLeft: '1em'}}>{option.city}</span>\n </Text>\n </Card>\n )\n }}\n renderValue={(_, option) => {\n if (!option) return ''\n return `${option.alternativeName} (${option.namePretty})`\n }}\n tabIndex={-1}\n value={currentTz?.value ?? userTz.value}\n />\n </Box>\n )\n}\n","import {Box, Dialog, Flex} from '@sanity/ui'\nimport {type ReactNode, useCallback, useState} from 'react'\nimport {ObjectInputMember, type ObjectInputProps} from 'sanity'\n\nimport type {RichDate} from '../types'\nimport {RelativeDateTimePicker} from './RelativeDateTimePicker'\nimport {TimezoneButton} from './TimezoneButton'\nimport {TimezoneSelector} from './TimezoneSelector'\n\nfunction isRichDate(value: unknown): value is RichDate {\n return (\n typeof value === 'object' && value !== null && '_type' in value && value._type === 'richDate'\n )\n}\n\nexport const RichDateInput = (props: ObjectInputProps): ReactNode => {\n const {onChange, value, members, schemaType} = props\n const {options} = schemaType\n const localMember = members.find((member) => member.kind === 'field' && member.name === 'local')\n const timezoneMember = members.find(\n (member) => member.kind === 'field' && member.name === 'timezone',\n )\n const [timezoneSelectorOpen, setTimezoneSelectorOpen] = useState(false)\n const onClose = useCallback(() => setTimezoneSelectorOpen(false), [])\n const onOpen = useCallback(() => setTimezoneSelectorOpen(true), [])\n\n const richDateValue = isRichDate(value) ? value : undefined\n\n return (\n <>\n <Flex>\n <Box flex={[1, 2, 4]}>\n {localMember && (\n <ObjectInputMember\n {...props}\n member={localMember}\n renderField={(renderFieldProps) => (\n <RelativeDateTimePicker\n {...renderFieldProps}\n dateValue={richDateValue}\n schemaType={{...renderFieldProps.schemaType, options}}\n inputProps={{...renderFieldProps.inputProps, onChange: onChange}}\n />\n )}\n />\n )}\n </Box>\n <Box flex={[1]} marginLeft={[2, 2, 3, 4]} marginTop={2}>\n {timezoneMember && (\n <ObjectInputMember\n {...props}\n member={timezoneMember}\n renderInput={() => (\n <TimezoneButton onClick={onOpen} timezone={richDateValue?.timezone ?? ''} />\n )}\n />\n )}\n </Box>\n </Flex>\n {timezoneSelectorOpen && (\n <Dialog onClose={onClose} header=\"Select a timezone\" id=\"timezone-select\" width={1}>\n <TimezoneSelector onChange={onChange} value={richDateValue} />\n </Dialog>\n )}\n </>\n )\n}\n","import {\n type DatetimeDefinition,\n defineField,\n defineType,\n type ObjectDefinition,\n type ObjectSchemaType,\n} from 'sanity'\n\nimport {RichDateInput} from './components/RichDateInput'\n\nconst richDateTypeName = 'richDate' as const\n\nexport type RichDateSchemaType = Omit<ObjectSchemaType, 'options'> & {\n options?: DatetimeDefinition['options']\n}\n\n/**\n * @public\n */\nexport interface RichDateDefinition extends Omit<ObjectDefinition, 'type' | 'fields' | 'options'> {\n type: typeof richDateTypeName\n options?: DatetimeDefinition['options']\n}\n\ndeclare module 'sanity' {\n //allows the custom input to be valid for the schema def\n export interface IntrinsicDefinitions {\n richDate: RichDateDefinition\n }\n}\n\nexport const richDateSchema = defineType({\n name: richDateTypeName,\n title: 'Rich Date',\n type: 'object',\n fields: [\n defineField({\n name: 'local',\n title: 'Local',\n type: 'string',\n }),\n defineField({\n name: 'utc',\n title: 'UTC',\n type: 'string',\n }),\n defineField({\n name: 'timezone',\n title: 'Timezone',\n type: 'string',\n }),\n defineField({\n name: 'offset',\n title: 'Offset',\n type: 'number',\n }),\n ],\n\n components: {\n input: RichDateInput,\n },\n})\n","import '@sanity/ui/styles.css'\nimport {definePlugin} from 'sanity'\n\nimport {type RichDateDefinition, richDateSchema, type RichDateSchemaType} from './schema'\nimport type {RichDate} from './types'\n\nexport const richDate = definePlugin({\n name: 'v3-rich-date-input',\n schema: {\n types: [richDateSchema],\n },\n})\n\nexport type {RichDate, RichDateDefinition, RichDateSchemaType}\n"],"mappings":";;;;;;;;;;;;;;;;AAUA,MAAaI,oBAAoBC,MAAYE,UAAkBC,cACtDN,OAAOG,MAAMG,WAAW,EAACC,IAAIT,GAAGO,QAAQ,EAAC,CAAC,GAWtCG,4BACXL,MACAM,cACAC,eACS;CACT,IAAMC,YAAY,IAAIZ,OAAOI,MAAMM,YAAY;CAC/C,uBAAO,IAAIL,KACT,CAAC,IAAIL,OACHY,UAAUC,YAAY,GACtBD,UAAUE,SAAS,GACnBF,UAAUG,QAAQ,GAClBH,UAAUI,SAAS,GACnBJ,UAAUK,WAAW,GACrBL,UAAUM,WAAW,GACrBN,UAAUO,gBAAgB,GAC1BR,UACF,CACF;AACF,GAQaS,yBAAyBC,KAAaC,WAA2B;CAC5E,IAAMlB,OAAO,IAAIC,KAAKgB,GAAG,GAEnBI,OADgBrB,KAAKoB,kBAAkB,IAAI,KACpBF;CAE7B,wBAAOI,IADiBrB,KAAKD,KAAKuB,QAAQ,IAAIF,OAAO,KAAK,GACnDC,EAAAA,CAAYE,YAAY;AACjC,GAQMI,oCAAoB,IAAIC,IAA0B,GAElDC,mBAAmB5B,aAAmC;CAC1D,IAAM6B,SAASH,kBAAkBI,IAAI9B,QAAQ;CAC7C,IAAI6B,QAAQ,OAAOA;CAEnB,IAAME,sBAAM,IAAIhC,KAAK,GACfiC,gBAAgB,IAAIC,KAAKC,eAAeC,KAAAA,GAAW;EAACnC;EAAUoC,cAAc;CAAM,CAAC,GACnFC,iBAAiB,IAAIJ,KAAKC,eAAeC,KAAAA,GAAW;EAACnC;EAAUoC,cAAc;CAAO,CAAC,GAKrFpB,SAJYrB,OAAOoC,KAAK,OAAO,EAAC7B,IAAIT,GAAGO,QAAQ,EAAC,CAIvCsC,CAAS,CACrBC,QAAQ,eAAe,MAAM,CAAC,CAC9BA,QAAQ,YAAY,IAAI,CAAC,CACzBA,QAAQ,QAAQ,EAAE,CAAC,CACnBA,QAAQ,SAAS,EAAE,GAEhBC,OAAqB;EACzBhB,cACEa,eAAeI,cAAcV,GAAG,CAAC,CAACW,MAAM,EAACC,WAAUA,SAAS,cAAc,CAAC,EAAEC,SAAS;EACxFnB,iBACEO,cAAcS,cAAcV,GAAG,CAAC,CAACW,MAAM,EAACC,WAAUA,SAAS,cAAc,CAAC,EAAEC,SAAS;EACvF5B;CACF;CAEA,OADAU,kBAAkBmB,IAAI7C,UAAUwC,IAAI,GAC7BA;AACT,GAOaM,2BAA2B9C,aAAyC;CAC/E,IAAI;EACF,OAAO4B,gBAAgB5B,QAAQ,CAAC,CAACwB;CACnC,QAAQ;EACN;CACF;AACF,GASauB,4BAA4B/C,aAAyC;CAChF,IAAI;EACF,OAAO,IAAIiC,KAAKC,eAAeC,KAAAA,GAAW,EAACnC,SAAQ,CAAC,CAAC,CAACgD,gBAAgB,CAAC,CAAChD;CAC1E,QAAQ;EACN;CACF;AACF,GAEMiD,mBAAmBjC,WAA2B;CAClD,IAAI,CAACA,QAAQ,OAAO;CACpB,IAAMkC,aAAalC,OAAOmC,WAAW,GAAG,IAAI,KAAK;CACjD,IAAI,CAACnC,OAAOoC,SAAS,GAAG,GAAG,OAAOF,aAAaG,OAAOrC,OAAOuB,QAAQ,QAAQ,EAAE,CAAC,IAAI;CAEpF,IAAM,CAACe,QAAQ,GAAGC,UAAU,KAAKvC,OAAOuB,QAAQ,QAAQ,EAAE,CAAC,CAACiB,MAAM,GAAG,CAAC,CAACC,IAAIJ,MAAM;CACjF,OAAOH,cAAcI,QAAQ,KAAKC;AACpC;AAEA,IAAIG;;;;;;;AAQJ,MAAaC,wBACPD,sBAEJA,oBAAoBzB,KAAK2B,kBAAkB,UAAU,CAAC,CACnDC,SAASC,SAA+B;CAGvC,IAAMC,WAAWD,KAAKN,MAAM,GAAG,GACzBQ,OAAOD,SAASE,SAAS,IAAIF,SAASG,GAAG,EAAE,IAAI/B,KAAAA;CACrD,IAAI,CAAC6B,MAAM,OAAO,CAAA;CAElB,IAAM,EAACxC,cAAcC,iBAAiBT,WAAUY,gBAAgBkC,IAAI;CACpE,OAAO,CACL;EACEtC;EACAC;EACAuC,MAAMA,KAAKG,WAAW,KAAK,GAAG;EAE9BL;EAEAM,YAAYN,KAAKK,WAAW,KAAK,GAAG;EACpCnD;EAEA4B,OAAO,GAAG5B,OAAM,GAAIQ,aAAY,GAAIsC,KAAI,GAAIrC;CAC9C,CAAC;AAEL,CAAC,CAAC,CACD4C,MAAMC,GAAGC,MAAMtB,gBAAgBqB,EAAEtD,MAAM,IAAIiC,gBAAgBsB,EAAEvD,MAAM,CAAC,GAEhE0C,oBC5JI8B,0BAAyBC,UAAA;CAAA,IAAAC,IAAAC,EAAA,EAAA,GACpC,EAAAJ,WAAAK,OAAAC,YAAAC,OAGIL,OADU,EAAAM,aAAAD,IAAUE;CAAA,AAAAN,EAAA,OAAAK,YAAAL,EAAA,OAAAE,OAAAK,UAAAP,EAAA,OAAAE,OAAAM,YAItBF,MAAAG,UAAA;EACE,IAAAC,YAAkB,IAAIC,KAAIC,eAAgB,GAC1CJ,WAAiBN,OAAKM,YAAcE,UAASG,gBAAiB,CAAC,CAAAC;EAG/D,IACE,CAACL,SACDM,MAAKC,QAASP,KAAK,KADnB,EAEE,UAAUA,UACZA,MAAKQ,SAAU,SAHf,EAIE,WAAWR,UACb,OAAOA,MAAKP,SAAW,UAAQ;GAE/BG,SAASf,MAAM,CAAC;GAAC;EAAA;EAInB,IAAA4B,cAAoBT,MAAKP,OAMzBiB,mBAAyBzB,yBACvB,IAAI0B,KAAKF,WAAW,GACpBR,UAASG,gBAAiB,CAAC,CAAAC,UAC3BN,QACF,GAEAa,YAAkBvC,SAAS0B,UAAUW,gBAAgB,GACrDG,YAAkB9B,iBAAiB2B,kBAAkBX,UAAU,0BAA0B,GAEzFe,UAAgB,CAAA;EAahBlB,AAXAkB,QAAOC,KAAMnC,IAAI8B,iBAAgBM,YAAa,GAAG,CAAC,KAAK,CAAC,CAAC,GACzDF,QAAOC,KAAMnC,IAAIiC,WAAW,CAAC,OAAO,CAAC,CAAC,GAEjCpB,OAAKM,YACRe,QAAOC,KAAMnC,IAAImB,UAAU,CAAC,UAAU,CAAC,CAAC,GAGtCN,OAAKK,WAAac,aACpBE,QAAOC,KAAMnC,IAAIgC,WAAW,CAAC,QAAQ,CAAC,CAAC,GAGzChB,SAASkB,OAAO;CAAC,GAClBvB,EAAA,KAAAK,UAAAL,EAAA,KAAAE,OAAAK,QAAAP,EAAA,KAAAE,OAAAM,UAAAR,EAAA,KAAAM,MAAAA,KAAAN,EAAA;CA/CH,IAAA0B,mBAAyBpB,IAiDxBqB;CAAA,AAAA3B,EAAA,OAAAE,QAMyByB,KAAA3B,EAAA,MAFxB2B,KAAAzB,OAAK0B,OAAS1B,OAAKM,WACf1B,SAASoB,MAAKM,UAAW,IAAIY,KAAKlB,MAAK0B,GAAI,CACxB,IAAlB1B,OAAKK,UAAL,GAAmBP,EAAA,KAAAE,OAAAF,EAAA,KAAA2B;CAH1B,IAAAE,gBACEF,IAEwBG;CAAA,AAAA9B,EAAA,OAAA6B,iBAAA7B,EAAA,OAAAE,SAEJ4B,KAAA5B,OAAK0B,MAAQnC,sBAAsBS,MAAK0B,KAAMC,aAAkB,IAAhE,IAAiE7B,EAAA,KAAA6B,eAAA7B,EAAA,KAAAE,OAAAF,EAAA,KAAA8B,MAAAA,KAAA9B,EAAA;CAAvF,IAAA+B,gBAAsBD,IAAiEE;CAQnF,OARmFhC,EAAA,OAAA+B,iBAAA/B,EAAA,QAAA0B,oBAAA1B,EAAA,QAAAD,SAGrFiC,KAAA,oBAAC,eAAD;EAAc,GACRjC;EACA,IAAAA,MAAKI,WAAW8B;EACVP,UAAAA;EACHK,OAAAA;CAAa,CAAA,GACpB/B,EAAA,KAAA+B,eAAA/B,EAAA,MAAA0B,kBAAA1B,EAAA,MAAAD,OAAAC,EAAA,MAAAgC,MAAAA,KAAAhC,EAAA,KALFgC;AAKE,GCtEOS,kBAAiBC,UAAA;CAAA,IAAAC,IAAAC,EAAA,CAAA,GAC5B,EAAAL,SAAAC,aAA4BE,OAAKG;CAAA,IAAAF,EAAA,OAAAH,UAAA;EAEjC,IAAAS,kBAAwBH,IADFC,KAAIC,eACFF,CAAS,CAAAI,gBAAiB,CAAC,CAAAC;EAEwCR,AAA7EE,KAAAR,wBAAwBG,QAAoD,KAAvCH,wBAAwBY,eAAe,GAACN,EAAA,KAAAH,UAAAG,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAA3F,IAAAS,QAAcP,IAA6EQ;CAAA,AAAAV,EAAA,OAAAW,OAAAC,IAAA,2BAAA,KAKhFF,KAAA,EAAAG,OAAQ,OAAM,GAACb,EAAA,KAAAU,MAAAA,KAAAV,EAAA;CAKhB,IAAAc,KAAAL,SAAAZ,UAAiBkB;CAEvB,OAFuBf,EAAA,OAAAJ,WAAAI,EAAA,OAAAc,MAPzBC,KAAA,oBAAC,QAAD;EACY,UAAA;EACH,OAAAL;EACE,SAAA;EACHnB,MAAAA;EACD,MAAA;EACIK;EACH,MAAAkB;EACK,cAAA;CAAmB,CAAA,GAC9Bd,EAAA,KAAAJ,SAAAI,EAAA,KAAAc,IAAAd,EAAA,KAAAe,MAAAA,KAAAf,EAAA,IATFe;AASE,GCROqB,oBAAmBC,UAAA;CAAA,IAAAC,IAAAC,EAAA,EAAA,GAC9B,EAAAN,UAAAE,UAA0BE,OAAKG;CAAA,AAAAF,EAAA,OAAAG,OAAAC,IAAA,2BAAA,KACIF,KAAAX,gBAAgB,GAACS,EAAA,KAAAE,MAAAA,KAAAF,EAAA;CAApD,IAAAK,eAAmCH,IAAsBI;CAAA,AAAAN,EAAA,OAAAH,QAGuCS,KAAAN,EAAA,MAAtEM,KAAAT,OAAKU,WAAaf,yBAAyBK,MAAKU,QAAqB,IAArEC,KAAAA,GAAsER,EAAA,KAAAH,OAAAG,EAAA,KAAAM;CAAhG,IAAAG,oBAA0BH,IAAsEI;CAAA,AAAAV,EAAA,OAAAS,qBAAAT,EAAA,OAAAH,OAAAU,YAE9FG,KAAAL,aAAYM,MAAMC,SAAQC,KAAEC,SAAUjB,OAAKU,QACY,KAAvDF,aAAYM,MAAME,OAAQA,GAAEC,SAAUL,iBAAiB,GAACT,EAAA,KAAAS,mBAAAT,EAAA,KAAAH,OAAAU,UAAAP,EAAA,KAAAU,MAAAA,KAAAV,EAAA;CAF1D,IAAAe,YACEL,IACwDM;CAAA,IAAAhB,EAAA,OAAAG,OAAAC,IAAA,2BAAA,GAAA;EAE1D,IAAAgB,aAAmBH,IADGC,KAAIC,eACPF,CAAS,CAAAI,gBAAiB,CAAC,CAAAC;EAG7BtB,AAFDgB,KAAAX,aAAYM,MAAMY,SAAQV,KAAEC,SAAUM,UACD,KAAnDf,aAAYM,KAAMa,OAAiC,KACnDnB,aAAY,IAAGL,EAAA,KAAAgB;CAAA,OAAAA,KAAAhB,EAAA;CAFjB,IAAAyB,SAAgBT,IAEGU;CAAA,AAAA1B,EAAA,OAAAL,YAAAK,EAAA,OAAAH,SAGjB6B,MAAAC,eAAA;EACE,IAAAC,cAAoBvB,aAAYM,MAAMkB,SAAQhB,KAAEhB,UAAW8B,UAAoB,KAA3DF,QAGpBM,UAAgB,CADM3C,IAAIwC,YAAWd,MAAO,CAAC,UAAU,CACtCgB,CAAa;EAG9B,IAAIjC,OAAKmC,KAAK;GACZ,IAAAC,mBAAyBxC,yBACvB,IAAIyC,KAAKrC,MAAKmC,GAAI,GAClBnC,MAAKU,UACLqB,YAAWd,IACb,GACAqB,YAAkBzD,SAASkD,YAAWd,MAAOmB,gBAAgB,GAC7DG,eAAqB9C,iBACnB2C,kBACAL,YAAWd,MACX,0BACF;GAGAiB,AAFAA,QAAOM,KAAMjD,IAAI6C,iBAAgBK,YAAa,GAAG,CAAC,KAAK,CAAC,CAAC,GACzDP,QAAOM,KAAMjD,IAAIgD,cAAc,CAAC,OAAO,CAAC,CAAC,GACzCL,QAAOM,KAAMjD,IAAI+C,WAAW,CAAC,QAAQ,CAAC,CAAC;EAAC;EAE1CxC,SAASoC,OAAO;CAAC,GAClB/B,EAAA,KAAAL,UAAAK,EAAA,KAAAH,OAAAG,EAAA,KAAA0B,MAAAA,KAAA1B,EAAA;CAzBH,IAAAuC,uBAA6Bb,IA2B5Bc;CAAA,AAAAxC,EAAA,QAAAG,OAAAC,IAAA,2BAAA,KAecoC,KAAA;EAAAC,kBACWC,SAAQC;EAAKC,mBACZF,SAAQC;EAAKE,eACjB;EAAIC,WACR;CACb,GAAC9C,EAAA,MAAAwC,MAAAA,KAAAxC,EAAA;CAiBM,IAAA+C,KAAAhC,WAASlB,SAAW4B,OAAM5B,OAAMmD;CAErC,OAFqChD,EAAA,QAAAuC,wBAAAvC,EAAA,QAAA+C,MAhC3CC,KAAA,oBAAC,KAAD;EAAc,SAAA;EACZ,UAAA,oBAAC,cAAD;GACY,UAAA;GACJrE,MAAAA;GACH,IAAA;GACO4D,UAAAA;GACV,YAAA;GACSlC,SAAAA;GACA,SAAA;GACG,aAAA;GACH,SAAAmC;GAMK,cAAAS;GAWD,aAAAC;GAIH,UAAA;GACH,OAAAH;EAAgC,CAAA;CAhCvC,CAAA,GAkCE/C,EAAA,MAAAuC,sBAAAvC,EAAA,MAAA+C,IAAA/C,EAAA,MAAAgD,MAAAA,KAAAhD,EAAA,KAlCNgD;AAkCM;AAjFsB,SAAAxB,QAAA2B,MAAA;CAAA,OAYFtC,KAAEuC,iBAAkB;AAAK;AAZvB,SAAAH,SAAAI,QAAA;CAAA,OAiEpB,oBAAC,MAAD;EAAS,IAAA;EAAkB,SAAA;EACzB,UAAA,qBAAC,MAAD;GAAY,MAAA;GAAgB,cAAA;GAA5B,UAAA;IACE,qBAAA,QAAA,EAAA,UAAA,CAAM,OAAIA,OAAMC,MAAe,EAAA,CAAA;IAC/B,oBAAA,QAAA;KAAa,OAAA;MAAAC,YAAa;MAAGC,YAAc;KAAK;KAAIH,UAAAA,OAAMI;IAAwB,CAAA;IAClF,oBAAA,QAAA;KAAa,OAAA,EAAAD,YAAa,MAAK;KAAIH,UAAAA,OAAMK;IAAa,CAAA;GAHnD;;CADF,CAAA;AAME;AAvEa,SAAAR,OAAAS,GAAAC,UAAA;CA2EA,OAAjBP,WACE,GAAGA,SAAMI,gBAAgB,IAAKJ,SAAMQ,WAAW,KADlC;AACqC;ACvFnE,SAASa,WAAWC,OAAmC;CACrD,OACE,OAAOA,SAAU,cAAYA,SAAkB,WAAWA,SAASA,MAAMC,UAAU;AAEvF;AAEA,MAAaC,iBAAgBC,UAAA;CAAA,IAAAC,IAAAC,EAAA,EAAA,GAC3B,EAAAC,UAAAN,OAAAO,SAAAC,eAA+CL,OAC/C,EAAAM,YAAkBD,YAAUE;CAAA,AAAAN,EAAA,OAAAG,UACoEG,KAAAN,EAAA,MAA5EM,KAAAH,QAAOI,KAAMC,KAA8D,GAACR,EAAA,KAAAG,SAAAH,EAAA,KAAAM;CAAhG,IAAAG,cAAoBH,IAA4EI;CAAA,AAAAV,EAAA,OAAAG,UAG/FO,KAAAV,EAAA,MAFsBU,KAAAP,QAAOI,KAC5BI,MACF,GAACX,EAAA,KAAAG,SAAAH,EAAA,KAAAU;CAFD,IAAAE,iBAAuBF,IAGvB,CAAAG,sBAAAC,2BAAwD1B,SAAS,EAAK,GAAC2B;CAAA,AAAAf,EAAA,OAAAgB,OAAAC,IAAA,2BAAA,KAC3CF,WAAMD,wBAAwB,EAAK,GAACd,EAAA,KAAAe,MAAAA,KAAAf,EAAA;CAAhE,IAAAkB,UAAgBH,IAAqDI;CAAA,AAAAnB,EAAA,OAAAgB,OAAAC,IAAA,2BAAA,KAC1CE,WAAML,wBAAwB,EAAI,GAACd,EAAA,KAAAmB,MAAAA,KAAAnB,EAAA;CAA9D,IAAAoB,SAAeD,IAEfE,gBAAsB1B,WAAWC,KAAyB,IAApCA,QAAA0B,KAAAA,GAAqCC;CAAA,AAAAvB,EAAA,OAAAgB,OAAAC,IAAA,2BAAA,KAK1CM,KAAA;EAAC;EAAG;EAAG;CAAC,GAACvB,EAAA,KAAAuB,MAAAA,KAAAvB,EAAA;CAAA,IAAAwB;CAAA,AAAAxB,EAAA,OAAAS,eAAAT,EAAA,OAAAE,YAAAF,EAAA,OAAAK,WAAAL,EAAA,QAAAD,SAAAC,EAAA,QAAAqB,iBACjBG,KAAAf,eACC,oBAAC,mBAAD;EAAkB,GACZV;EACIU,QAAAA;EACK,cAAAgB,qBACX,oBAAC,wBAAD;GAAuB,GACjBA;GACOJ,WAAAA;GACC,YAAA;IAAA,GAAII,iBAAgBrB;IAAWC;GAAS;GACxC,YAAA;IAAA,GAAIoB,iBAAgBC;IAAWxB;GAAoB;EAAC,CAAA;CAEnE,CAAA,GAEJF,EAAA,KAAAS,aAAAT,EAAA,KAAAE,UAAAF,EAAA,KAAAK,SAAAL,EAAA,MAAAD,OAAAC,EAAA,MAAAqB,eAAArB,EAAA,MAAAwB,MAAAA,KAAAxB,EAAA;CAAA,IAAA2B;CAAA,AAAA3B,EAAA,QAAAwB,KACGG,KAAA3B,EAAA,OAfN2B,KAAA,oBAAC,KAAD;EAAW,MAAAJ;EACRC,UAAAA;CADC,CAAA,GAeExB,EAAA,MAAAwB,IAAAxB,EAAA,MAAA2B;CAAA,IAAAC,IAAAC;CAAA,AAAA7B,EAAA,QAAAgB,OAAAC,IAAA,2BAAA,KACKW,KAAA,CAAC,CAAC,GAAeC,KAAA;EAAC;EAAG;EAAG;EAAG;CAAC,GAAC7B,EAAA,MAAA4B,IAAA5B,EAAA,MAAA6B,OAAAD,KAAA5B,EAAA,KAAA6B,KAAA7B,EAAA;CAAA,IAAA8B;CAAA,AAAA9B,EAAA,QAAAD,SAAAC,EAAA,QAAAqB,eAAAU,YAAA/B,EAAA,QAAAY,kBACrCkB,KAAAlB,kBACC,oBAAC,mBAAD;EAAkB,GACZb;EACIa,QAAAA;EACK,mBACX,oBAAC,gBAAD;GAAyBQ,SAAAA;GAAkB,UAAAC,eAAaU,YAAb;EAA6B,CAAA;CACzE,CAAA,GAEJ/B,EAAA,MAAAD,OAAAC,EAAA,MAAAqB,eAAAU,UAAA/B,EAAA,MAAAY,gBAAAZ,EAAA,MAAA8B,MAAAA,KAAA9B,EAAA;CAAA,IAAAgC;CAAA,AAAAhC,EAAA,QAAA8B,KACGE,MAAAhC,EAAA,OAVNgC,MAAA,oBAAC,KAAD;EAAW,MAAAJ;EAAiB,YAAAC;EAAyB,WAAA;EAClDC,UAAAA;CADC,CAAA,GAUE9B,EAAA,MAAA8B,IAAA9B,EAAA,MAAAgC;CAAA,IAAAC;CAAA,AAAAjC,EAAA,QAAAgC,OAAAhC,EAAA,QAAA2B,MA3BRM,MAAA,qBAAC,MAAD,EAAA,UAAA,CACEN,IAgBAK,GAjBG,EAAA,CAAA,GA4BEhC,EAAA,MAAAgC,KAAAhC,EAAA,MAAA2B,IAAA3B,EAAA,MAAAiC,OAAAA,MAAAjC,EAAA;CAAA,IAAAkC;CAAA,AAAAlC,EAAA,QAAAE,YAAAF,EAAA,QAAAqB,iBAAArB,EAAA,QAAAa,wBACNqB,MAAArB,wBACC,oBAAC,QAAD;EAAiBK;EAAgB,QAAA;EAAuB,IAAA;EAAyB,OAAA;EAC/E,UAAA,oBAAC,kBAAD;GAA4BhB;GAAiBmB,OAAAA;EAAa,CAAA;CADrD,CAAA,GAGRrB,EAAA,MAAAE,UAAAF,EAAA,MAAAqB,eAAArB,EAAA,MAAAa,sBAAAb,EAAA,MAAAkC,OAAAA,MAAAlC,EAAA;CAAA,IAAAmC;CACA,OADAnC,EAAA,QAAAiC,OAAAjC,EAAA,QAAAkC,OAlCHC,MAAA,qBAAA,UAAA,EAAA,UAAA,CACEF,KA6BCC,GAIA,EAAA,CAAA,GACAlC,EAAA,MAAAiC,KAAAjC,EAAA,MAAAkC,KAAAlC,EAAA,MAAAmC,OAAAA,MAAAnC,EAAA,KAnCHmC;AAmCG;AAjDsB,SAAA3B,MAAA4B,QAAA;CAAA,OAGkBA,OAAMC,SAAU,WAAWD,OAAME,SAAU;AAAO;AAHpE,SAAA3B,OAAA4B,UAAA;CAAA,OAKbH,SAAMC,SAAU,WAAWD,SAAME,SAAU;AAAU;ACVrE,MAqBaiB,iBAAiBb,WAAW;CACvCc,MAAMV;CACNW,OAAO;CACPL,MAAM;CACNM,QAAQ;EACNjB,YAAY;GACVe,MAAM;GACNC,OAAO;GACPL,MAAM;EACR,CAAC;EACDX,YAAY;GACVe,MAAM;GACNC,OAAO;GACPL,MAAM;EACR,CAAC;EACDX,YAAY;GACVe,MAAM;GACNC,OAAO;GACPL,MAAM;EACR,CAAC;EACDX,YAAY;GACVe,MAAM;GACNC,OAAO;GACPL,MAAM;EACR,CAAC;CAAC;CAGJO,YAAY,EACVC,OAAOf,cACT;AACF,CAAC,GCvDYqB,WAAWL,aAAa;CACnCM,MAAM;CACNC,QAAQ,EACNC,OAAO,CAACN,cAAc,EACxB;AACF,CAAC"}
\ No newline at end of file
+{"version":3,"file":"index.js","names":["{onChange}","(patch: FormPatch | PatchEvent | FormPatch[]) => {\n const formatter = new Intl.DateTimeFormat()\n const timezone = value?.timezone ?? formatter.resolvedOptions().timeZone\n\n // Type guard to check if patch is a set patch with a value\n if (\n !patch ||\n Array.isArray(patch) ||\n !('type' in patch) ||\n patch.type !== 'set' ||\n !('value' in patch) ||\n typeof patch.value !== 'string'\n ) {\n onChange(unset())\n return\n }\n\n const newDatetime = patch.value\n\n /* get what time the user \"meant\" to set without tz info\n * right now, newDatetime is the time the user set plus\n * their current offset, not the timezone offset\n */\n const newUtcDateObject = shiftWallClockToTimeZone(\n new Date(newDatetime),\n formatter.resolvedOptions().timeZone,\n timezone,\n )\n // offset may have changed based on DST, capture that\n const newOffset = tzOffset(timezone, newUtcDateObject)\n const localDate = formatInTimeZone(newUtcDateObject, timezone, \"yyyy-MM-dd'T'HH:mm:ssXXX\")\n\n const patches = []\n\n patches.push(set(newUtcDateObject.toISOString(), ['utc']))\n patches.push(set(localDate, ['local']))\n\n if (!value?.timezone) {\n patches.push(set(timezone, ['timezone']))\n }\n\n if (value?.offset !== newOffset) {\n patches.push(set(newOffset, ['offset']))\n }\n\n onChange(patches)\n }","offset","timezone","useCallback(\n (patch: FormPatch | PatchEvent | FormPatch[]) => {\n const formatter = new Intl.DateTimeFormat()\n const timezone = value?.timezone ?? formatter.resolvedOptions().timeZone\n\n // Type guard to check if patch is a set patch with a value\n if (\n !patch ||\n Array.isArray(patch) ||\n !('type' in patch) ||\n patch.type !== 'set' ||\n !('value' in patch) ||\n typeof patch.value !== 'string'\n ) {\n onChange(unset())\n return\n }\n\n const newDatetime = patch.value\n\n /* get what time the user \"meant\" to set without tz info\n * right now, newDatetime is the time the user set plus\n * their current offset, not the timezone offset\n */\n const newUtcDateObject = shiftWallClockToTimeZone(\n new Date(newDatetime),\n formatter.resolvedOptions().timeZone,\n timezone,\n )\n // offset may have changed based on DST, capture that\n const newOffset = tzOffset(timezone, newUtcDateObject)\n const localDate = formatInTimeZone(newUtcDateObject, timezone, \"yyyy-MM-dd'T'HH:mm:ssXXX\")\n\n const patches = []\n\n patches.push(set(newUtcDateObject.toISOString(), ['utc']))\n patches.push(set(localDate, ['local']))\n\n if (!value?.timezone) {\n patches.push(set(timezone, ['timezone']))\n }\n\n if (value?.offset !== newOffset) {\n patches.push(set(newOffset, ['offset']))\n }\n\n onChange(patches)\n },\n [onChange, value],\n )","value?.utc && value?.timezone\n ? tzOffset(value.timezone, new Date(value.utc))\n : (value?.offset ?? 0)","value?.utc","value?.utc ? getConstructedUTCDate(value.utc, displayOffset) : ''","<DateTimeInput\n {...props}\n id={props.inputProps.id}\n onChange={handleDateChange}\n value={dateToDisplay}\n />","getTimeZoneAbbreviation(timezone) ?? getTimeZoneAbbreviation(currentTimezone)","{width: '100%'}","<Button\n fontSize={1}\n style={{width: '100%'}}\n justify={'flex-start'}\n icon={EarthAmericasIcon}\n mode=\"ghost\"\n onClick={onClick}\n text={label ?? timezone}\n aria-label=\"Select a timezone\"\n />","label ?? timezone","getAllTimezones()","useMemo(() => getAllTimezones(), [])","value?.timezone ? resolveCanonicalTimeZone(value.timezone) : undefined","value?.timezone","allTimezones.find((tz) => tz.name === value?.timezone) ??\n allTimezones.find((tz) => tz.name === canonicalStoredTz)","timezone","tz","allTimezones.find((tz) => tz.name === userTzName) ??\n allTimezones.find((tz) => tz.abbreviation === 'GMT') ??\n allTimezones[0]","(tz) => tz.abbreviation === 'GMT'","(selectedTz: string) => {\n const newTimezone = allTimezones.find((tz) => tz.value === selectedTz) ?? userTz\n\n const timezonePatch = set(newTimezone.name, ['timezone'])\n const patches = [timezonePatch]\n\n // then, recalculate UTC and local from \"old\" time with the new offset\n if (value?.utc) {\n const newUtcDateObject = shiftWallClockToTimeZone(\n new Date(value.utc),\n value.timezone,\n newTimezone.name,\n )\n const newOffset = tzOffset(newTimezone.name, newUtcDateObject)\n const newLocalDate = formatInTimeZone(\n newUtcDateObject,\n newTimezone.name,\n \"yyyy-MM-dd'T'HH:mm:ssXXX\",\n )\n patches.push(set(newUtcDateObject.toISOString(), ['utc']))\n patches.push(set(newLocalDate, ['local']))\n patches.push(set(newOffset, ['offset']))\n }\n onChange(patches)\n }","value?.utc","useCallback(\n (selectedTz: string) => {\n const newTimezone = allTimezones.find((tz) => tz.value === selectedTz) ?? userTz\n\n const timezonePatch = set(newTimezone.name, ['timezone'])\n const patches = [timezonePatch]\n\n // then, recalculate UTC and local from \"old\" time with the new offset\n if (value?.utc) {\n const newUtcDateObject = shiftWallClockToTimeZone(\n new Date(value.utc),\n value.timezone,\n newTimezone.name,\n )\n const newOffset = tzOffset(newTimezone.name, newUtcDateObject)\n const newLocalDate = formatInTimeZone(\n newUtcDateObject,\n newTimezone.name,\n \"yyyy-MM-dd'T'HH:mm:ssXXX\",\n )\n patches.push(set(newUtcDateObject.toISOString(), ['utc']))\n patches.push(set(newLocalDate, ['local']))\n patches.push(set(newOffset, ['offset']))\n }\n onChange(patches)\n },\n [allTimezones, onChange, userTz, value],\n )","{\n floatingBoundary: document.body,\n referenceBoundary: document.body,\n constrainSize: true,\n placement: 'bottom-start',\n }","<Box padding={4}>\n <Autocomplete\n fontSize={2}\n icon={SearchIcon}\n id=\"timezone\"\n onChange={handleTimezoneChange}\n openButton\n options={allTimezones}\n padding={4}\n placeholder=\"Search for a city or time zone\"\n popover={{\n floatingBoundary: document.body,\n referenceBoundary: document.body,\n constrainSize: true,\n placement: 'bottom-start',\n }}\n renderOption={(option) => {\n return (\n <Card as=\"button\" padding={3}>\n <Text size={1} textOverflow=\"ellipsis\">\n <span>GMT{option.offset}</span>\n <span style={{fontWeight: 500, marginLeft: '1em'}}>{option.alternativeName}</span>\n <span style={{marginLeft: '1em'}}>{option.city}</span>\n </Text>\n </Card>\n )\n }}\n renderValue={(_, option) => {\n if (!option) return ''\n return `${option.alternativeName} (${option.namePretty})`\n }}\n tabIndex={-1}\n value={currentTz?.value ?? userTz.value}\n />\n </Box>","currentTz?.value ?? userTz.value","(option) => {\n return (\n <Card as=\"button\" padding={3}>\n <Text size={1} textOverflow=\"ellipsis\">\n <span>GMT{option.offset}</span>\n <span style={{fontWeight: 500, marginLeft: '1em'}}>{option.alternativeName}</span>\n <span style={{marginLeft: '1em'}}>{option.city}</span>\n </Text>\n </Card>\n )\n }","(_, option) => {\n if (!option) return ''\n return `${option.alternativeName} (${option.namePretty})`\n }","option","members.find((member) => member.kind === 'field' && member.name === 'local')","(member) => member.kind === 'field' && member.name === 'local'","members.find(\n (member) => member.kind === 'field' && member.name === 'timezone',\n )","(member) => member.kind === 'field' && member.name === 'timezone'","() => setTimezoneSelectorOpen(false)","useCallback(() => setTimezoneSelectorOpen(false), [])","() => setTimezoneSelectorOpen(true)","useCallback(() => setTimezoneSelectorOpen(true), [])","[1, 2, 4]","localMember && (\n <ObjectInputMember\n {...props}\n member={localMember}\n renderField={(renderFieldProps) => (\n <RelativeDateTimePicker\n {...renderFieldProps}\n dateValue={richDateValue}\n schemaType={{...renderFieldProps.schemaType, options}}\n inputProps={{...renderFieldProps.inputProps, onChange: onChange}}\n />\n )}\n />\n )","<Box flex={[1, 2, 4]}>\n {localMember && (\n <ObjectInputMember\n {...props}\n member={localMember}\n renderField={(renderFieldProps) => (\n <RelativeDateTimePicker\n {...renderFieldProps}\n dateValue={richDateValue}\n schemaType={{...renderFieldProps.schemaType, options}}\n inputProps={{...renderFieldProps.inputProps, onChange: onChange}}\n />\n )}\n />\n )}\n </Box>","[1]","[2, 2, 3, 4]","timezoneMember && (\n <ObjectInputMember\n {...props}\n member={timezoneMember}\n renderInput={() => (\n <TimezoneButton onClick={onOpen} timezone={richDateValue?.timezone ?? ''} />\n )}\n />\n )","timezone","<Box flex={[1]} marginLeft={[2, 2, 3, 4]} marginTop={2}>\n {timezoneMember && (\n <ObjectInputMember\n {...props}\n member={timezoneMember}\n renderInput={() => (\n <TimezoneButton onClick={onOpen} timezone={richDateValue?.timezone ?? ''} />\n )}\n />\n )}\n </Box>","<Flex>\n <Box flex={[1, 2, 4]}>\n {localMember && (\n <ObjectInputMember\n {...props}\n member={localMember}\n renderField={(renderFieldProps) => (\n <RelativeDateTimePicker\n {...renderFieldProps}\n dateValue={richDateValue}\n schemaType={{...renderFieldProps.schemaType, options}}\n inputProps={{...renderFieldProps.inputProps, onChange: onChange}}\n />\n )}\n />\n )}\n </Box>\n <Box flex={[1]} marginLeft={[2, 2, 3, 4]} marginTop={2}>\n {timezoneMember && (\n <ObjectInputMember\n {...props}\n member={timezoneMember}\n renderInput={() => (\n <TimezoneButton onClick={onOpen} timezone={richDateValue?.timezone ?? ''} />\n )}\n />\n )}\n </Box>\n </Flex>","timezoneSelectorOpen && (\n <Dialog onClose={onClose} header=\"Select a timezone\" id=\"timezone-select\" width={1}>\n <TimezoneSelector onChange={onChange} value={richDateValue} />\n </Dialog>\n )","<>\n <Flex>\n <Box flex={[1, 2, 4]}>\n {localMember && (\n <ObjectInputMember\n {...props}\n member={localMember}\n renderField={(renderFieldProps) => (\n <RelativeDateTimePicker\n {...renderFieldProps}\n dateValue={richDateValue}\n schemaType={{...renderFieldProps.schemaType, options}}\n inputProps={{...renderFieldProps.inputProps, onChange: onChange}}\n />\n )}\n />\n )}\n </Box>\n <Box flex={[1]} marginLeft={[2, 2, 3, 4]} marginTop={2}>\n {timezoneMember && (\n <ObjectInputMember\n {...props}\n member={timezoneMember}\n renderInput={() => (\n <TimezoneButton onClick={onOpen} timezone={richDateValue?.timezone ?? ''} />\n )}\n />\n )}\n </Box>\n </Flex>\n {timezoneSelectorOpen && (\n <Dialog onClose={onClose} header=\"Select a timezone\" id=\"timezone-select\" width={1}>\n <TimezoneSelector onChange={onChange} value={richDateValue} />\n </Dialog>\n )}\n </>","member"],"sources":["../src/utils/index.ts","../src/components/RelativeDateTimePicker.tsx","../src/components/TimezoneButton.tsx","../src/components/TimezoneSelector.tsx","../src/components/RichDateInput.tsx","../src/schema.ts","../src/index.ts"],"sourcesContent":["import {tz, TZDate} from '@date-fns/tz'\nimport {format} from 'date-fns/format'\n\nimport type {NormalizedTimeZone} from '../types'\n\n/**\n * Formats `date` as seen in `timeZone`, using date-fns v4's `in` context\n * option with the official `@date-fns/tz` package (the replacement for\n * `date-fns-tz`'s `formatInTimeZone`).\n */\nexport const formatInTimeZone = (date: Date, timeZone: string, formatStr: string): string => {\n return format(date, formatStr, {in: tz(timeZone)})\n}\n\n/**\n * Returns the UTC instant whose wall-clock time in `toTimeZone` matches the\n * wall-clock time that `date` has in `fromTimeZone`. Reads the date components\n * in the source time zone and constructs a `TZDate` from them in the target\n * time zone, the same way sanity core re-interprets dates across time zones.\n * Replaces the `zonedTimeToUtc(formatInTimeZone(...))` round-trip previously\n * performed with `date-fns-tz`.\n */\nexport const shiftWallClockToTimeZone = (\n date: Date,\n fromTimeZone: string,\n toTimeZone: string,\n): Date => {\n const wallClock = new TZDate(date, fromTimeZone)\n return new Date(\n +new TZDate(\n wallClock.getFullYear(),\n wallClock.getMonth(),\n wallClock.getDate(),\n wallClock.getHours(),\n wallClock.getMinutes(),\n wallClock.getSeconds(),\n wallClock.getMilliseconds(),\n toTimeZone,\n ),\n )\n}\n\n/* We have to \"fake\" a UTC date to make the datepicker look \"right\"\n * to the user. For example, if someone sets 7:00AM PST, which is 3PM UTC\n * and I am on the east coast, I want to have 12:00PM UTC, which will look like 7:00AM to me\n * In other words, UTC minus 3 hours, or (UTC(my offset - their offset))\n * this is purely cosmetic and should not be saved at all\n */\nexport const getConstructedUTCDate = (utc: string, offset: number): string => {\n const date = new Date(utc)\n const currentOffset = date.getTimezoneOffset() * -1\n const diff = currentOffset - offset\n const fakeUTCDate = new Date(date.getTime() - diff * 60 * 1000)\n return fakeUTCDate.toISOString()\n}\n\ninterface TimeZoneInfo {\n abbreviation: string\n alternativeName: string\n offset: string\n}\n\nconst timeZoneInfoCache = new Map<string, TimeZoneInfo>()\n\nconst getTimeZoneInfo = (timeZone: string): TimeZoneInfo => {\n const cached = timeZoneInfoCache.get(timeZone)\n if (cached) return cached\n\n const now = new Date()\n const longFormatter = new Intl.DateTimeFormat(undefined, {timeZone, timeZoneName: 'long'})\n const shortFormatter = new Intl.DateTimeFormat(undefined, {timeZone, timeZoneName: 'short'})\n const rawOffset = format(now, 'xxx', {in: tz(timeZone)})\n // If the offset is +02:00 then we can just show +2, if it has +13:45 then we\n // should show +13:45; remove the leading zero and the trailing :00, and drop\n // +0 entirely so UTC renders as plain \"GMT\"\n const offset = rawOffset\n .replace(/([+-])0(\\d)/, '$1$2')\n .replace(/([+-])0$/, '$1')\n .replace(/:00$/, '')\n .replace(/[+]0$/, '')\n\n const info: TimeZoneInfo = {\n abbreviation:\n shortFormatter.formatToParts(now).find(({type}) => type === 'timeZoneName')?.value ?? '',\n alternativeName:\n longFormatter.formatToParts(now).find(({type}) => type === 'timeZoneName')?.value ?? '',\n offset,\n }\n timeZoneInfoCache.set(timeZone, info)\n return info\n}\n\n/**\n * Returns the localized abbreviation (e.g. `PST`, `GMT+2`) for any valid IANA\n * time zone name, or `undefined` when the name is not recognized by the\n * runtime.\n */\nexport const getTimeZoneAbbreviation = (timeZone: string): string | undefined => {\n try {\n return getTimeZoneInfo(timeZone).abbreviation\n } catch {\n return undefined\n }\n}\n\n/**\n * Resolves any valid IANA time zone name to the runtime's canonical\n * identifier, e.g. `Europe/Kyiv` to `Europe/Kiev` when the runtime lists the\n * latter. Documents written with older plugin versions may store alias\n * spellings that are absent from `Intl.supportedValuesOf('timeZone')`.\n * Returns `undefined` when the name is not recognized.\n */\nexport const resolveCanonicalTimeZone = (timeZone: string): string | undefined => {\n try {\n return new Intl.DateTimeFormat(undefined, {timeZone}).resolvedOptions().timeZone\n } catch {\n return undefined\n }\n}\n\nconst offsetToMinutes = (offset: string): number => {\n if (!offset) return 0\n const multiplier = offset.startsWith('-') ? -1 : 1\n if (!offset.includes(':')) return multiplier * Number(offset.replace(/[+-]/, '')) * 60\n\n const [hours = 0, minutes = 0] = offset.replace(/[+-]/, '').split(':').map(Number)\n return multiplier * (hours * 60 + minutes)\n}\n\nlet allTimezonesCache: NormalizedTimeZone[] | undefined\n\n/**\n * Lists the IANA time zones known to the runtime, normalized for the timezone\n * selector. Mirrors how sanity core builds its time zone list from\n * `Intl.supportedValuesOf` instead of shipping a static time zone database.\n * Computed lazily and cached, as enumerating the time zones is expensive.\n */\nexport const getAllTimezones = (): NormalizedTimeZone[] => {\n if (allTimezonesCache) return allTimezonesCache\n\n allTimezonesCache = Intl.supportedValuesOf('timeZone')\n .flatMap((name): NormalizedTimeZone[] => {\n // Skip time zones without a city component (e.g. plain 'UTC'). The city\n // is the last segment: 'America/Indiana/Indianapolis' -> 'Indianapolis'\n const segments = name.split('/')\n const city = segments.length > 1 ? segments.at(-1) : undefined\n if (!city) return []\n\n const {abbreviation, alternativeName, offset} = getTimeZoneInfo(name)\n return [\n {\n abbreviation,\n alternativeName,\n city: city.replaceAll('_', ' '),\n // Main time zone name 'Africa/Dar_es_Salaam'\n name,\n // Time zone name with underscores removed\n namePretty: name.replaceAll('_', ' '),\n offset,\n // all searchable text - this is transformed before being rendered in `<AutoComplete>`\n value: `${offset} ${abbreviation} ${name} ${alternativeName}`,\n },\n ]\n })\n .sort((a, b) => offsetToMinutes(a.offset) - offsetToMinutes(b.offset))\n\n return allTimezonesCache\n}\n","import {tzOffset} from '@date-fns/tz'\nimport {type ReactNode, useCallback} from 'react'\nimport {DateTimeInput, type FieldProps, type FormPatch, type PatchEvent, set, unset} from 'sanity'\n\nimport type {RichDate} from '../types'\nimport {formatInTimeZone, getConstructedUTCDate, shiftWallClockToTimeZone} from '../utils'\n\ninterface RelativeDateTimePickerProps extends Omit<FieldProps, 'renderDefault'> {\n dateValue?: RichDate\n}\nexport const RelativeDateTimePicker = (props: RelativeDateTimePickerProps): ReactNode => {\n const {\n dateValue: value,\n inputProps: {onChange},\n } = props\n\n const handleDateChange = useCallback(\n (patch: FormPatch | PatchEvent | FormPatch[]) => {\n const formatter = new Intl.DateTimeFormat()\n const timezone = value?.timezone ?? formatter.resolvedOptions().timeZone\n\n // Type guard to check if patch is a set patch with a value\n if (\n !patch ||\n Array.isArray(patch) ||\n !('type' in patch) ||\n patch.type !== 'set' ||\n !('value' in patch) ||\n typeof patch.value !== 'string'\n ) {\n onChange(unset())\n return\n }\n\n const newDatetime = patch.value\n\n /* get what time the user \"meant\" to set without tz info\n * right now, newDatetime is the time the user set plus\n * their current offset, not the timezone offset\n */\n const newUtcDateObject = shiftWallClockToTimeZone(\n new Date(newDatetime),\n formatter.resolvedOptions().timeZone,\n timezone,\n )\n // offset may have changed based on DST, capture that\n const newOffset = tzOffset(timezone, newUtcDateObject)\n const localDate = formatInTimeZone(newUtcDateObject, timezone, \"yyyy-MM-dd'T'HH:mm:ssXXX\")\n\n const patches = []\n\n patches.push(set(newUtcDateObject.toISOString(), ['utc']))\n patches.push(set(localDate, ['local']))\n\n if (!value?.timezone) {\n patches.push(set(timezone, ['timezone']))\n }\n\n if (value?.offset !== newOffset) {\n patches.push(set(newOffset, ['offset']))\n }\n\n onChange(patches)\n },\n [onChange, value],\n )\n\n // Dynamically calculate the offset for the actual event date to handle DST correctly\n const displayOffset =\n value?.utc && value?.timezone\n ? tzOffset(value.timezone, new Date(value.utc))\n : (value?.offset ?? 0)\n\n const dateToDisplay = value?.utc ? getConstructedUTCDate(value.utc, displayOffset) : ''\n return (\n // @ts-expect-error -- slight mismatch in elementProps and renderDefault, but should line up in practice\n <DateTimeInput\n {...props}\n id={props.inputProps.id}\n onChange={handleDateChange}\n value={dateToDisplay}\n />\n )\n}\n","import {EarthAmericasIcon} from '@sanity/icons/EarthAmericas'\nimport {Button} from '@sanity/ui'\nimport {type ReactNode} from 'react'\n\nimport {getTimeZoneAbbreviation} from '../utils'\n\ninterface TimezoneButtonProps {\n onClick: () => void\n timezone: string\n}\n\nexport const TimezoneButton = (props: TimezoneButtonProps): ReactNode => {\n const {onClick, timezone} = props\n const formatter = new Intl.DateTimeFormat()\n const currentTimezone = formatter.resolvedOptions().timeZone\n\n const label = getTimeZoneAbbreviation(timezone) ?? getTimeZoneAbbreviation(currentTimezone)\n\n return (\n <Button\n fontSize={1}\n style={{width: '100%'}}\n justify={'flex-start'}\n icon={EarthAmericasIcon}\n mode=\"ghost\"\n onClick={onClick}\n text={label ?? timezone}\n aria-label=\"Select a timezone\"\n />\n )\n}\n","import {tzOffset} from '@date-fns/tz'\nimport {SearchIcon} from '@sanity/icons/Search'\nimport {Box, Card, Text} from '@sanity/ui'\nimport {Autocomplete} from '@sanity/ui/autocomplete'\nimport {type ReactNode, useCallback, useMemo} from 'react'\nimport {type ObjectInputProps, set} from 'sanity'\n\nimport type {RichDate} from '../types'\nimport {\n formatInTimeZone,\n getAllTimezones,\n resolveCanonicalTimeZone,\n shiftWallClockToTimeZone,\n} from '../utils'\n\ninterface TimezoneSelectorProps {\n onChange: Pick<ObjectInputProps, 'onChange'>['onChange']\n value?: RichDate\n}\n\nexport const TimezoneSelector = (props: TimezoneSelectorProps): ReactNode => {\n const {onChange, value} = props\n const allTimezones = useMemo(() => getAllTimezones(), [])\n // Stored names may be aliases the runtime does not list (e.g. 'Europe/Kyiv'\n // vs 'Europe/Kiev'), so fall back to matching on the canonical identifier\n const canonicalStoredTz = value?.timezone ? resolveCanonicalTimeZone(value.timezone) : undefined\n const currentTz =\n allTimezones.find((tz) => tz.name === value?.timezone) ??\n allTimezones.find((tz) => tz.name === canonicalStoredTz)\n const formatter = new Intl.DateTimeFormat()\n const userTzName = formatter.resolvedOptions().timeZone\n const userTz = (allTimezones.find((tz) => tz.name === userTzName) ??\n allTimezones.find((tz) => tz.abbreviation === 'GMT') ??\n allTimezones[0])!\n\n const handleTimezoneChange = useCallback(\n (selectedTz: string) => {\n const newTimezone = allTimezones.find((tz) => tz.value === selectedTz) ?? userTz\n\n const timezonePatch = set(newTimezone.name, ['timezone'])\n const patches = [timezonePatch]\n\n // then, recalculate UTC and local from \"old\" time with the new offset\n if (value?.utc) {\n const newUtcDateObject = shiftWallClockToTimeZone(\n new Date(value.utc),\n value.timezone,\n newTimezone.name,\n )\n const newOffset = tzOffset(newTimezone.name, newUtcDateObject)\n const newLocalDate = formatInTimeZone(\n newUtcDateObject,\n newTimezone.name,\n \"yyyy-MM-dd'T'HH:mm:ssXXX\",\n )\n patches.push(set(newUtcDateObject.toISOString(), ['utc']))\n patches.push(set(newLocalDate, ['local']))\n patches.push(set(newOffset, ['offset']))\n }\n onChange(patches)\n },\n [allTimezones, onChange, userTz, value],\n )\n\n return (\n // taken from Scheduled Publishing, again!\n // https://github.com/sanity-io/sanity-plugin-scheduled-publishing/blob/bb282e3df9a8a73df37fab8ee1fdd0e2430745be/src/components/dialogs/DialogTimeZone.tsx#L100\n <Box padding={4}>\n <Autocomplete\n fontSize={2}\n icon={SearchIcon}\n id=\"timezone\"\n onChange={handleTimezoneChange}\n openButton\n options={allTimezones}\n padding={4}\n placeholder=\"Search for a city or time zone\"\n popover={{\n floatingBoundary: document.body,\n referenceBoundary: document.body,\n constrainSize: true,\n placement: 'bottom-start',\n }}\n renderOption={(option) => {\n return (\n <Card as=\"button\" padding={3}>\n <Text size={1} textOverflow=\"ellipsis\">\n <span>GMT{option.offset}</span>\n <span style={{fontWeight: 500, marginLeft: '1em'}}>{option.alternativeName}</span>\n <span style={{marginLeft: '1em'}}>{option.city}</span>\n </Text>\n </Card>\n )\n }}\n renderValue={(_, option) => {\n if (!option) return ''\n return `${option.alternativeName} (${option.namePretty})`\n }}\n tabIndex={-1}\n value={currentTz?.value ?? userTz.value}\n />\n </Box>\n )\n}\n","import {Box, Dialog, Flex} from '@sanity/ui'\nimport {type ReactNode, useCallback, useState} from 'react'\nimport {ObjectInputMember, type ObjectInputProps} from 'sanity'\n\nimport type {RichDate} from '../types'\nimport {RelativeDateTimePicker} from './RelativeDateTimePicker'\nimport {TimezoneButton} from './TimezoneButton'\nimport {TimezoneSelector} from './TimezoneSelector'\n\nfunction isRichDate(value: unknown): value is RichDate {\n return (\n typeof value === 'object' && value !== null && '_type' in value && value._type === 'richDate'\n )\n}\n\nexport const RichDateInput = (props: ObjectInputProps): ReactNode => {\n const {onChange, value, members, schemaType} = props\n const {options} = schemaType\n const localMember = members.find((member) => member.kind === 'field' && member.name === 'local')\n const timezoneMember = members.find(\n (member) => member.kind === 'field' && member.name === 'timezone',\n )\n const [timezoneSelectorOpen, setTimezoneSelectorOpen] = useState(false)\n const onClose = useCallback(() => setTimezoneSelectorOpen(false), [])\n const onOpen = useCallback(() => setTimezoneSelectorOpen(true), [])\n\n const richDateValue = isRichDate(value) ? value : undefined\n\n return (\n <>\n <Flex>\n <Box flex={[1, 2, 4]}>\n {localMember && (\n <ObjectInputMember\n {...props}\n member={localMember}\n renderField={(renderFieldProps) => (\n <RelativeDateTimePicker\n {...renderFieldProps}\n dateValue={richDateValue}\n schemaType={{...renderFieldProps.schemaType, options}}\n inputProps={{...renderFieldProps.inputProps, onChange: onChange}}\n />\n )}\n />\n )}\n </Box>\n <Box flex={[1]} marginLeft={[2, 2, 3, 4]} marginTop={2}>\n {timezoneMember && (\n <ObjectInputMember\n {...props}\n member={timezoneMember}\n renderInput={() => (\n <TimezoneButton onClick={onOpen} timezone={richDateValue?.timezone ?? ''} />\n )}\n />\n )}\n </Box>\n </Flex>\n {timezoneSelectorOpen && (\n <Dialog onClose={onClose} header=\"Select a timezone\" id=\"timezone-select\" width={1}>\n <TimezoneSelector onChange={onChange} value={richDateValue} />\n </Dialog>\n )}\n </>\n )\n}\n","import {\n type DatetimeDefinition,\n defineField,\n defineType,\n type ObjectDefinition,\n type ObjectSchemaType,\n} from 'sanity'\n\nimport {RichDateInput} from './components/RichDateInput'\n\nconst richDateTypeName = 'richDate' as const\n\nexport type RichDateSchemaType = Omit<ObjectSchemaType, 'options'> & {\n options?: DatetimeDefinition['options']\n}\n\n/**\n * @public\n */\nexport interface RichDateDefinition extends Omit<ObjectDefinition, 'type' | 'fields' | 'options'> {\n type: typeof richDateTypeName\n options?: DatetimeDefinition['options']\n}\n\ndeclare module 'sanity' {\n //allows the custom input to be valid for the schema def\n export interface IntrinsicDefinitions {\n richDate: RichDateDefinition\n }\n}\n\nexport const richDateSchema = defineType({\n name: richDateTypeName,\n title: 'Rich Date',\n type: 'object',\n fields: [\n defineField({\n name: 'local',\n title: 'Local',\n type: 'string',\n }),\n defineField({\n name: 'utc',\n title: 'UTC',\n type: 'string',\n }),\n defineField({\n name: 'timezone',\n title: 'Timezone',\n type: 'string',\n }),\n defineField({\n name: 'offset',\n title: 'Offset',\n type: 'number',\n }),\n ],\n\n components: {\n input: RichDateInput,\n },\n})\n","import '@sanity/ui/styles.css'\nimport {definePlugin} from 'sanity'\n\nimport {type RichDateDefinition, richDateSchema, type RichDateSchemaType} from './schema'\nimport type {RichDate} from './types'\n\nexport const richDate = definePlugin({\n name: 'v3-rich-date-input',\n schema: {\n types: [richDateSchema],\n },\n})\n\nexport type {RichDate, RichDateDefinition, RichDateSchemaType}\n"],"mappings":"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"}
\ No newline at end of file