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