@appbuckets/react-ui
Version:
Just Another React UI Framework
452 lines (445 loc) • 12.6 kB
JavaScript
'use strict';
var tslib = require('tslib');
var React = require('react');
var clsx = require('clsx');
var reactUiCore = require('@appbuckets/react-ui-core');
var ReactDayPicker = require('react-day-picker/DayPicker');
var customHook = require('../utils/customHook.js');
var splitFieldProps = require('../utils/splitFieldProps.js');
require('../BucketTheme/BucketTheme.js');
var BucketContext = require('../BucketTheme/BucketContext.js');
var Button = require('../Button/Button.js');
var Input = require('../Input/Input.js');
var Modal = require('../Modal/Modal.js');
require('../Modal/Modal.context.js');
var Popup = require('../Popup/Popup.js');
function _interopDefaultLegacy(e) {
return e && typeof e === 'object' && 'default' in e ? e : { default: e };
}
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(
n,
k,
d.get
? d
: {
enumerable: true,
get: function () {
return e[k];
},
}
);
}
});
}
n['default'] = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/ _interopNamespace(React);
var clsx__default = /*#__PURE__*/ _interopDefaultLegacy(clsx);
var ReactDayPicker__default =
/*#__PURE__*/ _interopDefaultLegacy(ReactDayPicker);
/* --------
* Component Render
* -------- */
var DayPicker = function (receivedProps) {
var _a, _b, _c, _d;
/** Get component default props */
var props = BucketContext.useWithDefaultProps('dayPicker', receivedProps);
var _e = customHook.useSharedClassName(props),
className = _e.className,
_f = _e.rest,
/** Strict DayPicker Props */
clearable = _f.clearable,
clearButton = _f.clearButton,
closeOnDayPicked = _f.closeOnDayPicked,
userDefinedDate = _f.date,
defaultDate = _f.defaultDate,
defaultOpen = _f.defaultOpen,
format = _f.format,
onCalendarClose = _f.onCalendarClose,
onCalendarOpen = _f.onCalendarOpen,
onDayChange = _f.onDayChange,
onInputChange = _f.onInputChange,
userDefinedOpen = _f.open,
parse = _f.parse;
_f.showInputMask;
var trigger = _f.trigger,
triggerProps = _f.triggerProps,
type = _f.type,
/** Shared Field Props */
disabled = _f.disabled,
readOnly = _f.readOnly,
required = _f.required,
/** Strict DayPicker Props */
userDefinedFixedWeeks = _f.fixedWeeks;
_f.onTodayButtonClick;
var todayButton = _f.todayButton;
/** Strip useless props */
_f.ref;
var /** All other DayPicker Props Props */
rawRest = tslib.__rest(_f, [
'clearable',
'clearButton',
'closeOnDayPicked',
'date',
'defaultDate',
'defaultOpen',
'format',
'onCalendarClose',
'onCalendarOpen',
'onDayChange',
'onInputChange',
'open',
'parse',
'showInputMask',
'trigger',
'triggerProps',
'type',
'disabled',
'readOnly',
'required',
'fixedWeeks',
'onTodayButtonClick',
'todayButton',
'ref',
]);
var _g = tslib.__read(customHook.useSplitStateClassName(rawRest), 3),
allRest = _g[1],
inputState = _g[2];
var _h = tslib.__read(splitFieldProps(allRest), 2),
restFieldProps = _h[0],
restDayPickerProps = _h[1];
/* --------
* Auto Controlled Component State
* -------- */
var _j = tslib.__read(
reactUiCore.useAutoControlledValue(null, {
prop: userDefinedDate,
defaultProp: defaultDate,
}),
2
),
rawDate = _j[0],
trySetRawDate = _j[1];
var _k = tslib.__read(
reactUiCore.useAutoControlledValue(false, {
prop: userDefinedOpen,
defaultProp: defaultOpen,
}),
2
),
open = _k[0],
trySetOpen = _k[1];
/* --------
* Internal Function
* -------- */
var getToday = React__namespace.useCallback(function () {
var newDate = new Date();
newDate.setHours(0, 0, 0, 0);
return newDate;
}, []);
/* --------
* Date Parsing and Formatting
* -------- */
var castToDate = React__namespace.useCallback(
function (date) {
/** If no date, return null */
if (!date) {
return null;
}
/** Initialize the Casted Date variable */
var castedDate;
/** If a custom parse function exists, use to cast the date */
if (typeof parse === 'function') {
castedDate = parse(date);
} else if (date instanceof Date) {
/** Else, if is a valid date, use as is */
castedDate = date;
} else {
/** Use the date constructor if rawDate is a primitive type */
castedDate = new Date(date);
}
/** If casted date is invalid, return null */
if (
castedDate === null ||
!(castedDate instanceof Date) ||
(castedDate === null || castedDate === void 0
? void 0
: castedDate.toString()) === 'Invalid Date'
) {
return null;
}
/** Set Hours */
castedDate.setHours(0, 0, 0, 0);
return castedDate;
},
[parse]
);
var formatDate = React__namespace.useCallback(
function (date) {
/** If no date, return an empty string */
if (!date || date.toString() === 'Invalid Date') {
return '';
}
/** If a custom format function exists, use it */
if (typeof format === 'function') {
return format(date);
}
return date.toLocaleDateString();
},
[format]
);
var selectedDate = React__namespace.useMemo(
function () {
/** If no raw date exists, set as null */
if (rawDate === null || rawDate === undefined) {
return { object: null, formatted: '' };
}
/** Initialize the casted date variable, and formatted one */
var castedDate = castToDate(rawDate);
/** Return data */
return {
object: castedDate,
formatted: formatDate(castedDate),
};
},
[castToDate, formatDate, rawDate]
);
var _l = tslib.__read(
React__namespace.useState(
(_a = selectedDate.formatted) !== null && _a !== void 0 ? _a : ''
),
2
),
inputValue = _l[0],
setInputValue = _l[1];
/* --------
* Build Props Object used to pass to Event
* -------- */
var propsForEvent = tslib.__assign(tslib.__assign({}, props), {
date: (_b = selectedDate.object) !== null && _b !== void 0 ? _b : null,
timestamp:
(_d =
(_c = selectedDate.object) === null || _c === void 0
? void 0
: _c.valueOf()) !== null && _d !== void 0
? _d
: null,
});
/* --------
* Component Handlers
* -------- */
var handleCalendarOpen = function () {
if (onCalendarOpen) {
onCalendarOpen(null, propsForEvent);
}
trySetOpen(true);
};
var handleCalendarClose = function () {
if (onCalendarClose) {
onCalendarClose(null, propsForEvent);
}
trySetOpen(false);
};
var handleCalendarModalClose = function (e) {
/** Stop event Propagation */
e.stopPropagation();
/** Close the Calendar */
handleCalendarClose();
};
var evalDayChange = function (value, triggeredByInput) {
var _a, _b;
/** Build new Date Object */
var newDate = castToDate(value);
var currTimestamp =
(_b =
(_a = selectedDate.object) === null || _a === void 0
? void 0
: _a.valueOf()) !== null && _b !== void 0
? _b
: null;
var isValidNewDate = newDate && newDate.toString() !== 'Invalid Date';
var newDateObject = isValidNewDate ? newDate : null;
var newTimestamp = isValidNewDate ? newDate.valueOf() : null;
/** Check if date is changed */
if (currTimestamp !== newTimestamp && onDayChange) {
onDayChange(
null,
tslib.__assign(tslib.__assign({}, propsForEvent), {
date: newDate,
timestamp: newTimestamp,
})
);
}
if (closeOnDayPicked) {
handleCalendarClose();
}
if (!triggeredByInput) {
setInputValue(formatDate(newDate));
}
trySetRawDate(newDateObject);
};
var handleDayClick = function (day, modifiers, e) {
/** If calendar is disabled, or day is disabled, return */
if (disabled || modifiers.disabled) {
return;
}
/** Stop event Propagation */
e.stopPropagation();
/** Eval Day Change */
evalDayChange(day, false);
};
var handleInputChange = function (e, inputProps) {
/** Change Input Value */
setInputValue(inputProps.value);
/** Trigger Handler */
if (onInputChange) {
onInputChange(e, inputProps);
}
/** Eval day Change */
evalDayChange(inputProps.value, true);
};
var handleTodayButtonClick = function () {
evalDayChange(getToday(), false);
};
var handleClearDate = function () {
evalDayChange('', false);
};
/** Build the element class list */
var classes = clsx__default['default']('day-picker', className);
/* --------
* Build the Modal Trigger Memoized Element
* -------- */
var modalTrigger = (function () {
if (type === 'input') {
return undefined;
}
if (trigger) {
return trigger;
}
return React__namespace.createElement(
Button,
tslib.__assign(
{ icon: 'calendar', content: selectedDate.formatted },
triggerProps,
{ disabled: disabled, onClick: handleCalendarOpen }
)
);
})();
var calendarAddon = (function () {
/** In Portal no addons could be defined */
if (type === 'input') {
return null;
}
/** Build clear Button */
var clearButtonElement =
clearable &&
!!rawDate &&
Button.create(clearButton || 'Clear', {
autoGenerateKey: false,
defaultProps: {
size: 'small',
},
overrideProps: {
className: 'clear',
disabled: disabled,
onClick: handleClearDate,
},
});
/** Build today button */
var todayButtonElement = Button.create(todayButton, {
autoGenerateKey: false,
defaultProps: {
primary: true,
size: 'small',
},
overrideProps: {
className: 'today',
disabled: disabled,
onClick: handleTodayButtonClick,
},
});
/** If no content, return */
if (!clearButtonElement && !todayButtonElement) {
return null;
}
return React__namespace.createElement(
'div',
{ className: 'addons' },
todayButtonElement,
clearButtonElement
);
})();
/* --------
* Build the DayPicker Component
* -------- */
var dayPickerElement = React__namespace.createElement(
React__namespace.Fragment,
null,
React__namespace.createElement(
ReactDayPicker__default['default'],
// Component Props
tslib.__assign({}, restDayPickerProps, {
fixedWeeks:
userDefinedFixedWeeks !== null && userDefinedFixedWeeks !== void 0
? userDefinedFixedWeeks
: type === 'modal',
// Selected Days
month: selectedDate.object || undefined,
selectedDays: selectedDate.object || undefined,
// Handlers
onDayClick: handleDayClick,
onTodayButtonClick: handleDayClick,
})
),
calendarAddon
);
/* --------
* Return the Calendar as Input
* -------- */
if (type === 'input') {
return React__namespace.createElement(
Popup,
{
portalProps: {
open: open,
},
onOpen: handleCalendarOpen,
onClose: handleCalendarClose,
basic: false,
inverted: false,
position: 'bottom left',
openOn: ['focus'],
trigger: React__namespace.createElement(
Input,
tslib.__assign({}, inputState, restFieldProps, {
className: classes,
clearable: clearable && !!rawDate,
disabled: disabled,
readOnly: readOnly,
required: required,
value: inputValue,
onChange: handleInputChange,
})
),
},
dayPickerElement
);
}
return React__namespace.createElement(Modal, {
className: classes,
open: open,
trigger: modalTrigger,
content: dayPickerElement,
onClose: handleCalendarModalClose,
});
};
DayPicker.displayName = 'DayPicker';
module.exports = DayPicker;