react-timezone-select 3.2.2 → 3.2.4

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
File without changes
package/README.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # 🌐⌚ react-timezone-select
2
2
 
3
- [![NPM Downloads](https://img.shields.io/npm/dm/react-timezone-select?style=flat-square)](https://www.npmjs.com/package/react-timezone-select)
4
3
  [![npm](https://img.shields.io/npm/v/react-timezone-select?style=flat-square)](https://www.npmjs.com/package/react-timezone-select)
5
- [![GitHub issues](https://img.shields.io/github/issues/ndom91/react-timezone-select?style=flat-square)](https://github.com/ndom91/react-timezone-select/issues)
4
+ [![NPM Downloads](https://img.shields.io/npm/dm/react-timezone-select?style=flat-square)](https://www.npmjs.com/package/react-timezone-select)
6
5
  [![Skypack](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg?style=flat-square)](https://skypack.dev/view/react-timezone-select)
7
- [![Test CI](https://badgen.net/github/checks/ndom91/react-timezone-select/main?style=flat-square&label=tests)](https://github.com/ndom91/react-timezone-select/actions?query=workflow%3A%22Tests+CI%22)
8
- [![MIT](https://badgen.net/badge/license/MIT/blue?style=flat-square)](https://github.com/ndom91/react-timezone-select/blob/main/LICENSE)
6
+ [![Test CI](https://flat.badgen.net/github/checks/ndom91/react-timezone-select/main?style=flat-square&label=tests)](https://github.com/ndom91/react-timezone-select/actions?query=workflow%3A%22Tests+CI%22)
7
+ [![MIT](https://flat.badgen.net/badge/license/MIT/blue?style=flat-square)](https://github.com/ndom91/react-timezone-select/blob/main/LICENSE)
9
8
 
10
9
  Another react timezone select component, I know.. However this one has a few key benefits!
11
10
 
@@ -14,27 +13,31 @@ While looking around for a good option, I had trouble finding a timezone select
14
13
  1. Adjusted the choices automatically with Daylight Savings Time (DST)
15
14
  2. Didn't have a huge list of choices to scroll through when technically only 24 (ish) are necessary
16
15
 
17
- #### Demo: [ndom91.github.io/react-timezone-select](https://ndom91.github.io/react-timezone-select/)
18
-
16
+ > [!IMPORTANT]
17
+ >
18
+ > ### Demo: [ndom91.github.io/react-timezone-select](https://ndom91.github.io/react-timezone-select/)
19
+ >
19
20
  > This demo is also available in the `./examples` directory. Simply run `pnpm dev` in the root of the repository and the vite dev server will start, where you can then find the example app at [`localhost:3001`](http://localhost:3001).
20
21
 
21
22
  ## 🏗️ Installing
22
23
 
23
24
  ```bash
24
- // react-select is an optional peer dependency, unnecessary if using the hook
25
25
  npm install react-timezone-select react-select
26
26
  ```
27
27
 
28
+ > [!CAUTION]
29
+ > The package `react-select` is optional. It is unnecessary if you're only using [the hook](#-timezone-hook).
30
+
28
31
  ## 🔭 Usage
29
32
 
30
- ```jsx
31
- import React, { useState } from 'react'
32
- import ReactDOM from 'react-dom'
33
- import TimezoneSelect, { type ITimezone } from 'react-timezone-select'
33
+ ```tsx
34
+ import React, { useState } from "react"
35
+ import ReactDOM from "react-dom"
36
+ import TimezoneSelect, { type ITimezone } from "react-timezone-select"
34
37
 
35
38
  const App = () => {
36
39
  const [selectedTimezone, setSelectedTimezone] = useState<ITimezone>(
37
- Intl.DateTimeFormat().resolvedOptions().timeZone
40
+ Intl.DateTimeFormat().resolvedOptions().timeZone,
38
41
  )
39
42
 
40
43
  return (
@@ -42,26 +45,23 @@ const App = () => {
42
45
  <h2>react-timezone-select</h2>
43
46
  <blockquote>Please make a selection</blockquote>
44
47
  <div className="select-wrapper">
45
- <TimezoneSelect
46
- value={selectedTimezone}
47
- onChange={setSelectedTimezone}
48
- />
48
+ <TimezoneSelect value={selectedTimezone} onChange={setSelectedTimezone} />
49
49
  </div>
50
50
  <h3>Output:</h3>
51
51
  <div
52
52
  style={{
53
- backgroundColor: '#ccc',
54
- padding: '20px',
55
- margin: '20px auto',
56
- borderRadius: '5px',
57
- maxWidth: '600px',
53
+ backgroundColor: "#ccc",
54
+ padding: "20px",
55
+ margin: "20px auto",
56
+ borderRadius: "5px",
57
+ maxWidth: "600px",
58
58
  }}
59
59
  >
60
60
  <pre
61
61
  style={{
62
- margin: '0 20px',
62
+ margin: "0 20px",
63
63
  fontWeight: 500,
64
- fontFamily: 'monospace',
64
+ fontFamily: "monospace",
65
65
  }}
66
66
  >
67
67
  {JSON.stringify(selectedTimezone, null, 2)}
@@ -71,67 +71,109 @@ const App = () => {
71
71
  )
72
72
  }
73
73
 
74
- const rootElement = document.getElementById('root')
74
+ const rootElement = document.getElementById("root")
75
75
  ReactDOM.render(<App />, rootElement)
76
76
  ```
77
77
 
78
- ## 🪙 Tips
79
-
80
- ### 👤 Default Users Timezone
81
-
82
- If you'd like the user's own timezone to be set as the initially selected option on render, we can make use of the new `Intl` browser API by setting the default state value to `Intl.DateTimeFormat().resolvedOptions().timeZone`.
83
-
84
- ```jsx
85
- const [timezone, setTimezone] = useState(
86
- Intl.DateTimeFormat().resolvedOptions().timeZone
87
- )
88
- ```
89
-
90
- Thanks [@ndrwksr](https://github.com/ndom91/react-timezone-select/issues/25)
91
-
92
- ### 🕒 Custom Timezones
78
+ ## 🎨 Timezone Hook
93
79
 
94
- You can append custom choices of your own, or fully replace the listed timezone options.
80
+ 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.
95
81
 
96
- The `timezones` prop takes a dictionary of timezones. Don't worry, we'll prepend the `(GMT...)` part, you just have to pass the city(s) or region(s) you want in your label.
82
+ ```tsx
83
+ import { useTimezoneSelect, allTimezones } from "react-timezone-select"
97
84
 
98
- ```jsx
99
- import TimezoneSelect, { type ITimezone, allTimezones } from 'react-timezone-select'
85
+ const labelStyle = "original"
86
+ const timezones = {
87
+ ...allTimezones,
88
+ "Europe/Berlin": "Frankfurt",
89
+ }
100
90
 
101
- const [selectedTimezone, setSelectedTimezone] = useState<ITimezone>('Europe/Berlin')
91
+ const customSelect = () => {
92
+ const { options, parseTimezone } = useTimezoneSelect({ labelStyle, timezones })
102
93
 
103
- <TimezoneSelect
104
- value={selectedTimezone}
105
- onChange={setSelectedTimezone}
106
- timezones={{
107
- ...allTimezones,
108
- 'America/Lima': 'Pittsburgh',
109
- 'Europe/Berlin': 'Frankfurt',
110
- }}
111
- />
94
+ return (
95
+ <select onChange={(e) => onChange(parseTimezone(e.currentTarget.value))}>
96
+ {options.map((option) => (
97
+ <option value={option.value}>{option.label}</option>
98
+ ))}
99
+ </select>
100
+ )
101
+ }
112
102
  ```
113
103
 
114
- The above example will generate two additional choices in the select options, one with the label `'(GMT-5:00) Pittsburgh'` and another with `'(GMT+1:00) Frankfurt'`. You can omit spreading in the `allTimezones` object and then only your custom timezone options get rendered in the select component.
115
-
116
104
  ## 🕹️ Props
117
105
 
118
- - `value` - `string | Object` - Initial/current Timezone.
119
- ```
120
- 'America/Juneau' | {
106
+ <table>
107
+ <tbody>
108
+ <tr>
109
+ <th>Prop</th>
110
+ <th>Type</th>
111
+ <th>Default</th>
112
+ <th>Note</th>
113
+ </tr>
114
+ <tr>
115
+ <td><code>value</code></td>
116
+ <td><code>string | ITimezoneOption<string, string></code></td>
117
+ <td>null</td>
118
+ <td>Initial/current Timezone</td>
119
+ </tr>
120
+ <tr>
121
+ <td><code>onBlur</code></td>
122
+ <td><code>() => void</code></td>
123
+ <td>null</td>
124
+ <td></td>
125
+ </tr>
126
+ <tr>
127
+ <td><code>onChange</code></td>
128
+ <td><code>(timezone: ITimezoneOption) => void</code></td>
129
+ <td>null</td>
130
+ <td></td>
131
+ </tr>
132
+ <tr>
133
+ <td><code>labelStyle</code></td>
134
+ <td><code>'original' | 'altName' | 'abbrev' | 'offsetHidden'</code></td>
135
+ <td><code>'original'</code></td>
136
+ <td></td>
137
+ </tr>
138
+ <tr>
139
+ <td><code>displayValue</code></td>
140
+ <td><code>'GMT' | 'UTC'</code></td>
141
+ <td><code>'GMT'</code></td>
142
+ <td>Prefix for the label (i.e. <code>"(GMT+2:00)"</code> or <code>"(UTC+2:00)"</code>)</td>
143
+ </tr>
144
+ <tr>
145
+ <td><code>timezones</code></td>
146
+ <td><code>Record<string,string></code></td>
147
+ <td><code>allTimezones</code></td>
148
+ <td></td>
149
+ </tr>
150
+ <tr>
151
+ <td><code>currentDatetime</code></td>
152
+ <td><code>Date | string</code></td>
153
+ <td>null</td>
154
+ <td>Override datetime used to calculate timezone values (alternative to current datetime), useful for calculating different summer / winter times, etc.</td>
155
+ </tr>
156
+ </tbody>
157
+ </table>
158
+
159
+ #### Example `value`s:
160
+
161
+ ```ts
162
+ // string
163
+ value='America/Juneau'
164
+ // ITimezoneOption; i.e. `onChange` return value
165
+ value={{
121
166
  value: 'America/Juneau'
122
167
  label: '(GMT-8:00) Alaska,
123
168
  abbrev: 'AHST',
124
169
  offset: -8,
125
170
  altName: 'Alaskan Standard Time'
126
- }
127
- ```
128
- - `onBlur` - `() => void`
129
- - `onChange` - `(timezone) => void`
130
- - `labelStyle` - `'original' | 'altName' | 'abbrev' | 'offsetHidden'`
131
- - `displayValue` - `'GMT' | 'UTC'`
132
- - `timezones` - `Record<string,string>`
133
- - `currentDatetime` - `Date | string` - Set datetime used to calculate timezone values (alternative to current datetime)
171
+ }}
134
172
  ```
173
+
174
+ #### Example `timezones`:
175
+
176
+ ```ts
135
177
  timezones={{
136
178
  ...allTimezones,
137
179
  'America/Lima': 'Pittsburgh',
@@ -139,37 +181,48 @@ timezones={{
139
181
  }}
140
182
  ```
141
183
 
142
- - Any other [`react-select`](https://github.com/jedwatson/react-select#props) props
184
+ ## Tips
143
185
 
144
- ## 🎨 Custom Select component
186
+ ### 👤 Default Users Timezone
145
187
 
146
- 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.
188
+ If you'd like the user's own timezone to be set as the initially selected option on render, we can make use of the new `Intl` browser API by setting the default state value to `Intl.DateTimeFormat().resolvedOptions().timeZone`.
147
189
 
148
- ```jsx
149
- import { useTimezoneSelect, allTimezones } from 'react-timezone-select'
190
+ ```tsx
191
+ const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone)
192
+ ```
150
193
 
151
- const labelStyle = 'original'
152
- const timezones = {
153
- ...allTimezones,
154
- 'Europe/Berlin': 'Frankfurt'
155
- }
194
+ ### 🕒 Custom Timezones
156
195
 
157
- const customSelect = () => {
158
- const { options, parseTimezone } = useTimezoneSelect({ labelStyle, timezones })
196
+ You can append custom choices of your own, or fully replace the listed timezone options.
159
197
 
160
- return (
161
- <select onChange={e => onChange(parseTimezone(e.currentTarget.value))}>
162
- {options.map(option => (
163
- <option value={option.value}>{option.label}</option>
164
- ))}
165
- </select>
166
- )
167
- }
198
+ The `timezones` prop takes a dictionary of timezones in the format of "`{ tzIdentifier: Label }`" ([Timezone Identifiers](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)).
199
+
200
+ ```tsx
201
+ import TimezoneSelect, { type ITimezone, allTimezones } from 'react-timezone-select'
202
+
203
+ const [selectedTimezone, setSelectedTimezone] = useState<ITimezone>('Europe/Berlin')
204
+
205
+ <TimezoneSelect
206
+ value={selectedTimezone}
207
+ onChange={setSelectedTimezone}
208
+ timezones={{
209
+ ...allTimezones,
210
+ 'America/Lima': 'Pittsburgh',
211
+ 'Europe/Berlin': 'Frankfurt',
212
+ }}
213
+ />
168
214
  ```
169
215
 
216
+ The example above will include all original timezones and generate two additional choices:
217
+
218
+ - `'(GMT-5:00) Pittsburgh'`
219
+ - `'(GMT+1:00) Frankfurt'`
220
+
221
+ We'll prepend the correct `(GMT...)` part to the generated label, you just have to provide the string you want in your label. Also, you can omit spreading in the `allTimezones` object for a select dropdown consisting of only your custom choices.
222
+
170
223
  ## 🚧 Contributing
171
224
 
172
- 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!
225
+ Pull requests are always welcome! Please stick to repo formatting/linting settings, and if adding new features, please consider adding test(s) and documentation where appropriate!
173
226
 
174
227
  ## 🙏 Thanks
175
228
 
@@ -177,3 +230,7 @@ Pull requests are always welcome! Please stick to repo settings (prettier, eslin
177
230
  - [Carlos Matallin](https://github.com/matallo/)
178
231
  - [spacetime](https://github.com/spencermountain/spacetime)
179
232
  - [react-select](https://react-select.com)
233
+
234
+ ## 📝 License
235
+
236
+ MIT
package/dist/index.d.ts CHANGED
@@ -33,4 +33,4 @@ declare function useTimezoneSelect({ timezones, labelStyle, displayValue, curren
33
33
  };
34
34
  declare const TimezoneSelect: ({ value, onBlur, onChange, labelStyle, displayValue, timezones, currentDatetime, ...props }: Props) => react_jsx_runtime_js.JSX.Element;
35
35
 
36
- export { ILabelStyle, ITimezone, ITimezoneOption, Props, TimezoneSelectOptions, allTimezones, TimezoneSelect as default, useTimezoneSelect };
36
+ export { type ILabelStyle, type ITimezone, type ITimezoneOption, type Props, type TimezoneSelectOptions, allTimezones, TimezoneSelect as default, useTimezoneSelect };
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ "use client"
2
+
1
3
  var __defProp = Object.defineProperty;
2
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
@@ -119,7 +121,6 @@ var timezone_list_default = allTimezones;
119
121
 
120
122
  // src/index.tsx
121
123
  import { jsx } from "react/jsx-runtime";
122
- "use client";
123
124
  function useTimezoneSelect({
124
125
  timezones = timezone_list_default,
125
126
  labelStyle = "original",
@@ -167,15 +168,16 @@ function useTimezoneSelect({
167
168
  return null;
168
169
  }
169
170
  }).filter(Boolean).sort((a, b) => a.offset - b.offset);
170
- }, [labelStyle, timezones]);
171
+ }, [labelStyle, timezones, currentDatetime]);
171
172
  const findFuzzyTz = (zone) => {
173
+ var _a, _b;
172
174
  let currentTime;
173
175
  try {
174
176
  currentTime = (currentDatetime ? spacetime(currentDatetime) : spacetime.now()).goto(zone);
175
177
  } catch (err) {
176
178
  currentTime = (currentDatetime ? spacetime(currentDatetime) : spacetime.now()).goto("GMT");
177
179
  }
178
- return options.filter((tz) => tz.offset === currentTime.timezone().current.offset).map((tz) => {
180
+ return (_b = (_a = options.filter((tz) => tz.offset === currentTime.timezone().current.offset).map((tz) => {
179
181
  let score = 0;
180
182
  if (currentTime.timezones[tz.value.toLowerCase()] && !!currentTime.timezones[tz.value.toLowerCase()].dst === currentTime.timezone().hasDst) {
181
183
  if (tz.value.toLowerCase().indexOf(currentTime.tz.substring(currentTime.tz.indexOf("/") + 1)) !== -1) {
@@ -192,7 +194,7 @@ function useTimezoneSelect({
192
194
  score += 1;
193
195
  }
194
196
  return { tz, score };
195
- }).sort((a, b) => b.score - a.score)[0].tz;
197
+ }).sort((a, b) => b.score - a.score)) == null ? void 0 : _a[0]) == null ? void 0 : _b.tz;
196
198
  };
197
199
  const parseTimezone = (zone) => {
198
200
  if (typeof zone === "object" && zone.value && zone.label)
package/package.json CHANGED
@@ -1,20 +1,7 @@
1
1
  {
2
2
  "name": "react-timezone-select",
3
- "version": "3.2.2",
3
+ "version": "3.2.4",
4
4
  "description": "Usable, dynamic React Timezone Select",
5
- "scripts": {
6
- "dev": "concurrently \"tsup src/index.tsx --format esm --watch\" \"cd example && pnpm dev\"",
7
- "prepublishOnly": "pnpm run build",
8
- "postpublish": "pnpm run build:example && npm run deploy",
9
- "build": "tsup src/index.tsx --format esm --clean --dts",
10
- "build:example": "cd example && pnpm run build",
11
- "deploy": "gh-pages -d example/dist",
12
- "pretest": "pnpm run build",
13
- "test": "vitest",
14
- "test:watch": "vitest --watch",
15
- "test:ci": "pnpm run build && pnpm test",
16
- "tsc": "tsc"
17
- },
18
5
  "author": "Nico Domino <yo@ndo.dev>",
19
6
  "homepage": "https://github.com/ndom91/react-timezone-select",
20
7
  "repository": {
@@ -45,43 +32,43 @@
45
32
  }
46
33
  },
47
34
  "peerDependencies": {
48
- "react": "^18 || ^17.0.1 || ^16",
49
- "react-dom": "^18 || ^17.0.1 || ^16",
50
- "react-select": "^5.7.3"
35
+ "react": "^16 || ^17.0.1 || ^18 || ^19.0.0-0",
36
+ "react-dom": "^16 || ^17.0.1 || ^18 || ^19.0.0-0",
37
+ "react-select": "^5.8.0"
51
38
  },
52
39
  "dependencies": {
53
- "spacetime": "^7.4.8",
54
- "timezone-soft": "^1.5.1"
40
+ "spacetime": "^7.6.0",
41
+ "timezone-soft": "^1.5.2"
55
42
  },
56
43
  "devDependencies": {
57
- "@babel/core": "^7.23.5",
58
- "@testing-library/jest-dom": "^5.17.0",
59
- "@testing-library/react": "^14.1.2",
60
- "@types/jest": "^27.5.2",
61
- "@types/react": "^18.2.43",
62
- "@types/react-dom": "^18.2.17",
44
+ "@babel/core": "^7.24.5",
45
+ "@testing-library/jest-dom": "^6.4.5",
46
+ "@testing-library/react": "^15.0.7",
47
+ "@types/jest": "^29.5.12",
48
+ "@types/react": "^18.3.2",
49
+ "@types/react-dom": "^18.3.0",
63
50
  "@types/testing-library__jest-dom": "^5.14.9",
64
- "@typescript-eslint/eslint-plugin": "^6.13.2",
65
- "@typescript-eslint/parser": "^6.13.2",
51
+ "@typescript-eslint/eslint-plugin": "^7.9.0",
52
+ "@typescript-eslint/parser": "^7.9.0",
66
53
  "@vitejs/plugin-react": "^4.2.1",
67
- "concurrently": "^7.6.0",
68
- "esbuild": "^0.16.17",
54
+ "concurrently": "^8.2.2",
55
+ "esbuild": "^0.21.3",
69
56
  "esbuild-jest": "^0.5.0",
70
- "eslint": "^8.55.0",
57
+ "eslint": "^8.57.0",
71
58
  "eslint-config-prettier": "^9.1.0",
72
- "eslint-plugin-prettier": "5.0.1",
73
- "gh-pages": "^3.2.3",
59
+ "eslint-plugin-prettier": "5.1.3",
60
+ "gh-pages": "^6.1.1",
74
61
  "jest-environment-jsdom": "^29.7.0",
75
- "prettier": "^3.1.1",
62
+ "prettier": "^3.2.5",
76
63
  "react": "^18.2.0",
77
64
  "react-dom": "^18.2.0",
78
- "simple-git-hooks": "^2.9.0",
79
- "ts-jest": "^29.1.1",
80
- "tsup": "^6.7.0",
81
- "typescript": "^5.3.3",
82
- "vite": "^5.0.7",
83
- "vite-tsconfig-paths": "^4.2.2",
84
- "vitest": "^1.0.4"
65
+ "simple-git-hooks": "^2.11.1",
66
+ "ts-jest": "^29.1.2",
67
+ "tsup": "^8.0.2",
68
+ "typescript": "^5.4.5",
69
+ "vite": "^5.2.11",
70
+ "vite-tsconfig-paths": "^4.3.2",
71
+ "vitest": "^1.6.0"
85
72
  },
86
73
  "eslintConfig": {
87
74
  "parser": "@typescript-eslint/parser",
@@ -110,5 +97,16 @@
110
97
  "*.{js,jsx,ts,tsx}": [
111
98
  "eslint --fix"
112
99
  ]
100
+ },
101
+ "scripts": {
102
+ "dev": "concurrently \"tsup src/index.tsx --format esm --watch\" \"cd example && pnpm dev\"",
103
+ "build": "tsup src/index.tsx --format esm --clean --dts && sed -i '1i \"use client\"\\n' dist/index.js",
104
+ "build:example": "cd example && pnpm run build",
105
+ "deploy": "gh-pages -d example/dist",
106
+ "pretest": "pnpm run build",
107
+ "test": "vitest",
108
+ "test:watch": "vitest --watch",
109
+ "test:ci": "pnpm run build && pnpm test",
110
+ "tsc": "tsc"
113
111
  }
114
- }
112
+ }