react-timezone-range-picker 0.1.6 → 0.2.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
@@ -25,12 +25,47 @@
25
25
 
26
26
  The picker opens in basic mode on every mount. It provides a compact date-only range field and day-based quick options. Date and quick-option selections are applied immediately without an Apply button, and both returned times are set to `00:00:00`.
27
27
 
28
- Select **Advanced** to switch modes for the lifetime of the mounted component. Reloading the page or remounting the picker resets it to basic mode.
28
+ Select **Advanced** to open the full picker. In Advanced mode, use the **Basic** button on the left side of the footer to return to Basic mode.
29
29
 
30
30
  ### Advanced mode
31
31
 
32
32
  Advanced mode provides the full picker with separate start/end date and time fields, relative time options, around-time selection, and timezone selection. Changes to its form-based panels are submitted with the Apply button.
33
33
 
34
+ ### Restricting past or future ranges
35
+
36
+ Set `options.allowedTimeRange` to `"past"`, `"future"`, or `"all"` (the default). This filters quick options, limits date pickers, and validates date/time input against the current time in the selected timezone.
37
+
38
+ ```tsx
39
+ <TimezoneRangePicker
40
+ {...range}
41
+ onApply={handleTimeRangeApply}
42
+ options={{
43
+ allowedTimeRange: "future",
44
+ // Adds today as a whole calendar day to Last/Next day ranges
45
+ includeTodayInQuickRanges: true,
46
+ }}
47
+ />
48
+ ```
49
+
50
+ `Today`, `Yesterday`, and `Tomorrow` use complete calendar-day boundaries (for example, Today 00:00 through Tomorrow 00:00). By default, `Last 2 days` and `Next 2 days` select two complete days before or after today. Set `includeTodayInQuickRanges` to `true` to add the complete current day to those ranges.
51
+
52
+ ### Limiting the range length
53
+
54
+ Set `options.maxRange` to the longest range users may select, as a duration such as `{ months: 1 }`, `{ days: 30 }`, `{ weeks: 2 }` or `{ hours: 36 }`. The limit is measured from the start on the calendar, so `{ months: 1 }` allows Jan 15 → Feb 15.
55
+
56
+ - Quick options longer than the limit are hidden.
57
+ - In basic mode, once a start date is picked, days beyond the limit are disabled.
58
+ - Start and end times longer than the limit fail validation ("Range must not exceed 1 month").
59
+ - Around-a-time durations whose window exceeds the limit are not offered.
60
+
61
+ ```tsx
62
+ <TimezoneRangePicker
63
+ {...range}
64
+ onApply={handleTimeRangeApply}
65
+ options={{ maxRange: { months: 1 } }}
66
+ />
67
+ ```
68
+
34
69
  ---
35
70
 
36
71
  ## 📦 Installation
@@ -116,3 +151,16 @@ function App() {
116
151
  );
117
152
  }
118
153
  ```
154
+
155
+ ---
156
+
157
+ ## Releasing
158
+
159
+ Releases are published by the [Release workflow](https://github.com/GermaVinsmoke/react-timezone-range-picker/blob/main/.github/workflows/release.yml) when a new version reaches `main`:
160
+
161
+ 1. Bump `version` in `packages/ui/package.json` in your pull request.
162
+ 2. Merge it to `main`.
163
+
164
+ The workflow skips versions npm already has. For a new one it runs the tests, publishes the package to npm with provenance, then tags the commit `v<version>` and creates a GitHub Release with generated notes. If a run fails after publishing, re-running it only creates the missing tag and release.
165
+
166
+ npm authenticates the workflow through [trusted publishing](https://docs.npmjs.com/trusted-publishers), so no npm token is stored in the repository.
@@ -2,6 +2,7 @@ import { FC } from "react";
2
2
  import { TzRange } from "../interfaces";
3
3
  interface IAroundTimePanel {
4
4
  tzRange: TzRange;
5
+ onBasic: () => void;
5
6
  }
6
7
  declare const AroundTimePanel: FC<IAroundTimePanel>;
7
8
  export { AroundTimePanel };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/AroundTimePanel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAM3B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAOxC,UAAU,gBAAgB;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,QAAA,MAAM,eAAe,EAAE,EAAE,CAAC,gBAAgB,CAoGzC,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/AroundTimePanel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAe3B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAOxC,UAAU,gBAAgB;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,eAAe,EAAE,EAAE,CAAC,gBAAgB,CAiJzC,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { RangeDuration } from "../interfaces";
1
2
  export declare enum TimeOption {
2
3
  ThirtySeconds = "\u00B1 30 seconds",
3
4
  OneMinute = "\u00B1 1 minute",
@@ -13,4 +14,5 @@ export declare const getStartEndDateTime: (date: string | null, time: string, ti
13
14
  endDate: string | null;
14
15
  endTime: string;
15
16
  };
17
+ export declare const getAllowedTimeOptions: (maxRange?: RangeDuration) => TimeOption[];
16
18
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/AroundTimePanel/util.ts"],"names":[],"mappings":"AAEA,oBAAY,UAAU;IACpB,aAAa,sBAAiB;IAC9B,SAAS,oBAAe;IACxB,cAAc,sBAAiB;IAC/B,aAAa,sBAAiB;IAC9B,OAAO,kBAAa;IACpB,MAAM,iBAAY;CACnB;AAED,eAAO,MAAM,YAAY,cAOxB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,MAAM,EAAE,YAAY,UAAU;;;;;CAgE5F,CAAC"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/AroundTimePanel/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,oBAAY,UAAU;IACpB,aAAa,sBAAiB;IAC9B,SAAS,oBAAe;IACxB,cAAc,sBAAiB;IAC/B,aAAa,sBAAiB;IAC9B,OAAO,kBAAa;IACpB,MAAM,iBAAY;CACnB;AAED,eAAO,MAAM,YAAY,cAOxB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,MAAM,EAAE,YAAY,UAAU;;;;;CAgE5F,CAAC;AAIF,eAAO,MAAM,qBAAqB,GAAI,WAAW,aAAa,iBAQ1D,CAAC"}
@@ -1,2 +1,6 @@
1
- export declare const Footer: () => import("react").JSX.Element;
1
+ interface FooterProps {
2
+ onBasic: () => void;
3
+ }
4
+ export declare const Footer: ({ onBasic }: FooterProps) => import("react").JSX.Element;
5
+ export {};
2
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Footer/index.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,MAAM,mCA4BlB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Footer/index.tsx"],"names":[],"mappings":"AAKA,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,MAAM,GAAI,aAAa,WAAW,gCAqC9C,CAAC"}
@@ -6,6 +6,7 @@ export interface ITimeOptions {
6
6
  startTime: string;
7
7
  endTime: string;
8
8
  unit: QuickRangeUnit;
9
+ direction: "past" | "future" | "present";
9
10
  lineBreak?: boolean;
10
11
  }
11
12
  export declare const getTimeOptions: (timezoneName: string, options?: TimezoneRangePickerOptions) => ITimeOptions[];
@@ -1 +1 @@
1
- {"version":3,"file":"timeOptions.d.ts","sourceRoot":"","sources":["../../src/RelativeTimePanel/timeOptions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAG3D,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEtE,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAoED,eAAO,MAAM,cAAc,GACzB,cAAc,MAAM,EACpB,UAAU,0BAA0B,KACnC,YAAY,EASd,CAAC"}
1
+ {"version":3,"file":"timeOptions.d.ts","sourceRoot":"","sources":["../../src/RelativeTimePanel/timeOptions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAG3D,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEtE,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAyGD,eAAO,MAAM,cAAc,GACzB,cAAc,MAAM,EACpB,UAAU,0BAA0B,KACnC,YAAY,EAyBd,CAAC"}
@@ -2,6 +2,7 @@ import { FC } from "react";
2
2
  import { TzRange } from "../interfaces";
3
3
  interface IStartEndTimePanel {
4
4
  tzRange: TzRange;
5
+ onBasic: () => void;
5
6
  }
6
7
  declare const StartEndTimePanel: FC<IStartEndTimePanel>;
7
8
  export { StartEndTimePanel };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/StartEndTimePanel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAc3B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAOxC,UAAU,kBAAkB;IAC1B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,QAAA,MAAM,iBAAiB,EAAE,EAAE,CAAC,kBAAkB,CAuI7C,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/StartEndTimePanel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAkB3B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAOxC,UAAU,kBAAkB;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,iBAAiB,EAAE,EAAE,CAAC,kBAAkB,CA+K7C,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
@@ -2,6 +2,7 @@ import { FC } from "react";
2
2
  import { TzRange } from "../interfaces";
3
3
  interface ITimezonePanel {
4
4
  tzRange: TzRange;
5
+ onBasic: () => void;
5
6
  }
6
7
  declare const TimezonePanel: FC<ITimezonePanel>;
7
8
  export { TimezonePanel };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/TimezonePanel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAA2C,MAAM,OAAO,CAAC;AASpE,OAAO,EAAgB,OAAO,EAAE,MAAM,eAAe,CAAC;AAatD,UAAU,cAAc;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,QAAA,MAAM,aAAa,EAAE,EAAE,CAAC,cAAc,CA0HrC,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/TimezonePanel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAA2C,MAAM,OAAO,CAAC;AASpE,OAAO,EAAgB,OAAO,EAAE,MAAM,eAAe,CAAC;AAatD,UAAU,cAAc;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,aAAa,EAAE,EAAE,CAAC,cAAc,CA0HrC,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -2,6 +2,7 @@ import { FC } from "react";
2
2
  import { TzRange } from "../interfaces";
3
3
  interface AdvancedPickerViewProps {
4
4
  tzRange: TzRange;
5
+ onBasic: () => void;
5
6
  }
6
7
  export declare const AdvancedPickerView: FC<AdvancedPickerViewProps>;
7
8
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"AdvancedPickerView.d.ts","sourceRoot":"","sources":["../../src/TimezoneRangePicker/AdvancedPickerView.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAuB,MAAM,OAAO,CAAC;AAKhD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIxC,UAAU,uBAAuB;IAC/B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAoD1D,CAAC"}
1
+ {"version":3,"file":"AdvancedPickerView.d.ts","sourceRoot":"","sources":["../../src/TimezoneRangePicker/AdvancedPickerView.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAuB,MAAM,OAAO,CAAC;AAKhD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIxC,UAAU,uBAAuB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAoD1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"BasicPickerView.d.ts","sourceRoot":"","sources":["../../src/TimezoneRangePicker/BasicPickerView.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,EAAE,EAAgC,MAAM,OAAO,CAAC;AAKzD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIxC,UAAU,oBAAoB;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAOD,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CA+FpD,CAAC"}
1
+ {"version":3,"file":"BasicPickerView.d.ts","sourceRoot":"","sources":["../../src/TimezoneRangePicker/BasicPickerView.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,EAAE,EAAgC,MAAM,OAAO,CAAC;AAKzD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIxC,UAAU,oBAAoB;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAOD,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CAoHpD,CAAC"}