@sanity/rich-date-input 2.0.10 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2016 - 2020 Sanity.io
3
+ Copyright (c) 2023 Sanity.io
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,50 +1,84 @@
1
- > This is a **Sanity Studio v2 plugin. For the v3 version, please switch to the [main branch](https://github.com/sanity-io/rich-date-input).
1
+ > This is a **Sanity Studio v3** plugin.
2
+ > For the v2 version, please refer to the [studio-v2 branch](https://github.com/sanity-io/rich-date-input/tree/studio-v2).
2
3
 
3
- ### @sanity/rich-date-input
4
- A richer date/time type and input component for Sanity form builder
4
+ # V3 Rich Date Input
5
+
6
+ Provides a timezone-aware date input for Sanity Studio.
7
+
8
+ ![This is an image](assets/plugin.gif)
9
+
10
+ ## Installation
11
+
12
+ ```sh
13
+ npm install @sanity/rich-date-input
14
+ ```
5
15
 
6
16
  ## Usage
7
17
 
8
- - `sanity install @sanity/rich-date-input@studio-v2`
9
- - In your schema:
10
- ```js
11
- import richDate from 'part:@sanity/form-builder/input/rich-date/schema'
18
+ Add it as a plugin in `sanity.config.ts` (or .js):
19
+
20
+ ```ts
21
+ import {defineConfig} from 'sanity'
22
+ import {richDate} from '@sanity/rich-date-input'
23
+
24
+ export default defineConfig({
25
+ //...
26
+ plugins: [richDate()],
27
+ })
28
+ ```
29
+
30
+ Then, use `richDate` as a type in your schema:
12
31
 
13
- // ...
14
- export default createSchema({
15
- name: 'mySchema',
16
- types: [
17
- //...
18
- richDate
19
- ]
20
- })
32
+ ```ts
33
+ import {defineField, defineType} from 'sanity'
21
34
 
22
- ```
35
+ export default defineType({
36
+ name: 'event',
37
+ title: 'Event',
38
+ type: 'document',
39
+ fields: [
40
+ defineField({
41
+ name: 'scheduledAt',
42
+ title: 'Scheduled at',
43
+ type: 'richDate',
44
+ //this will take the same options available on the datetime type: https://www.sanity.io/docs/datetime-type
45
+ options: {
46
+ timeStep: 30,
47
+ },
48
+ }),
49
+ ],
50
+ })
51
+ ```
52
+
53
+ When a user selects a date, the timezone will be stored in the document. They can choose a different timezone, if desired. The date displayed will be the time as it would be in that timezone. UTC will be calculated from the timezone and local time.
23
54
 
24
- Typical data output:
55
+ The typical data output should be:
25
56
 
26
- ```js
57
+ ```ts
27
58
  {
28
59
  _type: 'richDate',
29
- local: '2017-02-21T10:15:00+01:00',
30
- utc: '2017-02-12T09:15:00Z',
60
+ local: '2023-02-21T10:15:00+01:00',
61
+ utc: '2023-02-12T09:15:00Z',
31
62
  timezone: 'Europe/Oslo',
32
63
  offset: 60
33
64
  }
34
65
  ```
35
66
 
36
- ## Options
67
+ ## License
37
68
 
38
- This component accepts the following options via the Sanity schema:
69
+ [MIT](LICENSE) © Sanity.io
39
70
 
40
- ```
41
- options.dateFormat || 'YYYY-MM-DD'
42
- options.timeFormat || 'HH:mm'
43
- options.calendarTodayLabel || 'Today'
44
- options.timeStep || 15
45
- options.inputUtc || false
46
- options.inputDate || true
47
- options.inputTime || true
48
- options.placeholderDate || moment().format(options.dateFormat)
49
- options.placeholderTime || moment().format(options.timeFormat)
50
- ```
71
+ ## Develop & test
72
+
73
+ This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
74
+ with default configuration for build & watch scripts.
75
+
76
+ See [Testing a plugin in Sanity Studio](https://github.com/sanity-io/plugin-kit#testing-a-plugin-in-sanity-studio)
77
+ on how to run this plugin with hotreload in the studio.
78
+
79
+ ### Release new version
80
+
81
+ Run ["CI & Release" workflow](https://github.com/sanity-io/v3-rich-date-input/actions/workflows/main.yml).
82
+ Make sure to select the main branch and check "Release new version".
83
+
84
+ Semantic release will only release on configured branches, so it is safe to run release on any branch.
@@ -0,0 +1,36 @@
1
+ import {DatetimeDefinition} from 'sanity'
2
+ import {ObjectDefinition} from 'sanity'
3
+ import {ObjectSchemaType} from 'sanity'
4
+ import {Plugin as Plugin_2} from 'sanity'
5
+
6
+ export declare interface RichDate {
7
+ local: string
8
+ utc: string
9
+ timezone: string
10
+ offset: number
11
+ }
12
+
13
+ export declare const richDate: Plugin_2<void>
14
+
15
+ /**
16
+ * @public
17
+ */
18
+ export declare interface RichDateDefinition
19
+ extends Omit<ObjectDefinition, 'type' | 'fields' | 'options'> {
20
+ type: typeof richDateTypeName
21
+ options?: DatetimeDefinition['options']
22
+ }
23
+
24
+ export declare type RichDateSchemaType = Omit<ObjectSchemaType, 'options'> & {
25
+ options?: DatetimeDefinition['options']
26
+ }
27
+
28
+ declare const richDateTypeName: 'richDate'
29
+
30
+ export {}
31
+
32
+ declare module 'sanity' {
33
+ interface IntrinsicDefinitions {
34
+ richDate: RichDateDefinition
35
+ }
36
+ }
@@ -0,0 +1,258 @@
1
+ import { DateTimeInput, unset, set, ObjectInputMember, defineType, defineField, definePlugin } from 'sanity';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { Box, Autocomplete, Card, Text, Button, Flex, Dialog } from '@sanity/ui';
4
+ import { getTimeZones } from '@vvo/tzdb';
5
+ import { formatInTimeZone, zonedTimeToUtc } from 'date-fns-tz';
6
+ import { SearchIcon, EarthAmericasIcon } from '@sanity/icons';
7
+ import { useState, useCallback } from 'react';
8
+ const unlocalizeDateTime = (datetime, timezone) => {
9
+ return formatInTimeZone(datetime, timezone, "yyyy-MM-dd HH:mm:ss");
10
+ };
11
+ const getConstructedUTCDate = (utc, offset) => {
12
+ const date = new Date(utc);
13
+ const currentOffset = ( /* @__PURE__ */new Date()).getTimezoneOffset() * -1;
14
+ const diff = currentOffset - offset;
15
+ const fakeUTCDate = new Date(date.getTime() - diff * 60 * 1e3);
16
+ return fakeUTCDate.toISOString();
17
+ };
18
+ const allTimezones = getTimeZones().map(tz => {
19
+ return {
20
+ abbreviation: tz.abbreviation,
21
+ alternativeName: tz.alternativeName,
22
+ mainCities: tz.mainCities.join(", "),
23
+ // Main time zone name 'Africa/Dar_es_Salaam'
24
+ name: tz.name,
25
+ // Time zone name with underscores removed
26
+ namePretty: tz.name.replaceAll("_", " "),
27
+ offset: tz.currentTimeFormat.split(" ")[0],
28
+ // all searchable text - this is transformed before being rendered in `<AutoComplete>`
29
+ value: "".concat(tz.currentTimeFormat, " ").concat(tz.abbreviation, " ").concat(tz.name),
30
+ currentTimeOffsetInMinutes: tz.currentTimeOffsetInMinutes,
31
+ group: tz.group
32
+ };
33
+ });
34
+ const RelativeDateTimePicker = props => {
35
+ var _a, _b;
36
+ const value = props.dateValue;
37
+ const timezone = (_a = value == null ? void 0 : value.timezone) != null ? _a : Intl.DateTimeFormat().resolvedOptions().timeZone;
38
+ const offset = (_b = value == null ? void 0 : value.offset) != null ? _b : ( /* @__PURE__ */new Date()).getTimezoneOffset() * -1;
39
+ const handleDateChange = patch => {
40
+ const patches = [];
41
+ const newDatetime = patch == null ? void 0 : patch.value;
42
+ if (!newDatetime || !("type" in patch) || patch.type !== "set") {
43
+ props.onChange(unset());
44
+ return;
45
+ }
46
+ const desiredDateTime = unlocalizeDateTime(newDatetime, Intl.DateTimeFormat().resolvedOptions().timeZone);
47
+ const utcDate = zonedTimeToUtc(desiredDateTime, timezone).toISOString();
48
+ const localDate = formatInTimeZone(utcDate, timezone, "yyyy-MM-dd'T'HH:mm:ssXXX");
49
+ patches.push(set(utcDate, ["utc"]));
50
+ patches.push(set(localDate, ["local"]));
51
+ if (!(value == null ? void 0 : value.timezone)) {
52
+ patches.push(set(timezone, ["timezone"]));
53
+ }
54
+ if (!(value == null ? void 0 : value.offset)) {
55
+ patches.push(set(offset, ["offset"]));
56
+ }
57
+ props.onChange(patches);
58
+ };
59
+ const dateToDisplay = (value == null ? void 0 : value.utc) ? getConstructedUTCDate(value.utc, value.offset) : "";
60
+ return /* @__PURE__ */jsx(DateTimeInput, {
61
+ ...props,
62
+ onChange: handleDateChange,
63
+ value: dateToDisplay
64
+ });
65
+ };
66
+ const TimezoneSelector = props => {
67
+ var _a, _b;
68
+ const {
69
+ onChange,
70
+ value
71
+ } = props;
72
+ const currentTz = allTimezones.find(tz => tz.name === (value == null ? void 0 : value.timezone));
73
+ const userTzName = Intl.DateTimeFormat().resolvedOptions().timeZone;
74
+ const userTz = (_a = allTimezones.find(tz => tz.name === userTzName)) != null ? _a : allTimezones.find(tz => tz.group.includes(userTzName));
75
+ const handleTimezoneChange = selectedTz => {
76
+ var _a2, _b2;
77
+ const newTimezone = (_a2 = allTimezones.find(tz => tz.value === selectedTz)) != null ? _a2 : userTz;
78
+ const offset = (_b2 = newTimezone.currentTimeOffsetInMinutes) != null ? _b2 : 0;
79
+ const timezonePatch = set(newTimezone.name, ["timezone"]);
80
+ const offsetPatch = set(offset, ["offset"]);
81
+ const patches = [timezonePatch, offsetPatch];
82
+ if (value == null ? void 0 : value.utc) {
83
+ const desiredDateTime = unlocalizeDateTime(value.utc, value.timezone);
84
+ const newUtcDate = zonedTimeToUtc(desiredDateTime, newTimezone.name).toISOString();
85
+ const newLocalDate = formatInTimeZone(newUtcDate, newTimezone.name, "yyyy-MM-dd'T'HH:mm:ssXXX");
86
+ patches.push(set(newUtcDate, ["utc"]));
87
+ patches.push(set(newLocalDate, ["local"]));
88
+ }
89
+ onChange(patches);
90
+ };
91
+ return (
92
+ //taken from Scheduled Publishing, again!
93
+ //https://github.com/sanity-io/sanity-plugin-scheduled-publishing/blob/bb282e3df9a8a73df37fab8ee1fdd0e2430745be/src/components/dialogs/DialogTimeZone.tsx#L100
94
+ /* @__PURE__ */
95
+ jsx(Box, {
96
+ padding: 4,
97
+ children: /* @__PURE__ */jsx(Autocomplete, {
98
+ fontSize: 2,
99
+ icon: SearchIcon,
100
+ id: "timezone",
101
+ onChange: handleTimezoneChange,
102
+ openButton: true,
103
+ options: allTimezones,
104
+ padding: 4,
105
+ placeholder: "Search for a city or time zone",
106
+ popover: {
107
+ boundaryElement: document.querySelector("body"),
108
+ constrainSize: true,
109
+ placement: "bottom-start"
110
+ },
111
+ renderOption: option => {
112
+ return /* @__PURE__ */jsx(Card, {
113
+ as: "button",
114
+ padding: 3,
115
+ children: /* @__PURE__ */jsxs(Text, {
116
+ size: 1,
117
+ textOverflow: "ellipsis",
118
+ children: [/* @__PURE__ */jsxs("span", {
119
+ children: ["GMT", option.offset]
120
+ }), /* @__PURE__ */jsx("span", {
121
+ style: {
122
+ fontWeight: 500,
123
+ marginLeft: "1em"
124
+ },
125
+ children: option.alternativeName
126
+ }), /* @__PURE__ */jsx("span", {
127
+ style: {
128
+ marginLeft: "1em"
129
+ },
130
+ children: option.mainCities
131
+ })]
132
+ })
133
+ });
134
+ },
135
+ renderValue: (_, option) => {
136
+ if (!option) return "";
137
+ return "".concat(option.alternativeName, " (").concat(option.namePretty, ")");
138
+ },
139
+ tabIndex: -1,
140
+ value: (_b = currentTz == null ? void 0 : currentTz.value) != null ? _b : userTz.value
141
+ })
142
+ })
143
+ );
144
+ };
145
+ const TimezoneButton = props => {
146
+ var _a, _b, _c, _d, _e;
147
+ const {
148
+ onClick,
149
+ timezone
150
+ } = props;
151
+ const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
152
+ const label = (_e = (_c = (_a = allTimezones.find(tz => tz.name === timezone)) == null ? void 0 : _a.abbreviation) != null ? _c : (_b = allTimezones.find(tz => tz.name === currentTimezone)) == null ? void 0 : _b.abbreviation) != null ? _e : (_d = allTimezones.find(tz => tz.group.includes(currentTimezone))) == null ? void 0 : _d.abbreviation;
153
+ return /* @__PURE__ */jsx(Button, {
154
+ fontSize: 1,
155
+ style: {
156
+ width: "100%"
157
+ },
158
+ justify: "flex-start",
159
+ icon: EarthAmericasIcon,
160
+ mode: "ghost",
161
+ onClick,
162
+ text: "".concat(label),
163
+ "aria-label": "Select a timezone"
164
+ });
165
+ };
166
+ const RichDateInput = props => {
167
+ const {
168
+ onChange,
169
+ value,
170
+ members,
171
+ schemaType
172
+ } = props;
173
+ const {
174
+ options
175
+ } = schemaType;
176
+ const localMember = members.find(member => member.kind === "field" && member.name === "local");
177
+ const timezoneMember = members.find(member => member.kind === "field" && member.name === "timezone");
178
+ const [timezoneSelectorOpen, setTimezoneSelectorOpen] = useState(false);
179
+ const onClose = useCallback(() => setTimezoneSelectorOpen(false), []);
180
+ const onOpen = useCallback(() => setTimezoneSelectorOpen(true), []);
181
+ return /* @__PURE__ */jsxs(Fragment, {
182
+ children: [/* @__PURE__ */jsxs(Flex, {
183
+ children: [/* @__PURE__ */jsx(Box, {
184
+ flex: [1, 2, 4],
185
+ children: localMember && /* @__PURE__ */jsx(ObjectInputMember, {
186
+ ...props,
187
+ member: localMember,
188
+ renderInput: renderInputProps => /* @__PURE__ */jsx(RelativeDateTimePicker, {
189
+ ...renderInputProps,
190
+ dateValue: value,
191
+ schemaType: {
192
+ ...renderInputProps.schemaType,
193
+ options
194
+ },
195
+ onChange
196
+ })
197
+ })
198
+ }), /* @__PURE__ */jsx(Box, {
199
+ flex: [1],
200
+ marginLeft: [2, 2, 3, 4],
201
+ children: timezoneMember && /* @__PURE__ */jsx(ObjectInputMember, {
202
+ ...props,
203
+ member: timezoneMember,
204
+ renderInput: () => {
205
+ var _a;
206
+ return /* @__PURE__ */jsx(TimezoneButton, {
207
+ onClick: onOpen,
208
+ timezone: (_a = value == null ? void 0 : value.timezone) != null ? _a : ""
209
+ });
210
+ }
211
+ })
212
+ })]
213
+ }), timezoneSelectorOpen && /* @__PURE__ */jsx(Dialog, {
214
+ onClose,
215
+ header: "Select a timezone",
216
+ id: "timezone-select",
217
+ width: 1,
218
+ children: /* @__PURE__ */jsx(TimezoneSelector, {
219
+ onChange,
220
+ value
221
+ })
222
+ })]
223
+ });
224
+ };
225
+ const richDateTypeName = "richDate";
226
+ const richDateSchema = defineType({
227
+ name: richDateTypeName,
228
+ title: "Rich Date",
229
+ type: "object",
230
+ fields: [defineField({
231
+ name: "local",
232
+ title: "Local",
233
+ type: "string"
234
+ }), defineField({
235
+ name: "utc",
236
+ title: "UTC",
237
+ type: "string"
238
+ }), defineField({
239
+ name: "timezone",
240
+ title: "Timezone",
241
+ type: "string"
242
+ }), defineField({
243
+ name: "offset",
244
+ title: "Offset",
245
+ type: "number"
246
+ })],
247
+ components: {
248
+ input: RichDateInput
249
+ }
250
+ });
251
+ const richDate = definePlugin({
252
+ name: "v3-rich-date-input",
253
+ schema: {
254
+ types: [richDateSchema]
255
+ }
256
+ });
257
+ export { richDate };
258
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../src/utils/index.ts","../src/components/RelativeDateTimePicker.tsx","../src/components/TimezoneSelector.tsx","../src/components/TimezoneButton.tsx","../src/components/RichDateInput.tsx","../src/schema.ts","../src/index.ts"],"sourcesContent":["import {getTimeZones} from '@vvo/tzdb'\nimport {NormalizedTimeZone} from '../types'\nimport {formatInTimeZone} from 'date-fns-tz'\n\nexport const unlocalizeDateTime = (datetime: string, timezone: string): string => {\n return formatInTimeZone(datetime, timezone, 'yyyy-MM-dd HH:mm:ss')\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 = new Date().getTimezoneOffset() * -1\n const diff = currentOffset - offset\n const fakeUTCDate = new Date(date.getTime() - diff * 60 * 1000)\n return fakeUTCDate.toISOString()\n}\n\n//keep some consistency with scheduled publishing\n//https://github.com/sanity-io/sanity-plugin-scheduled-publishing/blob/bb282e3df9a8a73df37fab8ee1fdd0e2430745be/src/hooks/useTimeZone.tsx#L17\nexport const allTimezones = getTimeZones().map((tz) => {\n return {\n abbreviation: tz.abbreviation,\n alternativeName: tz.alternativeName,\n mainCities: tz.mainCities.join(', '),\n // Main time zone name 'Africa/Dar_es_Salaam'\n name: tz.name,\n // Time zone name with underscores removed\n namePretty: tz.name.replaceAll('_', ' '),\n offset: tz.currentTimeFormat.split(' ')[0],\n // all searchable text - this is transformed before being rendered in `<AutoComplete>`\n value: `${tz.currentTimeFormat} ${tz.abbreviation} ${tz.name}`,\n currentTimeOffsetInMinutes: tz.currentTimeOffsetInMinutes,\n group: tz.group,\n } as NormalizedTimeZone\n})\n","import {DateTimeInput, FormPatch, PatchEvent, InputProps, set, unset} from 'sanity'\n\nimport {getConstructedUTCDate, unlocalizeDateTime} from '../utils'\nimport {RichDate} from '../types'\nimport {formatInTimeZone, zonedTimeToUtc} from 'date-fns-tz'\n\ninterface RelativeDateTimePickerProps extends Omit<InputProps, 'renderDefault'> {\n dateValue?: RichDate\n}\n\nexport const RelativeDateTimePicker = (props: RelativeDateTimePickerProps) => {\n const value = props.dateValue\n const timezone = value?.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone\n /*\n * if our offset is not coming from a lib, we have to reverse it\n * to get the real offset used everywhere\n * https://momentjscom.readthedocs.io/en/latest/moment/03-manipulating/09-utc-offset/\n */\n const offset = value?.offset ?? new Date().getTimezoneOffset() * -1\n const handleDateChange = (patch: FormPatch | PatchEvent | FormPatch[]) => {\n const patches = []\n const newDatetime = (patch as unknown as {value: string})?.value\n if (!newDatetime || !('type' in patch) || patch.type !== 'set') {\n props.onChange(unset())\n return\n }\n\n //get what time the user \"meant\" to set without tz info\n //since the datepicker always localizes to the user's timezone\n const desiredDateTime = unlocalizeDateTime(\n newDatetime,\n Intl.DateTimeFormat().resolvedOptions().timeZone,\n )\n\n //use the user-selected timezone here\n const utcDate = zonedTimeToUtc(desiredDateTime, timezone).toISOString()\n const localDate = formatInTimeZone(utcDate, timezone, \"yyyy-MM-dd'T'HH:mm:ssXXX\")\n\n patches.push(set(utcDate, ['utc']))\n patches.push(set(localDate, ['local']))\n\n if (!value?.timezone) {\n patches.push(set(timezone, ['timezone']))\n }\n\n if (!value?.offset) {\n patches.push(set(offset, ['offset']))\n }\n\n props.onChange(patches)\n }\n\n const dateToDisplay = value?.utc ? getConstructedUTCDate(value.utc, value.offset) : ''\n //@ts-expect-error -- slight mismatch in elementProps and renderDefault, but should line up in practice\n return <DateTimeInput {...props} onChange={handleDateChange} value={dateToDisplay} />\n}\n","import {SearchIcon} from '@sanity/icons'\nimport {ObjectInputProps, set} from 'sanity'\nimport {allTimezones, unlocalizeDateTime} from '../utils'\nimport {NormalizedTimeZone, RichDate} from '../types'\nimport {Autocomplete, Card, Text, Box} from '@sanity/ui'\nimport {formatInTimeZone, zonedTimeToUtc} from 'date-fns-tz'\n\ninterface TimezoneSelectorProps {\n onChange: Pick<ObjectInputProps, 'onChange'>['onChange']\n value?: RichDate\n}\n\nexport const TimezoneSelector = (props: TimezoneSelectorProps) => {\n const {onChange, value} = props\n const currentTz = allTimezones.find((tz) => tz.name === value?.timezone)\n const userTzName = Intl.DateTimeFormat().resolvedOptions().timeZone\n const userTz = (allTimezones.find((tz) => tz.name === userTzName) ??\n allTimezones.find((tz) => tz.group.includes(userTzName)))!\n\n const handleTimezoneChange = (selectedTz: string) => {\n const newTimezone =\n allTimezones.find((tz) => tz.value === selectedTz) ?? (userTz as NormalizedTimeZone)\n\n const offset = newTimezone.currentTimeOffsetInMinutes ?? 0\n const timezonePatch = set(newTimezone.name, ['timezone'])\n const offsetPatch = set(offset, ['offset'])\n const patches = [timezonePatch, offsetPatch]\n\n //then, recalculate UTC and local from \"old\" time with the new offset\n if (value?.utc) {\n const desiredDateTime = unlocalizeDateTime(value.utc, value.timezone)\n const newUtcDate = zonedTimeToUtc(desiredDateTime, newTimezone.name).toISOString()\n const newLocalDate = formatInTimeZone(\n newUtcDate,\n newTimezone.name,\n \"yyyy-MM-dd'T'HH:mm:ssXXX\",\n )\n patches.push(set(newUtcDate, ['utc']))\n patches.push(set(newLocalDate, ['local']))\n }\n onChange(patches)\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 boundaryElement: document.querySelector('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.mainCities}</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 {Button} from '@sanity/ui'\nimport {EarthAmericasIcon} from '@sanity/icons'\nimport {allTimezones} from '../utils'\n\ninterface TimezoneButtonProps {\n onClick: () => void\n timezone: string\n}\n\nexport const TimezoneButton = (props: TimezoneButtonProps) => {\n const {onClick, timezone} = props\n const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone\n\n const label =\n allTimezones.find((tz) => tz.name === timezone)?.abbreviation ??\n allTimezones.find((tz) => tz.name === currentTimezone)?.abbreviation ??\n allTimezones.find((tz) => tz.group.includes(currentTimezone))?.abbreviation\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}`}\n aria-label=\"Select a timezone\"\n />\n )\n}\n","import {ObjectInputMember, ObjectInputProps} from 'sanity'\nimport {Box, Flex, Dialog} from '@sanity/ui'\nimport {RelativeDateTimePicker} from './RelativeDateTimePicker'\nimport {TimezoneSelector} from './TimezoneSelector'\nimport {useCallback, useState} from 'react'\nimport {TimezoneButton} from './TimezoneButton'\nimport {RichDate} from '../types'\n\nexport const RichDateInput = (props: ObjectInputProps) => {\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 return (\n <>\n <Flex>\n <Box flex={[1, 2, 4]}>\n {localMember && (\n <ObjectInputMember\n {...props}\n member={localMember}\n renderInput={(renderInputProps) => (\n <RelativeDateTimePicker\n {...renderInputProps}\n dateValue={value as RichDate}\n schemaType={{...renderInputProps.schemaType, options}}\n onChange={onChange}\n />\n )}\n />\n )}\n </Box>\n <Box flex={[1]} marginLeft={[2, 2, 3, 4]}>\n {timezoneMember && (\n <ObjectInputMember\n {...props}\n member={timezoneMember}\n renderInput={() => (\n <TimezoneButton onClick={onOpen} timezone={value?.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={value as RichDate} />\n </Dialog>\n )}\n </>\n )\n}\n","import {\n DatetimeDefinition,\n ObjectDefinition,\n ObjectSchemaType,\n defineField,\n defineType,\n} from 'sanity'\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 {definePlugin} from 'sanity'\nimport {richDateSchema, RichDateDefinition, RichDateSchemaType} from './schema'\nimport {RichDate} from './types'\n\nexport const richDate = definePlugin({\n name: 'v3-rich-date-input',\n schema: {\n types: [richDateSchema],\n },\n})\n\nexport type {RichDateDefinition, RichDateSchemaType, RichDate}\n"],"names":["unlocalizeDateTime","datetime","timezone","formatInTimeZone","getConstructedUTCDate","utc","offset","date","Date","currentOffset","getTimezoneOffset","diff","fakeUTCDate","getTime","toISOString","allTimezones","getTimeZones","map","tz","abbreviation","alternativeName","mainCities","join","name","namePretty","replaceAll","currentTimeFormat","split","value","concat","currentTimeOffsetInMinutes","group","RelativeDateTimePicker","props","_a","_b","dateValue","Intl","DateTimeFormat","resolvedOptions","timeZone","handleDateChange","patch","patches","newDatetime","type","onChange","unset","desiredDateTime","utcDate","zonedTimeToUtc","localDate","push","set","dateToDisplay","DateTimeInput","TimezoneSelector","currentTz","find","userTzName","userTz","includes","handleTimezoneChange","selectedTz","newTimezone","timezonePatch","offsetPatch","newUtcDate","newLocalDate","jsx","Box","padding","children","Autocomplete","fontSize","icon","SearchIcon","id","openButton","options","placeholder","popover","boundaryElement","document","querySelector","constrainSize","placement","renderOption","option","Card","as","jsxs","Text","size","textOverflow","style","fontWeight","marginLeft","renderValue","_","tabIndex","TimezoneButton","_c","_d","_e","onClick","currentTimezone","label","Button","width","justify","EarthAmericasIcon","mode","text","RichDateInput","members","schemaType","localMember","member","kind","timezoneMember","timezoneSelectorOpen","setTimezoneSelectorOpen","useState","onClose","useCallback","onOpen","Fragment","Flex","flex","ObjectInputMember","renderInput","renderInputProps","Dialog","header","richDateTypeName","richDateSchema","defineType","title","fields","defineField","components","input","richDate","definePlugin","schema","types"],"mappings":"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"}