pebble-web 2.2.7 → 2.3.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pebble-web",
3
- "version": "2.2.7",
3
+ "version": "2.3.2",
4
4
  "author": "ritz078 <rkritesh078@gmail.com>",
5
5
  "license": "MIT",
6
6
  "main": "dist/pebble-web.js",
@@ -44,12 +44,12 @@
44
44
  "utility-types": "^3.10.0"
45
45
  },
46
46
  "devDependencies": {
47
- "pebble-shared": "^2.2.5"
47
+ "pebble-shared": "^2.2.9"
48
48
  },
49
49
  "greenkeeper": {
50
50
  "ignore": [
51
51
  "rheostat"
52
52
  ]
53
53
  },
54
- "gitHead": "9ea2025dd7943511c22812a3868961fcee363f28"
54
+ "gitHead": "f79f787b420cadf8dc8c3e77fa0dde498d7a75dd"
55
55
  }
@@ -12,7 +12,7 @@ import {
12
12
  wrapperStyle
13
13
  } from "./styles/Calendar.styles";
14
14
  import Button from "./Button";
15
- import { isSameDay, endOfDay, startOfDay } from "date-fns";
15
+ import { isSameDay, endOfDay, startOfDay, addDays, subDays } from "date-fns";
16
16
 
17
17
  class Calendar extends React.PureComponent<CalendarProps, CalendarState> {
18
18
  static defaultProps: Partial<CalendarProps> = {
@@ -20,7 +20,7 @@ class Calendar extends React.PureComponent<CalendarProps, CalendarState> {
20
20
  tileDots: []
21
21
  };
22
22
 
23
- state: CalendarState = {
23
+ state: Readonly<CalendarState> = {
24
24
  value: this.props.selected,
25
25
  singleSelectedDate: null
26
26
  };
@@ -35,7 +35,8 @@ class Calendar extends React.PureComponent<CalendarProps, CalendarState> {
35
35
  this.setState(
36
36
  {
37
37
  value: value as [Date, Date],
38
- singleSelectedDate: null
38
+ singleSelectedDate: null,
39
+ maxRangeDates: undefined
39
40
  },
40
41
  () => props.onChange(value as [Date, Date])
41
42
  );
@@ -45,7 +46,8 @@ class Calendar extends React.PureComponent<CalendarProps, CalendarState> {
45
46
  this.setState(
46
47
  {
47
48
  value,
48
- singleSelectedDate: null
49
+ singleSelectedDate: null,
50
+ maxRangeDates: undefined
49
51
  },
50
52
  () => props.onChange(value)
51
53
  );
@@ -55,6 +57,15 @@ class Calendar extends React.PureComponent<CalendarProps, CalendarState> {
55
57
 
56
58
  private onDayClick = (day: Date) => {
57
59
  const { onClickDay } = this.props;
60
+ if (this.props.range && this.props.maxRange) {
61
+ const { maxRange } = this.props;
62
+ this.setState({
63
+ maxRangeDates: {
64
+ future: addDays(day, maxRange),
65
+ past: subDays(day, maxRange)
66
+ }
67
+ });
68
+ }
58
69
  this.setState({ singleSelectedDate: [startOfDay(day), endOfDay(day)] });
59
70
  if (onClickDay) onClickDay(day);
60
71
  };
@@ -123,8 +134,11 @@ class Calendar extends React.PureComponent<CalendarProps, CalendarState> {
123
134
  className,
124
135
  onApply,
125
136
  onClear,
137
+ maxDate,
138
+ minDate,
126
139
  ...rest
127
140
  } = this.props;
141
+ const { maxRangeDates } = this.state;
128
142
 
129
143
  return (
130
144
  <div
@@ -156,6 +170,8 @@ class Calendar extends React.PureComponent<CalendarProps, CalendarState> {
156
170
  nextLabel={
157
171
  <i style={{ fontSize: 14 }} className="pi pi-arrow-right" />
158
172
  }
173
+ maxDate={maxDate || (maxRangeDates && maxRangeDates.future)}
174
+ minDate={minDate || (maxRangeDates && maxRangeDates.past)}
159
175
  />
160
176
 
161
177
  {(onClear || onApply) && (
@@ -0,0 +1,82 @@
1
+ import { cx } from "emotion";
2
+ import * as React from "react";
3
+ import {
4
+ disabledStyle,
5
+ selectedStar,
6
+ unSelectedStar,
7
+ wrapStyle
8
+ } from "./styles/Rating.styles";
9
+ import { RatingProps, RatingState } from "./typings/Rating";
10
+
11
+ function generateStars(maxRating: number, selectedValue: number) {
12
+ return Array.from({ length: maxRating }, (_, i) => {
13
+ return { active: i + 1 <= selectedValue };
14
+ });
15
+ }
16
+
17
+ class Rating extends React.PureComponent<RatingProps, RatingState> {
18
+ constructor(props: RatingProps) {
19
+ super(props);
20
+ this.state = {
21
+ stars: generateStars(props.maxRating, props.value)
22
+ };
23
+ }
24
+
25
+ componentDidUpdate(prevProps: RatingProps) {
26
+ const { maxRating, value } = this.props;
27
+ if (prevProps.maxRating !== maxRating) {
28
+ this.setState({
29
+ stars: generateStars(maxRating, value)
30
+ });
31
+ }
32
+ }
33
+
34
+ setRating = (rating: number) => {
35
+ const { maxRating, disabled } = this.props;
36
+ if (disabled) {
37
+ return;
38
+ }
39
+ this.setState({
40
+ stars: generateStars(maxRating, rating)
41
+ });
42
+ };
43
+
44
+ render() {
45
+ const { name, value, onChange, disabled, className } = this.props;
46
+ const { stars } = this.state;
47
+
48
+ const _className = cx(wrapStyle, className, disabled && disabledStyle);
49
+
50
+ return (
51
+ <div className={_className}>
52
+ {stars.map((star, starIndex) => {
53
+ const rating = starIndex + 1;
54
+ return (
55
+ <span
56
+ key={`${name}-${rating}`}
57
+ onMouseEnter={() => this.setRating(rating)}
58
+ onMouseLeave={() => this.setRating(value)}
59
+ onClick={() => {
60
+ if (disabled) {
61
+ return;
62
+ }
63
+ this.setRating(rating);
64
+ onChange(rating);
65
+ }}
66
+ >
67
+ <i
68
+ className={cx(
69
+ "pi pi-grade",
70
+ unSelectedStar,
71
+ star.active && selectedStar
72
+ )}
73
+ />
74
+ </span>
75
+ );
76
+ })}
77
+ </div>
78
+ );
79
+ }
80
+ }
81
+
82
+ export default Rating;
@@ -6,6 +6,8 @@ import {
6
6
  searchWrapperStyle,
7
7
  clearContainer
8
8
  } from "./styles/Search.styles";
9
+ import Loader from "./Loader";
10
+ import { colors } from "pebble-shared";
9
11
 
10
12
  class Search extends React.PureComponent<SearchProps> {
11
13
  searchInputRef: React.RefObject<HTMLInputElement> = React.createRef();
@@ -24,7 +26,8 @@ class Search extends React.PureComponent<SearchProps> {
24
26
  showSearchIcon,
25
27
  className,
26
28
  clearable,
27
- value
29
+ value,
30
+ loading
28
31
  } = this.props;
29
32
 
30
33
  const wrapperClassName = cx(searchWrapperStyle, {
@@ -48,6 +51,7 @@ class Search extends React.PureComponent<SearchProps> {
48
51
  value={value}
49
52
  {...inputProps}
50
53
  />
54
+ {loading && <Loader scale={0.4} color={colors.violet.base} />}
51
55
  {clearable && (
52
56
  <div
53
57
  className={cx(clearContainer, {
@@ -0,0 +1,35 @@
1
+ import * as React from "react";
2
+ import { Rating } from "../";
3
+ import { mount } from "enzyme";
4
+ import sinon from "sinon";
5
+
6
+ describe("Rating", () => {
7
+ test("should call onChange on click with correct arguments", () => {
8
+ const spy = sinon.spy();
9
+
10
+ const rating = mount(
11
+ <Rating name="test rating" maxRating={5} value={2} onChange={spy} />
12
+ );
13
+
14
+ rating.find("span").at(0).simulate("click");
15
+
16
+ expect(spy.calledWith(1)).toBeTruthy();
17
+ });
18
+
19
+ test("should not call onChange on click when disabled", () => {
20
+ const spy = sinon.spy();
21
+
22
+ const rating = mount(
23
+ <Rating
24
+ name="test rating"
25
+ maxRating={5}
26
+ value={2}
27
+ onChange={spy}
28
+ disabled
29
+ />
30
+ );
31
+
32
+ rating.find("span").at(0).simulate("click");
33
+ expect(spy.called).toBeFalsy();
34
+ });
35
+ });
@@ -21,6 +21,7 @@ import PopUp from "./PopUp";
21
21
  import PresetCalendar from "./PresetCalendar";
22
22
  import Radio from "./Radio";
23
23
  import RadioGroup from "./RadioGroup";
24
+ import Rating from "./Rating";
24
25
  import Search from "./Search";
25
26
  import SecondaryInput from "./SecondaryInput";
26
27
  import Select from "./Select";
@@ -62,6 +63,7 @@ export {
62
63
  PresetCalendar,
63
64
  Radio,
64
65
  RadioGroup,
66
+ Rating,
65
67
  Search,
66
68
  SecondaryInput,
67
69
  Select,
@@ -0,0 +1,22 @@
1
+ import { css } from "emotion";
2
+ import { colors } from "pebble-shared";
3
+ import { mixins } from "../../theme";
4
+
5
+ export const wrapStyle = css({
6
+ ...mixins.flexRow,
7
+ cursor: "pointer"
8
+ });
9
+
10
+ export const disabledStyle = css({
11
+ cursor: "not-allowed"
12
+ });
13
+
14
+ export const unSelectedStar = css({
15
+ marginLeft: "2px",
16
+ color: colors.gray.border,
17
+ fontSize: "20px"
18
+ });
19
+
20
+ export const selectedStar = css({
21
+ color: colors.yellow.base
22
+ });
@@ -23,6 +23,7 @@ export interface DateSingle extends CommonCalendarProps {
23
23
 
24
24
  export interface DateRange extends CommonCalendarProps {
25
25
  range: true;
26
+ maxRange?: number; // number of days
26
27
  selected?: [Date, Date];
27
28
  onChange: (value: [Date, Date]) => void;
28
29
  onApply?: (value?: [Date, Date]) => void;
@@ -33,4 +34,8 @@ export type CalendarProps = DateSingle | DateRange;
33
34
  export interface CalendarState {
34
35
  value?: [Date, Date] | Date;
35
36
  singleSelectedDate?: [Date, Date] | null;
37
+ maxRangeDates?: {
38
+ future: Date;
39
+ past: Date;
40
+ };
36
41
  }
@@ -0,0 +1,12 @@
1
+ export interface RatingProps {
2
+ name: string;
3
+ maxRating: number;
4
+ value: number;
5
+ onChange: (value: number) => void;
6
+ disabled?: boolean;
7
+ className?: string;
8
+ }
9
+
10
+ export interface RatingState {
11
+ stars: Array<{ active: boolean }>;
12
+ }
@@ -9,4 +9,5 @@ export interface SearchProps {
9
9
  className?: string;
10
10
  clearable?: boolean;
11
11
  inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
12
+ loading?: boolean;
12
13
  }