@sanity/rich-date-input

4.1.64.1.7
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":["{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
+{"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    />","_c","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","_c","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","_c","_temp","_temp2","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","_c","_Fragment"],"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