react-timezone-select 2.1.4 → 3.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/README.md CHANGED
@@ -125,7 +125,7 @@ The above example will generate two additional choices in the select options, on
125
125
  ```
126
126
  - `onBlur` - `() => void`
127
127
  - `onChange` - `(timezone) => void`
128
- - `labelStyle` - `'original' | 'altName' | 'abbrev'`
128
+ - `labelStyle` - `'original' | 'altName' | 'abbrev' | 'offsetHidden'`
129
129
  - `displayValue` - `'GMT' | 'UTC'`
130
130
  - `timezones` - `Record<string,string>`
131
131
  ```
@@ -136,7 +136,6 @@ timezones={{
136
136
  }}
137
137
  ```
138
138
 
139
- - `maxAbbrLength` - `number` - Truncate `abbrev` labelStyles string to length
140
139
  - Any other [`react-select`](https://github.com/jedwatson/react-select#props) props
141
140
 
142
141
  ## 🎨 Custom Select component
package/dist/index.cjs CHANGED
@@ -60,7 +60,7 @@ __export(src_exports, {
60
60
  useTimezoneSelect: () => useTimezoneSelect
61
61
  });
62
62
  module.exports = __toCommonJS(src_exports);
63
- var React = __toESM(require("react"), 1);
63
+ var import_react = __toESM(require("react"), 1);
64
64
  var import_react_select = __toESM(require("react-select"), 1);
65
65
  var import_spacetime = __toESM(require("spacetime"), 1);
66
66
  var import_timezone_soft = __toESM(require("timezone-soft"), 1);
@@ -153,26 +153,22 @@ var timezone_list_default = allTimezones;
153
153
  function useTimezoneSelect({
154
154
  timezones = timezone_list_default,
155
155
  labelStyle = "original",
156
- displayValue = "GMT",
157
- maxAbbrLength = 4
156
+ displayValue = "GMT"
158
157
  }) {
159
- const options = React.useMemo(() => {
158
+ const options = (0, import_react.useMemo)(() => {
160
159
  return Object.entries(timezones).map((zone) => {
161
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
160
+ var _a, _b, _c, _d;
162
161
  try {
163
162
  const now = import_spacetime.default.now(zone[0]);
163
+ const isDstString = now.isDST() ? "daylight" : "standard";
164
164
  const tz = now.timezone();
165
165
  const tzStrings = (0, import_timezone_soft.default)(zone[0]);
166
- let label = "";
167
- const standardAbbr = (_c = (_b = (_a = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _a.standard) == null ? void 0 : _b.abbr) != null ? _c : "";
168
- const dstAbbr = (_f = (_e = (_d = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _d.daylight) == null ? void 0 : _e.abbr) != null ? _f : standardAbbr;
169
- let abbr = now.isDST() ? dstAbbr : standardAbbr;
170
- const standardAltName = (_i = (_h = (_g = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _g.standard) == null ? void 0 : _h.name) != null ? _i : "";
171
- const dstAltName = (_l = (_k = (_j = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _j.daylight) == null ? void 0 : _k.name) != null ? _l : standardAltName;
172
- let altName = now.isDST() ? dstAltName : standardAltName;
166
+ const abbr = (_b = (_a = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _a[isDstString]) == null ? void 0 : _b.abbr;
167
+ const altName = (_d = (_c = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _c[isDstString]) == null ? void 0 : _d.name;
173
168
  const min = tz.current.offset * 60;
174
- const hr = `${min / 60 ^ 0}:` + (min % 60 === 0 ? "00" : Math.abs(min % 60));
169
+ const hr = `${min / 60 ^ 0}:${min % 60 === 0 ? "00" : Math.abs(min % 60)}`;
175
170
  const prefix = `(${displayValue}${hr.includes("-") ? hr : `+${hr}`}) ${zone[1]}`;
171
+ let label = "";
176
172
  switch (labelStyle) {
177
173
  case "original":
178
174
  label = prefix;
@@ -181,7 +177,10 @@ function useTimezoneSelect({
181
177
  label = `${prefix} ${altName ? `(${altName})` : ""}`;
182
178
  break;
183
179
  case "abbrev":
184
- label = `${prefix} (${abbr.substring(0, maxAbbrLength)})`;
180
+ label = `${prefix} (${abbr})`;
181
+ break;
182
+ case "offsetHidden":
183
+ label = `${prefix.replace(/^\(.*?\)\s*/, "")}`;
185
184
  break;
186
185
  default:
187
186
  label = `${prefix}`;
@@ -199,11 +198,11 @@ function useTimezoneSelect({
199
198
  }).filter(Boolean).sort((a, b) => a.offset - b.offset);
200
199
  }, [labelStyle, timezones]);
201
200
  const findFuzzyTz = (zone) => {
202
- let currentTime = import_spacetime.default.now("GMT");
201
+ let currentTime;
203
202
  try {
204
203
  currentTime = import_spacetime.default.now(zone);
205
204
  } catch (err) {
206
- return;
205
+ currentTime = import_spacetime.default.now("GMT");
207
206
  }
208
207
  return options.filter(
209
208
  (tz) => tz.offset === currentTime.timezone().current.offset
@@ -228,7 +227,7 @@ function useTimezoneSelect({
228
227
  score += 1;
229
228
  }
230
229
  return { tz, score };
231
- }).sort((a, b) => b.score - a.score).map(({ tz }) => tz)[0];
230
+ }).sort((a, b) => b.score - a.score)[0].tz;
232
231
  };
233
232
  const parseTimezone = (zone) => {
234
233
  if (typeof zone === "object" && zone.value && zone.label)
@@ -248,7 +247,6 @@ var TimezoneSelect = (_a) => {
248
247
  onChange,
249
248
  labelStyle,
250
249
  displayValue,
251
- maxAbbrLength,
252
250
  timezones
253
251
  } = _b, props = __objRest(_b, [
254
252
  "value",
@@ -256,19 +254,17 @@ var TimezoneSelect = (_a) => {
256
254
  "onChange",
257
255
  "labelStyle",
258
256
  "displayValue",
259
- "maxAbbrLength",
260
257
  "timezones"
261
258
  ]);
262
259
  const { options, parseTimezone } = useTimezoneSelect({
263
260
  timezones,
264
261
  labelStyle,
265
- displayValue,
266
- maxAbbrLength
262
+ displayValue
267
263
  });
268
264
  const handleChange = (tz) => {
269
265
  onChange && onChange(tz);
270
266
  };
271
- return /* @__PURE__ */ React.createElement(
267
+ return /* @__PURE__ */ import_react.default.createElement(
272
268
  import_react_select.default,
273
269
  __spreadValues({
274
270
  value: parseTimezone(value),
package/dist/index.d.ts CHANGED
@@ -1,35 +1,36 @@
1
+ import React from 'react';
1
2
  import { Props as Props$1 } from 'react-select';
2
3
 
3
- declare type ICustomTimezone = {
4
+ type ICustomTimezone = {
4
5
  [key: string]: string;
5
6
  };
6
- declare type ILabelStyle = 'original' | 'altName' | 'abbrev';
7
- declare type IDisplayValue = 'GMT' | 'UTC';
8
- declare type ITimezoneOption = {
7
+ type ILabelStyle = 'original' | 'altName' | 'abbrev' | 'offsetHidden';
8
+ type IDisplayValue = 'GMT' | 'UTC';
9
+ type ITimezoneOption = {
9
10
  value: string;
10
11
  label: string;
11
12
  abbrev?: string;
12
13
  altName?: string;
13
14
  offset?: number;
14
15
  };
15
- declare type ITimezone = ITimezoneOption | string;
16
- declare type TimezoneSelectOptions = {
16
+ type ITimezone = ITimezoneOption | string;
17
+ type TimezoneSelectOptions = {
17
18
  labelStyle?: ILabelStyle;
18
19
  displayValue?: IDisplayValue;
19
20
  timezones?: ICustomTimezone;
20
21
  maxAbbrLength?: number;
21
22
  };
22
- declare type Props = Omit<Props$1<ITimezone, false>, 'onChange'> & TimezoneSelectOptions & {
23
+ type Props = Omit<Props$1<ITimezone, false>, 'onChange'> & TimezoneSelectOptions & {
23
24
  value: ITimezone;
24
25
  onChange?: (timezone: ITimezone) => void;
25
26
  };
26
27
 
27
28
  declare const allTimezones: ICustomTimezone;
28
29
 
29
- declare function useTimezoneSelect({ timezones, labelStyle, displayValue, maxAbbrLength, }: TimezoneSelectOptions): {
30
+ declare function useTimezoneSelect({ timezones, labelStyle, displayValue, }: TimezoneSelectOptions): {
30
31
  parseTimezone: (zone: ITimezone) => ITimezoneOption;
31
32
  options: ITimezoneOption[];
32
33
  };
33
- declare const TimezoneSelect: ({ value, onBlur, onChange, labelStyle, displayValue, maxAbbrLength, timezones, ...props }: Props) => JSX.Element;
34
+ declare const TimezoneSelect: ({ value, onBlur, onChange, labelStyle, displayValue, timezones, ...props }: Props) => React.JSX.Element;
34
35
 
35
36
  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
@@ -28,7 +28,7 @@ var __objRest = (source, exclude) => {
28
28
  };
29
29
 
30
30
  // src/index.tsx
31
- import * as React from "react";
31
+ import React, { useMemo } from "react";
32
32
  import Select from "react-select";
33
33
  import spacetime from "spacetime";
34
34
  import soft from "timezone-soft";
@@ -121,26 +121,22 @@ var timezone_list_default = allTimezones;
121
121
  function useTimezoneSelect({
122
122
  timezones = timezone_list_default,
123
123
  labelStyle = "original",
124
- displayValue = "GMT",
125
- maxAbbrLength = 4
124
+ displayValue = "GMT"
126
125
  }) {
127
- const options = React.useMemo(() => {
126
+ const options = useMemo(() => {
128
127
  return Object.entries(timezones).map((zone) => {
129
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
128
+ var _a, _b, _c, _d;
130
129
  try {
131
130
  const now = spacetime.now(zone[0]);
131
+ const isDstString = now.isDST() ? "daylight" : "standard";
132
132
  const tz = now.timezone();
133
133
  const tzStrings = soft(zone[0]);
134
- let label = "";
135
- const standardAbbr = (_c = (_b = (_a = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _a.standard) == null ? void 0 : _b.abbr) != null ? _c : "";
136
- const dstAbbr = (_f = (_e = (_d = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _d.daylight) == null ? void 0 : _e.abbr) != null ? _f : standardAbbr;
137
- let abbr = now.isDST() ? dstAbbr : standardAbbr;
138
- const standardAltName = (_i = (_h = (_g = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _g.standard) == null ? void 0 : _h.name) != null ? _i : "";
139
- const dstAltName = (_l = (_k = (_j = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _j.daylight) == null ? void 0 : _k.name) != null ? _l : standardAltName;
140
- let altName = now.isDST() ? dstAltName : standardAltName;
134
+ const abbr = (_b = (_a = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _a[isDstString]) == null ? void 0 : _b.abbr;
135
+ const altName = (_d = (_c = tzStrings == null ? void 0 : tzStrings[0]) == null ? void 0 : _c[isDstString]) == null ? void 0 : _d.name;
141
136
  const min = tz.current.offset * 60;
142
- const hr = `${min / 60 ^ 0}:` + (min % 60 === 0 ? "00" : Math.abs(min % 60));
137
+ const hr = `${min / 60 ^ 0}:${min % 60 === 0 ? "00" : Math.abs(min % 60)}`;
143
138
  const prefix = `(${displayValue}${hr.includes("-") ? hr : `+${hr}`}) ${zone[1]}`;
139
+ let label = "";
144
140
  switch (labelStyle) {
145
141
  case "original":
146
142
  label = prefix;
@@ -149,7 +145,10 @@ function useTimezoneSelect({
149
145
  label = `${prefix} ${altName ? `(${altName})` : ""}`;
150
146
  break;
151
147
  case "abbrev":
152
- label = `${prefix} (${abbr.substring(0, maxAbbrLength)})`;
148
+ label = `${prefix} (${abbr})`;
149
+ break;
150
+ case "offsetHidden":
151
+ label = `${prefix.replace(/^\(.*?\)\s*/, "")}`;
153
152
  break;
154
153
  default:
155
154
  label = `${prefix}`;
@@ -167,11 +166,11 @@ function useTimezoneSelect({
167
166
  }).filter(Boolean).sort((a, b) => a.offset - b.offset);
168
167
  }, [labelStyle, timezones]);
169
168
  const findFuzzyTz = (zone) => {
170
- let currentTime = spacetime.now("GMT");
169
+ let currentTime;
171
170
  try {
172
171
  currentTime = spacetime.now(zone);
173
172
  } catch (err) {
174
- return;
173
+ currentTime = spacetime.now("GMT");
175
174
  }
176
175
  return options.filter(
177
176
  (tz) => tz.offset === currentTime.timezone().current.offset
@@ -196,7 +195,7 @@ function useTimezoneSelect({
196
195
  score += 1;
197
196
  }
198
197
  return { tz, score };
199
- }).sort((a, b) => b.score - a.score).map(({ tz }) => tz)[0];
198
+ }).sort((a, b) => b.score - a.score)[0].tz;
200
199
  };
201
200
  const parseTimezone = (zone) => {
202
201
  if (typeof zone === "object" && zone.value && zone.label)
@@ -216,7 +215,6 @@ var TimezoneSelect = (_a) => {
216
215
  onChange,
217
216
  labelStyle,
218
217
  displayValue,
219
- maxAbbrLength,
220
218
  timezones
221
219
  } = _b, props = __objRest(_b, [
222
220
  "value",
@@ -224,14 +222,12 @@ var TimezoneSelect = (_a) => {
224
222
  "onChange",
225
223
  "labelStyle",
226
224
  "displayValue",
227
- "maxAbbrLength",
228
225
  "timezones"
229
226
  ]);
230
227
  const { options, parseTimezone } = useTimezoneSelect({
231
228
  timezones,
232
229
  labelStyle,
233
- displayValue,
234
- maxAbbrLength
230
+ displayValue
235
231
  });
236
232
  const handleChange = (tz) => {
237
233
  onChange && onChange(tz);
@@ -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.1.4",
3
+ "version": "3.0.0",
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\"",
@@ -10,9 +10,9 @@
10
10
  "build:example": "cd example && pnpm run build",
11
11
  "deploy": "gh-pages -d example/dist",
12
12
  "pretest": "pnpm run build",
13
- "test": "jest",
14
- "test:watch": "jest --watch",
15
- "test:ci": "pnpm run build && jest --ci ",
13
+ "test": "vitest",
14
+ "test:watch": "vitest --watch",
15
+ "test:ci": "pnpm run build && pnpm test",
16
16
  "tsc": "tsc"
17
17
  },
18
18
  "author": "Nico Domino <yo@ndo.dev>",
@@ -52,66 +52,65 @@
52
52
  "react-select": "^5.7.0"
53
53
  },
54
54
  "dependencies": {
55
- "spacetime": "^7.4.1",
56
- "timezone-soft": "^1.4.1"
55
+ "spacetime": "^7.4.8",
56
+ "timezone-soft": "^1.5.1"
57
57
  },
58
58
  "devDependencies": {
59
- "@babel/core": "^7.20.7",
60
- "@testing-library/jest-dom": "^5.16.1",
61
- "@testing-library/react": "^12.1.2",
62
- "@types/jest": "^27.4.0",
63
- "@types/react": "^17.0.38",
64
- "@types/react-dom": "^17.0.11",
65
- "@types/testing-library__jest-dom": "^5.14.5",
66
- "concurrently": "^7.0.0",
67
- "esbuild": "^0.16.12",
59
+ "@babel/core": "^7.23.5",
60
+ "@testing-library/jest-dom": "^5.17.0",
61
+ "@testing-library/react": "^14.1.2",
62
+ "@types/jest": "^27.5.2",
63
+ "@types/react": "^18.2.43",
64
+ "@types/react-dom": "^18.2.17",
65
+ "@types/testing-library__jest-dom": "^5.14.9",
66
+ "@typescript-eslint/eslint-plugin": "^6.13.2",
67
+ "@typescript-eslint/parser": "^6.13.2",
68
+ "@vitejs/plugin-react": "^4.2.1",
69
+ "concurrently": "^7.6.0",
70
+ "esbuild": "^0.16.17",
68
71
  "esbuild-jest": "^0.5.0",
69
- "eslint": "^8.36.0",
70
- "eslint-config-prettier": "^8.8.0",
71
- "eslint-plugin-prettier": "^4.2.1",
72
+ "eslint": "^8.55.0",
73
+ "eslint-config-prettier": "^9.1.0",
74
+ "eslint-plugin-prettier": "5.0.1",
72
75
  "gh-pages": "^3.2.3",
73
- "jest": "^27.4.7",
74
- "prettier": "^2.5.1",
75
- "react": "^17",
76
- "react-dom": "^17",
77
- "simple-git-hooks": "^2.7.0",
78
- "ts-jest": "^27.1.3",
79
- "tsup": "^6.5.0",
80
- "typescript": "^4.5.5"
76
+ "jest-environment-jsdom": "^29.7.0",
77
+ "prettier": "^3.1.1",
78
+ "react": "^18.2.0",
79
+ "react-dom": "^18.2.0",
80
+ "simple-git-hooks": "^2.9.0",
81
+ "ts-jest": "^29.1.1",
82
+ "tsup": "^6.7.0",
83
+ "typescript": "^5.3.3",
84
+ "vite": "^5.0.7",
85
+ "vite-tsconfig-paths": "^4.2.2",
86
+ "vitest": "^1.0.4"
81
87
  },
82
88
  "eslintConfig": {
89
+ "parser": "@typescript-eslint/parser",
83
90
  "parserOptions": {
91
+ "ecmaVersion": "latest",
84
92
  "sourceType": "module"
85
93
  },
86
94
  "extends": [
87
95
  "eslint:recommended",
88
- "prettier"
96
+ "plugin:@typescript-eslint/recommended",
97
+ "plugin:prettier/recommended"
89
98
  ],
90
- "env": {
91
- "browser": true,
92
- "es6": true
93
- },
94
99
  "plugins": [
95
- "prettier"
100
+ "@typescript-eslint"
96
101
  ],
97
- "rules": {
98
- "prettier/prettier": "error"
99
- }
102
+ "root": true
100
103
  },
101
104
  "prettier": {
102
- "trailingComma": "es5",
103
105
  "semi": false,
104
106
  "singleQuote": true,
105
- "arrowParens": "avoid"
107
+ "maxLineLength": 100
106
108
  },
107
109
  "simple-git-hooks": {
108
110
  "pre-commit": "npx lint-staged"
109
111
  },
110
112
  "lint-staged": {
111
- "*.{js,jsx,ts,tsx,css,json}": [
112
- "prettier --write"
113
- ],
114
- "*.{js,jsx}": [
113
+ "*.{js,jsx,ts,tsx}": [
115
114
  "eslint --fix"
116
115
  ]
117
116
  }