dce-reactkit 4.1.0 → 4.1.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.
@@ -4,7 +4,7 @@
4
4
  * @author Gabe Abrams
5
5
  * @param [dateOrTimestamp=now] the date to get info on or a ms since epoch timestamp
6
6
  * @returns object with timestamp (ms since epoch) and numbers
7
- * corresponding to ET time values for year, month, day, hour, hour12, minute, isPM
7
+ * corresponding to ET time values for year, month, day, hour, hour12, minute, second, isPM
8
8
  * where hour is in 24hr time and hour12 is in 12hr time.
9
9
  */
10
10
  declare const getTimeInfoInET: (dateOrTimestamp?: Date | number) => {
@@ -15,6 +15,7 @@ declare const getTimeInfoInET: (dateOrTimestamp?: Date | number) => {
15
15
  hour: number;
16
16
  hour12: number;
17
17
  minute: number;
18
+ second: number;
18
19
  isPM: boolean;
19
20
  };
20
21
  export default getTimeInfoInET;
package/dist/esm/index.js CHANGED
@@ -2571,7 +2571,7 @@ const getMonthName = (month) => {
2571
2571
  * @author Gabe Abrams
2572
2572
  * @param [dateOrTimestamp=now] the date to get info on or a ms since epoch timestamp
2573
2573
  * @returns object with timestamp (ms since epoch) and numbers
2574
- * corresponding to ET time values for year, month, day, hour, hour12, minute, isPM
2574
+ * corresponding to ET time values for year, month, day, hour, hour12, minute, second, isPM
2575
2575
  * where hour is in 24hr time and hour12 is in 12hr time.
2576
2576
  */
2577
2577
  const getTimeInfoInET = (dateOrTimestamp) => {
@@ -2601,6 +2601,9 @@ const getTimeInfoInET = (dateOrTimestamp) => {
2601
2601
  const month = Number.parseInt(monthStr, 10);
2602
2602
  const day = Number.parseInt(dayStr, 10);
2603
2603
  const minute = Number.parseInt(minStr, 10);
2604
+ const second = (ending.split(' ')[0]
2605
+ ? Number.parseInt(ending.split(' ')[0], 10)
2606
+ : 0);
2604
2607
  const hour12 = Number.parseInt(hourStr, 10);
2605
2608
  // Convert from am/pm to 24hr
2606
2609
  const isAM = ending.toLowerCase().includes('am');
@@ -2622,6 +2625,7 @@ const getTimeInfoInET = (dateOrTimestamp) => {
2622
2625
  hour12,
2623
2626
  isPM,
2624
2627
  minute,
2628
+ second,
2625
2629
  };
2626
2630
  };
2627
2631
 
@@ -2631,20 +2635,56 @@ const getTimeInfoInET = (dateOrTimestamp) => {
2631
2635
  * @author Gardenia Liu
2632
2636
  */
2633
2637
  /*------------------------------------------------------------------------*/
2634
- /* ------------------------------ Component ----------------------------- */
2638
+ /* -------------------------------- State ------------------------------- */
2635
2639
  /*------------------------------------------------------------------------*/
2636
- const SimpleDateChooser = (props) => {
2637
- /*------------------------------------------------------------------------*/
2638
- /* -------------------------------- Setup ------------------------------- */
2639
- /*------------------------------------------------------------------------*/
2640
- /* -------------- Props ------------- */
2641
- const { ariaLabel, name, onChange, numMonthsToShow = 6, dontAllowFuture, dontAllowPast, } = props;
2642
- /*------------------------------------------------------------------------*/
2643
- /* ------------------------------- Render ------------------------------- */
2644
- /*------------------------------------------------------------------------*/
2645
- /*----------------------------------------*/
2646
- /* --------------- Main UI -------------- */
2647
- /*----------------------------------------*/
2640
+ /* -------------- Views ------------- */
2641
+ var View;
2642
+ (function (View) {
2643
+ // Date chooser
2644
+ View["DateChooser"] = "DateChooser";
2645
+ // Invalid date
2646
+ View["InvalidDate"] = "InvalidDate";
2647
+ })(View || (View = {}));
2648
+ /* ------------- Actions ------------ */
2649
+ // Types of actions
2650
+ var ActionType$a;
2651
+ (function (ActionType) {
2652
+ // Fix invalid date so it is now in range
2653
+ ActionType["FixInvalidDate"] = "FixInvalidDate";
2654
+ })(ActionType$a || (ActionType$a = {}));
2655
+ /**
2656
+ * Reducer that executes actions
2657
+ * @author Gardenia Liu
2658
+ * @param state current state
2659
+ * @param action action to execute
2660
+ * @returns updated state
2661
+ */
2662
+ const reducer$b = (state, action) => {
2663
+ switch (action.type) {
2664
+ case ActionType$a.FixInvalidDate: {
2665
+ return Object.assign(Object.assign({}, state), { view: View.DateChooser });
2666
+ }
2667
+ default: {
2668
+ return state;
2669
+ }
2670
+ }
2671
+ };
2672
+ /*------------------------------------------------------------------------*/
2673
+ /* --------------------------- Static Helpers --------------------------- */
2674
+ /*------------------------------------------------------------------------*/
2675
+ /**
2676
+ * Get the list of choices in the date chooser given props
2677
+ * @author Gardenia Liu
2678
+ * @author Gabe Abrams
2679
+ * @param opts object containing all arguments
2680
+ * @param opts.numMonthsToShow number of months to show
2681
+ * @param opts.dontAllowPast if true, the user isn't allowed to select dates in the past
2682
+ * @param opts.dontAllowFuture if true, the user isn't allowed to select dates in the future
2683
+ * @returns choices
2684
+ */
2685
+ const getChoices = (opts) => {
2686
+ // Destructure props
2687
+ const { dontAllowFuture, dontAllowPast, numMonthsToShow = 6, } = opts;
2648
2688
  // Determine the set of choices allowed
2649
2689
  const today = getTimeInfoInET();
2650
2690
  const choices = [];
@@ -2719,36 +2759,143 @@ const SimpleDateChooser = (props) => {
2719
2759
  days,
2720
2760
  });
2721
2761
  }
2722
- // Create choice options
2723
- const { month, day, year, } = props;
2724
- const monthOptions = [];
2725
- const dayOptions = [];
2726
- choices.forEach((choice) => {
2727
- // Create month option
2728
- monthOptions.push(React__default.createElement("option", { key: `${choice.year}-${choice.month}`, value: `${choice.month}-${choice.year}`, "aria-label": `choose ${choice.choiceName}`, onSelect: () => {
2729
- onChange(choice.month, choice.days[0], choice.year);
2730
- } }, choice.choiceName));
2731
- // This is the currently selected month
2732
- if (month === choice.month) {
2733
- // Create day options
2734
- choice.days.forEach((dayChoice) => {
2735
- const ordinal = getOrdinal(dayChoice);
2736
- dayOptions.push(React__default.createElement("option", { key: `${choice.year}-${choice.month}-${dayChoice}`, value: dayChoice, "aria-label": `choose date ${dayChoice}` },
2737
- dayChoice,
2738
- ordinal));
2762
+ // Return choices
2763
+ return choices;
2764
+ };
2765
+ /**
2766
+ * Checks whether a given date is outside the valid range of allowed choices
2767
+ * @author Gardenia Liu
2768
+ * @param opts object containing all arguments
2769
+ * @param opts.month 1-indexed month
2770
+ * @param opts.day day of the month
2771
+ * @param opts.year full year
2772
+ * @param opts.choices valid date choices
2773
+ * @returns true if date is out of range
2774
+ */
2775
+ const isDateOutOfRange = (opts) => {
2776
+ const { month, day, year, choices, } = opts;
2777
+ return !choices.some((choice) => {
2778
+ return (choice.month === month
2779
+ && choice.year === year
2780
+ && choice.days.includes(day));
2781
+ });
2782
+ };
2783
+ /*------------------------------------------------------------------------*/
2784
+ /* ------------------------------ Component ----------------------------- */
2785
+ /*------------------------------------------------------------------------*/
2786
+ const SimpleDateChooser = (props) => {
2787
+ /*------------------------------------------------------------------------*/
2788
+ /* -------------------------------- Setup ------------------------------- */
2789
+ /*------------------------------------------------------------------------*/
2790
+ /* -------------- Props ------------- */
2791
+ const { ariaLabel, name, dontAllowPast, dontAllowFuture, numMonthsToShow, onChange, month, day, year, } = props;
2792
+ // Get choices
2793
+ const choices = getChoices({
2794
+ numMonthsToShow,
2795
+ dontAllowPast,
2796
+ dontAllowFuture,
2797
+ });
2798
+ /* -------------- State ------------- */
2799
+ // Check if the currently selected date is out of range
2800
+ const currentSelectedDateOutOfRange = isDateOutOfRange({
2801
+ month,
2802
+ day,
2803
+ year,
2804
+ choices,
2805
+ });
2806
+ // Initial state
2807
+ const initialState = {
2808
+ view: (currentSelectedDateOutOfRange
2809
+ ? View.InvalidDate
2810
+ : View.DateChooser),
2811
+ };
2812
+ // Initialize state
2813
+ const [state, dispatch] = useReducer(reducer$b, initialState);
2814
+ // Destructure common state
2815
+ const { view, } = state;
2816
+ /*------------------------------------------------------------------------*/
2817
+ /* ------------------------- Component Functions ------------------------ */
2818
+ /*------------------------------------------------------------------------*/
2819
+ /**
2820
+ * Ask the user if they want to edit an invalid date
2821
+ * @author Gardenia Liu
2822
+ * @author Gabe Abrams
2823
+ */
2824
+ const askToEditInvalidDate = () => __awaiter(void 0, void 0, void 0, function* () {
2825
+ // Ask the user if they want to edit the date
2826
+ const confirmed = yield confirm('Are you sure?', 'The current date is outside the normal range. If you edit it, you\'ll need to choose a new date in the normal range.', {
2827
+ confirmButtonText: 'Edit Date',
2828
+ });
2829
+ // Check if user confirmed
2830
+ if (confirmed) {
2831
+ // Update the date to today
2832
+ const today = getTimeInfoInET();
2833
+ onChange(today.month, today.day, today.year);
2834
+ // Update state
2835
+ dispatch({
2836
+ type: ActionType$a.FixInvalidDate,
2739
2837
  });
2740
2838
  }
2741
2839
  });
2742
- return (React__default.createElement("div", { className: "SimpleDateChooser d-inline-block", "aria-label": `date chooser with selected date: ${month}/${day}/${year}` },
2743
- React__default.createElement("select", { "aria-label": `month for ${ariaLabel}`, className: "custom-select d-inline-block mr-1", style: { width: 'auto' }, id: `SimpleDateChooser-${name}-month`, value: `${month}-${year}`, onChange: (e) => {
2744
- const choice = choices[e.target.selectedIndex];
2745
- // Change day, month, and year
2746
- onChange(choice.month, choice.days[0], choice.year);
2747
- } }, monthOptions),
2748
- React__default.createElement("select", { "aria-label": `day for ${ariaLabel}`, className: "custom-select d-inline-block", style: { width: 'auto' }, id: `SimpleDateChooser-${name}-day`, value: day, onChange: (e) => {
2749
- // Only change the day
2750
- onChange(month, Number.parseInt(e.target.value, 10), year);
2751
- } }, dayOptions)));
2840
+ /*------------------------------------------------------------------------*/
2841
+ /* ------------------------------- Render ------------------------------- */
2842
+ /*------------------------------------------------------------------------*/
2843
+ /*----------------------------------------*/
2844
+ /* ---------------- Views --------------- */
2845
+ /*----------------------------------------*/
2846
+ // Body that will be filled with the current view
2847
+ let body;
2848
+ /* ---------- DateChooser ---------- */
2849
+ if (view === View.DateChooser) {
2850
+ // Create lists of options
2851
+ const monthOptions = [];
2852
+ const dayOptions = [];
2853
+ // Render each option and add it to the list
2854
+ choices.forEach((choice) => {
2855
+ // Create month option
2856
+ monthOptions.push(React__default.createElement("option", { key: `${choice.year}-${choice.month}`, value: `${choice.month}-${choice.year}`, "aria-label": `choose ${choice.choiceName}`, onSelect: () => {
2857
+ onChange(choice.month, choice.days[0], choice.year);
2858
+ } }, choice.choiceName));
2859
+ // This is the currently selected month
2860
+ if (month === choice.month) {
2861
+ // Create day options
2862
+ choice.days.forEach((dayChoice) => {
2863
+ const ordinal = getOrdinal(dayChoice);
2864
+ dayOptions.push(React__default.createElement("option", { key: `${choice.year}-${choice.month}-${dayChoice}`, value: dayChoice, "aria-label": `choose date ${dayChoice}` },
2865
+ dayChoice,
2866
+ ordinal));
2867
+ });
2868
+ }
2869
+ });
2870
+ // Create body
2871
+ body = (React__default.createElement("div", { className: "SimpleDateChooser-inner-container d-inline-block", "aria-label": `date chooser with selected date: ${month}/${day}/${year}` },
2872
+ React__default.createElement("select", { "aria-label": `month for ${ariaLabel}`, className: "custom-select d-inline-block mr-1", style: { width: 'auto' }, id: `SimpleDateChooser-${name}-month`, value: `${month}-${year}`, onChange: (e) => {
2873
+ const choice = choices[e.target.selectedIndex];
2874
+ // Change day, month, and year
2875
+ onChange(choice.month, choice.days[0], choice.year);
2876
+ } }, monthOptions),
2877
+ React__default.createElement("select", { "aria-label": `day for ${ariaLabel}`, className: "custom-select d-inline-block", style: { width: 'auto' }, id: `SimpleDateChooser-${name}-day`, value: day, onChange: (e) => {
2878
+ // Only change the day
2879
+ onChange(month, Number.parseInt(e.target.value, 10), year);
2880
+ } }, dayOptions)));
2881
+ }
2882
+ /* --------- DateOutOfRange --------- */
2883
+ if (view === View.InvalidDate) {
2884
+ body = (React__default.createElement("div", { className: "SimpleDateChooser-inner-container d-inline-block" },
2885
+ React__default.createElement("button", { type: "button", className: "btn btn-light", onClick: askToEditInvalidDate, "aria-label": `edit date for ${ariaLabel}` },
2886
+ getMonthName(month).full,
2887
+ ' ',
2888
+ day,
2889
+ getOrdinal(day),
2890
+ ",",
2891
+ ' ',
2892
+ year),
2893
+ React__default.createElement("button", { type: "button", className: "btn btn-secondary", onClick: askToEditInvalidDate, "aria-label": `edit date for ${ariaLabel}` }, "Edit")));
2894
+ }
2895
+ /*----------------------------------------*/
2896
+ /* --------------- Main UI -------------- */
2897
+ /*----------------------------------------*/
2898
+ return (React__default.createElement("span", { className: "SimpleDateChooser-outer-container" }, body));
2752
2899
  };
2753
2900
 
2754
2901
  /**