react-timezone-select
Advanced tools
Comparing version 3.2.3 to 3.2.4
@@ -36,2 +36,2 @@ import * as react_jsx_runtime_js from 'react/jsx-runtime.js'; | ||
export { ILabelStyle, ITimezone, ITimezoneOption, Props, TimezoneSelectOptions, allTimezones, TimezoneSelect as default, useTimezoneSelect }; | ||
export { type ILabelStyle, type ITimezone, type ITimezoneOption, type Props, type TimezoneSelectOptions, allTimezones, TimezoneSelect as default, useTimezoneSelect }; |
@@ -171,4 +171,5 @@ "use client" | ||
}).filter(Boolean).sort((a, b) => a.offset - b.offset); | ||
}, [labelStyle, timezones]); | ||
}, [labelStyle, timezones, currentDatetime]); | ||
const findFuzzyTz = (zone) => { | ||
var _a, _b; | ||
let currentTime; | ||
@@ -180,3 +181,3 @@ try { | ||
} | ||
return options.filter((tz) => tz.offset === currentTime.timezone().current.offset).map((tz) => { | ||
return (_b = (_a = options.filter((tz) => tz.offset === currentTime.timezone().current.offset).map((tz) => { | ||
let score = 0; | ||
@@ -198,3 +199,3 @@ if (currentTime.timezones[tz.value.toLowerCase()] && !!currentTime.timezones[tz.value.toLowerCase()].dst === currentTime.timezone().hasDst) { | ||
return { tz, score }; | ||
}).sort((a, b) => b.score - a.score)[0].tz; | ||
}).sort((a, b) => b.score - a.score)) == null ? void 0 : _a[0]) == null ? void 0 : _b.tz; | ||
}; | ||
@@ -201,0 +202,0 @@ const parseTimezone = (zone) => { |
{ | ||
"name": "react-timezone-select", | ||
"version": "3.2.3", | ||
"version": "3.2.4", | ||
"description": "Usable, dynamic React Timezone Select", | ||
"scripts": { | ||
"dev": "concurrently \"tsup src/index.tsx --format esm --watch\" \"cd example && pnpm dev\"", | ||
"prepublishOnly": "pnpm run build", | ||
"postpublish": "pnpm run build:example && npm run deploy", | ||
"build": "tsup src/index.tsx --format esm --clean --dts && sed -i '1i \"use client\"\\n' dist/index.js", | ||
"build:example": "cd example && pnpm run build", | ||
"deploy": "gh-pages -d example/dist", | ||
"pretest": "pnpm run build", | ||
"test": "vitest", | ||
"test:watch": "vitest --watch", | ||
"test:ci": "pnpm run build && pnpm test", | ||
"tsc": "tsc" | ||
}, | ||
"author": "Nico Domino <yo@ndo.dev>", | ||
@@ -48,39 +35,39 @@ "homepage": "https://github.com/ndom91/react-timezone-select", | ||
"peerDependencies": { | ||
"react": "^18 || ^17.0.1 || ^16", | ||
"react-dom": "^18 || ^17.0.1 || ^16", | ||
"react-select": "^5.7.3" | ||
"react": "^16 || ^17.0.1 || ^18 || ^19.0.0-0", | ||
"react-dom": "^16 || ^17.0.1 || ^18 || ^19.0.0-0", | ||
"react-select": "^5.8.0" | ||
}, | ||
"dependencies": { | ||
"spacetime": "^7.4.8", | ||
"timezone-soft": "^1.5.1" | ||
"spacetime": "^7.6.0", | ||
"timezone-soft": "^1.5.2" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.23.5", | ||
"@testing-library/jest-dom": "^5.17.0", | ||
"@testing-library/react": "^14.1.2", | ||
"@types/jest": "^27.5.2", | ||
"@types/react": "^18.2.43", | ||
"@types/react-dom": "^18.2.17", | ||
"@babel/core": "^7.24.5", | ||
"@testing-library/jest-dom": "^6.4.5", | ||
"@testing-library/react": "^15.0.7", | ||
"@types/jest": "^29.5.12", | ||
"@types/react": "^18.3.2", | ||
"@types/react-dom": "^18.3.0", | ||
"@types/testing-library__jest-dom": "^5.14.9", | ||
"@typescript-eslint/eslint-plugin": "^6.13.2", | ||
"@typescript-eslint/parser": "^6.13.2", | ||
"@typescript-eslint/eslint-plugin": "^7.9.0", | ||
"@typescript-eslint/parser": "^7.9.0", | ||
"@vitejs/plugin-react": "^4.2.1", | ||
"concurrently": "^7.6.0", | ||
"esbuild": "^0.16.17", | ||
"concurrently": "^8.2.2", | ||
"esbuild": "^0.21.3", | ||
"esbuild-jest": "^0.5.0", | ||
"eslint": "^8.55.0", | ||
"eslint": "^8.57.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-prettier": "5.0.1", | ||
"gh-pages": "^3.2.3", | ||
"eslint-plugin-prettier": "5.1.3", | ||
"gh-pages": "^6.1.1", | ||
"jest-environment-jsdom": "^29.7.0", | ||
"prettier": "^3.1.1", | ||
"prettier": "^3.2.5", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"simple-git-hooks": "^2.9.0", | ||
"ts-jest": "^29.1.1", | ||
"tsup": "^6.7.0", | ||
"typescript": "^5.3.3", | ||
"vite": "^5.0.7", | ||
"vite-tsconfig-paths": "^4.2.2", | ||
"vitest": "^1.0.4" | ||
"simple-git-hooks": "^2.11.1", | ||
"ts-jest": "^29.1.2", | ||
"tsup": "^8.0.2", | ||
"typescript": "^5.4.5", | ||
"vite": "^5.2.11", | ||
"vite-tsconfig-paths": "^4.3.2", | ||
"vitest": "^1.6.0" | ||
}, | ||
@@ -114,3 +101,14 @@ "eslintConfig": { | ||
] | ||
}, | ||
"scripts": { | ||
"dev": "concurrently \"tsup src/index.tsx --format esm --watch\" \"cd example && pnpm dev\"", | ||
"build": "tsup src/index.tsx --format esm --clean --dts && sed -i '1i \"use client\"\\n' dist/index.js", | ||
"build:example": "cd example && pnpm run build", | ||
"deploy": "gh-pages -d example/dist", | ||
"pretest": "pnpm run build", | ||
"test": "vitest", | ||
"test:watch": "vitest --watch", | ||
"test:ci": "pnpm run build && pnpm test", | ||
"tsc": "tsc" | ||
} | ||
} | ||
} |
231
README.md
# đâ react-timezone-select | ||
[![npm](https://img.shields.io/npm/v/react-timezone-select?style=flat-square)](https://www.npmjs.com/package/react-timezone-select) | ||
[![NPM Downloads](https://img.shields.io/npm/dm/react-timezone-select?style=flat-square)](https://www.npmjs.com/package/react-timezone-select) | ||
[![npm](https://img.shields.io/npm/v/react-timezone-select?style=flat-square)](https://www.npmjs.com/package/react-timezone-select) | ||
[![GitHub issues](https://img.shields.io/github/issues/ndom91/react-timezone-select?style=flat-square)](https://github.com/ndom91/react-timezone-select/issues) | ||
[![Skypack](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg?style=flat-square)](https://skypack.dev/view/react-timezone-select) | ||
[![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) | ||
[![MIT](https://badgen.net/badge/license/MIT/blue?style=flat-square)](https://github.com/ndom91/react-timezone-select/blob/main/LICENSE) | ||
[![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) | ||
[![MIT](https://flat.badgen.net/badge/license/MIT/blue?style=flat-square)](https://github.com/ndom91/react-timezone-select/blob/main/LICENSE) | ||
@@ -17,4 +16,6 @@ Another react timezone select component, I know.. However this one has a few key benefits! | ||
#### Demo: [ndom91.github.io/react-timezone-select](https://ndom91.github.io/react-timezone-select/) | ||
> [!IMPORTANT] | ||
> | ||
> ### Demo: [ndom91.github.io/react-timezone-select](https://ndom91.github.io/react-timezone-select/) | ||
> | ||
> 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). | ||
@@ -25,16 +26,18 @@ | ||
```bash | ||
// react-select is an optional peer dependency, unnecessary if using the hook | ||
npm install react-timezone-select react-select | ||
``` | ||
> [!CAUTION] | ||
> The package `react-select` is optional. It is unnecessary if you're only using [the hook](#-timezone-hook). | ||
## đ Usage | ||
```jsx | ||
import React, { useState } from 'react' | ||
import ReactDOM from 'react-dom' | ||
import TimezoneSelect, { type ITimezone } from 'react-timezone-select' | ||
```tsx | ||
import React, { useState } from "react" | ||
import ReactDOM from "react-dom" | ||
import TimezoneSelect, { type ITimezone } from "react-timezone-select" | ||
const App = () => { | ||
const [selectedTimezone, setSelectedTimezone] = useState<ITimezone>( | ||
Intl.DateTimeFormat().resolvedOptions().timeZone | ||
Intl.DateTimeFormat().resolvedOptions().timeZone, | ||
) | ||
@@ -47,6 +50,3 @@ | ||
<div className="select-wrapper"> | ||
<TimezoneSelect | ||
value={selectedTimezone} | ||
onChange={setSelectedTimezone} | ||
/> | ||
<TimezoneSelect value={selectedTimezone} onChange={setSelectedTimezone} /> | ||
</div> | ||
@@ -56,7 +56,7 @@ <h3>Output:</h3> | ||
style={{ | ||
backgroundColor: '#ccc', | ||
padding: '20px', | ||
margin: '20px auto', | ||
borderRadius: '5px', | ||
maxWidth: '600px', | ||
backgroundColor: "#ccc", | ||
padding: "20px", | ||
margin: "20px auto", | ||
borderRadius: "5px", | ||
maxWidth: "600px", | ||
}} | ||
@@ -66,5 +66,5 @@ > | ||
style={{ | ||
margin: '0 20px', | ||
margin: "0 20px", | ||
fontWeight: 500, | ||
fontFamily: 'monospace', | ||
fontFamily: "monospace", | ||
}} | ||
@@ -79,8 +79,114 @@ > | ||
const rootElement = document.getElementById('root') | ||
const rootElement = document.getElementById("root") | ||
ReactDOM.render(<App />, rootElement) | ||
``` | ||
## đĒ Tips | ||
## đ¨ Timezone Hook | ||
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. | ||
```tsx | ||
import { useTimezoneSelect, allTimezones } from "react-timezone-select" | ||
const labelStyle = "original" | ||
const timezones = { | ||
...allTimezones, | ||
"Europe/Berlin": "Frankfurt", | ||
} | ||
const customSelect = () => { | ||
const { options, parseTimezone } = useTimezoneSelect({ labelStyle, timezones }) | ||
return ( | ||
<select onChange={(e) => onChange(parseTimezone(e.currentTarget.value))}> | ||
{options.map((option) => ( | ||
<option value={option.value}>{option.label}</option> | ||
))} | ||
</select> | ||
) | ||
} | ||
``` | ||
## đšī¸ Props | ||
<table> | ||
<tbody> | ||
<tr> | ||
<th>Prop</th> | ||
<th>Type</th> | ||
<th>Default</th> | ||
<th>Note</th> | ||
</tr> | ||
<tr> | ||
<td><code>value</code></td> | ||
<td><code>string | ITimezoneOption<string, string></code></td> | ||
<td>null</td> | ||
<td>Initial/current Timezone</td> | ||
</tr> | ||
<tr> | ||
<td><code>onBlur</code></td> | ||
<td><code>() => void</code></td> | ||
<td>null</td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td><code>onChange</code></td> | ||
<td><code>(timezone: ITimezoneOption) => void</code></td> | ||
<td>null</td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td><code>labelStyle</code></td> | ||
<td><code>'original' | 'altName' | 'abbrev' | 'offsetHidden'</code></td> | ||
<td><code>'original'</code></td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td><code>displayValue</code></td> | ||
<td><code>'GMT' | 'UTC'</code></td> | ||
<td><code>'GMT'</code></td> | ||
<td>Prefix for the label (i.e. <code>"(GMT+2:00)"</code> or <code>"(UTC+2:00)"</code>)</td> | ||
</tr> | ||
<tr> | ||
<td><code>timezones</code></td> | ||
<td><code>Record<string,string></code></td> | ||
<td><code>allTimezones</code></td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td><code>currentDatetime</code></td> | ||
<td><code>Date | string</code></td> | ||
<td>null</td> | ||
<td>Override datetime used to calculate timezone values (alternative to current datetime), useful for calculating different summer / winter times, etc.</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
#### Example `value`s: | ||
```ts | ||
// string | ||
value='America/Juneau' | ||
// ITimezoneOption; i.e. `onChange` return value | ||
value={{ | ||
value: 'America/Juneau' | ||
label: '(GMT-8:00) Alaska, | ||
abbrev: 'AHST', | ||
offset: -8, | ||
altName: 'Alaskan Standard Time' | ||
}} | ||
``` | ||
#### Example `timezones`: | ||
```ts | ||
timezones={{ | ||
...allTimezones, | ||
'America/Lima': 'Pittsburgh', | ||
'Europe/Berlin': 'Frankfurt', | ||
}} | ||
``` | ||
## ⨠Tips | ||
### đ¤ Default Users Timezone | ||
@@ -90,10 +196,6 @@ | ||
```jsx | ||
const [timezone, setTimezone] = useState( | ||
Intl.DateTimeFormat().resolvedOptions().timeZone | ||
) | ||
```tsx | ||
const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone) | ||
``` | ||
Thanks [@ndrwksr](https://github.com/ndom91/react-timezone-select/issues/25) | ||
### đ Custom Timezones | ||
@@ -103,5 +205,5 @@ | ||
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. | ||
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)). | ||
```jsx | ||
```tsx | ||
import TimezoneSelect, { type ITimezone, allTimezones } from 'react-timezone-select' | ||
@@ -122,61 +224,12 @@ | ||
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. | ||
The example above will include all original timezones and generate two additional choices: | ||
## đšī¸ Props | ||
- `'(GMT-5:00) Pittsburgh'` | ||
- `'(GMT+1:00) Frankfurt'` | ||
- `value` - `string | Object` - Initial/current Timezone. | ||
``` | ||
'America/Juneau' | { | ||
value: 'America/Juneau' | ||
label: '(GMT-8:00) Alaska, | ||
abbrev: 'AHST', | ||
offset: -8, | ||
altName: 'Alaskan Standard Time' | ||
} | ||
``` | ||
- `onBlur` - `() => void` | ||
- `onChange` - `(timezone) => void` | ||
- `labelStyle` - `'original' | 'altName' | 'abbrev' | 'offsetHidden'` | ||
- `displayValue` - `'GMT' | 'UTC'` | ||
- `timezones` - `Record<string,string>` | ||
- `currentDatetime` - `Date | string` - Set datetime used to calculate timezone values (alternative to current datetime) | ||
``` | ||
timezones={{ | ||
...allTimezones, | ||
'America/Lima': 'Pittsburgh', | ||
'Europe/Berlin': 'Frankfurt', | ||
}} | ||
``` | ||
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. | ||
- Any other [`react-select`](https://github.com/jedwatson/react-select#props) props | ||
## đ¨ Custom Select component | ||
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. | ||
```jsx | ||
import { useTimezoneSelect, allTimezones } from 'react-timezone-select' | ||
const labelStyle = 'original' | ||
const timezones = { | ||
...allTimezones, | ||
'Europe/Berlin': 'Frankfurt' | ||
} | ||
const customSelect = () => { | ||
const { options, parseTimezone } = useTimezoneSelect({ labelStyle, timezones }) | ||
return ( | ||
<select onChange={e => onChange(parseTimezone(e.currentTarget.value))}> | ||
{options.map(option => ( | ||
<option value={option.value}>{option.label}</option> | ||
))} | ||
</select> | ||
) | ||
} | ||
``` | ||
## đ§ Contributing | ||
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! | ||
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! | ||
@@ -189,1 +242,5 @@ ## đ Thanks | ||
- [react-select](https://react-select.com) | ||
## đ License | ||
MIT |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21904
279
237
+ Addedreact@19.0.0-rc-fb9a90fa48-20240614(transitive)
+ Addedreact-dom@19.0.0-rc-fb9a90fa48-20240614(transitive)
+ Addedscheduler@0.25.0-rc-fb9a90fa48-20240614(transitive)
Updatedspacetime@^7.6.0
Updatedtimezone-soft@^1.5.2