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.
package/dist/cjs/index.js CHANGED
@@ -2598,7 +2598,7 @@ const getMonthName = (month) => {
2598
2598
  * @author Gabe Abrams
2599
2599
  * @param [dateOrTimestamp=now] the date to get info on or a ms since epoch timestamp
2600
2600
  * @returns object with timestamp (ms since epoch) and numbers
2601
- * corresponding to ET time values for year, month, day, hour, hour12, minute, isPM
2601
+ * corresponding to ET time values for year, month, day, hour, hour12, minute, second, isPM
2602
2602
  * where hour is in 24hr time and hour12 is in 12hr time.
2603
2603
  */
2604
2604
  const getTimeInfoInET = (dateOrTimestamp) => {
@@ -2628,6 +2628,9 @@ const getTimeInfoInET = (dateOrTimestamp) => {
2628
2628
  const month = Number.parseInt(monthStr, 10);
2629
2629
  const day = Number.parseInt(dayStr, 10);
2630
2630
  const minute = Number.parseInt(minStr, 10);
2631
+ const second = (ending.split(' ')[0]
2632
+ ? Number.parseInt(ending.split(' ')[0], 10)
2633
+ : 0);
2631
2634
  const hour12 = Number.parseInt(hourStr, 10);
2632
2635
  // Convert from am/pm to 24hr
2633
2636
  const isAM = ending.toLowerCase().includes('am');
@@ -2649,6 +2652,7 @@ const getTimeInfoInET = (dateOrTimestamp) => {
2649
2652
  hour12,
2650
2653
  isPM,
2651
2654
  minute,
2655
+ second,
2652
2656
  };
2653
2657
  };
2654
2658
 
@@ -2658,20 +2662,56 @@ const getTimeInfoInET = (dateOrTimestamp) => {
2658
2662
  * @author Gardenia Liu
2659
2663
  */
2660
2664
  /*------------------------------------------------------------------------*/
2661
- /* ------------------------------ Component ----------------------------- */
2665
+ /* -------------------------------- State ------------------------------- */
2662
2666
  /*------------------------------------------------------------------------*/
2663
- const SimpleDateChooser = (props) => {
2664
- /*------------------------------------------------------------------------*/
2665
- /* -------------------------------- Setup ------------------------------- */
2666
- /*------------------------------------------------------------------------*/
2667
- /* -------------- Props ------------- */
2668
- const { ariaLabel, name, onChange, numMonthsToShow = 6, dontAllowFuture, dontAllowPast, } = props;
2669
- /*------------------------------------------------------------------------*/
2670
- /* ------------------------------- Render ------------------------------- */
2671
- /*------------------------------------------------------------------------*/
2672
- /*----------------------------------------*/
2673
- /* --------------- Main UI -------------- */
2674
- /*----------------------------------------*/
2667
+ /* -------------- Views ------------- */
2668
+ var View;
2669
+ (function (View) {
2670
+ // Date chooser
2671
+ View["DateChooser"] = "DateChooser";
2672
+ // Invalid date
2673
+ View["InvalidDate"] = "InvalidDate";
2674
+ })(View || (View = {}));
2675
+ /* ------------- Actions ------------ */
2676
+ // Types of actions
2677
+ var ActionType$a;
2678
+ (function (ActionType) {
2679
+ // Fix invalid date so it is now in range
2680
+ ActionType["FixInvalidDate"] = "FixInvalidDate";
2681
+ })(ActionType$a || (ActionType$a = {}));
2682
+ /**
2683
+ * Reducer that executes actions
2684
+ * @author Gardenia Liu
2685
+ * @param state current state
2686
+ * @param action action to execute
2687
+ * @returns updated state
2688
+ */
2689
+ const reducer$b = (state, action) => {
2690
+ switch (action.type) {
2691
+ case ActionType$a.FixInvalidDate: {
2692
+ return Object.assign(Object.assign({}, state), { view: View.DateChooser });
2693
+ }
2694
+ default: {
2695
+ return state;
2696
+ }
2697
+ }
2698
+ };
2699
+ /*------------------------------------------------------------------------*/
2700
+ /* --------------------------- Static Helpers --------------------------- */
2701
+ /*------------------------------------------------------------------------*/
2702
+ /**
2703
+ * Get the list of choices in the date chooser given props
2704
+ * @author Gardenia Liu
2705
+ * @author Gabe Abrams
2706
+ * @param opts object containing all arguments
2707
+ * @param opts.numMonthsToShow number of months to show
2708
+ * @param opts.dontAllowPast if true, the user isn't allowed to select dates in the past
2709
+ * @param opts.dontAllowFuture if true, the user isn't allowed to select dates in the future
2710
+ * @returns choices
2711
+ */
2712
+ const getChoices = (opts) => {
2713
+ // Destructure props
2714
+ const { dontAllowFuture, dontAllowPast, numMonthsToShow = 6, } = opts;
2675
2715
  // Determine the set of choices allowed
2676
2716
  const today = getTimeInfoInET();
2677
2717
  const choices = [];
@@ -2746,36 +2786,143 @@ const SimpleDateChooser = (props) => {
2746
2786
  days,
2747
2787
  });
2748
2788
  }
2749
- // Create choice options
2750
- const { month, day, year, } = props;
2751
- const monthOptions = [];
2752
- const dayOptions = [];
2753
- choices.forEach((choice) => {
2754
- // Create month option
2755
- monthOptions.push(React__default["default"].createElement("option", { key: `${choice.year}-${choice.month}`, value: `${choice.month}-${choice.year}`, "aria-label": `choose ${choice.choiceName}`, onSelect: () => {
2756
- onChange(choice.month, choice.days[0], choice.year);
2757
- } }, choice.choiceName));
2758
- // This is the currently selected month
2759
- if (month === choice.month) {
2760
- // Create day options
2761
- choice.days.forEach((dayChoice) => {
2762
- const ordinal = getOrdinal(dayChoice);
2763
- dayOptions.push(React__default["default"].createElement("option", { key: `${choice.year}-${choice.month}-${dayChoice}`, value: dayChoice, "aria-label": `choose date ${dayChoice}` },
2764
- dayChoice,
2765
- ordinal));
2789
+ // Return choices
2790
+ return choices;
2791
+ };
2792
+ /**
2793
+ * Checks whether a given date is outside the valid range of allowed choices
2794
+ * @author Gardenia Liu
2795
+ * @param opts object containing all arguments
2796
+ * @param opts.month 1-indexed month
2797
+ * @param opts.day day of the month
2798
+ * @param opts.year full year
2799
+ * @param opts.choices valid date choices
2800
+ * @returns true if date is out of range
2801
+ */
2802
+ const isDateOutOfRange = (opts) => {
2803
+ const { month, day, year, choices, } = opts;
2804
+ return !choices.some((choice) => {
2805
+ return (choice.month === month
2806
+ && choice.year === year
2807
+ && choice.days.includes(day));
2808
+ });
2809
+ };
2810
+ /*------------------------------------------------------------------------*/
2811
+ /* ------------------------------ Component ----------------------------- */
2812
+ /*------------------------------------------------------------------------*/
2813
+ const SimpleDateChooser = (props) => {
2814
+ /*------------------------------------------------------------------------*/
2815
+ /* -------------------------------- Setup ------------------------------- */
2816
+ /*------------------------------------------------------------------------*/
2817
+ /* -------------- Props ------------- */
2818
+ const { ariaLabel, name, dontAllowPast, dontAllowFuture, numMonthsToShow, onChange, month, day, year, } = props;
2819
+ // Get choices
2820
+ const choices = getChoices({
2821
+ numMonthsToShow,
2822
+ dontAllowPast,
2823
+ dontAllowFuture,
2824
+ });
2825
+ /* -------------- State ------------- */
2826
+ // Check if the currently selected date is out of range
2827
+ const currentSelectedDateOutOfRange = isDateOutOfRange({
2828
+ month,
2829
+ day,
2830
+ year,
2831
+ choices,
2832
+ });
2833
+ // Initial state
2834
+ const initialState = {
2835
+ view: (currentSelectedDateOutOfRange
2836
+ ? View.InvalidDate
2837
+ : View.DateChooser),
2838
+ };
2839
+ // Initialize state
2840
+ const [state, dispatch] = React.useReducer(reducer$b, initialState);
2841
+ // Destructure common state
2842
+ const { view, } = state;
2843
+ /*------------------------------------------------------------------------*/
2844
+ /* ------------------------- Component Functions ------------------------ */
2845
+ /*------------------------------------------------------------------------*/
2846
+ /**
2847
+ * Ask the user if they want to edit an invalid date
2848
+ * @author Gardenia Liu
2849
+ * @author Gabe Abrams
2850
+ */
2851
+ const askToEditInvalidDate = () => __awaiter(void 0, void 0, void 0, function* () {
2852
+ // Ask the user if they want to edit the date
2853
+ 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.', {
2854
+ confirmButtonText: 'Edit Date',
2855
+ });
2856
+ // Check if user confirmed
2857
+ if (confirmed) {
2858
+ // Update the date to today
2859
+ const today = getTimeInfoInET();
2860
+ onChange(today.month, today.day, today.year);
2861
+ // Update state
2862
+ dispatch({
2863
+ type: ActionType$a.FixInvalidDate,
2766
2864
  });
2767
2865
  }
2768
2866
  });
2769
- return (React__default["default"].createElement("div", { className: "SimpleDateChooser d-inline-block", "aria-label": `date chooser with selected date: ${month}/${day}/${year}` },
2770
- React__default["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) => {
2771
- const choice = choices[e.target.selectedIndex];
2772
- // Change day, month, and year
2773
- onChange(choice.month, choice.days[0], choice.year);
2774
- } }, monthOptions),
2775
- React__default["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) => {
2776
- // Only change the day
2777
- onChange(month, Number.parseInt(e.target.value, 10), year);
2778
- } }, dayOptions)));
2867
+ /*------------------------------------------------------------------------*/
2868
+ /* ------------------------------- Render ------------------------------- */
2869
+ /*------------------------------------------------------------------------*/
2870
+ /*----------------------------------------*/
2871
+ /* ---------------- Views --------------- */
2872
+ /*----------------------------------------*/
2873
+ // Body that will be filled with the current view
2874
+ let body;
2875
+ /* ---------- DateChooser ---------- */
2876
+ if (view === View.DateChooser) {
2877
+ // Create lists of options
2878
+ const monthOptions = [];
2879
+ const dayOptions = [];
2880
+ // Render each option and add it to the list
2881
+ choices.forEach((choice) => {
2882
+ // Create month option
2883
+ monthOptions.push(React__default["default"].createElement("option", { key: `${choice.year}-${choice.month}`, value: `${choice.month}-${choice.year}`, "aria-label": `choose ${choice.choiceName}`, onSelect: () => {
2884
+ onChange(choice.month, choice.days[0], choice.year);
2885
+ } }, choice.choiceName));
2886
+ // This is the currently selected month
2887
+ if (month === choice.month) {
2888
+ // Create day options
2889
+ choice.days.forEach((dayChoice) => {
2890
+ const ordinal = getOrdinal(dayChoice);
2891
+ dayOptions.push(React__default["default"].createElement("option", { key: `${choice.year}-${choice.month}-${dayChoice}`, value: dayChoice, "aria-label": `choose date ${dayChoice}` },
2892
+ dayChoice,
2893
+ ordinal));
2894
+ });
2895
+ }
2896
+ });
2897
+ // Create body
2898
+ body = (React__default["default"].createElement("div", { className: "SimpleDateChooser-inner-container d-inline-block", "aria-label": `date chooser with selected date: ${month}/${day}/${year}` },
2899
+ React__default["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) => {
2900
+ const choice = choices[e.target.selectedIndex];
2901
+ // Change day, month, and year
2902
+ onChange(choice.month, choice.days[0], choice.year);
2903
+ } }, monthOptions),
2904
+ React__default["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) => {
2905
+ // Only change the day
2906
+ onChange(month, Number.parseInt(e.target.value, 10), year);
2907
+ } }, dayOptions)));
2908
+ }
2909
+ /* --------- DateOutOfRange --------- */
2910
+ if (view === View.InvalidDate) {
2911
+ body = (React__default["default"].createElement("div", { className: "SimpleDateChooser-inner-container d-inline-block" },
2912
+ React__default["default"].createElement("button", { type: "button", className: "btn btn-light", onClick: askToEditInvalidDate, "aria-label": `edit date for ${ariaLabel}` },
2913
+ getMonthName(month).full,
2914
+ ' ',
2915
+ day,
2916
+ getOrdinal(day),
2917
+ ",",
2918
+ ' ',
2919
+ year),
2920
+ React__default["default"].createElement("button", { type: "button", className: "btn btn-secondary", onClick: askToEditInvalidDate, "aria-label": `edit date for ${ariaLabel}` }, "Edit")));
2921
+ }
2922
+ /*----------------------------------------*/
2923
+ /* --------------- Main UI -------------- */
2924
+ /*----------------------------------------*/
2925
+ return (React__default["default"].createElement("span", { className: "SimpleDateChooser-outer-container" }, body));
2779
2926
  };
2780
2927
 
2781
2928
  /**