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