New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@cashstar/react-timezone

Package Overview
Dependencies
Maintainers
2
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cashstar/react-timezone - npm Package Compare versions

Comparing version 1.0.3 to 2.0.0

test/testUtils.js

9

index.js
var TimezoneAutocomplete = require('./lib/components/TimezoneAutocomplete').default;
var timezoneShape = require('./lib/utils/types').timezoneShape;
var injectTimezone = require('./lib/inject').default;
var timezoneData = require('./lib/data/timezoneData').default;
var timeHelper = require('./lib/utils/time').default;

@@ -8,3 +9,7 @@ module.exports = {

timezoneShape: timezoneShape,
injectTimezone: injectTimezone
getAllTimezones: () => timezoneData,
timezoneSearch: timeHelper.tzSearch,
guessUserTimezone: timeHelper.guessUserTz,
isTimezoneMatch: timeHelper.isValueInCityOrZone,
compareTimezones: timeHelper.compareByCityAndZone
};

@@ -8,3 +8,4 @@ module.exports = {

},
verbose: true
verbose: true,
setupTestFrameworkScriptFile: '<rootDir>/testSetup.js'
};

@@ -159,12 +159,3 @@ 'use strict';

inputProps: {},
menuStyle: {
borderRadius: '2px',
boxShadow: '0 2px 12px rgba(0, 0, 0, 0.1)',
background: 'rgba(255, 255, 255, 0.9)',
fontSize: '1rem',
position: 'sticky',
overflow: 'auto',
width: '100%',
minWidth: 'initial'
},
menuStyle: {},
wrapperProps: {},

@@ -171,0 +162,0 @@ minLength: 3

@@ -41,3 +41,4 @@ 'use strict';

if (typeof value !== 'string') {
console.warn(false, 'Fields passed to \'filterBy\' should have string values. Value will be converted to a string; results may be unexpected.');
console.warn( // eslint-disable-line
false, 'Fields passed to \'filterBy\' should have string values. Value will be converted to a string; results may be unexpected.');

@@ -44,0 +45,0 @@ // Coerce to string since `toString` isn't null-safe.

@@ -25,3 +25,3 @@ 'use strict';

return function (filterField) {
return _search2.default.isMatch(timezoneToSearch[filterField], fieldsToFilterBy[filterField]);
return _search2.default.isMatch(fieldsToFilterBy[filterField], timezoneToSearch[filterField]);
};

@@ -59,3 +59,4 @@ };

// so unset global.Intl to trick moment-timezone into using its fallback
// see https://github.com/moment/moment-timezone/issues/441
// see https://github.com/moment/moment-timezone/issues/441 and
// see https://github.com/moment/moment-timezone/issues/517
// TODO: Clean this up when that issue is resolved

@@ -92,2 +93,11 @@ var globalIntl = global.Intl;

/**
* Compares the city and zoneAbbr of the two provided timezones and returns:
* 1: when timezone1 has a city or zoneAbbr less than timezone2
* -1: when timezone1 has a city or zoneAbbr greater than timezone2
* 0: when timezone1 and timezone2 are equal
* @param {object} timezone1
* @param {object} timezone2
* @return {number}
*/
var compareByCityAndZone = function compareByCityAndZone(timezone1, timezone2) {

@@ -94,0 +104,0 @@ var city1 = timezone1.city.toLowerCase();

@@ -6,3 +6,3 @@ 'use strict';

});
exports.timezoneShape = exports.timezoneHelperPropTypes = exports.timezoneValuePropTypes = undefined;
exports.timezoneShape = undefined;

@@ -15,24 +15,7 @@ var _propTypes = require('prop-types');

var string = _propTypes2.default.string,
func = _propTypes2.default.func,
shape = _propTypes2.default.shape,
arrayOf = _propTypes2.default.arrayOf;
var timezoneValuePropTypes = exports.timezoneValuePropTypes = {
var string = _propTypes2.default.string;
var timezoneShape = exports.timezoneShape = {
city: string.isRequired,
zoneName: string.isRequired,
zoneAbbr: string.isRequired
};
var timezoneHelperPropTypes = exports.timezoneHelperPropTypes = {
allTimezones: arrayOf(timezoneValuePropTypes),
change: func.isRequired,
search: func.isRequired,
guessCurrent: func.isRequired,
match: func.isRequired,
compare: func.isRequired
};
var timezoneShape = exports.timezoneShape = shape({
value: timezoneValuePropTypes,
helper: timezoneHelperPropTypes
});
};
{
"name": "@cashstar/react-timezone",
"version": "1.0.3",
"version": "2.0.0",
"description": "A timezone picker widget in React",

@@ -14,7 +14,6 @@ "main": "index.js",

"test:jest": "jest",
"test:coverage": "jest --coverage",
"test:nocache": "jest --no-cache",
"test:watch": "jest --watch",
"precover": "rimraf coverage && mkdir -p ./coverage/",
"cover": "NODE_ENV=test node --max-old-space-size=2048 $(which nyc) npm run test:jest",
"coveralls": "nyc npm run test:jest && nyc report --reporter=text-lcov | coveralls",
"coveralls": "jest --coverage && cat ./coverage/lcov.info | coveralls",
"storybook": "start-storybook -p 9001 -c .storybook",

@@ -46,8 +45,3 @@ "tag": "git tag v$npm_package_version",

"invariant": "^2.2.2",
"moment": "^2.18.1",
"moment-timezone": "^0.5.13",
"nyc": "^11.2.1",
"react": "^15.6.1",
"react-autocomplete": "^1.7.1",
"react-dom": "^15.6.1"
"react-autocomplete": "^1.7.2"
},

@@ -67,4 +61,5 @@ "devDependencies": {

"babel-register": "^6.26.0",
"enzyme": "^2.9.1",
"eslint": "^4.5.0",
"enzyme": "^3.2.0",
"enzyme-adapter-react-15": "^1.0.5",
"eslint": "^4.14.0",
"eslint-config-airbnb": "^15.1.0",

@@ -78,9 +73,18 @@ "eslint-plugin-babel": "^4.1.2",

"jsdom": "^11.2.0",
"less": "^2.7.2",
"moment": "^2.20.1",
"moment-timezone": "^0.5.14",
"prop-types": "^15.5.10",
"react": "^15.6.2",
"react-a11y-alt": "^0.3.5",
"react-test-renderer": "^15.6.1",
"react-dom": "^15.6.2",
"react-test-renderer": "^15.6.2",
"rimraf": "^2.6.1",
"semver": "^5.4.1"
},
"peerDependencies": {
"moment": "^2.18.0",
"moment-timezone": "^0.5.0",
"react": "^15.0.0",
"react-dom": "^15.0.0"
}
}

@@ -0,2 +1,291 @@

[![Build Status](https://travis-ci.org/erin-doyle/react-timezone.svg?branch=master)](https://travis-ci.org/erin-doyle/react-timezone)
[![Coverage Status](https://coveralls.io/repos/github/erin-doyle/react-timezone/badge.svg)](https://coveralls.io/github/erin-doyle/react-timezone)
# react-timezone
Timezone picker widget using React
_TODO: add gif of TimezoneAutocomplete in action_
## Getting Started
### Local Demo
To run the demo on your own computer:
* Clone this repository
* `npm install`
* `npm run storybook`
* Visit http://localhost:9001/
### Install dependencies
Ensure packages are installed with correct version numbers by running:
```sh
(
export PKG=react-timezone;
npm info "$PKG" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g; s/ *//g' | xargs npm install --save "$PKG"
)
```
Which produces and runs a command like:
```sh
npm install --save react-timezone moment@>=#.## moment-timezone@>=#.## react@>=#.## react-dom@>=#.##
```
## Usage
The TimezoneAutocomplete component is an auto-complete input that shows fuzzy matches based on the text entered
into the field and refreshes matches shown with each additional character entered.
TimezoneAutocomplete without any customization:
```javascript
<div>
<label>
Closest City or Timezone
</label>
<TimezoneAutocomplete onTimezoneChange={(timezone) => console.log(`new timezone: ${timezone}`)} />
</div>
```
## Timezone Object
The Timezone object that is passed to onTimezoneChange has the following shape:
- `city` (string) - the major city in that timezone (i.e. Los Angeles)
- `zoneName` (string) - the [moment-timezone Name property](https://momentjs.com/timezone/docs/#/zone-object/name/)
which is the uniquely identifying name of the timezone (i.e. America/Los_Angeles)
- `zoneAbbr` (string) - the [moment-timezone Abbr property](https://momentjs.com/timezone/docs/#/zone-object/abbr/)
which is the abbreviation for the timezone (i.e. PST or PDT)
The shape can be imported for use in defining PropTypes in your project by:
```javascript
import { timezoneShape } from 'react-timezone';
```
## API
### Props
`onTimezoneChange: Function` (optional)
Default value: function() {}
Arguments: `timezone: Object` ([Timezone object](#timezone-object))
Invoked when the user selects an item from the dropdown menu.
```javascript
onTimezoneChange={(timezone) => console.log(`${timezone.city} - ${timezone.zoneName} - ${timezone.zoneAbbr}`)}
```
`onMenuVisibilityChange: Function` (optional)
Default value: function() {}
Arguments: `isOpen: Boolean`
Invoked every time the dropdown menu's visibility changes (i.e. every time it is displayed/hidden).
```javascript
onMenuVisibilityChange={(isOpen) => console.log(isOpen ? 'I\'m open!' : 'I\'m closed!')}
```
`inputProps: Object` (optional)
Default value: {}
These props will be applied to the `<input />` element rendered by TimezoneAutocomplete.
Any properties supported by HTMLInputElement can be specified, apart from the following which are set by TimezoneAutocomplete:
- value
- autoComplete
- role
- aria-autocomplete
inputProps is commonly used for (but not limited to) placeholder, event handlers (onFocus, onBlur, etc.), autoFocus, etc..
```javascript
inputProps={{
placeholder: 'Enter a city or timezone',
onFocus: () => console.log('onFocus'),
onBlur: () => console.log('onBlur')
}}
```
`menuStyle: Object` (optional)
Default value:
```json
{
borderRadius: '3px',
boxShadow: '0 2px 12px rgba(0, 0, 0, 0.1)',
background: 'rgba(255, 255, 255, 0.9)',
padding: '2px 0',
fontSize: '90%',
position: 'fixed',
overflow: 'auto',
maxHeight: '50%'
}
```
Styles that are applied to the dropdown menu in the default renderMenu implementation.
```javascript
menuStyle={{
borderRadius: '3px',
border: '1px solid',
backgroundColor: 'pink',
boxSizing: 'border-box',
marginBottom: '1%',
padding: '10px 10px',
width: '100%',
height: '100%',
color: 'purple',
fontWeight: 'bold',
fontSize: '0.9rem',
lineHeight: '2',
}}
```
`wrapperProps: Object` (optional)
Default value: {}
Props that are applied to the element which wraps the `<input />` and dropdown menu
elements rendered by TimezoneAutocomplete.
```javascript
wrapperProps={{
id: 'timezone-picker-search-input-wrapper',
className: 'wrapper-class-name',
style: {
backgroundColor: 'gray',
width: '30%',
margin: '15px'
}
}}
```
`minLength: number` (optional)
Default value: 3
The number of characters the user must enter before the dropdown opens displaying any
matching timezone options.
### Helper Functions
A number of helper functions are provided for use in dealing with timezone values, searching and matching.
`getAllTimezones`
Arguments: None
Returns an Array of all of the [Timezone objects](#timezone-object) used as the source of data
by the TimezoneAutocomplete and other helper functions.
`timezoneSearch`
Arguments: `filterFields: Object`
Returns an Array of [Timezone objects](#timezone-object) matching the search criteria provided in the filterFields
argument. The filterFields object should have as keys any of the properties in the [Timezone object](#timezone-object)
with, as corresponding values, the string to search for in the respective field. Any combination
of the keys (city, zoneName, or zoneAbbr) may be used.
For example:
```javascript
let matches;
matches = timezoneSearch({ city: 'New' });
/*
[
{ city: "New York", zoneName: "America/New_York", zoneAbbr: "EST" },
{ city: "New Salem", zoneName: "America/North_Dakota/New_Salem", zoneAbbr: "CST" },
{ city: "Canada/Newfoundland", zoneName: "Canada/Newfoundland", zoneAbbr: "NST" }
]
*/
matches = timezoneSearch({ city: 'New', zoneName: 'America' });
/*
[
{ city: "New York", zoneName: "America/New_York", zoneAbbr: "EST" },
{ city: "New Salem", zoneName: "America/North_Dakota/New_Salem", zoneAbbr: "CST" }
]
*/
matches = timezoneSearch({ city: 'New', zoneName: 'America', zoneAbbr: 'EST' });
/*
[
{ city: "New York", zoneName: "America/New_York", zoneAbbr: "EST" }
]
*/
```
`guessUserTimezone`
Arguments: None
Returns the [Timezone object](#timezone-object) of the timezone it deduces the user to be in.
```javascript
const timezone = guessUserTimezone();
console.log(`This user is in: ${timezone.city} - ${timezone.zoneAbbr}`);
```
`isTimezoneMatch`
Arguments: `timezone: Object` ([Timezone object](#timezone-object)) `, searchValue: String, minLength: number (optional)`
Returns true or false as to whether the searchValue is a match to the timezone.
The optional minLength argument provides a the minimum length the searchValue must be before searching is allowed.
```javascript
const timezone = { city: "New York", zoneName: "America/New_York", zoneAbbr: "EST" };
let isMatch;
isMatch = isTimezoneMatch(timezone, 'New York');
// true
isMatch = isTimezoneMatch(timezone, 'EST');
// true
isMatch = isTimezoneMatch(timezone, 'Somewhere Else');
// false
isMatch = isTimezoneMatch(timezone, 'New', 5);
// false
isMatch = isTimezoneMatch(timezone, 'New York', 5);
// true
```
`compareTimezones`
Arguments: `timezone1: Object` ([Timezone object](#timezone-object))`, timezone2: Object` ([Timezone object](#timezone-object))
Compares the city and zoneAbbr of the two provided timezones and returns:
* 1: when timezone1 is considered less than timezone2
* -1: when timezone1 is considered greater than timezone2
* 0: when timezone1 and timezone2 are equal
```javascript
let comparison;
comparison = compareTimezones(
{ city: "Chicago", zoneName: "America/Chicago", zoneAbbr: "CST" },
{ city: "New York", zoneName: "America/New_York", zoneAbbr: "EST" }
);
console.log(comparison);
// 1
comparison = compareTimezones(
{ city: "Port-au-Prince", zoneName: "America/Port-au-Prince", zoneAbbr: "EST" },
{ city: "New York", zoneName: "America/New_York", zoneAbbr: "EST" }
);
console.log(comparison);
// -1
comparison = compareTimezones(
{ city: "New York", zoneName: "America/New_York", zoneAbbr: "EST" },
{ city: "New York", zoneName: "America/New_York", zoneAbbr: "EST" }
);
console.log(comparison);
// 0
```

@@ -109,12 +109,3 @@ import React from 'react';

inputProps: {},
menuStyle: {
borderRadius: '2px',
boxShadow: '0 2px 12px rgba(0, 0, 0, 0.1)',
background: 'rgba(255, 255, 255, 0.9)',
fontSize: '1rem',
position: 'sticky',
overflow: 'auto',
width: '100%',
minWidth: 'initial'
},
menuStyle: {},
wrapperProps: {},

@@ -121,0 +112,0 @@ minLength: 3

@@ -36,3 +36,3 @@ /**

if (typeof value !== 'string') {
console.warn(
console.warn( // eslint-disable-line
false,

@@ -39,0 +39,0 @@ `Fields passed to 'filterBy' should have string values. \

@@ -11,3 +11,3 @@ import moment from 'moment-timezone';

filterField => (
searchHelper.isMatch(timezoneToSearch[filterField], fieldsToFilterBy[filterField])
searchHelper.isMatch(fieldsToFilterBy[filterField], timezoneToSearch[filterField])
)

@@ -45,3 +45,4 @@ );

// so unset global.Intl to trick moment-timezone into using its fallback
// see https://github.com/moment/moment-timezone/issues/441
// see https://github.com/moment/moment-timezone/issues/441 and
// see https://github.com/moment/moment-timezone/issues/517
// TODO: Clean this up when that issue is resolved

@@ -80,2 +81,11 @@ const globalIntl = global.Intl;

/**
* Compares the city and zoneAbbr of the two provided timezones and returns:
* 1: when timezone1 has a city or zoneAbbr less than timezone2
* -1: when timezone1 has a city or zoneAbbr greater than timezone2
* 0: when timezone1 and timezone2 are equal
* @param {object} timezone1
* @param {object} timezone2
* @return {number}
*/
const compareByCityAndZone = (timezone1, timezone2) => {

@@ -82,0 +92,0 @@ const city1 = timezone1.city.toLowerCase();

import PropTypes from 'prop-types';
const { string, func, shape, arrayOf } = PropTypes;
const { string } = PropTypes;
export const timezoneValuePropTypes = {
export const timezoneShape = {
city: string.isRequired,

@@ -11,15 +11,1 @@ zoneName: string.isRequired,

};
export const timezoneHelperPropTypes = {
allTimezones: arrayOf(timezoneValuePropTypes),
change: func.isRequired,
search: func.isRequired,
guessCurrent: func.isRequired,
match: func.isRequired,
compare: func.isRequired
};
export const timezoneShape = shape({
value: timezoneValuePropTypes,
helper: timezoneHelperPropTypes
});
import React from 'react';
import { shallow } from 'enzyme';
import { EASTERN_TZ } from '../testUtils';

@@ -13,3 +14,3 @@ import TimezoneAutocomplete, { formatTimezone, parseTimezone } from '../../src/components/TimezoneAutocomplete';

zoneName: 'America/New_York',
zoneAbbr: 'EDT'
zoneAbbr: EASTERN_TZ
};

@@ -49,4 +50,5 @@

it('should return a string representation of the timezone object', () => {
const { city, zoneAbbr } = mockTimezone;
const displayResult = formatTimezone(mockTimezone);
expect(displayResult).toBe('New York - EDT');
expect(displayResult).toBe(`${city} - ${zoneAbbr}`);
});

@@ -53,0 +55,0 @@ });

import tzMaps from '../../src/data/timezoneData';
import searchHelper from '../../src/utils/search';
import {
EASTERN_TZ,
PACIFIC_TZ,
CENTRAL_TZ,
NEWFOUNDLAND_TZ
} from '../testUtils';
describe('Search utils', () => {

@@ -90,6 +95,6 @@ describe('isMatch', () => {

expect(results).toEqual([
{ city: 'New York', zoneName: 'America/New_York', zoneAbbr: 'EDT' },
{ city: 'New Salem', zoneName: 'America/North_Dakota/New_Salem', zoneAbbr: 'CDT' },
{ city: 'Canada/Newfoundland', zoneName: 'Canada/Newfoundland', zoneAbbr: 'NDT' },
{ city: 'US/Pacific-New', zoneName: 'US/Pacific-New', zoneAbbr: 'PDT' }
{ city: 'New York', zoneName: 'America/New_York', zoneAbbr: EASTERN_TZ },
{ city: 'New Salem', zoneName: 'America/North_Dakota/New_Salem', zoneAbbr: CENTRAL_TZ },
{ city: 'Canada/Newfoundland', zoneName: 'Canada/Newfoundland', zoneAbbr: NEWFOUNDLAND_TZ },
{ city: 'US/Pacific-New', zoneName: 'US/Pacific-New', zoneAbbr: PACIFIC_TZ }
]);

@@ -109,3 +114,3 @@ });

expect(results).toEqual([
{ city: 'New York', zoneName: 'America/New_York', zoneAbbr: 'EDT' }
{ city: 'New York', zoneName: 'America/New_York', zoneAbbr: EASTERN_TZ }
]);

@@ -112,0 +117,0 @@ });

/* eslint-disable max-len */ // lots of long test names and that's ok
import timeHelper from '../../src/utils/time';
import { EASTERN_TZ } from '../testUtils';
const mockTimezone = {

@@ -44,8 +44,8 @@ city: 'Some City',

it('should return the matching timezone object containing the provided city and zone abbreviation', () => {
const cityToSearchFor = 'New York';
const zoneToSearchFor = 'EDT';
const cityToSearchFor = 'New';
const zoneToSearchFor = EASTERN_TZ;
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneAbbr: zoneToSearchFor });
expect(result).toHaveLength(1);
expect(result[0].city).toEqual(cityToSearchFor);
expect(result[0].zoneAbbr).toEqual(zoneToSearchFor);
expect(result[0].city).toContain(cityToSearchFor);
expect(result[0].zoneAbbr).toContain(zoneToSearchFor);
});

@@ -61,2 +61,20 @@

describe('tzSearch with city and name arguments', () => {
it('should return the matching timezone object containing the provided city and zone name', () => {
const cityToSearchFor = 'New';
const zoneToSearchFor = 'America';
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneName: zoneToSearchFor });
expect(result).toHaveLength(2);
expect(result[0].city).toContain(cityToSearchFor);
expect(result[0].zoneName).toContain(zoneToSearchFor);
});
it('should return an empty array when a timezone object does not exist containing the provided city and zone name', () => {
const cityToSearchFor = 'Some City that should not exist in the Timezone data';
const zoneToSearchFor = 'ABCDEFG';
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneName: zoneToSearchFor });
expect(result).toHaveLength(0);
});
});
describe('tzSearch with filterFields that do not exist', () => {

@@ -63,0 +81,0 @@ it('should return an empty array if passed only filterFields that do not exist on the timezone object', () => {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc