@sanity/rich-date-input 0.147.10-ts-client.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,261 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', {
4
+ value: true
5
+ });
6
+ var sanity = require('sanity');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+ var ui = require('@sanity/ui');
9
+ var tzdb = require('@vvo/tzdb');
10
+ var dateFnsTz = require('date-fns-tz');
11
+ var icons = require('@sanity/icons');
12
+ var react = require('react');
13
+ const unlocalizeDateTime = (datetime, timezone) => {
14
+ return dateFnsTz.formatInTimeZone(datetime, timezone, "yyyy-MM-dd HH:mm:ss");
15
+ };
16
+ const getConstructedUTCDate = (utc, offset) => {
17
+ const date = new Date(utc);
18
+ const currentOffset = /* @__PURE__ */new Date().getTimezoneOffset() * -1;
19
+ const diff = currentOffset - offset;
20
+ const fakeUTCDate = new Date(date.getTime() - diff * 60 * 1e3);
21
+ return fakeUTCDate.toISOString();
22
+ };
23
+ const allTimezones = tzdb.getTimeZones().map(tz => {
24
+ return {
25
+ abbreviation: tz.abbreviation,
26
+ alternativeName: tz.alternativeName,
27
+ mainCities: tz.mainCities.join(", "),
28
+ // Main time zone name 'Africa/Dar_es_Salaam'
29
+ name: tz.name,
30
+ // Time zone name with underscores removed
31
+ namePretty: tz.name.replaceAll("_", " "),
32
+ offset: tz.currentTimeFormat.split(" ")[0],
33
+ // all searchable text - this is transformed before being rendered in `<AutoComplete>`
34
+ value: "".concat(tz.currentTimeFormat, " ").concat(tz.abbreviation, " ").concat(tz.name),
35
+ currentTimeOffsetInMinutes: tz.currentTimeOffsetInMinutes
36
+ };
37
+ });
38
+ const RelativeDateTimePicker = props => {
39
+ var _a, _b;
40
+ const value = props.dateValue;
41
+ const timezone = (_a = value == null ? void 0 : value.timezone) != null ? _a : Intl.DateTimeFormat().resolvedOptions().timeZone;
42
+ const offset = (_b = value == null ? void 0 : value.offset) != null ? _b : /* @__PURE__ */new Date().getTimezoneOffset() * -1;
43
+ const handleDateChange = patch => {
44
+ const patches = [];
45
+ const newDatetime = patch == null ? void 0 : patch.value;
46
+ if (!newDatetime || !("type" in patch) || patch.type !== "set") {
47
+ props.onChange(sanity.unset());
48
+ return;
49
+ }
50
+ const desiredDateTime = unlocalizeDateTime(newDatetime, Intl.DateTimeFormat().resolvedOptions().timeZone);
51
+ const utcDate = dateFnsTz.zonedTimeToUtc(desiredDateTime, timezone).toISOString();
52
+ const localDate = dateFnsTz.formatInTimeZone(utcDate, timezone, "yyyy-MM-dd'T'HH:mm:ssXXX");
53
+ patches.push(sanity.set(utcDate, ["utc"]));
54
+ patches.push(sanity.set(localDate, ["local"]));
55
+ if (!(value == null ? void 0 : value.timezone)) {
56
+ patches.push(sanity.set(timezone, ["timezone"]));
57
+ }
58
+ if (!(value == null ? void 0 : value.offset)) {
59
+ patches.push(sanity.set(offset, ["offset"]));
60
+ }
61
+ props.onChange(patches);
62
+ };
63
+ const dateToDisplay = (value == null ? void 0 : value.utc) ? getConstructedUTCDate(value.utc, value.offset) : "";
64
+ return /* @__PURE__ */jsxRuntime.jsx(sanity.DateTimeInput, {
65
+ ...props,
66
+ onChange: handleDateChange,
67
+ value: dateToDisplay
68
+ });
69
+ };
70
+ const TimezoneSelector = props => {
71
+ var _a;
72
+ const {
73
+ onChange,
74
+ value
75
+ } = props;
76
+ const currentTz = allTimezones.find(tz => tz.name === (value == null ? void 0 : value.timezone));
77
+ const userTz = allTimezones.find(tz => tz.name === Intl.DateTimeFormat().resolvedOptions().timeZone);
78
+ const handleTimezoneChange = selectedTz => {
79
+ var _a2, _b;
80
+ const newTimezone = (_a2 = allTimezones.find(tz => tz.value === selectedTz)) != null ? _a2 : userTz;
81
+ const offset = (_b = newTimezone.currentTimeOffsetInMinutes) != null ? _b : 0;
82
+ const timezonePatch = sanity.set(newTimezone.name, ["timezone"]);
83
+ const offsetPatch = sanity.set(offset, ["offset"]);
84
+ const patches = [timezonePatch, offsetPatch];
85
+ if (value == null ? void 0 : value.utc) {
86
+ const desiredDateTime = unlocalizeDateTime(value.utc, value.timezone);
87
+ const newUtcDate = dateFnsTz.zonedTimeToUtc(desiredDateTime, newTimezone.name).toISOString();
88
+ const newLocalDate = dateFnsTz.formatInTimeZone(newUtcDate, newTimezone.name, "yyyy-MM-dd'T'HH:mm:ssXXX");
89
+ patches.push(sanity.set(newUtcDate, ["utc"]));
90
+ patches.push(sanity.set(newLocalDate, ["local"]));
91
+ }
92
+ onChange(patches);
93
+ };
94
+ return (
95
+ //taken from Scheduled Publishing, again!
96
+ //https://github.com/sanity-io/sanity-plugin-scheduled-publishing/blob/bb282e3df9a8a73df37fab8ee1fdd0e2430745be/src/components/dialogs/DialogTimeZone.tsx#L100
97
+ /* @__PURE__ */
98
+ jsxRuntime.jsx(ui.Box, {
99
+ padding: 4,
100
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Autocomplete, {
101
+ fontSize: 2,
102
+ icon: icons.SearchIcon,
103
+ id: "timezone",
104
+ onChange: handleTimezoneChange,
105
+ openButton: true,
106
+ options: allTimezones,
107
+ padding: 4,
108
+ placeholder: "Search for a city or time zone",
109
+ popover: {
110
+ boundaryElement: document.querySelector("body"),
111
+ constrainSize: true,
112
+ placement: "bottom-start"
113
+ },
114
+ renderOption: option => {
115
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
116
+ as: "button",
117
+ padding: 3,
118
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
119
+ size: 1,
120
+ textOverflow: "ellipsis",
121
+ children: [/* @__PURE__ */jsxRuntime.jsxs("span", {
122
+ children: ["GMT", option.offset]
123
+ }), /* @__PURE__ */jsxRuntime.jsx("span", {
124
+ style: {
125
+ fontWeight: 500,
126
+ marginLeft: "1em"
127
+ },
128
+ children: option.alternativeName
129
+ }), /* @__PURE__ */jsxRuntime.jsx("span", {
130
+ style: {
131
+ marginLeft: "1em"
132
+ },
133
+ children: option.mainCities
134
+ })]
135
+ })
136
+ });
137
+ },
138
+ renderValue: (_, option) => {
139
+ if (!option) return "";
140
+ return "".concat(option.alternativeName, " (").concat(option.namePretty, ")");
141
+ },
142
+ tabIndex: -1,
143
+ value: (_a = currentTz == null ? void 0 : currentTz.value) != null ? _a : userTz.value
144
+ })
145
+ })
146
+ );
147
+ };
148
+ const TimezoneButton = props => {
149
+ var _a, _b, _c;
150
+ const {
151
+ onClick,
152
+ timezone
153
+ } = props;
154
+ const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
155
+ const label = (_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;
156
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
157
+ fontSize: 1,
158
+ style: {
159
+ width: "100%"
160
+ },
161
+ justify: "flex-start",
162
+ icon: icons.EarthAmericasIcon,
163
+ mode: "ghost",
164
+ onClick,
165
+ text: "".concat(label),
166
+ "aria-label": "Select a timezone"
167
+ });
168
+ };
169
+ const RichDateInput = props => {
170
+ const {
171
+ onChange,
172
+ value,
173
+ members,
174
+ schemaType
175
+ } = props;
176
+ const {
177
+ options
178
+ } = schemaType;
179
+ const localMember = members.find(member => member.kind === "field" && member.name === "local");
180
+ const timezoneMember = members.find(member => member.kind === "field" && member.name === "timezone");
181
+ const [timezoneSelectorOpen, setTimezoneSelectorOpen] = react.useState(false);
182
+ const onClose = react.useCallback(() => setTimezoneSelectorOpen(false), []);
183
+ const onOpen = react.useCallback(() => setTimezoneSelectorOpen(true), []);
184
+ return /* @__PURE__ */jsxRuntime.jsxs(jsxRuntime.Fragment, {
185
+ children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
186
+ children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
187
+ flex: [1, 2, 4],
188
+ children: localMember && /* @__PURE__ */jsxRuntime.jsx(sanity.ObjectInputMember, {
189
+ ...props,
190
+ member: localMember,
191
+ renderInput: renderInputProps => /* @__PURE__ */jsxRuntime.jsx(RelativeDateTimePicker, {
192
+ ...renderInputProps,
193
+ dateValue: value,
194
+ schemaType: {
195
+ ...renderInputProps.schemaType,
196
+ options
197
+ },
198
+ onChange
199
+ })
200
+ })
201
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
202
+ flex: [1],
203
+ marginLeft: [2, 2, 3, 4],
204
+ children: timezoneMember && /* @__PURE__ */jsxRuntime.jsx(sanity.ObjectInputMember, {
205
+ ...props,
206
+ member: timezoneMember,
207
+ renderInput: () => {
208
+ var _a;
209
+ return /* @__PURE__ */jsxRuntime.jsx(TimezoneButton, {
210
+ onClick: onOpen,
211
+ timezone: (_a = value == null ? void 0 : value.timezone) != null ? _a : ""
212
+ });
213
+ }
214
+ })
215
+ })]
216
+ }), timezoneSelectorOpen && /* @__PURE__ */jsxRuntime.jsx(ui.Dialog, {
217
+ onClose,
218
+ header: "Select a timezone",
219
+ id: "timezone-select",
220
+ width: 1,
221
+ children: /* @__PURE__ */jsxRuntime.jsx(TimezoneSelector, {
222
+ onChange,
223
+ value
224
+ })
225
+ })]
226
+ });
227
+ };
228
+ const richDateTypeName = "richDate";
229
+ const richDateSchema = sanity.defineType({
230
+ name: richDateTypeName,
231
+ title: "Rich Date",
232
+ type: "object",
233
+ fields: [sanity.defineField({
234
+ name: "local",
235
+ title: "Local",
236
+ type: "string"
237
+ }), sanity.defineField({
238
+ name: "utc",
239
+ title: "UTC",
240
+ type: "string"
241
+ }), sanity.defineField({
242
+ name: "timezone",
243
+ title: "Timezone",
244
+ type: "string"
245
+ }), sanity.defineField({
246
+ name: "offset",
247
+ title: "Offset",
248
+ type: "number"
249
+ })],
250
+ components: {
251
+ input: RichDateInput
252
+ }
253
+ });
254
+ const richDate = sanity.definePlugin({
255
+ name: "v3-rich-date-input",
256
+ schema: {
257
+ types: [richDateSchema]
258
+ }
259
+ });
260
+ exports.richDate = richDate;
261
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.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 } 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 userTz = allTimezones.find(\n (tz) => tz.name === Intl.DateTimeFormat().resolvedOptions().timeZone,\n )!\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'\nimport {NormalizedTimeZone} from '../types'\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 const label =\n allTimezones.find((tz: NormalizedTimeZone) => tz.name === timezone)?.abbreviation ??\n allTimezones.find((tz: NormalizedTimeZone) => tz.name === 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","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","userTz","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","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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"}
package/package.json CHANGED
@@ -1,14 +1,7 @@
1
1
  {
2
2
  "name": "@sanity/rich-date-input",
3
- "version": "0.147.10-ts-client.1+5473a24ff",
4
- "description": "Date/time input components for Sanity form builder",
5
- "main": "lib/index.js",
6
- "author": "Sanity.io <hello@sanity.io>",
7
- "license": "MIT",
8
- "scripts": {
9
- "clean": "rimraf lib",
10
- "prepublishOnly": "sanity-check"
11
- },
3
+ "version": "1.0.0",
4
+ "description": "A timezone-aware datetime type and input component for Sanity Studio",
12
5
  "keywords": [
13
6
  "sanity",
14
7
  "cms",
@@ -18,25 +11,87 @@
18
11
  "rich-date-input",
19
12
  "sanity-plugin"
20
13
  ],
21
- "dependencies": {
22
- "@sanity/generate-help-url": "0.147.10-ts-client.1+5473a24ff",
23
- "lodash": "^4.17.15",
24
- "moment": "^2.19.1",
25
- "moment-timezone": "^0.5.11",
26
- "prop-types": "^15.6.0",
27
- "react-datepicker": "^1.8.0"
28
- },
29
- "devDependencies": {
30
- "@sanity/check": "0.147.10-ts-client.1+5473a24ff",
31
- "rimraf": "^2.7.1"
14
+ "homepage": "https://github.com/sanity-io/rich-date-input#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/sanity-io/rich-date-input/issues"
32
17
  },
33
18
  "repository": {
34
19
  "type": "git",
35
- "url": "git+https://github.com/sanity-io/sanity.git"
20
+ "url": "git+ssh://git@github.com/sanity-io/rich-date-input.git"
36
21
  },
37
- "bugs": {
38
- "url": "https://github.com/sanity-io/sanity/issues"
22
+ "license": "MIT",
23
+ "author": "Sanity.io <hello@sanity.io>",
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "source": "./src/index.ts",
28
+ "require": "./dist/index.js",
29
+ "import": "./dist/index.esm.js",
30
+ "default": "./dist/index.esm.js"
31
+ },
32
+ "./package.json": "./package.json"
33
+ },
34
+ "main": "./dist/index.js",
35
+ "module": "./dist/index.esm.js",
36
+ "source": "./src/index.ts",
37
+ "types": "./dist/index.d.ts",
38
+ "files": [
39
+ "dist",
40
+ "sanity.json",
41
+ "src",
42
+ "v2-incompatible.js"
43
+ ],
44
+ "scripts": {
45
+ "build": "run-s clean && plugin-kit verify-package --silent && pkg-utils build --strict && pkg-utils --strict",
46
+ "clean": "rimraf dist",
47
+ "format": "prettier --write --cache --ignore-unknown .",
48
+ "link-watch": "plugin-kit link-watch",
49
+ "lint": "eslint .",
50
+ "prepublishOnly": "run-s build",
51
+ "watch": "pkg-utils watch --strict",
52
+ "prebuild": "plugin-kit verify-package --silent && pkg-utils",
53
+ "prepare": "husky install"
54
+ },
55
+ "dependencies": {
56
+ "@sanity/icons": "^2.7.0",
57
+ "@sanity/incompatible-plugin": "^1.0.4",
58
+ "@sanity/ui": "^1.9.3",
59
+ "@vvo/tzdb": "^6.112.0",
60
+ "date-fns-tz": "^2.0.0"
61
+ },
62
+ "devDependencies": {
63
+ "@commitlint/cli": "^18.4.1",
64
+ "@commitlint/config-conventional": "^18.4.0",
65
+ "@sanity/pkg-utils": "^3.2.3",
66
+ "@sanity/plugin-kit": "^3.1.10",
67
+ "@sanity/semantic-release-preset": "^4.1.6",
68
+ "@types/react": "^18.2.37",
69
+ "@typescript-eslint/eslint-plugin": "^6.11.0",
70
+ "@typescript-eslint/parser": "^6.11.0",
71
+ "eslint": "^8.53.0",
72
+ "eslint-config-prettier": "^9.0.0",
73
+ "eslint-config-sanity": "^7.0.1",
74
+ "eslint-plugin-prettier": "^5.0.1",
75
+ "eslint-plugin-react": "^7.33.2",
76
+ "eslint-plugin-react-hooks": "^4.6.0",
77
+ "husky": "^8.0.3",
78
+ "lint-staged": "^15.1.0",
79
+ "npm-run-all": "^4.1.5",
80
+ "prettier": "^3.1.0",
81
+ "prettier-plugin-packagejson": "^2.4.6",
82
+ "react": "^18.2.0",
83
+ "react-dom": "^18.2.0",
84
+ "react-is": "^18.2.0",
85
+ "rimraf": "^5.0.5",
86
+ "sanity": "^3.19.3",
87
+ "styled-components": "^5.3.11",
88
+ "typescript": "^5.2.2"
89
+ },
90
+ "peerDependencies": {
91
+ "react": "^18",
92
+ "sanity": "^3"
39
93
  },
40
- "homepage": "https://www.sanity.io/",
41
- "gitHead": "5473a24ff3431de02eed65e8b70e3487fb03e2da"
94
+ "engines": {
95
+ "node": ">=14"
96
+ }
42
97
  }
package/sanity.json CHANGED
@@ -1,21 +1,8 @@
1
1
  {
2
- "paths": {
3
- "source": "./src",
4
- "compiled": "./lib"
5
- },
6
-
7
2
  "parts": [
8
3
  {
9
- "implements": "part:@sanity/form-builder/input/rich-date",
10
- "path": "RichDate"
11
- },
12
- {
13
- "implements": "part:@sanity/form-builder/input/rich-date/schema",
14
- "path": "schema"
15
- },
16
- {
17
- "implements": "part:@sanity/base/component",
18
- "path": "story.js"
4
+ "implements": "part:@sanity/base/sanity-root",
5
+ "path": "./v2-incompatible.js"
19
6
  }
20
7
  ]
21
8
  }
@@ -0,0 +1,56 @@
1
+ import {DateTimeInput, FormPatch, PatchEvent, InputProps, set, unset} from 'sanity'
2
+
3
+ import {getConstructedUTCDate, unlocalizeDateTime} from '../utils'
4
+ import {RichDate} from '../types'
5
+ import {formatInTimeZone, zonedTimeToUtc} from 'date-fns-tz'
6
+
7
+ interface RelativeDateTimePickerProps extends Omit<InputProps, 'renderDefault'> {
8
+ dateValue?: RichDate
9
+ }
10
+
11
+ export const RelativeDateTimePicker = (props: RelativeDateTimePickerProps) => {
12
+ const value = props.dateValue
13
+ const timezone = value?.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone
14
+ /*
15
+ * if our offset is not coming from a lib, we have to reverse it
16
+ * to get the real offset used everywhere
17
+ * https://momentjscom.readthedocs.io/en/latest/moment/03-manipulating/09-utc-offset/
18
+ */
19
+ const offset = value?.offset ?? new Date().getTimezoneOffset() * -1
20
+ const handleDateChange = (patch: FormPatch | PatchEvent | FormPatch[]) => {
21
+ const patches = []
22
+ const newDatetime = (patch as unknown as {value: string})?.value
23
+ if (!newDatetime || !('type' in patch) || patch.type !== 'set') {
24
+ props.onChange(unset())
25
+ return
26
+ }
27
+
28
+ //get what time the user "meant" to set without tz info
29
+ //since the datepicker always localizes to the user's timezone
30
+ const desiredDateTime = unlocalizeDateTime(
31
+ newDatetime,
32
+ Intl.DateTimeFormat().resolvedOptions().timeZone,
33
+ )
34
+
35
+ //use the user-selected timezone here
36
+ const utcDate = zonedTimeToUtc(desiredDateTime, timezone).toISOString()
37
+ const localDate = formatInTimeZone(utcDate, timezone, "yyyy-MM-dd'T'HH:mm:ssXXX")
38
+
39
+ patches.push(set(utcDate, ['utc']))
40
+ patches.push(set(localDate, ['local']))
41
+
42
+ if (!value?.timezone) {
43
+ patches.push(set(timezone, ['timezone']))
44
+ }
45
+
46
+ if (!value?.offset) {
47
+ patches.push(set(offset, ['offset']))
48
+ }
49
+
50
+ props.onChange(patches)
51
+ }
52
+
53
+ const dateToDisplay = value?.utc ? getConstructedUTCDate(value.utc, value.offset) : ''
54
+ //@ts-expect-error -- slight mismatch in elementProps and renderDefault, but should line up in practice
55
+ return <DateTimeInput {...props} onChange={handleDateChange} value={dateToDisplay} />
56
+ }
@@ -0,0 +1,58 @@
1
+ import {ObjectInputMember, ObjectInputProps} from 'sanity'
2
+ import {Box, Flex, Dialog} from '@sanity/ui'
3
+ import {RelativeDateTimePicker} from './RelativeDateTimePicker'
4
+ import {TimezoneSelector} from './TimezoneSelector'
5
+ import {useCallback, useState} from 'react'
6
+ import {TimezoneButton} from './TimezoneButton'
7
+ import {RichDate} from '../types'
8
+
9
+ export const RichDateInput = (props: ObjectInputProps) => {
10
+ const {onChange, value, members, schemaType} = props
11
+ const {options} = schemaType
12
+ const localMember = members.find((member) => member.kind === 'field' && member.name === 'local')
13
+ const timezoneMember = members.find(
14
+ (member) => member.kind === 'field' && member.name === 'timezone',
15
+ )
16
+ const [timezoneSelectorOpen, setTimezoneSelectorOpen] = useState(false)
17
+ const onClose = useCallback(() => setTimezoneSelectorOpen(false), [])
18
+ const onOpen = useCallback(() => setTimezoneSelectorOpen(true), [])
19
+
20
+ return (
21
+ <>
22
+ <Flex>
23
+ <Box flex={[1, 2, 4]}>
24
+ {localMember && (
25
+ <ObjectInputMember
26
+ {...props}
27
+ member={localMember}
28
+ renderInput={(renderInputProps) => (
29
+ <RelativeDateTimePicker
30
+ {...renderInputProps}
31
+ dateValue={value as RichDate}
32
+ schemaType={{...renderInputProps.schemaType, options}}
33
+ onChange={onChange}
34
+ />
35
+ )}
36
+ />
37
+ )}
38
+ </Box>
39
+ <Box flex={[1]} marginLeft={[2, 2, 3, 4]}>
40
+ {timezoneMember && (
41
+ <ObjectInputMember
42
+ {...props}
43
+ member={timezoneMember}
44
+ renderInput={() => (
45
+ <TimezoneButton onClick={onOpen} timezone={value?.timezone ?? ''} />
46
+ )}
47
+ />
48
+ )}
49
+ </Box>
50
+ </Flex>
51
+ {timezoneSelectorOpen && (
52
+ <Dialog onClose={onClose} header="Select a timezone" id="timezone-select" width={1}>
53
+ <TimezoneSelector onChange={onChange} value={value as RichDate} />
54
+ </Dialog>
55
+ )}
56
+ </>
57
+ )
58
+ }
@@ -0,0 +1,30 @@
1
+ import {Button} from '@sanity/ui'
2
+ import {EarthAmericasIcon} from '@sanity/icons'
3
+ import {allTimezones} from '../utils'
4
+ import {NormalizedTimeZone} from '../types'
5
+
6
+ interface TimezoneButtonProps {
7
+ onClick: () => void
8
+ timezone: string
9
+ }
10
+
11
+ export const TimezoneButton = (props: TimezoneButtonProps) => {
12
+ const {onClick, timezone} = props
13
+ const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone
14
+ const label =
15
+ allTimezones.find((tz: NormalizedTimeZone) => tz.name === timezone)?.abbreviation ??
16
+ allTimezones.find((tz: NormalizedTimeZone) => tz.name === currentTimezone)?.abbreviation
17
+
18
+ return (
19
+ <Button
20
+ fontSize={1}
21
+ style={{width: '100%'}}
22
+ justify={'flex-start'}
23
+ icon={EarthAmericasIcon}
24
+ mode="ghost"
25
+ onClick={onClick}
26
+ text={`${label}`}
27
+ aria-label="Select a timezone"
28
+ />
29
+ )
30
+ }