aio-input
Version:
generate all input types in react j[A[C[B[A[D[D[B[A[C[F[C[C[C[C[C[C[C[C[C[C[C[C[C[C[B[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C[C
1,142 lines • 186 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { createElement as _createElement } from "react";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { createRef, useContext, createContext, useState, useEffect, useRef, Fragment } from 'react';
import usePopup from "aio-popup";
import * as UT from 'aio-utils';
import AIODate from 'aio-date';
import { $ } from 'aio-deps';
import './index.css';
//@ts-ignore
import successSound from "./success.mp3";
//@ts-ignore
import errorSound from "./error.mp3";
import AIOCanvas from 'aio-canvas';
const Context = createContext({});
const Provider = ({ value, children }) => {
return (_jsx(Context.Provider, { value: value, children: children }));
};
const useProvider = () => useContext(Context);
const AIOInput = (p) => {
const fixMultiple = (props) => {
props.multiple = true;
if (!props.value) {
props.value = [];
}
if (!Array.isArray(props.value)) {
props.value = [];
}
};
const props = Object.assign({}, p);
if (props.type === 'text') {
if (typeof props.value !== 'string') {
props.value = '';
}
}
else if (props.type === 'number') {
if (typeof props.value !== 'number') {
props.value = undefined;
}
}
else if (props.type === 'panels') {
props.deSelect = true;
}
else if (props.type === 'multiSelect') {
props.type = 'select';
if (props.text === undefined) {
props.text = 'Select Items';
}
fixMultiple(props);
}
else if (props.type === 'multiDate') {
props.type = 'date';
props.option = Object.assign(Object.assign({}, props.option), { text: (o) => o, value: (o) => o });
fixMultiple(props);
}
else if (props.type === 'multiTime') {
props.type = 'time';
props.option = Object.assign(Object.assign({}, props.option), { text: (o) => o, value: (o) => o });
fixMultiple(props);
}
else if (props.type === 'multiButtons') {
props.type = 'buttons';
fixMultiple(props);
}
else if (props.type === 'multiSlider') {
props.type = 'range';
props.round = 0;
fixMultiple(props);
}
else if (props.type === 'slider') {
props.type = 'range';
props.round = 0;
}
else if (props.type === 'multiSpinner') {
props.type = 'range';
if (!props.round || typeof props.round !== 'number') {
props.round = 1;
}
fixMultiple(props);
}
else if (props.type === 'spinner') {
props.type = 'range';
if (!props.round || typeof props.round !== 'number') {
props.round = 1;
}
}
else if (props.type === 'multiCheckbox') {
props.type = 'radio';
fixMultiple(props);
}
else if (props.type === 'multiImage') {
props.type = 'image';
fixMultiple(props);
}
else if (props.type === 'multiPanels') {
props.type = 'panels';
fixMultiple(props);
}
else if (props.type === 'multiFile') {
props.type = 'file';
fixMultiple(props);
}
else if (props.type === 'range') {
return null;
}
else if (props.type === 'tree') {
if (props.size === undefined) {
props.size = 36;
}
}
if (props.type === 'file') {
if (props.placeholder === undefined && props.text === undefined && props.multiple) {
props.text = 'Select Files';
}
props.deSelect = props.deSelect !== false ? true : false;
}
else if (props.type === 'select' && !props.text && props.multiple) {
props.text = 'Select Items';
}
else if (props.type === 'date') {
if (props.multiple) {
props.text = props.text || `Select Dates`;
}
}
else if (props.type === 'time') {
if (props.multiple) {
props.text = props.text || `Select Times`;
}
}
if (props.type === 'text' && (props.options || props.fetchSuggestions) && !props.isSuggestion) {
return _jsx(SuggestionInput, Object.assign({}, props));
}
return _jsx(AIOINPUT, Object.assign({}, props));
};
export default AIOInput;
function AIOINPUT(props) {
const propsRef = useRef(props);
propsRef.current = props;
let [types] = useState(getTypes(props));
let [DATE] = useState(new AIODate());
let { type, value, attrs = {}, rtl } = props;
const changable = !!props.onChange && props.disabled !== true;
let [parentDom] = useState(createRef());
const isInputFocusedRef = useRef(false);
const setInputFocused = (v) => isInputFocusedRef.current = v;
const domRef = useRef(undefined);
const setDomRef = (dom) => domRef.current = dom;
const getDomRef = () => domRef.current;
let [datauniqid] = useState('aiobutton' + (Math.round(Math.random() * 10000000)));
let popup = usePopup({ rtl: props.rtl });
const optionsHook = useOptions();
const optionDetailsRef = useRef({ list: [], dic: {} });
const dateHook = useDate(() => {
return Object.assign(Object.assign({}, props), { type: props.type === 'date' ? 'date' : 'time' });
});
let [showPassword, SetShowPassword] = useState(false);
function setShowPassword(state) { SetShowPassword(state === undefined ? !showPassword : state); }
function getPopover() {
const dom = getDomRef();
let className = 'aio-input-popover ai-border-radius-md';
className += ` aio-input-popover-${rtl ? 'rtl' : 'ltr'}`;
if (types.hasOption) {
className += ' aio-input-dropdown';
}
const popover = (props.popover || {});
let body = null;
if (popover.body) {
body = popover.body;
}
else if (type === 'date') {
body = _jsx(CalendarWraper, { onClose: closePopup });
}
else if (type === 'time') {
body = _jsx(CalendarWraper, { onClose: closePopup });
}
else {
if (optionDetailsRef.current.list.length === 0) {
return;
}
body = _jsx(Options, {});
}
const modalAttrs = UT.AddToAttrs(Object.assign({}, popover.modalAttrs), { className });
let obj = Object.assign(Object.assign({}, (props.popover || {})), { rtl: !!props.rtl, focus: !types.hasKeyboard, position: popover.position || 'popover', fitHorizontal: ['text', 'number', 'textarea'].indexOf(type) !== -1 || (type === 'select' && !!props.multiple) || !!popover.fitHorizontal, onClose: () => closePopup(), body, getTarget: () => $(dom.current), modalAttrs });
return obj;
}
function closePopup() {
popup.removeModal();
setTimeout(() => $(parentDom.current).focus(), 0);
}
function openPopover() {
let open = !!popup.getModals().length;
if (open) {
return;
}
const popover = getPopover();
if (!popover) {
return;
}
popup.addModal(popover);
}
function AIChange(a, b) {
if (props.onChange) {
props.onChange(a, b);
}
}
function click(e) {
if (type === 'checkbox') {
AIChange(!value, e);
}
else if (types.isDropdown) {
openPopover();
}
else if (typeof props.onClick === 'function') {
props.onClick(e);
}
else if (attrs.onClick) {
attrs.onClick();
}
}
function optionClick(optionDetail) {
let { attrs = {}, onClick, close } = optionDetail;
if (onClick) {
onClick(optionDetail.optionOrg, optionDetail);
}
else if (attrs.onClick) {
attrs.onClick(optionDetail);
}
else if (changable) {
if (types.isInput) { /*do nothing*/ }
else if (type === 'tree') { /*do nothing*/ }
else if (type === 'file') { /*do nothing*/ }
else if (type === 'toggleButton') {
let newIndex = optionDetail.index + 1;
if (newIndex > optionDetailsRef.current.list.length - 1) {
newIndex = 0;
}
const newOptionDetail = optionDetailsRef.current.list[newIndex];
AIChange(newOptionDetail.value, newOptionDetail);
}
else if (types.isMultiple) {
let { maxLength } = props, newValue;
value = value || [];
if (value.indexOf(optionDetail.value) === -1) {
newValue = value.concat(optionDetail.value);
}
else {
newValue = value.filter((o) => o !== optionDetail.value);
}
while (!!maxLength && newValue.length > maxLength) {
newValue = newValue.slice(1, newValue.length);
}
AIChange(newValue, optionDetail);
}
else {
if (optionDetail.value !== props.value) {
AIChange(optionDetail.value, optionDetail);
}
else if (props.deSelect) {
if (type === 'radio' || type === 'tabs' || type === 'buttons' || type === 'panels') {
AIChange(undefined, optionDetail);
}
}
}
}
if (close) {
closePopup();
}
}
function tagClick(optionDetail, isRemove) {
var _a, _b;
if (props.disabled === true || optionDetail.disabled === true) {
return;
}
const propsValue = props.value || [];
let newValue = [];
if (isRemove !== false) {
if (props.type === 'tags') {
newValue = propsValue.filter((rpv, i) => rpv !== undefined && i !== optionDetail.index);
}
else if (props.type === 'file') {
if (props.multiple) {
newValue = propsValue.filter((rpv) => rpv.name !== optionDetail.value);
}
else {
newValue = undefined;
}
}
else {
newValue = propsValue.filter((rpv) => rpv !== optionDetail.value);
}
AIChange(newValue, optionDetail);
}
else if ((_a = optionDetail.tagAttrs) === null || _a === void 0 ? void 0 : _a.onClick) {
(_b = optionDetail.tagAttrs) === null || _b === void 0 ? void 0 : _b.onClick(optionDetail);
}
}
//inja kheili mohemme baraye inke chejoori option ha sakhte beshan type ha dastane khodeshoono daran baraye sakhtan option ha
//tags options nadare pas value ro be onvane options dar nazar migire
//date time options nadare pas dateDetails ro be onvane options dar nazar migire
function getOptionDetails() {
let optionOrgs = [];
if (type === 'date' || type === 'time') {
if (!props.multiple) {
return { list: [], dic: {} };
}
optionOrgs = dateValueDetails.map((o) => (Object.assign({}, o)));
}
else if (type === 'file') {
optionOrgs = getFileOptions(props.value);
}
else if (type === 'tags') {
optionOrgs = props.value || [];
}
else if (props.options) {
optionOrgs = props.options;
}
else {
optionOrgs = [];
}
return optionsHook.getOptions({ rootProps: props, optionOrgs, optionProp: props.option || {}, getOptionDetails: () => optionDetailsRef.current.list });
}
//use in mutiple date and time
function getDateValueDetails() {
if (!props.multiple || !types.isDate) {
return [];
}
const { value = [] } = props;
let values = Array.isArray(value) ? [...value] : (value !== undefined ? [value] : []);
return values.map((o) => dateHook.getDateDetails(o));
}
function getFileOptions(v) {
const value = !v ? [] : (Array.isArray(v) ? v : [v]);
return value.map((file) => {
let filename = file.name || 'untitle';
let fileSize = file.size || 0;
try {
const minName = UT.Ellipsis(filename, 20, 'center');
const sizeString = new UT.FileClass().SizeToString(fileSize);
const tagBefore = _jsx(FileIcon, { file: file }, file.name);
return { tagText: minName, tagSubtext: sizeString, tagBefore, value: filename };
}
catch (_a) {
return { tagText: 'untitle' };
}
});
}
const isDraggable = () => types.hasOption && !!props.onSwap;
const render = () => {
if (types.hasTags) {
return _jsx(HasTags, {});
} //date , time , select , file
if (types.isRootOptions) {
return _jsx(RootOptions, {});
} //tabs , buttons , tags , radio
if (types.isInput) {
return _jsx(Input_Input, {});
} //text , number , textarea , password, 'color'
if (type === 'range') {
return _jsx(Input_Range, {});
} //slider , 'spinner'
if (type === 'toggleButton') {
return _jsx(Input_ToggleButton, {});
}
if (type === 'mask') {
return _jsx(Input_Mask, {});
}
if (type === 'panels') {
return _jsx(Panels, {});
}
if (type === 'tree') {
return _jsx(Input_Tree, {});
}
if (type === 'list') {
return _jsx(List, {});
}
if (type === 'image') {
return _jsx(Input_Image, {});
}
return _jsx(AILayout, {});
};
useEffect(() => {
if (props.isSuggestion && isInputFocusedRef.current) {
const { options = [] } = props;
if (options.length) {
openPopover();
}
else {
closePopup();
}
}
}, [props.isSuggestion ? props.options : undefined]);
if (!type) {
return null;
}
const dateValueDetails = getDateValueDetails();
optionDetailsRef.current = getOptionDetails();
return (_jsxs(Provider, { value: {
changable, AIChange, optionDetails: optionDetailsRef.current, popup, setDomRef, getDomRef, dateHook, optionsHook, tagClick,
rootProps: Object.assign(Object.assign({}, props), { value }), datauniqid, touch: 'ontouchstart' in document.documentElement, isDraggable, openPopover,
click, optionClick, types, showPassword, setShowPassword, DATE, dateValueDetails, setInputFocused
}, children: [render(), " ", popup.render()] }));
}
// #endregion main
// #region types
function getTypes(props) {
function isDropdown() {
if (['select', 'date', 'time'].indexOf(type) !== -1) {
return true;
}
if (['text', 'number', 'textarea'].indexOf(type) !== -1 && props.options) {
return true;
}
if (type === 'button' && props.popover) {
return true;
}
return false;
}
let { type, multiple, optionsWrap = ['radio', 'select'].indexOf(type) !== -1 } = props;
let isMultiple;
if (type === 'tags') {
isMultiple = true;
}
else if (['radio', 'range', 'file', 'image', 'buttons', 'select', 'date', 'time', 'panels', 'tabs'].indexOf(type) !== -1) {
isMultiple = !!multiple;
}
else {
isMultiple = false;
}
;
return {
isDate: ['date', 'time'].indexOf(type) !== -1,
isMultiple,
isInput: ['text', 'number', 'textarea', 'password', 'color'].indexOf(type) !== -1,
isDropdown: isDropdown(),
hasOption: ['text', 'number', 'textarea', 'color', 'select', 'radio', 'tabs', 'list', 'buttons', 'tags'].indexOf(type) !== -1,
isRootOptions: ['radio', 'tabs', 'buttons', 'tags'].indexOf(type) !== -1,
ai_height: ['text', 'number', 'password', 'color', 'select', 'date', 'time', 'checkbox', 'file'].indexOf(type) !== -1,
hasPlaceholder: ['text', 'number', 'textarea', 'color', 'select', 'image', 'date', 'time'].indexOf(type) !== -1,
hasKeyboard: ['text', 'textarea', 'number', 'password'].indexOf(type) !== -1,
hasText: ['checkbox', 'button', 'select'].indexOf(type) !== -1,
hasSearch: ['select'].indexOf(type) !== -1,
hasWrap: !!optionsWrap,
hasTags: ['date', 'time', 'select', 'file'].indexOf(type) !== -1,
hasInlineDeSelect: ['text', 'number', 'date', 'time', 'select', 'file'].indexOf(type) !== -1
};
}
export const AIMask = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'mask' }));
export const AIText = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'text' }));
export const AINumber = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'number' }));
export const AITextarea = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'textarea' }));
export const AIPassword = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'password' }));
export const AIColor = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'color' }));
export const AIToggleButton = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'toggleButton' }));
export const AISelect = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'select' }));
export const AIMultiSelect = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'multiSelect' }));
export const AIRadio = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'radio' }));
export const AIMultiCheckbox = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'multiCheckbox' }));
export const AITabs = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'tabs' }));
export const AIButtons = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'buttons' }));
export const AIMultiButtons = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'multiButtons' }));
export const AITags = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'tags' }));
export const AITree = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'tree' }));
export const AIImage = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'image' }));
export const AIMultiImage = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'multiImage' }));
export const AIFile = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'file' }));
export const AIMultiFile = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'multiFile' }));
export const AICheckbox = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'checkbox' }));
export const AIDate = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'date' }));
export const AIMultiDate = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'multiDate' }));
export const AITime = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'time' }));
export const AIMultiTime = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'multiTime' }));
export const AIPanels = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'panels' }));
export const AIMultiPanels = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'multiPanels' }));
export const AIList = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'list' }));
export const AISlider = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'slider' }));
export const AIMultiSlider = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'multiSlider' }));
export const AISpinner = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'spinner' }));
export const AIMultiSpinner = (props) => _jsx(AIOInput, Object.assign({}, props, { type: 'multiSpinner' }));
// #endregion types
// #region layout
const useLayout = () => {
const { rootProps, click, optionClick, types, changable, AIChange, showPassword, setShowPassword, touch, datauniqid, popup, tagClick, isDraggable, optionDetails } = useProvider();
const getCheckbox = (optionDetail, isTag) => {
if (isTag) {
return null;
}
const { multiple, type, checkIcon } = rootProps;
const hasCheckbox = !!optionDetail ? typeof optionDetail.checked === 'boolean' : rootProps.type === 'checkbox';
if (!hasCheckbox) {
return null;
}
const checked = !!optionDetail ? optionDetail.checked : !!rootProps.value;
if (rootProps.switchOptions) {
return _jsx(Switch, { value: rootProps.value, switchOptions: rootProps.switchOptions });
}
return (_jsx(CheckIcon, { round: !multiple && type === 'radio', checked: checked, checkIcon: optionDetail ? optionDetail.checkIcon : checkIcon }));
};
const getDragIcon = (optionDetail) => {
if (!isDraggable() || !optionDetail) {
return null;
}
const d = "M9,3H11V5H9V3M13,3H15V5H13V3M9,7H11V9H9V7M13,7H15V9H13V7M9,11H11V13H9V11M13,11H15V13H13V11M9,15H11V17H9V15M13,15H15V17H13V15M9,19H11V21H9V19M13,19H15V21H13V19Z";
return (_jsx("svg", { viewBox: "8 4 10 13", role: "presentation", style: { width: 12, height: '1.8rem' }, children: _jsx("path", { d: d, style: { fill: 'currentcolor' } }) }));
};
const getBefore = (optionDetail, isTag, indent) => {
const before = isTag ? (optionDetail === null || optionDetail === void 0 ? void 0 : optionDetail.tagBefore) || new UT.GetSvg('em').getIcon('mdiCircleMedium', 0.7) : (optionDetail ? optionDetail === null || optionDetail === void 0 ? void 0 : optionDetail.before : rootProps.before);
const dragIcon = getDragIcon(optionDetail);
const Indent = (!!indent && indent !== null) ? indent : null;
const Checkbox = getCheckbox(optionDetail, isTag);
const FileIconNode = rootProps.type === 'file' && !rootProps.multiple && !!rootProps.value ? _jsx(FileIcon, { file: rootProps.value }) : null;
const res = [
dragIcon,
Indent,
Checkbox,
before,
FileIconNode
].filter((o) => o !== undefined && o !== null && !!o);
if (!res.length) {
return null;
}
return _jsx("div", { className: "aio-input-before", children: res.map((o, i) => _jsx(Fragment, { children: o }, 'layoutbefore' + i)) });
};
const getAfter = (optionDetail, isTag) => {
const after = isTag ? optionDetail === null || optionDetail === void 0 ? void 0 : optionDetail.tagAfter : (optionDetail ? optionDetail === null || optionDetail === void 0 ? void 0 : optionDetail.after : rootProps.after);
const hasDeselect = !rootProps.multiple && !!rootProps.deSelect && types.hasInlineDeSelect && !optionDetail && !!changable && rootProps.value !== undefined && rootProps.value !== null && rootProps.value !== '';
const hasPreview = !!rootProps.preview && !optionDetail && !!changable && rootProps.type === 'password';
const hasTagRemove = !!isTag && !!changable;
function getCaret() {
if (isTag || !types.isDropdown || optionDetail || (types.isInput && !rootProps.options)) {
return null;
}
let { caret } = rootProps;
if (caret === false) {
return null;
}
return _jsx("div", { className: 'aio-input-caret', children: caret === undefined ? new UT.GetSvg('em').getIcon('mdiChevronDown', .8) : caret });
}
const res = [
after,
hasDeselect ? _jsx("div", { className: 'aio-input-deSelect', onClick: (e) => {
e.stopPropagation();
e.preventDefault();
AIChange(undefined, undefined);
}, children: new UT.GetSvg('em').getIcon('mdiClose', .8) }, `afterdeselect`) : null,
hasPreview ? _jsx("div", { className: 'aio-input-password-preview', onClick: () => setShowPassword(), children: new UT.GetSvg('em').getIcon(showPassword ? 'mdiEyeOff' : 'mdiEye', .8) }, `afterpreview`) : null,
hasTagRemove ? _jsx("div", { className: `aio-input-tag-icon aio-input-tag-remove`, onClick: (e) => { e.stopPropagation(); tagClick(optionDetail, true); }, children: new UT.GetSvg('em').getIcon('mdiClose', 0.7) }) : null,
getCaret()
].filter((o) => o !== undefined && o !== null);
if (!res.length) {
return null;
}
return _jsx(_Fragment, { children: res.map((o, i) => _jsx("div", { className: "aio-input-after", children: o }, 'layoutafter' + i)) });
};
const getClassName = (optionDetail, isTag) => {
const { type, rtl, round, vertical } = rootProps;
const disabled = rootProps.disabled || (optionDetail === null || optionDetail === void 0 ? void 0 : optionDetail.disabled);
const res = [];
if (optionDetail) {
if (optionDetail.className) {
res.push(optionDetail.className);
}
if (isTag) {
res.push(`aio-input-tag ai-padding-sm ai-border-radius-sm aio-input-${type}-tag`);
res.push('aio-input-active-bgcolor');
}
else {
res.push(`aio-input-option ai-border-radius-md aio-input-${type}-option ai-height ai-padding-md ai-padding-h`);
if (types.isDropdown) {
res.push(`aio-input-dropdown-option`);
}
if (optionDetail.active === true) {
res.push('active');
if (type === 'tabs') {
res.push('aio-input-active-color');
}
if (type === 'buttons') {
res.push('aio-input-active-bgcolor');
}
if (type === 'toggleButton') {
res.push('aio-input-active-bgcolor');
}
}
if (optionDetail.justify === true) {
res.push('aio-input-option-justify');
}
if (type === 'tree') {
let size = rootProps.size || 36;
size = Math.round(size / 12) * 12;
if (size < 24) {
size = 24;
}
if (size > 120) {
size = 120;
}
res.push(`aio-input-size-${size}`);
}
}
}
else {
if (rootProps.className) {
res.push(rootProps.className);
}
res.push(`aio-input`);
if (['radio', 'buttons', 'tabs'].indexOf(rootProps.type) === -1) {
res.push(`ai-padding-md`);
}
res.push('ai-border-radius-md');
res.push(`aio-input-${type}`);
if (touch) {
res.push('aio-input-touch');
}
if (types.isInput) {
res.push(`aio-input-input`);
}
if (type === 'select' && rootProps.multiple && !rootProps.hideTags) {
res.push('aio-input-multiselect');
}
if (types.ai_height) {
res.push(`ai-height ai-padding-h`);
}
if (rootProps.justify) {
res.push('aio-input-justify');
}
res.push(rtl ? 'aio-input-rtl' : 'aio-input-ltr');
if (!!popup.getModals().length && ['text', 'number', 'textarea'].indexOf(type) !== -1) {
res.push('z-index-input');
}
if (type === 'range') {
if (round) {
res.push('aio-input-range-round');
}
if (vertical) {
res.push('aio-input-range-vertical');
}
else {
res.push('aio-input-range-horizontal');
}
}
}
if (disabled === true) {
res.push('disabled');
}
if (datauniqid) {
res.push(datauniqid);
}
return res.join(' ');
};
const getStyle = (optionDetail) => {
const style = (optionDetail ? optionDetail === null || optionDetail === void 0 ? void 0 : optionDetail.style : rootProps.style) || {};
if (rootProps.type === 'list' && optionDetail) {
style.height = rootProps.size || 36;
}
return style;
};
const keyDown = (e) => {
const code = e.keyCode;
if (code === 13) {
click(e);
}
};
const getAttrs = (optionDetail, isTag) => {
const disabled = rootProps.disabled || (optionDetail === null || optionDetail === void 0 ? void 0 : optionDetail.disabled);
let attrs;
if (isTag) {
attrs = optionDetail === null || optionDetail === void 0 ? void 0 : optionDetail.tagAttrs;
}
else if (optionDetail) {
attrs = optionDetail.attrs;
}
else {
attrs = rootProps.attrs;
}
return UT.AddToAttrs(attrs, {
className: getClassName(optionDetail, isTag),
style: getStyle(optionDetail),
attrs: {
onClick: disabled === true ? undefined : (e) => {
e.stopPropagation();
if (optionDetail) {
if (isTag) {
tagClick(optionDetail, false);
}
else {
optionClick(optionDetail);
}
}
else {
click(e);
}
},
"data-index": optionDetail === null || optionDetail === void 0 ? void 0 : optionDetail.index,
onKeyDown: (e) => keyDown(e),
}
});
};
const getText = (optionDetail, isTag) => {
const { type } = rootProps;
if (optionDetail) {
if (isTag && optionDetail.tagText !== undefined) {
return optionDetail.tagText;
}
return optionDetail.text;
}
else {
if (rootProps.type === 'select' && !rootProps.multiple) {
if (rootProps.text !== undefined) {
return rootProps.text;
}
if (rootProps.value !== null && rootProps.value !== undefined) {
const option = optionDetails.dic[`a${rootProps.value}`];
if (option) {
return option.text;
}
}
}
if (rootProps.type === 'mask') {
return _jsx(AIMaskComponent, {});
}
if (type === 'tags') {
return _jsx(Options, { isTag: true });
}
else {
return rootProps.text;
}
}
};
const getSubtext = (optionDetail, isTag) => {
if (optionDetail) {
if (isTag && optionDetail.tagSubtext !== undefined) {
return optionDetail.tagSubtext;
}
return optionDetail.subtext;
}
else {
return rootProps.subtext;
}
};
return { getText, getSubtext, getBefore, getAfter, getAttrs };
};
const AILayout = (props) => {
const { isTag, optionDetail, indent, html } = props;
const { rootProps } = useProvider();
const layout = useLayout();
return (_jsx(Layout, { optionDetail: optionDetail, html: html, text: props.text || layout.getText(optionDetail, isTag), subtext: layout.getSubtext(optionDetail, isTag), before: layout.getBefore(optionDetail, isTag, indent), after: layout.getAfter(optionDetail, isTag), attrs: layout.getAttrs(optionDetail, isTag), placeholder: rootProps.placeholder, justify: optionDetail ? optionDetail.justify : rootProps.justify }));
};
const Layout = (props) => {
let { rootProps, setDomRef } = useProvider();
let { optionDetail, html } = props;
let { type } = rootProps;
let [dom] = useState(createRef());
// const [recognition, setRecognition] = useState<any>()
// useEffect(() => {
// if (!('webkitSpeechRecognition' in window)) { return }
// let { voice } = rootProps;
// if (!voice || !changable || !types.hasKeyboard) { return }
// // @ts-ignore
// const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
// if (!SpeechRecognition) { return }
// const recognition = new SpeechRecognition();
// recognition.lang = { en: 'en-US', fa: 'fa-IR' }[voice];
// recognition.continuous = true;
// recognition.interimResults = false;
// recognition.onresult = (event: any) => {
// const result = event.results[0][0].transcript;
// AIChange(result, undefined);
// };
// recognition.onerror = (event: any) => {
// console.error('خطا در تشخیص گفتار: ', event.error);
// };
// recognition.onend = () => {
// console.log('تشخیص گفتار پایان یافت.');
// };
// setRecognition(recognition)
// return () => { recognition.stop(); };
// }, []);
function cls(key, hasSubtext) {
let className = `aio-input-${key}`;
if (optionDetail) {
className += ` aio-input-${type}-option-${key}`;
}
else {
className += ` aio-input-${type}-${key}`;
}
if (hasSubtext) {
className += ` aio-input-has-subtext`;
}
return className;
}
function Text() {
let { text, placeholder, justify, subtext } = props;
if (text === undefined && placeholder !== undefined) {
text = _jsx("div", { className: 'aio-input-placeholder', children: placeholder });
}
if (text !== undefined) {
const className = `${cls('value', !!subtext)}${justify ? ' aio-input-value-justify' : ''}`;
return _jsx("div", { className: className, "data-subtext": subtext, children: text });
}
else if (type === 'checkbox') {
return null;
}
else {
return _jsx("div", { style: { flex: 1 } });
}
}
// function startVoice() {
// recognition.start();
// }
// function voice() {
// if (!recognition) { return null }
// return <div className='aio-input-voice' onClick={() => startVoice()}>{I('mdiMicrophoneOutline', 0.8)}</div>
// }
let content = (_jsxs(_Fragment, { children: [!!props.before && props.before, Text(), !!props.after && props.after, html !== undefined && html] }));
if (!optionDetail) {
setDomRef(dom);
}
return (_jsx("label", Object.assign({ tabIndex: optionDetail ? undefined : 1, ref: dom }, props.attrs, { children: content })));
};
const HasTags = () => {
let { rootProps, optionDetails, dateHook } = useProvider();
const { type, value, multiple, hideTags } = rootProps;
const getOptionDetails = () => {
if (!multiple || hideTags) {
return [];
}
if (type === 'select') {
let values = Array.isArray(value) ? [...value] : (value !== undefined ? [value] : []);
if (!values.length) {
return [];
}
return values.map((o) => optionDetails.dic['a' + o]);
}
if (type === 'date' || type === 'time' || type === 'file') {
return optionDetails.list;
}
return [];
};
const getOptions = () => {
const optionDetails = getOptionDetails();
return !optionDetails.length ? null : _jsx(Options, { isTag: true, optionDetails: getOptionDetails() });
};
const getText = () => {
var _a;
if (rootProps.text) {
return rootProps.text;
}
if (type === 'date' || type === 'time') {
return _jsx("div", { style: { direction: 'ltr', width: 'fit-content' }, children: dateHook.getDateText(rootProps.value, true) });
}
if (type === 'select') {
return (_a = optionDetails.dic['a' + rootProps.value]) === null || _a === void 0 ? void 0 : _a.text;
}
if (type === 'file') {
if (!!rootProps.value) {
try {
return rootProps.value.name;
}
catch (_b) { }
}
}
};
const options = getOptions();
const text = getText();
const html = type === 'file' ? _jsx(InputFile, {}) : undefined;
return options === null ? _jsx(AILayout, { html: html, text: text }) : _jsxs("div", { className: 'aio-input-multiselect-container', children: [_jsx(AILayout, { text: text, html: html }), options] });
};
const RootOptions = () => _jsx(AILayout, { text: _jsx(Options, {}) });
const Input_Input = () => _jsx(AILayout, { text: _jsx(Input, {}) });
const Input_Range = () => {
const { rootProps: props } = useProvider();
return (_jsx(AIRangeComponent, { fill: props.fill, grooveAttrs: props.grooveAttrs, point: props.point, ranges: props.ranges, start: props.start, end: props.end, max: props.max, min: props.min, step: props.step, labels: props.labels, size: props.size, handle: props.handle, rotate: props.rotate, round: props.round, reverse: props.reverse, vertical: props.vertical, rangesDisabled: props.rangesDisabled, className: props.className, style: props.style, attrs: props.attrs, disabled: props.disabled, text: props.text, value: props.value, onChange: props.onChange, multiple: props.multiple }));
};
const Input_Tree = () => {
const { rootProps } = useProvider();
function getProps() {
const props = rootProps;
return {
size: rootProps.size || 36,
indent: props.indent || 24,
value: props.value || [],
actions: props.actions,
addText: props.addText,
onAdd: props.onAdd,
onRemove: props.onRemove,
onToggle: props.onToggle,
removeText: props.removeText,
setChilds: props.setChilds,
onChange: props.onChange || (() => { }),
option: props.option,
attrs: props.attrs,
className: props.className,
rtl: props.rtl,
style: props.style,
};
}
return _jsx(AITreeComponent, Object.assign({}, getProps()));
};
const Input_Mask = () => _jsx(AILayout, { text: _jsx(AIMaskComponent, {}) });
const Input_ToggleButton = () => {
const { optionDetails, rootProps } = useProvider();
let option = optionDetails.list.find((o) => rootProps.value !== undefined && o.value === rootProps.value) || optionDetails.list[0];
return !option ? null : _jsx(AILayout, { optionDetail: option });
};
export const CheckIcon = (props) => {
if (props.checked === undefined) {
return null;
}
if (Array.isArray(props.checkIcon)) {
return _jsx(_Fragment, { children: props.checkIcon[props.checked === false ? 0 : 1] || null });
}
return (_jsx("div", { className: 'aio-input-check-out aio-input-active-color' + (props.checked ? ' checked' : '') + (props.round ? ' aio-input-check-round' : ''), style: { background: 'none' }, children: _jsx("div", { className: 'aio-input-active-bg aio-input-check-in' }) }));
};
const Switch = ({ value = false, switchOptions = {} }) => {
const { rootProps } = useProvider();
const { onChange = () => { } } = rootProps;
const { textButton = null, textOff = null, textOn = null, bgOn, bgOff, colorOn, colorOff, groove, size, width, attrs } = switchOptions || {};
const Attrs = UT.AddToAttrs(attrs, { className: ['aio-input-switch', !!value ? 'active' : ''], style: { fontSize: size, width, background: !!value ? bgOn : bgOff }, attrs: { onClick: () => onChange(!value) } });
const buttonAttrs = UT.AddToAttrs({}, { className: ['aio-input-switch-button', !!value ? 'active' : ''], style: { background: !!value ? colorOn : colorOff } });
return (_jsxs("div", Object.assign({}, Attrs, { children: [_jsx("div", { className: "aio-input-switch-off-content", children: _jsx("div", { className: "aio-input-switch-text", children: textOff }) }), _jsx("div", { className: "aio-input-switch-on-content", children: _jsx("div", { className: "aio-input-switch-text", children: textOn }) }), !!groove && _jsx("div", { className: "aio-input-switch-groove" }), _jsx("div", Object.assign({}, buttonAttrs, { children: textButton }))] })));
};
// #endregion layout
// #region input
const Input = () => {
const { rootProps, types, showPassword, optionDetails, AIChange, changable, setInputFocused } = useProvider();
const { type, delay = 500 } = rootProps;
const { maxLength = Infinity, spin = true } = rootProps;
let { filter = [] } = rootProps;
let [dom] = useState(createRef());
let [temp] = useState({ atimeout: undefined, btimeout: undefined, clicked: false });
let [datauniqid] = useState(`ac${Math.round(Math.random() * 100000)}`);
let [value, setValue] = useState(rootProps.value || '');
let valueRef = useRef(value);
const getRef = () => {
const { inputAttrs = {} } = rootProps;
if (inputAttrs.ref) {
return inputAttrs.ref;
}
return dom;
};
valueRef.current = value;
function setSwip() {
if (type === 'number' && rootProps.swip) {
new UT.Swip({
speedY: rootProps.swip * 0.2, reverseY: true, minY: rootProps.min, maxY: rootProps.max,
stepY: rootProps.swip,
dom: () => {
const ref = getRef();
if (ref !== null && ref.current !== null) {
const res = $(ref.current);
return res;
}
},
start: () => {
let vref = +valueRef.current;
vref = isNaN(vref) ? 0 : vref;
return [0, vref];
},
move: (p) => {
let { y } = p.change || { y: 0 };
if (rootProps.min !== undefined && y < rootProps.min) {
y = rootProps.min;
}
if (rootProps.max !== undefined && y > rootProps.max) {
y = rootProps.max;
}
change(y);
}
});
}
}
useEffect(() => { setSwip(); }, []);
function getValidValue() {
let v = rootProps.value;
if (type === 'number') {
if (v === '') {
return undefined;
} //important because +('') is 0
else if (!isNaN(+v)) {
v = +v;
if (typeof rootProps.min === 'number' && v < rootProps.min) {
v = rootProps.min;
}
else if (typeof rootProps.max === 'number' && v > rootProps.max) {
v = rootProps.max;
}
}
}
return v;
}
function update() {
clearTimeout(temp.atimeout);
temp.atimeout = setTimeout(() => {
let v = getValidValue();
if (v !== value) {
setValue(v);
}
}, delay);
}
useEffect(() => { update(); }, [rootProps.value]);
function change(value) {
if (!changable) {
return;
}
if (!Array.isArray(filter)) {
filter = [];
}
if (types.hasKeyboard) {
value = UT.keyboard_filter(value, { maxLength, filter, toPersian: true });
}
if (rootProps.type === 'number') {
if (value === '') {
value = undefined;
}
else {
value = +value;
}
}
setValue(value);
if (!rootProps.blurChange) {
clearTimeout(temp.btimeout);
temp.btimeout = setTimeout(() => AIChange(value, undefined), delay);
}
}
function click() {
if (rootProps.autoHighlight === false) {
return;
}
if (temp.clicked) {
return;
}
temp.clicked = true;
$(getRef().current).focus().select();
}
function blur() {
temp.clicked = false;
setInputFocused(false);
if (rootProps.blurChange && changable) {
AIChange(value, undefined);
}
}
function inputFocus() {
setInputFocused(true);
}
function getInputAttrs() {
let InputAttrs = UT.AddToAttrs(rootProps.inputAttrs, {
className: !spin ? 'no-spin' : undefined,
style: rootProps.justify ? { textAlign: 'center' } : undefined
});
let p = Object.assign(Object.assign({}, InputAttrs), { ref: getRef(), value, type, disabled: rootProps.disabled, placeholder: rootProps.placeholder, list: rootProps.options ? datauniqid : undefined, onClick: () => click(), onChange: (e) => change(e.target.value), onBlur: () => blur(), onFocus: () => inputFocus() });
if (type === 'password' && showPassword) {
p = Object.assign(Object.assign({}, p), { type: 'text', style: Object.assign(Object.assign({}, p.style), { textAlign: 'center' }) });
}
if (filter.length === 1 && filter[0] === 'number') {
p.pattern = "\d*";
p.inputMode = "numeric";
}
return p;
}
let attrs = getInputAttrs();
if (type === 'color') {
return (_jsxs("label", { style: { width: '100%', height: '100%', background: value }, children: [_jsx("input", Object.assign({}, attrs, { style: { opacity: 0 } })), !!optionDetails.list.length && _jsx("datalist", { id: datauniqid, children: optionDetails.list.map((o) => _jsx("option", { value: o.value })) })] }));
}
else if (type === 'textarea') {
return _jsx("textarea", Object.assign({}, attrs));
}
else {
return (_jsx("input", Object.assign({}, attrs)));
}
};
export const useForm = (p) => {
const initDataRef = useRef(JSON.parse(JSON.stringify(p.data)));
const initDataStringRef = useRef(JSON.stringify(p.data));
const tagsResultRef = useRef([]);
const fieldChangesRef = useRef({});
const getChanges = () => {
return Object.keys(fieldChangesRef.current).map((field) => fieldChangesRef.current[field]);
};
const getInput = (input) => {
const { option = {} } = p;
const obj = {};
for (let prop in option) {
if (prop === 'validate') {
continue;
}
obj[prop] = option[prop]({ field: input.field, data: dataRef.current });
}
return Object.assign(Object.assign({}, obj), input);
};
const getTag = (param) => {
const change = (v) => {
const error = errorHook.getErrorByInput(input, v);
if (!error) {
changeByInput(input, v, error);
}
};
let valuePresent = '';
const { value, input, disabled } = param;
if (!input.tag) {
return;
}
let label = input.tag === true ? input.label : input.tag;
if ((value === undefined || value === null || value === '') && input.type !== 'checkbox') {
return;
}
if (input.type === 'date') {
const { dateUnit = 'day', jalali } = input;
if (dateUnit === 'month') {
valuePresent = new AIODate().getDateByPattern(value, '{year}/{month}', jalali);
}
else if (dateUnit === 'day') {
valuePresent = new AIODate().getDateByPattern(value, '{year}/{month}/{day}', jalali);
}
}
else if (input.type === 'time') {
const { timeUnit = { year: true, month: true, day: true }, jalali } = input;
valuePresent = new AIODate().getDateByPattern(value, `{year}/{month}/{day}${timeUnit.hour ? ` - {hour} : ${timeUnit.minute ? '{minute}' : '00'}` : ''}`, jalali);
}
else if (['radio', 'select', 'buttons', 'toggleButton'].indexOf(input.type) !== -1) {
const { options = [] } = input;
if (input.multiple) {
if (!Array.isArray(value) || !value.length) {
return;
}
valuePresent = options.filter((o) => value.indexOf(o.value) !== -1).map((o) => o.text).join(' | ');
}
else {
valuePresent = options.find((o) => o.value === value).text;
}
}
else if (input.type === 'checkbox') {
valuePresent = input.text || input.label;
label = (_jsx("div", { className: "ai-tag-checkbox", onClick: () => change(!value), children: _jsx(CheckIcon, { checked: !!value }) }));
}
else if (typeof value === 'number') {
valuePresent = UT.SplitNumber(value)