dce-reactkit 4.1.0 → 4.1.1

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/esm/index.js CHANGED
@@ -2631,20 +2631,56 @@ const getTimeInfoInET = (dateOrTimestamp) => {
2631
2631
  * @author Gardenia Liu
2632
2632
  */
2633
2633
  /*------------------------------------------------------------------------*/
2634
- /* ------------------------------ Component ----------------------------- */
2634
+ /* -------------------------------- State ------------------------------- */
2635
2635
  /*------------------------------------------------------------------------*/
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
- /*----------------------------------------*/
2636
+ /* -------------- Views ------------- */
2637
+ var View;
2638
+ (function (View) {
2639
+ // Date chooser
2640
+ View["DateChooser"] = "DateChooser";
2641
+ // Invalid date
2642
+ View["InvalidDate"] = "InvalidDate";
2643
+ })(View || (View = {}));
2644
+ /* ------------- Actions ------------ */
2645
+ // Types of actions
2646
+ var ActionType$a;
2647
+ (function (ActionType) {
2648
+ // Fix invalid date so it is now in range
2649
+ ActionType["FixInvalidDate"] = "FixInvalidDate";
2650
+ })(ActionType$a || (ActionType$a = {}));
2651
+ /**
2652
+ * Reducer that executes actions
2653
+ * @author Gardenia Liu
2654
+ * @param state current state
2655
+ * @param action action to execute
2656
+ * @returns updated state
2657
+ */
2658
+ const reducer$b = (state, action) => {
2659
+ switch (action.type) {
2660
+ case ActionType$a.FixInvalidDate: {
2661
+ return Object.assign(Object.assign({}, state), { view: View.DateChooser });
2662
+ }
2663
+ default: {
2664
+ return state;
2665
+ }
2666
+ }
2667
+ };
2668
+ /*------------------------------------------------------------------------*/
2669
+ /* --------------------------- Static Helpers --------------------------- */
2670
+ /*------------------------------------------------------------------------*/
2671
+ /**
2672
+ * Get the list of choices in the date chooser given props
2673
+ * @author Gardenia Liu
2674
+ * @author Gabe Abrams
2675
+ * @param opts object containing all arguments
2676
+ * @param opts.numMonthsToShow number of months to show
2677
+ * @param opts.dontAllowPast if true, the user isn't allowed to select dates in the past
2678
+ * @param opts.dontAllowFuture if true, the user isn't allowed to select dates in the future
2679
+ * @returns choices
2680
+ */
2681
+ const getChoices = (opts) => {
2682
+ // Destructure props
2683
+ const { dontAllowFuture, dontAllowPast, numMonthsToShow = 6, } = opts;
2648
2684
  // Determine the set of choices allowed
2649
2685
  const today = getTimeInfoInET();
2650
2686
  const choices = [];
@@ -2719,36 +2755,143 @@ const SimpleDateChooser = (props) => {
2719
2755
  days,
2720
2756
  });
2721
2757
  }
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));
2758
+ // Return choices
2759
+ return choices;
2760
+ };
2761
+ /**
2762
+ * Checks whether a given date is outside the valid range of allowed choices
2763
+ * @author Gardenia Liu
2764
+ * @param opts object containing all arguments
2765
+ * @param opts.month 1-indexed month
2766
+ * @param opts.day day of the month
2767
+ * @param opts.year full year
2768
+ * @param opts.choices valid date choices
2769
+ * @returns true if date is out of range
2770
+ */
2771
+ const isDateOutOfRange = (opts) => {
2772
+ const { month, day, year, choices, } = opts;
2773
+ return !choices.some((choice) => {
2774
+ return (choice.month === month
2775
+ && choice.year === year
2776
+ && choice.days.includes(day));
2777
+ });
2778
+ };
2779
+ /*------------------------------------------------------------------------*/
2780
+ /* ------------------------------ Component ----------------------------- */
2781
+ /*------------------------------------------------------------------------*/
2782
+ const SimpleDateChooser = (props) => {
2783
+ /*------------------------------------------------------------------------*/
2784
+ /* -------------------------------- Setup ------------------------------- */
2785
+ /*------------------------------------------------------------------------*/
2786
+ /* -------------- Props ------------- */
2787
+ const { ariaLabel, name, dontAllowPast, dontAllowFuture, numMonthsToShow, onChange, month, day, year, } = props;
2788
+ // Get choices
2789
+ const choices = getChoices({
2790
+ numMonthsToShow,
2791
+ dontAllowPast,
2792
+ dontAllowFuture,
2793
+ });
2794
+ /* -------------- State ------------- */
2795
+ // Check if the currently selected date is out of range
2796
+ const currentSelectedDateOutOfRange = isDateOutOfRange({
2797
+ month,
2798
+ day,
2799
+ year,
2800
+ choices,
2801
+ });
2802
+ // Initial state
2803
+ const initialState = {
2804
+ view: (currentSelectedDateOutOfRange
2805
+ ? View.InvalidDate
2806
+ : View.DateChooser),
2807
+ };
2808
+ // Initialize state
2809
+ const [state, dispatch] = useReducer(reducer$b, initialState);
2810
+ // Destructure common state
2811
+ const { view, } = state;
2812
+ /*------------------------------------------------------------------------*/
2813
+ /* ------------------------- Component Functions ------------------------ */
2814
+ /*------------------------------------------------------------------------*/
2815
+ /**
2816
+ * Ask the user if they want to edit an invalid date
2817
+ * @author Gardenia Liu
2818
+ * @author Gabe Abrams
2819
+ */
2820
+ const askToEditInvalidDate = () => __awaiter(void 0, void 0, void 0, function* () {
2821
+ // Ask the user if they want to edit the date
2822
+ 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.', {
2823
+ confirmButtonText: 'Edit Date',
2824
+ });
2825
+ // Check if user confirmed
2826
+ if (confirmed) {
2827
+ // Update the date to today
2828
+ const today = getTimeInfoInET();
2829
+ onChange(today.month, today.day, today.year);
2830
+ // Update state
2831
+ dispatch({
2832
+ type: ActionType$a.FixInvalidDate,
2739
2833
  });
2740
2834
  }
2741
2835
  });
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)));
2836
+ /*------------------------------------------------------------------------*/
2837
+ /* ------------------------------- Render ------------------------------- */
2838
+ /*------------------------------------------------------------------------*/
2839
+ /*----------------------------------------*/
2840
+ /* ---------------- Views --------------- */
2841
+ /*----------------------------------------*/
2842
+ // Body that will be filled with the current view
2843
+ let body;
2844
+ /* ---------- DateChooser ---------- */
2845
+ if (view === View.DateChooser) {
2846
+ // Create lists of options
2847
+ const monthOptions = [];
2848
+ const dayOptions = [];
2849
+ // Render each option and add it to the list
2850
+ choices.forEach((choice) => {
2851
+ // Create month option
2852
+ monthOptions.push(React__default.createElement("option", { key: `${choice.year}-${choice.month}`, value: `${choice.month}-${choice.year}`, "aria-label": `choose ${choice.choiceName}`, onSelect: () => {
2853
+ onChange(choice.month, choice.days[0], choice.year);
2854
+ } }, choice.choiceName));
2855
+ // This is the currently selected month
2856
+ if (month === choice.month) {
2857
+ // Create day options
2858
+ choice.days.forEach((dayChoice) => {
2859
+ const ordinal = getOrdinal(dayChoice);
2860
+ dayOptions.push(React__default.createElement("option", { key: `${choice.year}-${choice.month}-${dayChoice}`, value: dayChoice, "aria-label": `choose date ${dayChoice}` },
2861
+ dayChoice,
2862
+ ordinal));
2863
+ });
2864
+ }
2865
+ });
2866
+ // Create body
2867
+ body = (React__default.createElement("div", { className: "SimpleDateChooser-inner-container d-inline-block", "aria-label": `date chooser with selected date: ${month}/${day}/${year}` },
2868
+ 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) => {
2869
+ const choice = choices[e.target.selectedIndex];
2870
+ // Change day, month, and year
2871
+ onChange(choice.month, choice.days[0], choice.year);
2872
+ } }, monthOptions),
2873
+ 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) => {
2874
+ // Only change the day
2875
+ onChange(month, Number.parseInt(e.target.value, 10), year);
2876
+ } }, dayOptions)));
2877
+ }
2878
+ /* --------- DateOutOfRange --------- */
2879
+ if (view === View.InvalidDate) {
2880
+ body = (React__default.createElement("div", { className: "SimpleDateChooser-inner-container d-inline-block" },
2881
+ React__default.createElement("button", { type: "button", className: "btn btn-light", onClick: askToEditInvalidDate, "aria-label": `edit date for ${ariaLabel}` },
2882
+ getMonthName(month).full,
2883
+ ' ',
2884
+ day,
2885
+ getOrdinal(day),
2886
+ ",",
2887
+ ' ',
2888
+ year),
2889
+ React__default.createElement("button", { type: "button", className: "btn btn-secondary", onClick: askToEditInvalidDate, "aria-label": `edit date for ${ariaLabel}` }, "Edit")));
2890
+ }
2891
+ /*----------------------------------------*/
2892
+ /* --------------- Main UI -------------- */
2893
+ /*----------------------------------------*/
2894
+ return (React__default.createElement("span", { className: "SimpleDateChooser-outer-container" }, body));
2752
2895
  };
2753
2896
 
2754
2897
  /**