first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
@@ -0,0 +1,3 @@
import * as React from 'react';
import type { IDatePickerProps } from './DatePicker.types';
export declare const DatePickerBase: React.FunctionComponent<IDatePickerProps>;
@@ -0,0 +1,397 @@
define(["require", "exports", "tslib", "react", "@fluentui/utilities", "../../Calendar", "@fluentui/date-time-utilities", "../../Callout", "../../Styling", "../../TextField", "../../FocusTrapZone", "@fluentui/react-hooks", "./defaults"], function (require, exports, tslib_1, React, utilities_1, Calendar_1, date_time_utilities_1, Callout_1, Styling_1, TextField_1, FocusTrapZone_1, react_hooks_1, defaults_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DatePickerBase = void 0;
var getClassNames = (0, utilities_1.classNamesFunction)();
var DEFAULT_PROPS = {
allowTextInput: false,
formatDate: function (date) { return (date ? date.toDateString() : ''); },
parseDateFromString: function (dateStr) {
//if dateStr is DATE ONLY ISO 8601 -> add time so Date.parse() won't convert it to UTC
//See here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse#date_time_string_format
if (dateStr.match(/^\d{4}(-\d{2}){2}$/)) {
dateStr += 'T12:00';
}
var date = Date.parse(dateStr);
return date ? new Date(date) : null;
},
firstDayOfWeek: date_time_utilities_1.DayOfWeek.Sunday,
initialPickerDate: new Date(),
isRequired: false,
isMonthPickerVisible: true,
showMonthPickerAsOverlay: false,
strings: defaults_1.defaultDatePickerStrings,
highlightCurrentMonth: false,
highlightSelectedMonth: false,
borderless: false,
pickerAriaLabel: 'Calendar',
showWeekNumbers: false,
firstWeekOfYear: date_time_utilities_1.FirstWeekOfYear.FirstDay,
showGoToToday: true,
showCloseButton: false,
underlined: false,
allFocusable: false,
};
function useFocusLogic() {
var textFieldRef = React.useRef(null);
var preventFocusOpeningPicker = React.useRef(false);
var focus = function () {
var _a, _b;
(_b = (_a = textFieldRef.current) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a);
};
var preventNextFocusOpeningPicker = function () {
preventFocusOpeningPicker.current = true;
};
return [textFieldRef, focus, preventFocusOpeningPicker, preventNextFocusOpeningPicker];
}
function useCalendarVisibility(_a, focus) {
var allowTextInput = _a.allowTextInput, onAfterMenuDismiss = _a.onAfterMenuDismiss;
var _b = React.useState(false), isCalendarShown = _b[0], setIsCalendarShown = _b[1];
var isMounted = React.useRef(false);
var async = (0, react_hooks_1.useAsync)();
React.useEffect(function () {
if (isMounted.current && !isCalendarShown) {
// In browsers like IE, textfield gets unfocused when datepicker is collapsed
if (allowTextInput) {
async.requestAnimationFrame(focus);
}
// If DatePicker's menu (Calendar) is closed, run onAfterMenuDismiss
onAfterMenuDismiss === null || onAfterMenuDismiss === void 0 ? void 0 : onAfterMenuDismiss();
}
isMounted.current = true;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isCalendarShown]);
return [isCalendarShown, setIsCalendarShown];
}
function useSelectedDate(_a) {
var formatDate = _a.formatDate, value = _a.value, onSelectDate = _a.onSelectDate;
var _b = (0, react_hooks_1.useControllableValue)(value, undefined, function (ev, newValue) {
return onSelectDate === null || onSelectDate === void 0 ? void 0 : onSelectDate(newValue);
}), selectedDate = _b[0], setSelectedDateState = _b[1];
var _c = React.useState(function () { return (value && formatDate ? formatDate(value) : ''); }), formattedDate = _c[0], setFormattedDate = _c[1];
var setSelectedDate = function (newDate) {
setSelectedDateState(newDate);
setFormattedDate(newDate && formatDate ? formatDate(newDate) : '');
};
React.useEffect(function () {
setFormattedDate(value && formatDate ? formatDate(value) : '');
}, [formatDate, value]);
return [selectedDate, formattedDate, setSelectedDate, setFormattedDate];
}
function useErrorMessage(_a, selectedDate, setSelectedDate, inputValue, isCalendarShown) {
var _b;
var isRequired = _a.isRequired, allowTextInput = _a.allowTextInput, strings = _a.strings, parseDateFromString = _a.parseDateFromString, onSelectDate = _a.onSelectDate, formatDate = _a.formatDate, minDate = _a.minDate, maxDate = _a.maxDate, textField = _a.textField;
var _c = React.useState(), errorMessage = _c[0], setErrorMessage = _c[1];
var _d = React.useState(), statusMessage = _d[0], setStatusMessage = _d[1];
var isFirstLoadRef = React.useRef(true);
var validateOnLoad = (_b = textField === null || textField === void 0 ? void 0 : textField.validateOnLoad) !== null && _b !== void 0 ? _b : true;
var validateTextInput = function (date) {
if (date === void 0) { date = null; }
if (allowTextInput) {
if (inputValue || date) {
// Don't parse if the selected date has the same formatted string as what we're about to parse.
// The formatted string might be ambiguous (ex: "1/2/3" or "New Year Eve") and the parser might
// not be able to come up with the exact same date.
if (selectedDate && !errorMessage && formatDate && formatDate(date !== null && date !== void 0 ? date : selectedDate) === inputValue) {
return;
}
date = date || parseDateFromString(inputValue);
// Check if date is null, or date is Invalid Date
if (!date || isNaN(date.getTime())) {
// Reset invalid input field, if formatting is available
setSelectedDate(selectedDate);
// default the newer isResetStatusMessage string to invalidInputErrorMessage for legacy support
var selectedText = formatDate ? formatDate(selectedDate) : '';
var statusText = strings.isResetStatusMessage
? (0, utilities_1.format)(strings.isResetStatusMessage, inputValue, selectedText)
: strings.invalidInputErrorMessage || '';
setStatusMessage(statusText);
}
else {
// Check against optional date boundaries
if (isDateOutOfBounds(date, minDate, maxDate)) {
setErrorMessage(strings.isOutOfBoundsErrorMessage || ' ');
}
else {
setSelectedDate(date);
setErrorMessage(undefined);
setStatusMessage(undefined);
}
}
}
else {
// Only show error for empty inputValue if it is a required field
setErrorMessage(isRequired ? strings.isRequiredErrorMessage || ' ' : undefined);
// If no input date string or input date string is invalid
// date variable will be null, callback should expect null value for this case
onSelectDate === null || onSelectDate === void 0 ? void 0 : onSelectDate(date);
}
}
else if (isRequired && !inputValue) {
// Check when DatePicker is a required field but has NO input value
setErrorMessage(strings.isRequiredErrorMessage || ' ');
}
else {
// Cleanup the error message and status message
setErrorMessage(undefined);
setStatusMessage(undefined);
}
};
React.useEffect(function () {
if (isFirstLoadRef.current) {
isFirstLoadRef.current = false;
if (!validateOnLoad) {
return;
}
}
if (isRequired && !selectedDate) {
setErrorMessage(strings.isRequiredErrorMessage || ' ');
}
else if (selectedDate && isDateOutOfBounds(selectedDate, minDate, maxDate)) {
setErrorMessage(strings.isOutOfBoundsErrorMessage || ' ');
}
else {
setErrorMessage(undefined);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
// We don't want to compare the date itself, since two instances of date at the same time are not equal
// eslint-disable-next-line react-hooks/exhaustive-deps
minDate && (0, date_time_utilities_1.getDatePartHashValue)(minDate),
// eslint-disable-next-line react-hooks/exhaustive-deps
maxDate && (0, date_time_utilities_1.getDatePartHashValue)(maxDate),
// eslint-disable-next-line react-hooks/exhaustive-deps
selectedDate && (0, date_time_utilities_1.getDatePartHashValue)(selectedDate),
isRequired,
validateOnLoad,
]);
return [
isCalendarShown ? undefined : errorMessage,
validateTextInput,
setErrorMessage,
isCalendarShown ? undefined : statusMessage,
setStatusMessage,
];
}
exports.DatePickerBase = React.forwardRef(function (propsWithoutDefaults, forwardedRef) {
var _a, _b;
var props = (0, utilities_1.getPropsWithDefaults)(DEFAULT_PROPS, propsWithoutDefaults);
var firstDayOfWeek = props.firstDayOfWeek, strings = props.strings, label = props.label, theme = props.theme, className = props.className, styles = props.styles, initialPickerDate = props.initialPickerDate, isRequired = props.isRequired, disabled = props.disabled, ariaLabel = props.ariaLabel, pickerAriaLabel = props.pickerAriaLabel, placeholder = props.placeholder, allowTextInput = props.allowTextInput, borderless = props.borderless, minDate = props.minDate, maxDate = props.maxDate, showCloseButton = props.showCloseButton, calendarProps = props.calendarProps, calloutProps = props.calloutProps, textFieldProps = props.textField, underlined = props.underlined, allFocusable = props.allFocusable, _c = props.calendarAs, CalendarType = _c === void 0 ? Calendar_1.Calendar : _c, tabIndex = props.tabIndex, _d = props.disableAutoFocus, disableAutoFocus = _d === void 0 ? true : _d;
var id = (0, react_hooks_1.useId)('DatePicker', props.id);
var calloutId = (0, react_hooks_1.useId)('DatePicker-Callout');
var calendar = React.useRef(null);
var datePickerDiv = React.useRef(null);
var _e = useFocusLogic(), textFieldRef = _e[0], focus = _e[1], preventFocusOpeningPicker = _e[2], preventNextFocusOpeningPicker = _e[3];
var _f = useCalendarVisibility(props, focus), isCalendarShown = _f[0], setIsCalendarShown = _f[1];
var _g = useSelectedDate(props), selectedDate = _g[0], formattedDate = _g[1], setSelectedDate = _g[2], setFormattedDate = _g[3];
var _h = useErrorMessage(props, selectedDate, setSelectedDate, formattedDate, isCalendarShown), errorMessage = _h[0], validateTextInput = _h[1], setErrorMessage = _h[2], statusMessage = _h[3], setStatusMessage = _h[4];
var showDatePickerPopup = React.useCallback(function () {
if (!isCalendarShown) {
preventNextFocusOpeningPicker();
setIsCalendarShown(true);
}
}, [isCalendarShown, preventNextFocusOpeningPicker, setIsCalendarShown]);
React.useImperativeHandle(props.componentRef, function () { return ({
focus: focus,
reset: function () {
setIsCalendarShown(false);
setSelectedDate(undefined);
setErrorMessage(undefined);
setStatusMessage(undefined);
},
showDatePickerPopup: showDatePickerPopup,
}); }, [focus, setErrorMessage, setIsCalendarShown, setSelectedDate, setStatusMessage, showDatePickerPopup]);
var onTextFieldFocus = function () {
if (disableAutoFocus) {
return;
}
if (!allowTextInput) {
if (!preventFocusOpeningPicker.current) {
showDatePickerPopup();
}
preventFocusOpeningPicker.current = false;
}
};
var onSelectDate = function (date) {
if (props.calendarProps && props.calendarProps.onSelectDate) {
props.calendarProps.onSelectDate(date);
}
calendarDismissed(date);
};
var onCalloutPositioned = function () {
var shouldFocus = true;
// If the user has specified that the callout shouldn't use initial focus, then respect
// that and don't attempt to set focus. That will default to true within the callout
// so we need to check if it's undefined here.
if (props.calloutProps && props.calloutProps.setInitialFocus !== undefined) {
shouldFocus = props.calloutProps.setInitialFocus;
}
if (calendar.current && shouldFocus) {
calendar.current.focus();
}
};
var onTextFieldBlur = function (ev) {
validateTextInput();
};
var onTextFieldChanged = function (ev, newValue) {
var _a;
var textField = props.textField;
if (allowTextInput) {
if (isCalendarShown) {
dismissDatePickerPopup();
}
setFormattedDate(newValue);
}
(_a = textField === null || textField === void 0 ? void 0 : textField.onChange) === null || _a === void 0 ? void 0 : _a.call(textField, ev, newValue);
};
var onTextFieldKeyDown = function (ev) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
switch (ev.which) {
case utilities_1.KeyCodes.enter:
ev.preventDefault();
ev.stopPropagation();
if (!isCalendarShown) {
validateTextInput();
showDatePickerPopup();
}
else {
// When DatePicker allows input date string directly,
// it is expected to hit another enter to close the popup
if (props.allowTextInput) {
dismissDatePickerPopup();
}
}
break;
case utilities_1.KeyCodes.escape:
handleEscKey(ev);
break;
case utilities_1.KeyCodes.down:
if (ev.altKey && !isCalendarShown) {
showDatePickerPopup();
}
break;
default:
break;
}
};
var onTextFieldClick = function (ev) {
// default openOnClick to !props.disableAutoFocus for legacy support of disableAutoFocus behavior
var openOnClick = props.openOnClick || !props.disableAutoFocus;
if (openOnClick && !isCalendarShown && !props.disabled) {
showDatePickerPopup();
return;
}
if (props.allowTextInput) {
dismissDatePickerPopup();
}
};
var onIconClick = function (ev) {
ev.stopPropagation();
if (!isCalendarShown && !props.disabled) {
showDatePickerPopup();
}
else if (props.allowTextInput) {
dismissDatePickerPopup();
}
};
var dismissDatePickerPopup = function (newlySelectedDate) {
if (isCalendarShown) {
setIsCalendarShown(false);
validateTextInput(newlySelectedDate);
if (!allowTextInput && newlySelectedDate) {
setSelectedDate(newlySelectedDate);
}
}
};
var renderTextfieldDescription = function (inputProps, defaultRender) {
return (React.createElement(React.Fragment, null,
inputProps.description || inputProps.onRenderDescription ? defaultRender(inputProps) : null,
React.createElement("div", { "aria-live": "assertive", className: classNames.statusMessage }, statusMessage)));
};
var renderReadOnlyInput = function (inputProps) {
var divProps = (0, utilities_1.getNativeProps)(inputProps, utilities_1.divProperties);
// Need to merge styles so the provided styles win over the default ones. This is due to the classnames having the
// same specificity.
var readOnlyTextFieldClassName = (0, Styling_1.mergeStyles)(divProps.className, classNames.readOnlyTextField);
// Talkback on Android treats readonly inputs as disabled, so swipe gestures to open the Calendar
// don't register. Workaround is rendering a div with role="combobox" (passed in via TextField props).
return (React.createElement("div", tslib_1.__assign({}, divProps, { className: readOnlyTextFieldClassName, tabIndex: tabIndex || 0 }), formattedDate || (
// Putting the placeholder in a separate span fixes specificity issues for the text color
React.createElement("span", { className: classNames.readOnlyPlaceholder }, placeholder))));
};
/**
* Callback for closing the calendar callout
*/
var calendarDismissed = function (newlySelectedDate) {
preventNextFocusOpeningPicker();
dismissDatePickerPopup(newlySelectedDate);
// don't need to focus the text box, if necessary the focusTrapZone will do it
};
var calloutDismissed = function (ev) {
calendarDismissed();
};
var handleEscKey = function (ev) {
if (isCalendarShown) {
ev.stopPropagation();
calendarDismissed();
}
};
var onCalendarDismissed = function (ev) {
calendarDismissed();
};
var classNames = getClassNames(styles, {
theme: theme,
className: className,
disabled: disabled,
underlined: underlined,
label: !!label,
isDatePickerShown: isCalendarShown,
});
var nativeProps = (0, utilities_1.getNativeProps)(props, utilities_1.divProperties, ['value']);
var iconProps = textFieldProps && textFieldProps.iconProps;
var textFieldId = textFieldProps && textFieldProps.id && textFieldProps.id !== id ? textFieldProps.id : id + '-label';
var readOnly = !allowTextInput && !disabled;
var dataIsFocusable = (_b = (_a = textFieldProps === null || textFieldProps === void 0 ? void 0 : textFieldProps['data-is-focusable']) !== null && _a !== void 0 ? _a : props['data-is-focusable']) !== null && _b !== void 0 ? _b : true;
// Props to create a semantic but non-focusable button when the datepicker has a text input
// Used for voice control and touch screen reader accessibility
var iconA11yProps = allowTextInput
? {
role: 'button',
'aria-expanded': isCalendarShown,
'aria-label': ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : label,
'aria-labelledby': textFieldProps && textFieldProps['aria-labelledby'],
}
: {};
return (React.createElement("div", tslib_1.__assign({}, nativeProps, { className: classNames.root, ref: forwardedRef }),
React.createElement("div", { ref: datePickerDiv, "aria-owns": isCalendarShown ? calloutId : undefined, className: classNames.wrapper },
React.createElement(TextField_1.TextField, tslib_1.__assign({ role: "combobox", label: label, "aria-expanded": isCalendarShown, "aria-required": isRequired, ariaLabel: ariaLabel, "aria-haspopup": "dialog", "aria-controls": isCalendarShown ? calloutId : undefined, required: isRequired, disabled: disabled, errorMessage: errorMessage, placeholder: placeholder, borderless: borderless, value: formattedDate, componentRef: textFieldRef, underlined: underlined, tabIndex: tabIndex, readOnly: !allowTextInput }, textFieldProps, { "data-is-focusable": dataIsFocusable, id: textFieldId, className: (0, utilities_1.css)(classNames.textField, textFieldProps && textFieldProps.className), iconProps: tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ iconName: 'Calendar' }, iconA11yProps), iconProps), { className: (0, utilities_1.css)(classNames.icon, iconProps && iconProps.className), onClick: onIconClick }),
// eslint-disable-next-line react/jsx-no-bind
onRenderDescription: renderTextfieldDescription,
// eslint-disable-next-line react/jsx-no-bind
onKeyDown: onTextFieldKeyDown,
// eslint-disable-next-line react/jsx-no-bind
onFocus: onTextFieldFocus,
// eslint-disable-next-line react/jsx-no-bind
onBlur: onTextFieldBlur,
// eslint-disable-next-line react/jsx-no-bind
onClick: onTextFieldClick,
// eslint-disable-next-line react/jsx-no-bind
onChange: onTextFieldChanged, onRenderInput: readOnly ? renderReadOnlyInput : undefined }))),
isCalendarShown && (React.createElement(Callout_1.Callout, tslib_1.__assign({ id: calloutId, role: "dialog", ariaLabel: pickerAriaLabel, isBeakVisible: false, gapSpace: 0, doNotLayer: false, target: datePickerDiv.current, directionalHint: Callout_1.DirectionalHint.bottomLeftEdge }, calloutProps, { className: (0, utilities_1.css)(classNames.callout, calloutProps && calloutProps.className),
// eslint-disable-next-line react/jsx-no-bind
onDismiss: calloutDismissed,
// eslint-disable-next-line react/jsx-no-bind
onPositioned: onCalloutPositioned }),
React.createElement(FocusTrapZone_1.FocusTrapZone, { isClickableOutsideFocusTrap: true, disableFirstFocus: disableAutoFocus },
React.createElement(CalendarType, tslib_1.__assign({}, calendarProps, {
// eslint-disable-next-line react/jsx-no-bind
onSelectDate: onSelectDate,
// eslint-disable-next-line react/jsx-no-bind
onDismiss: onCalendarDismissed, isMonthPickerVisible: props.isMonthPickerVisible, showMonthPickerAsOverlay: props.showMonthPickerAsOverlay, today: props.today, value: selectedDate || initialPickerDate, firstDayOfWeek: firstDayOfWeek, strings: strings, highlightCurrentMonth: props.highlightCurrentMonth, highlightSelectedMonth: props.highlightSelectedMonth, showWeekNumbers: props.showWeekNumbers, firstWeekOfYear: props.firstWeekOfYear, showGoToToday: props.showGoToToday, dateTimeFormatter: props.dateTimeFormatter, minDate: minDate, maxDate: maxDate, componentRef: calendar, showCloseButton: showCloseButton, allFocusable: allFocusable })))))));
});
exports.DatePickerBase.displayName = 'DatePickerBase';
function isDateOutOfBounds(date, minDate, maxDate) {
return (!!minDate && (0, date_time_utilities_1.compareDatePart)(minDate, date) > 0) || (!!maxDate && (0, date_time_utilities_1.compareDatePart)(maxDate, date) < 0);
}
});
//# sourceMappingURL=DatePicker.base.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
import * as React from 'react';
import type { IDatePickerProps } from './DatePicker.types';
export declare const DatePicker: React.FunctionComponent<IDatePickerProps>;
@@ -0,0 +1,9 @@
define(["require", "exports", "@fluentui/utilities", "./DatePicker.base", "./DatePicker.styles"], function (require, exports, utilities_1, DatePicker_base_1, DatePicker_styles_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DatePicker = void 0;
exports.DatePicker = (0, utilities_1.styled)(DatePicker_base_1.DatePickerBase, DatePicker_styles_1.styles, undefined, {
scope: 'DatePicker',
});
});
//# sourceMappingURL=DatePicker.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DatePicker.js","sourceRoot":"../src/","sources":["components/DatePicker/DatePicker.tsx"],"names":[],"mappings":";;;;IAMa,QAAA,UAAU,GAA8C,IAAA,kBAAM,EAAC,gCAAc,EAAE,0BAAM,EAAE,SAAS,EAAE;QAC7G,KAAK,EAAE,YAAY;KACpB,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { styled } from '@fluentui/utilities';\nimport { DatePickerBase } from './DatePicker.base';\nimport { styles } from './DatePicker.styles';\nimport type { IDatePickerProps } from './DatePicker.types';\n\nexport const DatePicker: React.FunctionComponent<IDatePickerProps> = styled(DatePickerBase, styles, undefined, {\n scope: 'DatePicker',\n});\n"]}
@@ -0,0 +1,2 @@
import type { IDatePickerStyleProps, IDatePickerStyles } from './DatePicker.types';
export declare const styles: (props: IDatePickerStyleProps) => IDatePickerStyles;
@@ -0,0 +1,100 @@
define(["require", "exports", "@fluentui/style-utilities"], function (require, exports, style_utilities_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.styles = void 0;
var GlobalClassNames = {
root: 'ms-DatePicker',
callout: 'ms-DatePicker-callout',
withLabel: 'ms-DatePicker-event--with-label',
withoutLabel: 'ms-DatePicker-event--without-label',
disabled: 'msDatePickerDisabled ',
};
var TEXTFIELD_HEIGHT = 32;
var styles = function (props) {
var _a;
var className = props.className, theme = props.theme, disabled = props.disabled, underlined = props.underlined, label = props.label, isDatePickerShown = props.isDatePickerShown;
var palette = theme.palette, semanticColors = theme.semanticColors, fonts = theme.fonts;
var classNames = (0, style_utilities_1.getGlobalClassNames)(GlobalClassNames, theme);
var DatePickerIcon = {
color: palette.neutralSecondary,
fontSize: style_utilities_1.FontSizes.icon,
lineHeight: '18px',
pointerEvents: 'none',
position: 'absolute',
right: '4px',
padding: '5px',
};
return {
root: [classNames.root, theme.fonts.large, isDatePickerShown && 'is-open', style_utilities_1.normalize, className],
textField: [
{
position: 'relative',
selectors: {
'& input[readonly]': {
cursor: 'pointer',
},
input: {
selectors: {
'::-ms-clear': {
display: 'none',
},
},
},
},
},
disabled && {
selectors: {
'& input[readonly]': {
cursor: 'default',
},
},
},
],
callout: [classNames.callout],
icon: [
DatePickerIcon,
label ? classNames.withLabel : classNames.withoutLabel,
{ paddingTop: '7px' },
!disabled && [
classNames.disabled,
{
pointerEvents: 'initial',
cursor: 'pointer',
},
],
disabled && {
color: semanticColors.disabledText,
cursor: 'default',
},
],
statusMessage: [
fonts.small,
{
color: semanticColors.errorText,
marginTop: 5,
},
],
readOnlyTextField: [
{
cursor: 'pointer',
height: TEXTFIELD_HEIGHT,
lineHeight: TEXTFIELD_HEIGHT - 2,
overflow: 'hidden',
textOverflow: 'ellipsis',
},
underlined && {
lineHeight: TEXTFIELD_HEIGHT + 2,
},
],
readOnlyPlaceholder: (_a = {
color: semanticColors.inputPlaceholderText
},
_a[style_utilities_1.HighContrastSelector] = {
color: 'GrayText',
},
_a),
};
};
exports.styles = styles;
});
//# sourceMappingURL=DatePicker.styles.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DatePicker.styles.js","sourceRoot":"../src/","sources":["components/DatePicker/DatePicker.styles.ts"],"names":[],"mappings":"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","sourcesContent":["import { normalize, getGlobalClassNames, FontSizes, HighContrastSelector } from '@fluentui/style-utilities';\nimport type { IDatePickerStyleProps, IDatePickerStyles } from './DatePicker.types';\nimport type { IStyle } from '@fluentui/style-utilities';\n\nconst GlobalClassNames = {\n root: 'ms-DatePicker',\n callout: 'ms-DatePicker-callout',\n withLabel: 'ms-DatePicker-event--with-label',\n withoutLabel: 'ms-DatePicker-event--without-label',\n disabled: 'msDatePickerDisabled ',\n};\n\nconst TEXTFIELD_HEIGHT = 32;\n\nexport const styles = (props: IDatePickerStyleProps): IDatePickerStyles => {\n const { className, theme, disabled, underlined, label, isDatePickerShown } = props;\n const { palette, semanticColors, fonts } = theme;\n const classNames = getGlobalClassNames(GlobalClassNames, theme);\n\n const DatePickerIcon: IStyle = {\n color: palette.neutralSecondary,\n fontSize: FontSizes.icon,\n lineHeight: '18px',\n pointerEvents: 'none',\n position: 'absolute',\n right: '4px',\n padding: '5px',\n };\n\n return {\n root: [classNames.root, theme.fonts.large, isDatePickerShown && 'is-open', normalize, className],\n textField: [\n {\n position: 'relative',\n selectors: {\n '& input[readonly]': {\n cursor: 'pointer',\n },\n input: {\n selectors: {\n '::-ms-clear': {\n display: 'none',\n },\n },\n },\n },\n },\n disabled && {\n selectors: {\n '& input[readonly]': {\n cursor: 'default',\n },\n },\n },\n ],\n callout: [classNames.callout],\n icon: [\n DatePickerIcon,\n label ? classNames.withLabel : classNames.withoutLabel,\n { paddingTop: '7px' },\n !disabled && [\n classNames.disabled,\n {\n pointerEvents: 'initial',\n cursor: 'pointer',\n },\n ],\n disabled && {\n color: semanticColors.disabledText,\n cursor: 'default',\n },\n ],\n statusMessage: [\n fonts.small,\n {\n color: semanticColors.errorText,\n marginTop: 5,\n },\n ],\n readOnlyTextField: [\n {\n cursor: 'pointer',\n height: TEXTFIELD_HEIGHT,\n lineHeight: TEXTFIELD_HEIGHT - 2,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n underlined && {\n lineHeight: TEXTFIELD_HEIGHT + 2,\n },\n ],\n readOnlyPlaceholder: {\n color: semanticColors.inputPlaceholderText,\n [HighContrastSelector]: {\n color: 'GrayText',\n },\n },\n };\n};\n"]}
@@ -0,0 +1,266 @@
import * as React from 'react';
import { DayOfWeek, FirstWeekOfYear } from '@fluentui/date-time-utilities';
import type { ICalendarProps } from '../../Calendar';
import type { ICalendarStrings, IDateFormatting } from '@fluentui/date-time-utilities';
import type { IStyle, ITheme } from '@fluentui/style-utilities';
import type { IRefObject, IBaseProps, IStyleFunctionOrObject, IComponentAs } from '@fluentui/utilities';
import type { ICalloutProps } from '../../Callout';
import type { ITextFieldProps } from '../../TextField';
/**
* {@docCategory DatePicker}
*/
export interface IDatePicker {
/** Sets focus to the text field */
focus(): void;
/** Reset the state of the picker to the default */
reset(): void;
/** Open the datepicker callout */
showDatePickerPopup(): void;
}
/**
* {@docCategory DatePicker}
*/
export interface IDatePickerProps extends IBaseProps<IDatePicker>, React.HTMLAttributes<HTMLElement>, React.RefAttributes<HTMLDivElement> {
/**
* Optional callback to access the IDatePicker interface. Use this instead of ref for accessing
* the public methods and properties of the component.
*/
componentRef?: IRefObject<IDatePicker>;
/**
* Call to provide customized styling that will layer on top of the variant rules.
*/
styles?: IStyleFunctionOrObject<IDatePickerStyleProps, IDatePickerStyles>;
/**
* Theme provided by High-Order Component.
*/
theme?: ITheme;
/**
* Pass callout props to callout component
*/
calloutProps?: ICalloutProps;
/**
* Pass calendar props to calendar component
*/
calendarProps?: ICalendarProps;
/**
* Pass textField props to textField component.
* Prop name is "textField" for compatibility with upcoming slots work.
*/
textField?: ITextFieldProps;
/**
* Custom Calendar to be used for date picking
*/
calendarAs?: IComponentAs<ICalendarProps>;
/**
* Callback issued when a date is selected
*/
onSelectDate?: (date: Date | null | undefined) => void;
/**
* Label for the DatePicker
*/
label?: string;
/**
* Whether the DatePicker is a required field or not
* @defaultvalue false
*/
isRequired?: boolean;
/**
* Disabled state of the DatePicker.
* @defaultvalue false
*/
disabled?: boolean;
/**
* Aria Label for TextField of the DatePicker for screen reader users.
*/
ariaLabel?: string;
/**
* Whether or not the Textfield of the DatePicker is underlined.
* @defaultvalue false
*/
underlined?: boolean;
/**
* Aria label for date picker popup for screen reader users.
* @defaultvalue Calendar
*/
pickerAriaLabel?: string;
/**
* Whether the month picker is shown beside the day picker or hidden.
* @defaultvalue true
*/
isMonthPickerVisible?: boolean;
/**
* Show month picker on top of date picker when visible.
* @defaultvalue false
*/
showMonthPickerAsOverlay?: boolean;
/**
* Whether the DatePicker allows input a date string directly or not
* @defaultvalue false
*/
allowTextInput?: boolean;
/**
* Whether the DatePicker should open automatically when the control is focused
* WARNING: setting this to false creates an accessibility violation and is not recommended
* @defaultvalue true
*/
disableAutoFocus?: boolean;
/**
* Whether the DatePicker should open when the input is clicked
* @defaultvalue true
*/
openOnClick?: boolean;
/**
* Placeholder text for the DatePicker
*/
placeholder?: string;
/**
* Value of today. If unspecified, current time in client machine will be used.
*/
today?: Date;
/**
* Default value of the DatePicker, if any
*/
value?: Date;
/**
* Optional method to format the chosen date to a string to display in the DatePicker
* @defaultvalue date.toString()
*/
formatDate?: (date?: Date) => string;
/**
* Optional method to parse the text input value to date, it is only useful when allowTextInput is set to true
* @defaultvalue new Date(Date.parse(dateStr))
*/
parseDateFromString?: (dateStr: string) => Date | null;
/**
* The first day of the week for your locale.
* @defaultvalue DayOfWeek.Sunday
*/
firstDayOfWeek?: DayOfWeek;
/**
* Localized strings to use in the DatePicker
*/
strings?: IDatePickerStrings;
/**
* Whether the month picker should highlight the current month
* @defaultvalue false
*/
highlightCurrentMonth?: boolean;
/**
* Whether the month picker should highlight the selected month
* @defaultvalue false
*/
highlightSelectedMonth?: boolean;
/**
* Whether the calendar should show the week number (weeks 1 to 53) before each week row
* @defaultvalue false
*/
showWeekNumbers?: boolean;
/**
* Defines when the first week of the year should start, FirstWeekOfYear.FirstDay,
* FirstWeekOfYear.FirstFullWeek or FirstWeekOfYear.FirstFourDayWeek are the possible values
* @defaultvalue FirstWeekOfYear.FirstFullWeek
*/
firstWeekOfYear?: FirstWeekOfYear;
/**
* Whether the "Go to today" link should be shown or not
*/
showGoToToday?: boolean;
/**
* Determines if the DatePicker has a border.
* @defaultvalue false
*/
borderless?: boolean;
/**
* Optional CSS class for the DatePicker root element.
*/
className?: string;
/**
* Apply additional formatting to dates, for example localized date formatting.
*/
dateTimeFormatter?: IDateFormatting;
/**
* The minimum allowable date.
*/
minDate?: Date;
/**
* The maximum allowable date.
*/
maxDate?: Date;
/**
* The initially highlighted date.
*/
initialPickerDate?: Date;
/**
* Allows all elements to be focused, including disabled ones
* @defaultvalue false
*/
allFocusable?: boolean;
/**
* Callback that runs after DatePicker's menu (Calendar) is closed
*/
onAfterMenuDismiss?: () => void;
/**
* Whether the CalendarDay close button should be shown or not.
*/
showCloseButton?: boolean;
/**
* The tabIndex of the TextField
*/
tabIndex?: number;
}
/**
* {@docCategory DatePicker}
*/
export interface IDatePickerStrings extends ICalendarStrings {
/**
* Error message to render for TextField if isRequired validation fails.
*/
isRequiredErrorMessage?: string;
/**
* Error message to render for TextField if input date string parsing fails.
*/
invalidInputErrorMessage?: string;
/**
* Error message to render for TextField if date boundary (minDate, maxDate) validation fails.
*/
isOutOfBoundsErrorMessage?: string;
/**
* Status message to render for TextField the input date parsing fails,
* and the typed value is cleared and reset to the previous value.
* e.g. "Invalid entry `{0}`, date reset to `{1}`"
*/
isResetStatusMessage?: string;
}
/**
* {@docCategory DatePicker}
*/
export interface IDatePickerStyleProps {
/**
* Theme provided by High-Order Component.
*/
theme: ITheme;
/**
* Accept custom classNames
*/
className?: string;
disabled?: boolean;
underlined?: boolean;
label?: boolean;
isDatePickerShown?: boolean;
}
/**
* {@docCategory DatePicker}
*/
export interface IDatePickerStyles {
/**
* Style for the root element.
*/
root: IStyle;
textField: IStyle;
callout: IStyle;
icon: IStyle;
statusMessage?: IStyle;
wrapper?: IStyle;
readOnlyTextField?: IStyle;
readOnlyPlaceholder?: IStyle;
}
@@ -0,0 +1,5 @@
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
});
//# sourceMappingURL=DatePicker.types.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
import type { IDatePickerStrings } from './DatePicker.types';
export declare const defaultDatePickerStrings: IDatePickerStrings;
@@ -0,0 +1,7 @@
define(["require", "exports", "tslib", "../../Calendar"], function (require, exports, tslib_1, Calendar_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultDatePickerStrings = void 0;
exports.defaultDatePickerStrings = tslib_1.__assign(tslib_1.__assign({}, Calendar_1.defaultCalendarStrings), { prevMonthAriaLabel: 'Go to previous month', nextMonthAriaLabel: 'Go to next month', prevYearAriaLabel: 'Go to previous year', nextYearAriaLabel: 'Go to next year', closeButtonAriaLabel: 'Close date picker', isRequiredErrorMessage: 'Field is required', invalidInputErrorMessage: 'Invalid date format', isResetStatusMessage: 'Invalid entry "{0}", date reset to "{1}"' });
});
//# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
{"version":3,"file":"defaults.js","sourceRoot":"../src/","sources":["components/DatePicker/defaults.ts"],"names":[],"mappings":";;;;IAGa,QAAA,wBAAwB,yCAChC,iCAAsB,KACzB,kBAAkB,EAAE,sBAAsB,EAC1C,kBAAkB,EAAE,kBAAkB,EACtC,iBAAiB,EAAE,qBAAqB,EACxC,iBAAiB,EAAE,iBAAiB,EACpC,oBAAoB,EAAE,mBAAmB,EACzC,sBAAsB,EAAE,mBAAmB,EAC3C,wBAAwB,EAAE,qBAAqB,EAC/C,oBAAoB,EAAE,0CAA0C,IAChE","sourcesContent":["import { defaultCalendarStrings } from '../../Calendar';\nimport type { IDatePickerStrings } from './DatePicker.types';\n\nexport const defaultDatePickerStrings: IDatePickerStrings = {\n ...defaultCalendarStrings,\n prevMonthAriaLabel: 'Go to previous month',\n nextMonthAriaLabel: 'Go to next month',\n prevYearAriaLabel: 'Go to previous year',\n nextYearAriaLabel: 'Go to next year',\n closeButtonAriaLabel: 'Close date picker',\n isRequiredErrorMessage: 'Field is required',\n invalidInputErrorMessage: 'Invalid date format',\n isResetStatusMessage: 'Invalid entry \"{0}\", date reset to \"{1}\"',\n};\n"]}
@@ -0,0 +1,5 @@
export * from './DatePicker';
export * from './DatePicker.base';
export * from './DatePicker.types';
export * from '../Calendar/Calendar.types';
export * from './defaults';
+10
View File
@@ -0,0 +1,10 @@
define(["require", "exports", "tslib", "./DatePicker", "./DatePicker.base", "./DatePicker.types", "../Calendar/Calendar.types", "./defaults"], function (require, exports, tslib_1, DatePicker_1, DatePicker_base_1, DatePicker_types_1, Calendar_types_1, defaults_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
tslib_1.__exportStar(DatePicker_1, exports);
tslib_1.__exportStar(DatePicker_base_1, exports);
tslib_1.__exportStar(DatePicker_types_1, exports);
tslib_1.__exportStar(Calendar_types_1, exports);
tslib_1.__exportStar(defaults_1, exports);
});
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["components/DatePicker/index.ts"],"names":[],"mappings":";;;IAAA,4CAA6B;IAC7B,iDAAkC;IAClC,kDAAmC;IACnC,gDAA2C;IAC3C,0CAA2B","sourcesContent":["export * from './DatePicker';\nexport * from './DatePicker.base';\nexport * from './DatePicker.types';\nexport * from '../Calendar/Calendar.types';\nexport * from './defaults';\n"]}