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