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