armstrong-react
Advanced tools
Comparing version 4.0.0-pre1 to 4.0.0-pre10
@@ -24,3 +24,3 @@ import * as React from "react"; | ||
declare type DialogLayerCloseReason = "x-clicked" | "background" | "user"; | ||
export interface IDialogLayerProps { | ||
export interface IDialogLayerPropsCore { | ||
title?: string; | ||
@@ -31,2 +31,4 @@ layerClass?: string; | ||
height?: number; | ||
} | ||
export interface IDialogLayerProps extends IDialogLayerPropsCore { | ||
onClose: (e: DialogLayerCloseReason) => void; | ||
@@ -46,3 +48,3 @@ } | ||
} | ||
export interface IUseDialogSettings extends IUsePortalSettings { | ||
export interface IUseDialogSettings extends IUsePortalSettings, IDialogLayerPropsCore { | ||
beforeDialogClose?: (reason: DialogLayerCloseReason) => Promise<boolean>; | ||
@@ -49,0 +51,0 @@ } |
@@ -31,3 +31,2 @@ "use strict"; | ||
if (clickedElement && clickedElement.classList && clickedElement.classList.contains("dialog-layer")) { | ||
//e.reason = "background" | ||
onClose("background"); | ||
@@ -37,3 +36,2 @@ } | ||
var onCloseByX = React.useCallback(function (e) { | ||
//e.reason = "x-clicked" | ||
onClose("x-clicked"); | ||
@@ -60,2 +58,4 @@ }, [onClose]); | ||
var _this = this; | ||
settings = settings || {}; | ||
var hostElement = settings.hostElement, initiallyOpen = settings.initiallyOpen, beforeDialogClose = settings.beforeDialogClose, rest = tslib_1.__rest(settings, ["hostElement", "initiallyOpen", "beforeDialogClose"]); | ||
return usePortal(function (p) { | ||
@@ -66,4 +66,4 @@ var onClose = React.useCallback(function (reason) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
case 0: | ||
if (!(settings && settings.beforeDialogClose)) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, settings.beforeDialogClose(reason)]; | ||
if (!beforeDialogClose) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, beforeDialogClose(reason)]; | ||
case 1: | ||
@@ -79,7 +79,7 @@ if (_a.sent()) { | ||
}); | ||
}); }, [p.onClose, settings && settings.beforeDialogClose]); | ||
}); }, [p.onClose, beforeDialogClose]); | ||
var onUserClose = React.useCallback(function () { return onClose("user"); }, [onClose]); | ||
return (React.createElement(exports.DialogLayer, { onClose: onClose }, | ||
return (React.createElement(exports.DialogLayer, tslib_1.__assign({}, rest, { onClose: onClose }), | ||
React.createElement(DialogLayerComponent, { onClose: onUserClose }))); | ||
}, settings); | ||
}, { hostElement: hostElement, initiallyOpen: initiallyOpen }); | ||
} | ||
@@ -86,0 +86,0 @@ exports.useDialog = useDialog; |
import * as React from "react"; | ||
import { IDialogLayerPropsCore } from "./dialog"; | ||
export declare const DialogProvider: React.FC<{}>; | ||
export declare function useDialogProvider<T>(component: React.FC<IDialogProviderProps<T>>, settings?: IDialogSettings): () => Promise<T>; | ||
export declare function useConfirmDialogProvider(component: React.FC<IDialogProviderProps<boolean>>, settings?: IDialogSettings): () => Promise<boolean>; | ||
interface IDialogSettings { | ||
title?: string; | ||
className?: string; | ||
export declare function useDialogProvider<TResult, TArg = void>(component: React.FC<IDialogProviderProps<TResult, TArg>>, settings?: IDialogSettings): (argument?: TArg) => Promise<TResult>; | ||
export declare function useConfirmDialogProvider(component: React.FC<IDialogProviderProps<boolean>>, settings?: IDialogSettings): (argument?: void) => Promise<boolean>; | ||
interface IDialogSettings extends IDialogLayerPropsCore { | ||
allowCloseOnBackgroundClick?: boolean; | ||
} | ||
export interface IDialogProviderProps<T> { | ||
export interface IDialogProviderProps<T, TArg = void> { | ||
close(): void; | ||
choose(data: T): void; | ||
argument?: TArg; | ||
} | ||
export {}; |
@@ -5,8 +5,8 @@ "use strict"; | ||
var React = require("react"); | ||
var _ = require("underscore"); | ||
var dialog_1 = require("./dialog"); | ||
var _ = require("underscore"); | ||
var DialogProviderContext = React.createContext(undefined); | ||
exports.DialogProvider = function (p) { | ||
var ref = React.useRef(); | ||
return (React.createElement(DialogProviderContext.Provider, { value: { useDialogPromise: function (c, s) { return ref.current && ref.current.useDialogPromise(c, s); } } }, | ||
return (React.createElement(DialogProviderContext.Provider, { value: { useDialogPromise: function (component, argument, settings) { return ref.current && ref.current.useDialogPromise(component, argument, settings); } } }, | ||
p.children, | ||
@@ -18,5 +18,6 @@ React.createElement(DialogStack, { ref: ref }))); | ||
if (!ctx) { | ||
// tslint:disable-next-line: no-console | ||
console.log("You are trying to use DialogProvider Context, but no DialogProvider was found in the component hierarchy"); | ||
} | ||
return React.useCallback(function () { return ctx.useDialogPromise(component, settings); }, [component, settings]); | ||
return React.useCallback(function (argument) { return ctx.useDialogPromise(component, argument, settings); }, [component, settings]); | ||
} | ||
@@ -34,3 +35,3 @@ exports.useDialogProvider = useDialogProvider; | ||
React.useImperativeHandle(ref, function () { return ({ | ||
useDialogPromise: function (Body, settings) { | ||
useDialogPromise: function (Body, argument, settings) { | ||
var _this = this; | ||
@@ -48,10 +49,10 @@ return new Promise(function (resolve) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
}; | ||
setDialogContent(dialogContent.concat([tslib_1.__assign({ body: React.createElement(Body, { close: close, choose: choose }), close: close }, (settings || {}))])); | ||
setDialogContent(dialogContent.concat([tslib_1.__assign({ body: React.createElement(Body, { argument: argument, close: close, choose: choose }), close: close }, (settings || {}))])); | ||
return [2 /*return*/]; | ||
}); | ||
}); }); | ||
} | ||
}, | ||
}); }, [dialogContent, closeDialog, setDialogContent]); | ||
return (React.createElement(React.Fragment, null, dialogContent.map(function (dc, idx) { return (React.createElement(dialog_1.Dialog, { key: idx, className: dc.className, isOpen: true, onClose: dc.close, title: dc.title, closeOnBackgroundClick: !!dc.allowCloseOnBackgroundClick }, dc.body)); }))); | ||
return (React.createElement(React.Fragment, null, dialogContent.map(function (dc, idx) { return (React.createElement(dialog_1.Dialog, { key: idx, layerClass: dc.layerClass, width: dc.width, height: dc.height, className: dc.className, isOpen: true, onClose: dc.close, title: dc.title, closeOnBackgroundClick: !!dc.allowCloseOnBackgroundClick }, dc.body)); }))); | ||
} | ||
var DialogStack = React.forwardRef(DialogStackRef); |
import * as React from "react"; | ||
export interface IIconProps extends React.HTMLAttributes<HTMLElement> { | ||
/** (string) The icons 'classname' eg Icon.Icomoon.Rocket */ | ||
/** (string) The icons 'className' eg Icon.Icomoon.Rocket */ | ||
icon: string; | ||
/** (string) CSS classname property */ | ||
/** (string) CSS className property */ | ||
className?: string; | ||
@@ -7,0 +7,0 @@ } |
@@ -147,3 +147,5 @@ "use strict"; | ||
Form.Bind = new formBinders_1.FormBinder(); | ||
// tslint:disable-next-line: only-arrow-functions | ||
Form.jsonDataBinder = function (data) { return new JsonDataBinder(data); }; | ||
// tslint:disable-next-line: only-arrow-functions | ||
Form.jsonDataBinderWithClone = function (data) { return new JsonDataBinder(FormDataClone.custom(data)); }; | ||
@@ -150,0 +152,0 @@ function ParentFormContext(props) { |
@@ -386,16 +386,2 @@ "use strict"; | ||
} | ||
KeyboardHelper.getNumericRegEx = function (options) { | ||
if (options) { | ||
if (options.allowNegative) { | ||
if (options.decimals) { | ||
return /[\d\.\-]/; | ||
} | ||
return /[\d\-]/; | ||
} | ||
if (options.decimals) { | ||
return /[\d\.]/; | ||
} | ||
} | ||
return /\d/; | ||
}; | ||
KeyboardHelper.numericKeyPress = function (e, options) { | ||
@@ -402,0 +388,0 @@ var element = e.currentTarget; |
@@ -28,3 +28,3 @@ import * as React from "react"; | ||
/** | ||
* Add the value changed event handler, calling the supplied `notifyChanged` function when a change event has occured | ||
* Add the value changed event handler, calling the supplied `notifyChanged` function when a change event has occurred | ||
*/ | ||
@@ -31,0 +31,0 @@ handleValueChanged(props: TComponentProps, dataBinder: IDataBinder<TData>, notifyChanged: () => void): void; |
@@ -24,2 +24,3 @@ import * as React from "react"; | ||
bind: FormBinder<T>; | ||
notifyChange: () => void; | ||
} | ||
@@ -26,0 +27,0 @@ export interface IUseForm<T> extends IUseFormProps<T> { |
@@ -20,3 +20,3 @@ "use strict"; | ||
} | ||
return (React.createElement(form_1.ParentFormContext, null, props.children({ bind: new formBinders_1.FormBinder(), dataBinder: ctx && ctx.dataBinder }))); | ||
return (React.createElement(form_1.ParentFormContext, null, props.children({ bind: new formBinders_1.FormBinder(), dataBinder: ctx && ctx.dataBinder, notifyChange: ctx.notifyChange }))); | ||
}, | ||
@@ -51,4 +51,4 @@ }; | ||
}, [dataBinder, onDataBinderChange]); | ||
return { dataBinder: dataBinder, bind: bind, DataForm: DataForm, context: context }; | ||
return { dataBinder: dataBinder, bind: bind, DataForm: DataForm, context: context, notifyChange: onDataBinderChange }; | ||
} | ||
exports.useForm = useForm; |
@@ -12,3 +12,3 @@ import * as React from "react"; | ||
export interface IAutoCompleteInputProps extends IFormInputProps<AutoCompleteInput> { | ||
/** (string) CSS classname property */ | ||
/** (string) CSS className property */ | ||
className?: string; | ||
@@ -35,3 +35,3 @@ /** (IAutoCompleteOption | IAutoCompleteOption[]) The current/returned value or values if multi select */ | ||
goButtonContent?: React.ReactElement<any> | string; | ||
/** ((IAutoCompleteOption | IAutoCompleteOption[]) => void) Fires when the selection is changed. Returns a single value or an array dependent on multiselect */ | ||
/** ((IAutoCompleteOption | IAutoCompleteOption[]) => void) Fires when the selection is changed. Returns a single value or an array dependent on multiSelect */ | ||
onSelected?: (selectedOption: IAutoCompleteOption | IAutoCompleteOption[]) => void; | ||
@@ -38,0 +38,0 @@ /** (number) How many items to show before scrolling. Defaults to 3 */ |
@@ -1,46 +0,25 @@ | ||
import * as moment from "moment"; | ||
import * as React from "react"; | ||
import { IFormInputHTMLProps } from "../form"; | ||
export interface ICalendarInputProps extends IFormInputHTMLProps<React.InputHTMLAttributes<HTMLInputElement>> { | ||
/** The current date */ | ||
date?: string; | ||
/** The 'wire' format of the date */ | ||
format?: string; | ||
/** The 'display' format of the date (to use in the UI) */ | ||
displayFormat?: string; | ||
/** The minimum date */ | ||
min?: string; | ||
/** The maximum date */ | ||
max?: string; | ||
onDateChanged?: (date: string) => void; | ||
/** Always show the calendar inline (not as a popup) */ | ||
alwaysShowCalendar?: boolean; | ||
nativeInput?: boolean; | ||
/** The icon to display */ | ||
icon?: string; | ||
/** Is the control disabled */ | ||
disabled?: boolean; | ||
/** Disable the ability to clear the current date */ | ||
disableClear?: boolean; | ||
/** Callback when the selected date has changed */ | ||
onDateChanged?: (date: string) => void; | ||
} | ||
export interface ICalendarInputState { | ||
inputValue?: string; | ||
selectedMonthStart?: moment.Moment; | ||
pickerBodyVisible?: boolean; | ||
showOnTop?: boolean; | ||
calendarOffset?: number; | ||
} | ||
export declare class CalendarInput extends React.Component<ICalendarInputProps, ICalendarInputState> { | ||
private format; | ||
private inputElement; | ||
private bodyElement; | ||
static defaultProps: Partial<ICalendarInputProps>; | ||
constructor(props: ICalendarInputProps); | ||
onDaySelected(date: moment.Moment): void; | ||
isEndOfMonth(date: moment.Moment): boolean; | ||
fallsWithinRange(date: moment.Moment): boolean; | ||
calcTop(): void; | ||
getDaysInMonth(): any[]; | ||
getDayComponent(notInCurrentMonth: boolean, dayClicked: (d: moment.Moment) => void, date: moment.Moment): JSX.Element; | ||
changeMonth(increment: number): void; | ||
checkDate(dateString: string): void; | ||
componentWillUnmount(): void; | ||
componentDidMount(): void; | ||
componentWillReceiveProps(nextProps: ICalendarInputProps): void; | ||
handleEvent(e: Event): void; | ||
resetState(props: Readonly<ICalendarInputProps>): void; | ||
onInputFocus(): void; | ||
shouldShowOnTop(): boolean; | ||
propsDateAsMoment(): moment.Moment; | ||
render(): JSX.Element; | ||
} | ||
export declare const CalendarInput: React.FC<ICalendarInputProps>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var moment = require("moment"); | ||
var React = require("react"); | ||
var ReactDOM = require("react-dom"); | ||
var _ = require("underscore"); | ||
var config_1 = require("../../../config/config"); | ||
var useCalendar_1 = require("../../../hooks/useCalendar"); | ||
var classHelpers_1 = require("../../../utilities/classHelpers"); | ||
var hooks_1 = require("../../../utilities/hooks"); | ||
var icon_1 = require("../../display/icon"); | ||
@@ -14,119 +13,55 @@ var grid_1 = require("../../layout/grid"); | ||
var validationWrapper_1 = require("../validationWrapper"); | ||
var isoFormat = "YYYY-MM-DD"; | ||
var CalendarInput = /** @class */ (function (_super) { | ||
tslib_1.__extends(CalendarInput, _super); | ||
function CalendarInput(props) { | ||
var _this = _super.call(this, props) || this; | ||
if (!config_1.isLocaleSet()) { | ||
// tslint:disable-next-line:no-console | ||
console.warn("Using CalendarInput without setting the global Armstrong locale is not recommended. See https://github.com/Rocketmakers/armstrong-react#form---calendar--datepickers"); | ||
exports.CalendarInput = function (props) { | ||
var icon = props.icon, placeholder = props.placeholder, alwaysShowCalendar = props.alwaysShowCalendar, disableClear = props.disableClear, className = props.className, disabled = props.disabled, validationMode = props.validationMode, min = props.min, max = props.max, date = props.date; | ||
var mouseWheelDispose = React.useRef(undefined); | ||
var inputElement = React.useRef(); | ||
var bodyElement = React.useRef(); | ||
var rootElement = React.useRef(); | ||
var _a = React.useState(false), pickerBodyVisible = _a[0], setPickerBodyVisible = _a[1]; | ||
var _b = React.useState(false), showOnTop = _b[0], setShowOnTop = _b[1]; | ||
var _c = React.useState(0), calendarOffset = _c[0], setCalendarOffset = _c[1]; | ||
var onDateChanged = React.useCallback(function (d) { | ||
setPickerBodyVisible(false); | ||
if (props.onDateChanged) { | ||
props.onDateChanged(d); | ||
} | ||
_this.format = _this.props.nativeInput ? isoFormat : props.format; | ||
var initialDate = props.date ? moment(props.date, isoFormat, true) : null; | ||
var inputValue = ""; | ||
var selectedMonthStart = moment().startOf("month"); | ||
if (initialDate) { | ||
inputValue = initialDate.format(_this.format); | ||
selectedMonthStart = initialDate.clone().startOf("month"); | ||
}, [props.onDateChanged, setPickerBodyVisible]); | ||
var _d = useCalendar_1.useCalendar({ format: props.format, displayFormat: props.displayFormat, minDate: min, maxDate: max, selectedDate: date, onDateChanged: onDateChanged }), month = _d.month, clearSelectedDate = _d.clearSelectedDate, nextMonth = _d.nextMonth, previousMonth = _d.previousMonth, selectDate = _d.selectDate, selectedDate = _d.selectedDate, selectedDateDisplay = _d.selectedDateDisplay; | ||
var calcTop = React.useCallback(function () { | ||
if (inputElement.current) { | ||
var bounds = inputElement.current.getBoundingClientRect(); | ||
setCalendarOffset(bounds.bottom); | ||
} | ||
_this.state = { inputValue: inputValue, pickerBodyVisible: false, showOnTop: false, calendarOffset: 0, selectedMonthStart: selectedMonthStart }; | ||
return _this; | ||
} | ||
CalendarInput.prototype.onDaySelected = function (date) { | ||
if (!this.fallsWithinRange(date)) { | ||
return; | ||
} | ||
var newDate = date.clone(); | ||
this.setState({ pickerBodyVisible: false, inputValue: newDate.format(this.format) }); | ||
if (this.props.onDateChanged) { | ||
this.props.onDateChanged(newDate.format(isoFormat)); | ||
} | ||
}; | ||
CalendarInput.prototype.isEndOfMonth = function (date) { | ||
var endOfMonth = date.clone().endOf("month"); | ||
return endOfMonth.isSame(date, "day"); | ||
}; | ||
CalendarInput.prototype.fallsWithinRange = function (date) { | ||
if (this.props.min && date.isBefore(moment(this.props.min, isoFormat, true), "day")) { | ||
return false; | ||
} | ||
if (this.props.max && date.isAfter(moment(this.props.max, isoFormat, true), "day")) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
CalendarInput.prototype.calcTop = function () { | ||
if (this.inputElement) { | ||
var bounds = this.inputElement.getBoundingClientRect(); | ||
this.setState({ calendarOffset: bounds.bottom }); | ||
} | ||
}; | ||
CalendarInput.prototype.getDaysInMonth = function () { | ||
var days = []; | ||
var a = this.state.selectedMonthStart.clone().startOf("month").startOf("day"); | ||
var b = a.clone().endOf("month"); | ||
var firstDay = false; | ||
for (var m = moment(a); m.isBefore(b); m.add(1, "days")) { | ||
if (!firstDay) { | ||
firstDay = true; | ||
var firstDayIndex = m.weekday(); | ||
for (var i = firstDayIndex; i > 0; i--) { | ||
days.push(this.getDayComponent(true, this.onDaySelected.bind(this), m.clone().subtract(i, "days"))); | ||
} | ||
}, [inputElement]); | ||
var disposal = React.useCallback(function (newCurrent) { | ||
if (newCurrent === void 0) { newCurrent = undefined; } | ||
if (mouseWheelDispose.current) { | ||
try { | ||
mouseWheelDispose.current(); | ||
} | ||
days.push(this.getDayComponent(false, this.onDaySelected.bind(this), m.clone())); | ||
if (this.isEndOfMonth(m)) { | ||
var lastDayIndex = m.weekday(); | ||
for (var i = 1; i < 7 - lastDayIndex; i++) { | ||
days.push(this.getDayComponent(true, this.onDaySelected.bind(this), m.clone().add(i, "days"))); | ||
} | ||
catch (error) { | ||
// noop | ||
} | ||
mouseWheelDispose.current = newCurrent; | ||
} | ||
return days; | ||
}; | ||
CalendarInput.prototype.getDayComponent = function (notInCurrentMonth, dayClicked, date) { | ||
var d = date.clone(); | ||
var dateWithinRange = this.fallsWithinRange(d); | ||
var isSelected = d.format(isoFormat) === this.props.date; | ||
var isToday = d.clone().startOf("day").isSame(moment().startOf("day")); | ||
return React.createElement(CalendarDay, { key: "Calendar_day_" + date.format("DDMMYYYY"), selected: isSelected, isToday: isToday, withinRange: dateWithinRange, notInCurrentMonth: notInCurrentMonth, dayClicked: dayClicked, date: d }); | ||
}; | ||
CalendarInput.prototype.changeMonth = function (increment) { | ||
var _this = this; | ||
this.setState({ selectedMonthStart: this.state.selectedMonthStart.clone().add(increment, "months") }, function () { | ||
_this.shouldShowOnTop(); | ||
}); | ||
}; | ||
CalendarInput.prototype.checkDate = function (dateString) { | ||
if (dateString === this.state.inputValue) { | ||
}, []); | ||
React.useEffect(function () { | ||
if (!config_1.isLocaleSet()) { | ||
// tslint:disable-next-line:no-console | ||
console.warn("Using CalendarInput without setting the global Armstrong locale is not recommended. See https://github.com/Rocketmakers/armstrong-react#form---calendar--datepickers"); | ||
} | ||
window.removeEventListener("mousedown", handleEvent); | ||
return function () { | ||
window.addEventListener("mousedown", handleEvent); | ||
disposal(); | ||
}; | ||
}, []); | ||
hooks_1.useDidUpdateEffect(function () { | ||
selectDate(date); | ||
}, [date]); | ||
var handleEvent = React.useCallback(function (e) { | ||
var domNode = rootElement.current; | ||
if (!domNode) { | ||
return; | ||
} | ||
var m = moment(dateString, this.format, false); | ||
if (m.isValid() && this.fallsWithinRange(m)) { | ||
var formattedDate = m.format(this.format); | ||
if (this.props.onDateChanged) { | ||
this.props.onDateChanged(m.format(isoFormat)); | ||
} | ||
} | ||
else { | ||
this.resetState(this.props); | ||
} | ||
}; | ||
CalendarInput.prototype.componentWillUnmount = function () { | ||
if (!this.props.nativeInput) { | ||
window.removeEventListener("mousedown", this); | ||
} | ||
}; | ||
CalendarInput.prototype.componentDidMount = function () { | ||
if (!this.props.nativeInput) { | ||
window.addEventListener("mousedown", this); | ||
} | ||
}; | ||
CalendarInput.prototype.componentWillReceiveProps = function (nextProps) { | ||
if (this.props.date !== nextProps.date) { | ||
this.resetState(nextProps); | ||
} | ||
}; | ||
CalendarInput.prototype.handleEvent = function (e) { | ||
var domNode = ReactDOM.findDOMNode(this); | ||
if (domNode.contains(e.target) && e.type !== "mousewheel" && e.type !== "keydown") { | ||
@@ -139,120 +74,76 @@ return; | ||
} | ||
document.removeEventListener("mousewheel", this, false); | ||
if (!this.state.inputValue) { | ||
this.resetState(this.props); | ||
} | ||
else { | ||
this.setState({ pickerBodyVisible: false }); | ||
} | ||
}; | ||
CalendarInput.prototype.resetState = function (props) { | ||
var selectedDate = props.date ? moment(props.date, isoFormat, true) : null; | ||
if (selectedDate) { | ||
this.setState({ | ||
pickerBodyVisible: false, | ||
inputValue: selectedDate.format(this.format), | ||
selectedMonthStart: selectedDate.clone().startOf("month"), | ||
}); | ||
} | ||
else { | ||
this.setState({ | ||
pickerBodyVisible: false, | ||
inputValue: "", | ||
selectedMonthStart: moment().startOf("month"), | ||
}); | ||
} | ||
}; | ||
CalendarInput.prototype.onInputFocus = function () { | ||
var _this = this; | ||
document.addEventListener("mousewheel", this, false); | ||
this.calcTop(); | ||
this.setState({ pickerBodyVisible: true }, function () { | ||
_this.shouldShowOnTop(); | ||
}); | ||
}; | ||
CalendarInput.prototype.shouldShowOnTop = function () { | ||
if (this.props.nativeInput || !this.inputElement) { | ||
disposal(); | ||
setPickerBodyVisible(false); | ||
}, [rootElement, setPickerBodyVisible]); | ||
var shouldShowOnTop = React.useCallback(function () { | ||
if (!inputElement.current) { | ||
return; | ||
} | ||
var height = this.bodyElement.clientHeight + 50; | ||
var visibleBottom = (window.innerHeight + window.scrollY); | ||
var inputRect = this.inputElement.getBoundingClientRect(); | ||
var height = bodyElement.current.clientHeight + 50; | ||
var inputRect = inputElement.current.getBoundingClientRect(); | ||
var remainingSpace = window.innerHeight - inputRect.bottom; | ||
if (remainingSpace < height) { | ||
this.setState({ showOnTop: true }); | ||
setShowOnTop(true); | ||
return true; | ||
} | ||
else { | ||
this.setState({ showOnTop: false }); | ||
return false; | ||
} | ||
}; | ||
CalendarInput.prototype.propsDateAsMoment = function () { | ||
return moment(this.props.date, isoFormat, true); | ||
}; | ||
CalendarInput.prototype.render = function () { | ||
var _this = this; | ||
var validationMessage = formCore_1.DataValidationMessage.get(this.props); | ||
var _a = this.props, icon = _a.icon, placeholder = _a.placeholder, alwaysShowCalendar = _a.alwaysShowCalendar, disableClear = _a.disableClear, onDateChanged = _a.onDateChanged, className = _a.className, disabled = _a.disabled, validationMode = _a.validationMode, nativeInput = _a.nativeInput, min = _a.min, max = _a.max, date = _a.date; | ||
var _b = this.state, selectedMonthStart = _b.selectedMonthStart, pickerBodyVisible = _b.pickerBodyVisible, showOnTop = _b.showOnTop, inputValue = _b.inputValue, calendarOffset = _b.calendarOffset; | ||
var weekdays = _.range(0, 7).map(function (n) { return React.createElement("div", { className: "date-picker-week-day", key: "day_name_" + n }, moment().startOf("week").add(n, "days").format("dd")); }); | ||
var days = this.getDaysInMonth(); | ||
var currentDisplayDate = selectedMonthStart.format("MMMM - YYYY"); | ||
var classes = classHelpers_1.ClassHelpers.classNames("date-picker-body", { | ||
"date-picker-body-visible": pickerBodyVisible && !alwaysShowCalendar, | ||
"date-picker-top": showOnTop, | ||
"always-show-calendar": alwaysShowCalendar, | ||
}); | ||
var rootClasses = classHelpers_1.ClassHelpers.classNames("date-picker", "armstrong-input", className, { | ||
"has-icon": icon !== null, | ||
"disabled": disabled, | ||
"show-validation": (validationMode !== "none" && validationMessage), | ||
}); | ||
if (nativeInput) { | ||
return (React.createElement("div", { className: rootClasses }, | ||
icon && React.createElement(icon_1.Icon, { icon: icon }), | ||
React.createElement("input", tslib_1.__assign({ ref: function (i) { return _this.inputElement = i; } }, formCore_1.DataValidationMessage.spread(validationMessage), { type: "date", min: min || "", max: max || "", onChange: function (e) { return _this.checkDate(e.target.value); }, value: this.propsDateAsMoment().format(this.format), placeholder: placeholder })))); | ||
} | ||
return (React.createElement("div", { className: rootClasses }, | ||
React.createElement(icon_1.Icon, { icon: icon || icon_1.Icon.Icomoon.calendar2 }), | ||
!alwaysShowCalendar && | ||
React.createElement("input", tslib_1.__assign({ className: "cal-input", ref: function (i) { return _this.inputElement = i; } }, formCore_1.DataValidationMessage.spread(validationMessage), { disabled: disabled, type: "text", value: inputValue, onKeyDown: function (e) { return _this.handleEvent(e.nativeEvent); }, onFocus: function (e) { return _this.onInputFocus(); }, onChange: function (e) { }, placeholder: placeholder })), | ||
!alwaysShowCalendar && date && !disableClear && | ||
React.createElement("div", { className: "clear-date-button", onClick: function () { return onDateChanged(null); } }, | ||
React.createElement(icon_1.Icon, { icon: icon_1.Icon.Icomoon.cross })), | ||
React.createElement("div", { ref: function (b) { return _this.bodyElement = b; }, className: classes, style: { top: calendarOffset + "px" } }, | ||
React.createElement("div", { className: "date-picker-body-wrapper" }, | ||
React.createElement(grid_1.Grid, { className: "date-picker-header" }, | ||
React.createElement(grid_1.Row, null, | ||
React.createElement(grid_1.Col, { onClick: function () { return _this.changeMonth(-1); }, width: "auto" }, "<"), | ||
React.createElement(grid_1.Col, null, currentDisplayDate), | ||
React.createElement(grid_1.Col, { onClick: function () { return _this.changeMonth(1); }, width: "auto" }, ">"))), | ||
React.createElement("div", { className: "date-picker-days" }, | ||
weekdays, | ||
days))), | ||
React.createElement(validationWrapper_1.ValidationLabel, { message: validationMessage, mode: validationMode }))); | ||
}; | ||
CalendarInput.defaultProps = { | ||
format: "L", | ||
validationMode: "none", | ||
}; | ||
return CalendarInput; | ||
}(React.Component)); | ||
exports.CalendarInput = CalendarInput; | ||
var CalendarDay = /** @class */ (function (_super) { | ||
tslib_1.__extends(CalendarDay, _super); | ||
function CalendarDay() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
CalendarDay.prototype.render = function () { | ||
var _a = this.props, notInCurrentMonth = _a.notInCurrentMonth, selected = _a.selected, isToday = _a.isToday, withinRange = _a.withinRange, date = _a.date, dayClicked = _a.dayClicked; | ||
var classes = classHelpers_1.ClassHelpers.classNames({ | ||
"not-in-month": notInCurrentMonth, | ||
"selected-day": selected, | ||
"is-today": isToday, | ||
"day-disabled": !withinRange, | ||
}); | ||
return React.createElement("div", { className: classes, onClick: function () { return dayClicked(date); } }, date.format("DD")); | ||
}; | ||
return CalendarDay; | ||
}(React.Component)); | ||
setShowOnTop(false); | ||
return false; | ||
}, [inputElement, bodyElement, setShowOnTop]); | ||
var onInputFocus = React.useCallback(function () { | ||
disposal(function () { return document.removeEventListener("mousewheel", handleEvent, false); }); | ||
document.addEventListener("mousewheel", handleEvent, false); | ||
calcTop(); | ||
setPickerBodyVisible(true); | ||
shouldShowOnTop(); | ||
}, [calcTop, shouldShowOnTop]); | ||
var validationMessage = formCore_1.DataValidationMessage.get(props); | ||
var weekdays = React.useMemo(function () { return month.daysOfWeek.map(function (n) { return React.createElement("div", { className: "date-picker-week-day", key: "day_name_" + n }, n); }); }, [month.daysOfWeek]); | ||
var currentDisplayDate = month.shortName + " - " + month.year; | ||
var classes = React.useMemo(function () { return classHelpers_1.ClassHelpers.classNames("date-picker-body", { | ||
"date-picker-body-visible": pickerBodyVisible && !alwaysShowCalendar, | ||
"date-picker-top": showOnTop, | ||
"always-show-calendar": alwaysShowCalendar, | ||
}); }, [pickerBodyVisible, alwaysShowCalendar, showOnTop, alwaysShowCalendar]); | ||
var rootClasses = React.useMemo(function () { return classHelpers_1.ClassHelpers.classNames("date-picker", "armstrong-input", className, { | ||
"has-icon": icon !== null, | ||
"disabled": disabled, | ||
"show-validation": (validationMode !== "none" && validationMessage), | ||
}); }, [className, icon, disabled, validationMode, validationMessage]); | ||
var days = month.weeks.reduce(function (w, c) { | ||
w.push.apply(w, c.days); | ||
return w; | ||
}, []); | ||
return (React.createElement("div", { ref: rootElement, className: rootClasses }, | ||
React.createElement(icon_1.Icon, { icon: icon || icon_1.Icon.Icomoon.calendar2 }), | ||
!alwaysShowCalendar && | ||
React.createElement("input", tslib_1.__assign({ className: "cal-input", ref: inputElement }, formCore_1.DataValidationMessage.spread(validationMessage), { disabled: disabled, type: "text", value: selectedDateDisplay, onKeyDown: function (e) { return handleEvent(e.nativeEvent); }, onFocus: onInputFocus, onChange: function (e) { }, placeholder: placeholder })), | ||
!alwaysShowCalendar && selectedDate && !disableClear && | ||
React.createElement("div", { className: "clear-date-button", onClick: clearSelectedDate }, | ||
React.createElement(icon_1.Icon, { icon: icon_1.Icon.Icomoon.cross })), | ||
React.createElement("div", { ref: bodyElement, className: classes, style: { top: calendarOffset + "px" } }, | ||
React.createElement("div", { className: "date-picker-body-wrapper" }, | ||
React.createElement(grid_1.Grid, { className: "date-picker-header" }, | ||
React.createElement(grid_1.Row, null, | ||
React.createElement(grid_1.Col, { onClick: previousMonth, width: "auto" }, "<"), | ||
React.createElement(grid_1.Col, null, currentDisplayDate), | ||
React.createElement(grid_1.Col, { onClick: nextMonth, width: "auto" }, ">"))), | ||
React.createElement("div", { className: "date-picker-days" }, | ||
weekdays, | ||
days.map(function (day) { return React.createElement(CalendarDay, { key: day.date, day: day, dayClicked: selectDate }); })))), | ||
React.createElement(validationWrapper_1.ValidationLabel, { message: validationMessage, mode: validationMode }))); | ||
}; | ||
exports.CalendarInput.defaultProps = { | ||
displayFormat: "L", | ||
validationMode: "none", | ||
}; | ||
var CalendarDay = function (props) { | ||
var day = props.day, dayClicked = props.dayClicked; | ||
var classes = React.useMemo(function () { return classHelpers_1.ClassHelpers.classNames({ | ||
"not-in-month": !day.isCurrentMonth, | ||
"selected-day": day.isCurrentDate, | ||
"is-today": day.isToday, | ||
"day-disabled": day.outOfRange, | ||
}); }, [day.isCurrentMonth, day.isCurrentDate, day.isToday, day.outOfRange]); | ||
var onClick = React.useCallback(function () { return dayClicked(day.date); }, [day]); | ||
return React.createElement("div", { className: classes, onClick: onClick }, day.dayNumber); | ||
}; |
@@ -20,13 +20,13 @@ "use strict"; | ||
var buildValue = React.useCallback(function () { | ||
var value = ""; | ||
var code = ""; | ||
var current = document.getElementById("input_" + uniq.current + "_0"); | ||
lengthPerBox.forEach(function () { | ||
value += current.value; | ||
code += current.value; | ||
current = current.nextSibling; | ||
}); | ||
if (numeric) { | ||
value = parseInt(value, 10); | ||
code = parseInt(code, 10); | ||
} | ||
if (onChange) { | ||
onChange(value); | ||
onChange(code); | ||
} | ||
@@ -33,0 +33,0 @@ }, [uniq, lengthPerBox, onChange, numeric]); |
@@ -11,2 +11,6 @@ import * as React from "react"; | ||
date?: string; | ||
/** (string) Min Date string in YYYY-MM-DD format */ | ||
minDate?: string; | ||
/** (string) Max Date string in YYYY-MM-DD format */ | ||
maxDate?: string; | ||
/** ((string) => void) Event which returns the date when it changes and is valid */ | ||
@@ -16,6 +20,2 @@ onChange?: (date: string) => void; | ||
yearsFromNow?: number; | ||
/** (number) How many years to skip in the dropdown (useful for age and date limiting) */ | ||
startYearCap?: number; | ||
/** (boolean) Should the picker let you choose years from the future rather than the past */ | ||
futureDates?: boolean; | ||
/** (boolean) Should the picker disallow user interaction */ | ||
@@ -22,0 +22,0 @@ disabled?: boolean; |
@@ -6,3 +6,3 @@ "use strict"; | ||
var classHelpers_1 = require("../../../utilities/classHelpers"); | ||
var dateHelpers_1 = require("../../../utilities/dateHelpers"); | ||
var dates_1 = require("../../../utilities/dates"); | ||
var formatting_1 = require("../../../utilities/formatting"); | ||
@@ -16,11 +16,8 @@ var hooks_1 = require("../../../utilities/hooks"); | ||
exports.DateInput = function (props) { | ||
var dayLabel = props.dayLabel, monthLabel = props.monthLabel, yearLabel = props.yearLabel, futureDates = props.futureDates, yearsFromNow = props.yearsFromNow, startYearCap = props.startYearCap, className = props.className, validationMode = props.validationMode, disabled = props.disabled, datePartOrder = props.datePartOrder, tabIndex = props.tabIndex, date = props.date, onChange = props.onChange; | ||
var dayLabel = props.dayLabel, monthLabel = props.monthLabel, yearLabel = props.yearLabel, yearsFromNow = props.yearsFromNow, className = props.className, validationMode = props.validationMode, disabled = props.disabled, datePartOrder = props.datePartOrder, tabIndex = props.tabIndex, date = props.date, minDate = props.minDate, maxDate = props.maxDate, onChange = props.onChange; | ||
var _a = React.useState({ day: null, month: null, year: null, date: null }), dateState = _a[0], setDateState = _a[1]; | ||
var daysArrayByMonth = React.useMemo(function () { | ||
return dateHelpers_1.DateHelpers.getDaysArrayByMonth(dateState.month, dateState.year); | ||
}, [dateState.month, dateState.year]); | ||
React.useEffect(function () { | ||
validateProps(); | ||
if (date) { | ||
setDateState(dateHelpers_1.DateHelpers.getDateParts(date)); | ||
setDateState(dates_1.Dates.getDateParts(date)); | ||
} | ||
@@ -37,3 +34,3 @@ }, []); | ||
if (date) { | ||
setDateState(dateHelpers_1.DateHelpers.getDateParts(date, true)); | ||
setDateState(dates_1.Dates.getDateParts(date, true)); | ||
} | ||
@@ -44,19 +41,44 @@ else { | ||
}, [date]); | ||
var hasDayPart = React.useMemo(function () { | ||
return datePartOrder.indexOf("day") > -1; | ||
}, [datePartOrder]); | ||
var hasYearPart = React.useMemo(function () { | ||
return datePartOrder.indexOf("year") > -1; | ||
}, [datePartOrder]); | ||
var validationMessage = formCore_1.DataValidationMessage.get(props); | ||
var dayArray = React.useMemo(function () { | ||
return dates_1.Dates.getDaysArrayByMonth(dateState.month, dateState.year, minDate, maxDate); | ||
}, [dateState.month, dateState.year, minDate, maxDate]); | ||
var monthArray = React.useMemo(function () { | ||
return dates_1.Dates.getMonthValuesInRange(dateState.year, minDate, maxDate); | ||
}, [dateState.year, minDate, maxDate]); | ||
var yearArray = React.useMemo(function () { | ||
return dates_1.Dates.getYearValues(minDate, maxDate, yearsFromNow); | ||
}, [minDate, maxDate, yearsFromNow]); | ||
var handleDataChanged = React.useCallback(function (d) { | ||
var newDate = dateHelpers_1.DateHelpers.toDateFormat(d); | ||
var day = datePartOrder.indexOf("day") === -1 ? 1 : null; | ||
var year = datePartOrder.indexOf("year") === -1 ? 2000 : null; | ||
setDateState(tslib_1.__assign({}, d, { date: newDate, day: day, year: year })); | ||
if (onChange && newDate) { | ||
onChange(newDate); | ||
var newState = {}; | ||
newState.year = !hasYearPart ? 2000 : d.year; | ||
newState.day = !hasDayPart ? 1 : d.day; | ||
var days = dates_1.Dates.getDaysArrayByMonth(d.month, d.year, minDate, maxDate); | ||
if (d.day && days.indexOf(newState.day) === -1) { | ||
newState.day = days[0]; | ||
} | ||
}, [datePartOrder, onChange]); | ||
var validationMessage = formCore_1.DataValidationMessage.get(props); | ||
newState.month = d.month; | ||
var months = dates_1.Dates.getMonthValuesInRange(d.year, minDate, maxDate); | ||
if (d.month && months.map(function (a) { return a.value; }).indexOf(newState.month) === -1) { | ||
newState.month = months[0].value; | ||
} | ||
newState.date = dates_1.Dates.toDateFormat(newState); | ||
setDateState(newState); | ||
if (onChange && newState.date) { | ||
onChange(newState.date); | ||
} | ||
}, [hasDayPart, hasYearPart, onChange, minDate, maxDate]); | ||
var options = React.useMemo(function () { | ||
return { | ||
day: options_1.buildOptions(dayLabel, daysArrayByMonth, function (v) { return v; }, function (v) { return formatting_1.Formatting.twoDigitNumber(parseInt(v, 10)); }), | ||
month: options_1.buildOptions(monthLabel, dateHelpers_1.DateHelpers.getMonthValues(), function (v) { return v.value; }, function (v) { return v.label; }), | ||
year: options_1.buildOptions(yearLabel, dateHelpers_1.DateHelpers.getYearValues(futureDates, yearsFromNow, startYearCap), function (v) { return v; }, function (v) { return v.toString(); }), | ||
day: options_1.buildOptions(dayLabel, dayArray, function (v) { return v; }, function (v) { return formatting_1.Formatting.twoDigitNumber(v); }), | ||
month: options_1.buildOptions(monthLabel, monthArray, function (v) { return v.value; }, function (v) { return v.label; }), | ||
year: options_1.buildOptions(yearLabel, yearArray, function (v) { return v; }, function (v) { return v.toString(); }), | ||
}; | ||
}, [dayLabel, monthLabel, yearLabel, daysArrayByMonth, futureDates, yearsFromNow, startYearCap]); | ||
}, [dayLabel, monthLabel, yearLabel, dayArray, monthArray, yearArray]); | ||
var classes = React.useMemo(function () { return classHelpers_1.ClassHelpers.classNames("armstrong-input", "date-input", className, { | ||
@@ -63,0 +85,0 @@ "show-validation": (validationMode !== "none" && validationMessage), |
@@ -7,5 +7,5 @@ "use strict"; | ||
var classHelpers_1 = require("../../../utilities/classHelpers"); | ||
var dateHelpers_1 = require("../../../utilities/dateHelpers"); | ||
var formatting_1 = require("../../../utilities/formatting"); | ||
var hooks_1 = require("../../../utilities/hooks"); | ||
var times_1 = require("../../../utilities/times"); | ||
var grid_1 = require("../../layout/grid"); | ||
@@ -22,3 +22,3 @@ var formCore_1 = require("../formCore"); | ||
if (time) { | ||
var newTime = dateHelpers_1.DateHelpers.getTimeParts(time); | ||
var newTime = times_1.Times.getTimeParts(time); | ||
setTimeState({ hours: newTime.hours, minutes: newTime.minutes }); | ||
@@ -29,3 +29,3 @@ } | ||
if (time) { | ||
var newTime = dateHelpers_1.DateHelpers.getTimeParts(time); | ||
var newTime = times_1.Times.getTimeParts(time); | ||
var needsUpdate = void 0; | ||
@@ -32,0 +32,0 @@ var hours = timeState.hours, minutes = timeState.minutes; |
@@ -6,3 +6,3 @@ import * as React from "react"; | ||
debugMode?: boolean; | ||
/** (string) CSS classname property */ | ||
/** (string) CSS className property */ | ||
className?: string; | ||
@@ -20,3 +20,3 @@ /** (boolean) Wether the table should expand and divide to fill its container */ | ||
height?: number | string; | ||
/** (string) CSS classname property */ | ||
/** (string) CSS className property */ | ||
className?: string; | ||
@@ -38,5 +38,5 @@ /** (string) An HTML tag to use for the root element instead of <div> */ | ||
tagName?: string; | ||
/** (string) CSS classname property */ | ||
/** (string) CSS className property */ | ||
className?: string; | ||
} | ||
export declare const Col: React.FC<IColProps>; |
@@ -75,3 +75,3 @@ "use strict"; | ||
toggleMenu: toggleMenu, | ||
isOpen: isOpen.current | ||
isOpen: isOpen.current, | ||
}; | ||
@@ -78,0 +78,0 @@ }, [openMenu, closeMenu, toggleMenu, isOpen]); |
@@ -8,3 +8,3 @@ import * as React from "react"; | ||
/** (TabItem[]) The tab items. Controls the header and the content */ | ||
children?: React.ReactElement<ITabItemProps> | React.ReactElement<ITabItemProps>[]; | ||
children?: React.ReactElement<ITabItemProps> | Array<React.ReactElement<ITabItemProps>>; | ||
/** ((index: number) => void) Fires when the tab is changed by the user */ | ||
@@ -11,0 +11,0 @@ onTabChanged?: (index: number) => void; |
{ | ||
"name": "armstrong-react", | ||
"version": "4.0.0-pre1", | ||
"version": "4.0.0-pre10", | ||
"description": "Rocketmakers Armstrong library of React components", | ||
@@ -52,2 +52,4 @@ "main": "./dist/index.js", | ||
"react-dom": "^16.8.6", | ||
"react-hooks-testing-library": "^0.5.0", | ||
"react-test-renderer": "^16.8.6", | ||
"ts-loader": "^5.3.3", | ||
@@ -54,0 +56,0 @@ "tslint": "^5.16.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
816833
15868
16
175