react-timezone-select 2.0.1 → 2.1.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/README.md CHANGED
@@ -138,6 +138,32 @@ timezones={{
138
138
  - `maxAbbrLength` - `number` - Truncate `abbrev` labelStyles string to length
139
139
  - Any other [`react-select`](https://github.com/jedwatson/react-select#props) props
140
140
 
141
+ ## 🎨 Custom Select component
142
+
143
+ By default, `react-timezone-select` uses [`react-select`](https://github.com/jedwatson/react-select) as underlying select component. If you'd like to bring your own select component, you can use the `useTimezoneSelect` hook instead of the `TimezoneSelect` component to render the timezones using your self-provided select component.
144
+
145
+ ```jsx
146
+ import { useTimezoneSelect, allTimezones } from 'react-timezone-select'
147
+
148
+ const labelStyle = 'original'
149
+ const timezones = {
150
+ ...allTimezones,
151
+ 'Europe/Berlin': 'Frankfurt'
152
+ }
153
+
154
+ const customSelect = () => {
155
+ const { options, parseTimezone } = useTimezoneSelect({ labelStyle, timezones })
156
+
157
+ return (
158
+ <select onChange={e => onChange(parseTimezone(e.currentTarget.value))}>
159
+ {options.map(option => (
160
+ <option value={option.value}>{option.label}</option>
161
+ ))}
162
+ </select>
163
+ )
164
+ }
165
+ ```
166
+
141
167
  ## 🚧 Contributing
142
168
 
143
169
  Pull requests are always welcome! Please stick to repo settings (prettier, eslint, etc.), and if adding new features, please consider adding test(s) and documentation where appropriate!
package/dist/index.cjs CHANGED
@@ -2,8 +2,34 @@ var __create = Object.create;
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
6
  var __getProtoOf = Object.getPrototypeOf;
6
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
9
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
+ var __spreadValues = (a, b) => {
11
+ for (var prop in b || (b = {}))
12
+ if (__hasOwnProp.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ if (__getOwnPropSymbols)
15
+ for (var prop of __getOwnPropSymbols(b)) {
16
+ if (__propIsEnum.call(b, prop))
17
+ __defNormalProp(a, prop, b[prop]);
18
+ }
19
+ return a;
20
+ };
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
7
33
  var __export = (target, all) => {
8
34
  for (var name in all)
9
35
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -30,7 +56,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
56
  var src_exports = {};
31
57
  __export(src_exports, {
32
58
  allTimezones: () => timezone_list_default,
33
- default: () => TimezoneSelect
59
+ default: () => TimezoneSelect,
60
+ useTimezoneSelect: () => useTimezoneSelect
34
61
  });
35
62
  module.exports = __toCommonJS(src_exports);
36
63
  var React = __toESM(require("react"), 1);
@@ -123,27 +150,24 @@ var allTimezones = {
123
150
  var timezone_list_default = allTimezones;
124
151
 
125
152
  // src/index.tsx
126
- var TimezoneSelect = ({
127
- value,
128
- onBlur,
129
- onChange,
130
- labelStyle = "original",
153
+ function useTimezoneSelect({
131
154
  timezones = timezone_list_default,
132
- maxAbbrLength = 4,
133
- ...props
134
- }) => {
135
- const getOptions = React.useMemo(
136
- () => Object.entries(timezones).reduce((selectOptions, zone) => {
155
+ labelStyle = "original",
156
+ maxAbbrLength = 4
157
+ }) {
158
+ const options = React.useMemo(() => {
159
+ return Object.entries(timezones).map((zone) => {
160
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
137
161
  try {
138
162
  const now = import_spacetime.default.now(zone[0]);
139
163
  const tz = now.timezone();
140
164
  const tzStrings = (0, import_timezone_soft.default)(zone[0]);
141
165
  let label = "";
142
- const standardAbbr = tzStrings?.[0]?.standard?.abbr ?? "";
143
- const dstAbbr = tzStrings?.[0]?.daylight?.abbr ?? standardAbbr;
166
+ const standardAbbr = (_c = (_b = (_a = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _a.standard) == null ? void 0 : _b.abbr) != null ? _c : "";
167
+ const dstAbbr = (_f = (_e = (_d = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _d.daylight) == null ? void 0 : _e.abbr) != null ? _f : standardAbbr;
144
168
  let abbr = now.isDST() ? dstAbbr : standardAbbr;
145
- const standardAltName = tzStrings?.[0]?.standard?.name ?? "";
146
- const dstAltName = tzStrings?.[0]?.daylight?.name ?? standardAltName;
169
+ const standardAltName = (_i = (_h = (_g = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _g.standard) == null ? void 0 : _h.name) != null ? _i : "";
170
+ const dstAltName = (_l = (_k = (_j = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _j.daylight) == null ? void 0 : _k.name) != null ? _l : standardAltName;
147
171
  let altName = now.isDST() ? dstAltName : standardAltName;
148
172
  const min = tz.current.offset * 60;
149
173
  const hr = `${min / 60 ^ 0}:` + (min % 60 === 0 ? "00" : Math.abs(min % 60));
@@ -161,23 +185,18 @@ var TimezoneSelect = ({
161
185
  default:
162
186
  label = `${prefix}`;
163
187
  }
164
- selectOptions.push({
188
+ return {
165
189
  value: tz.name,
166
190
  label,
167
191
  offset: tz.current.offset,
168
192
  abbrev: abbr,
169
193
  altName
170
- });
171
- return selectOptions;
172
- } catch {
173
- return selectOptions;
194
+ };
195
+ } catch (e) {
196
+ return null;
174
197
  }
175
- }, []).sort((a, b) => a.offset - b.offset),
176
- [labelStyle, timezones]
177
- );
178
- const handleChange = (tz) => {
179
- onChange && onChange(tz);
180
- };
198
+ }).filter(Boolean).sort((a, b) => a.offset - b.offset);
199
+ }, [labelStyle, timezones]);
181
200
  const findFuzzyTz = (zone) => {
182
201
  let currentTime = import_spacetime.default.now("GMT");
183
202
  try {
@@ -185,7 +204,7 @@ var TimezoneSelect = ({
185
204
  } catch (err) {
186
205
  return;
187
206
  }
188
- return getOptions.filter(
207
+ return options.filter(
189
208
  (tz) => tz.offset === currentTime.timezone().current.offset
190
209
  ).map((tz) => {
191
210
  let score = 0;
@@ -214,23 +233,49 @@ var TimezoneSelect = ({
214
233
  if (typeof zone === "object" && zone.value && zone.label)
215
234
  return zone;
216
235
  if (typeof zone === "string") {
217
- return getOptions.find((tz) => tz.value === zone) || zone.indexOf("/") !== -1 && findFuzzyTz(zone);
236
+ return options.find((tz) => tz.value === zone) || zone.indexOf("/") !== -1 && findFuzzyTz(zone);
218
237
  } else if (zone.value && !zone.label) {
219
- return getOptions.find((tz) => tz.value === zone.value);
238
+ return options.find((tz) => tz.value === zone.value);
220
239
  }
221
240
  };
241
+ return { options, parseTimezone };
242
+ }
243
+ var TimezoneSelect = (_a) => {
244
+ var _b = _a, {
245
+ value,
246
+ onBlur,
247
+ onChange,
248
+ labelStyle,
249
+ maxAbbrLength,
250
+ timezones
251
+ } = _b, props = __objRest(_b, [
252
+ "value",
253
+ "onBlur",
254
+ "onChange",
255
+ "labelStyle",
256
+ "maxAbbrLength",
257
+ "timezones"
258
+ ]);
259
+ const { options, parseTimezone } = useTimezoneSelect({
260
+ timezones,
261
+ labelStyle,
262
+ maxAbbrLength
263
+ });
264
+ const handleChange = (tz) => {
265
+ onChange && onChange(tz);
266
+ };
222
267
  return /* @__PURE__ */ React.createElement(
223
268
  import_react_select.default,
224
- {
269
+ __spreadValues({
225
270
  value: parseTimezone(value),
226
271
  onChange: handleChange,
227
- options: getOptions,
228
- onBlur,
229
- ...props
230
- }
272
+ options,
273
+ onBlur
274
+ }, props)
231
275
  );
232
276
  };
233
277
  // Annotate the CommonJS export names for ESM import in node:
234
278
  0 && (module.exports = {
235
- allTimezones
279
+ allTimezones,
280
+ useTimezoneSelect
236
281
  });
package/dist/index.d.ts CHANGED
@@ -1,27 +1,33 @@
1
1
  import { Props as Props$1 } from 'react-select';
2
2
 
3
- declare type ICustomTimezone = {
3
+ type ICustomTimezone = {
4
4
  [key: string]: string;
5
5
  };
6
- declare type ILabelStyle = 'original' | 'altName' | 'abbrev';
7
- interface ITimezoneOption {
6
+ type ILabelStyle = 'original' | 'altName' | 'abbrev';
7
+ type ITimezoneOption = {
8
8
  value: string;
9
9
  label: string;
10
10
  abbrev?: string;
11
11
  altName?: string;
12
12
  offset?: number;
13
- }
14
- declare type ITimezone = ITimezoneOption | string;
15
- interface Props extends Omit<Props$1<ITimezone, false>, 'onChange'> {
16
- value: ITimezone;
13
+ };
14
+ type ITimezone = ITimezoneOption | string;
15
+ type TimezoneSelectOptions = {
17
16
  labelStyle?: ILabelStyle;
18
- onChange?: (timezone: ITimezoneOption) => void;
19
17
  timezones?: ICustomTimezone;
20
18
  maxAbbrLength?: number;
21
- }
19
+ };
20
+ type Props = Omit<Props$1<ITimezone, false>, 'onChange'> & TimezoneSelectOptions & {
21
+ value: ITimezone;
22
+ onChange?: (timezone: ITimezoneOption) => void;
23
+ };
22
24
 
23
25
  declare const allTimezones: ICustomTimezone;
24
26
 
25
- declare const TimezoneSelect: ({ value, onBlur, onChange, labelStyle, timezones, maxAbbrLength, ...props }: Props) => JSX.Element;
27
+ declare function useTimezoneSelect({ timezones, labelStyle, maxAbbrLength, }: TimezoneSelectOptions): {
28
+ parseTimezone: (zone: ITimezone) => ITimezoneOption;
29
+ options: ITimezoneOption[];
30
+ };
31
+ declare const TimezoneSelect: ({ value, onBlur, onChange, labelStyle, maxAbbrLength, timezones, ...props }: Props) => JSX.Element;
26
32
 
27
- export { ILabelStyle, ITimezone, ITimezoneOption, Props, allTimezones, TimezoneSelect as default };
33
+ export { ILabelStyle, ITimezone, ITimezoneOption, Props, TimezoneSelectOptions, allTimezones, TimezoneSelect as default, useTimezoneSelect };
@@ -0,0 +1,43 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7
+ <meta name="theme-color" content="#000000">
8
+ <!--
9
+ manifest.json provides metadata used when your web app is added to the
10
+ homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
11
+ -->
12
+ <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
13
+ <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
14
+ <!--
15
+ Notice the use of %PUBLIC_URL% in the tags above.
16
+ It will be replaced with the URL of the `public` folder during the build.
17
+ Only files inside the `public` folder can be referenced from the HTML.
18
+
19
+ Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
20
+ work correctly both with client-side routing and a non-root public URL.
21
+ Learn how to configure a non-root public URL by running `npm run build`.
22
+ -->
23
+ <title>React App</title>
24
+ </head>
25
+
26
+ <body>
27
+ <noscript>
28
+ You need to enable JavaScript to run this app.
29
+ </noscript>
30
+ <div id="root"></div>
31
+ <!--
32
+ This HTML file is a template.
33
+ If you open it directly in the browser, you will see an empty page.
34
+
35
+ You can add webfonts, meta tags, or analytics to this file.
36
+ The build step will place the bundled scripts into the <body> tag.
37
+
38
+ To begin the development, run `npm start` or `yarn start`.
39
+ To create a production bundle, use `npm run build` or `yarn build`.
40
+ -->
41
+ </body>
42
+
43
+ </html>
package/dist/index.js CHANGED
@@ -1,3 +1,32 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+ var __objRest = (source, exclude) => {
18
+ var target = {};
19
+ for (var prop in source)
20
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
21
+ target[prop] = source[prop];
22
+ if (source != null && __getOwnPropSymbols)
23
+ for (var prop of __getOwnPropSymbols(source)) {
24
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
25
+ target[prop] = source[prop];
26
+ }
27
+ return target;
28
+ };
29
+
1
30
  // src/index.tsx
2
31
  import * as React from "react";
3
32
  import Select from "react-select";
@@ -89,27 +118,24 @@ var allTimezones = {
89
118
  var timezone_list_default = allTimezones;
90
119
 
91
120
  // src/index.tsx
92
- var TimezoneSelect = ({
93
- value,
94
- onBlur,
95
- onChange,
96
- labelStyle = "original",
121
+ function useTimezoneSelect({
97
122
  timezones = timezone_list_default,
98
- maxAbbrLength = 4,
99
- ...props
100
- }) => {
101
- const getOptions = React.useMemo(
102
- () => Object.entries(timezones).reduce((selectOptions, zone) => {
123
+ labelStyle = "original",
124
+ maxAbbrLength = 4
125
+ }) {
126
+ const options = React.useMemo(() => {
127
+ return Object.entries(timezones).map((zone) => {
128
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
103
129
  try {
104
130
  const now = spacetime.now(zone[0]);
105
131
  const tz = now.timezone();
106
132
  const tzStrings = soft(zone[0]);
107
133
  let label = "";
108
- const standardAbbr = tzStrings?.[0]?.standard?.abbr ?? "";
109
- const dstAbbr = tzStrings?.[0]?.daylight?.abbr ?? standardAbbr;
134
+ const standardAbbr = (_c = (_b = (_a = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _a.standard) == null ? void 0 : _b.abbr) != null ? _c : "";
135
+ const dstAbbr = (_f = (_e = (_d = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _d.daylight) == null ? void 0 : _e.abbr) != null ? _f : standardAbbr;
110
136
  let abbr = now.isDST() ? dstAbbr : standardAbbr;
111
- const standardAltName = tzStrings?.[0]?.standard?.name ?? "";
112
- const dstAltName = tzStrings?.[0]?.daylight?.name ?? standardAltName;
137
+ const standardAltName = (_i = (_h = (_g = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _g.standard) == null ? void 0 : _h.name) != null ? _i : "";
138
+ const dstAltName = (_l = (_k = (_j = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _j.daylight) == null ? void 0 : _k.name) != null ? _l : standardAltName;
113
139
  let altName = now.isDST() ? dstAltName : standardAltName;
114
140
  const min = tz.current.offset * 60;
115
141
  const hr = `${min / 60 ^ 0}:` + (min % 60 === 0 ? "00" : Math.abs(min % 60));
@@ -127,23 +153,18 @@ var TimezoneSelect = ({
127
153
  default:
128
154
  label = `${prefix}`;
129
155
  }
130
- selectOptions.push({
156
+ return {
131
157
  value: tz.name,
132
158
  label,
133
159
  offset: tz.current.offset,
134
160
  abbrev: abbr,
135
161
  altName
136
- });
137
- return selectOptions;
138
- } catch {
139
- return selectOptions;
162
+ };
163
+ } catch (e) {
164
+ return null;
140
165
  }
141
- }, []).sort((a, b) => a.offset - b.offset),
142
- [labelStyle, timezones]
143
- );
144
- const handleChange = (tz) => {
145
- onChange && onChange(tz);
146
- };
166
+ }).filter(Boolean).sort((a, b) => a.offset - b.offset);
167
+ }, [labelStyle, timezones]);
147
168
  const findFuzzyTz = (zone) => {
148
169
  let currentTime = spacetime.now("GMT");
149
170
  try {
@@ -151,7 +172,7 @@ var TimezoneSelect = ({
151
172
  } catch (err) {
152
173
  return;
153
174
  }
154
- return getOptions.filter(
175
+ return options.filter(
155
176
  (tz) => tz.offset === currentTime.timezone().current.offset
156
177
  ).map((tz) => {
157
178
  let score = 0;
@@ -180,23 +201,49 @@ var TimezoneSelect = ({
180
201
  if (typeof zone === "object" && zone.value && zone.label)
181
202
  return zone;
182
203
  if (typeof zone === "string") {
183
- return getOptions.find((tz) => tz.value === zone) || zone.indexOf("/") !== -1 && findFuzzyTz(zone);
204
+ return options.find((tz) => tz.value === zone) || zone.indexOf("/") !== -1 && findFuzzyTz(zone);
184
205
  } else if (zone.value && !zone.label) {
185
- return getOptions.find((tz) => tz.value === zone.value);
206
+ return options.find((tz) => tz.value === zone.value);
186
207
  }
187
208
  };
209
+ return { options, parseTimezone };
210
+ }
211
+ var TimezoneSelect = (_a) => {
212
+ var _b = _a, {
213
+ value,
214
+ onBlur,
215
+ onChange,
216
+ labelStyle,
217
+ maxAbbrLength,
218
+ timezones
219
+ } = _b, props = __objRest(_b, [
220
+ "value",
221
+ "onBlur",
222
+ "onChange",
223
+ "labelStyle",
224
+ "maxAbbrLength",
225
+ "timezones"
226
+ ]);
227
+ const { options, parseTimezone } = useTimezoneSelect({
228
+ timezones,
229
+ labelStyle,
230
+ maxAbbrLength
231
+ });
232
+ const handleChange = (tz) => {
233
+ onChange && onChange(tz);
234
+ };
188
235
  return /* @__PURE__ */ React.createElement(
189
236
  Select,
190
- {
237
+ __spreadValues({
191
238
  value: parseTimezone(value),
192
239
  onChange: handleChange,
193
- options: getOptions,
194
- onBlur,
195
- ...props
196
- }
240
+ options,
241
+ onBlur
242
+ }, props)
197
243
  );
198
244
  };
199
245
  export {
200
246
  timezone_list_default as allTimezones,
201
- TimezoneSelect as default
247
+ TimezoneSelect as default,
248
+ useTimezoneSelect
202
249
  };
@@ -0,0 +1,26 @@
1
+ * {
2
+ font-family: Helvetica;
3
+ }
4
+
5
+ .App {
6
+ display: flex;
7
+ align-items: center;
8
+ flex-direction: column;
9
+ }
10
+
11
+ .select-wrapper {
12
+ margin-top: 50px;
13
+ width: 500px;
14
+ }
15
+
16
+ .code,
17
+ .code span {
18
+ background-color: #efefef;
19
+ font-family: monospace;
20
+ }
21
+
22
+ .code {
23
+ padding: 10px;
24
+ line-height: 2;
25
+ font-size: 1.4rem;
26
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-timezone-select",
3
- "version": "2.0.1",
3
+ "version": "2.1.1",
4
4
  "description": "Usable, dynamic React Timezone Select",
5
5
  "scripts": {
6
6
  "dev": "concurrently \"tsup src/index.tsx --format esm --watch\" \"cd example && pnpm dev\"",