UNPKG

aio-input

Version:

generate all input types in react j

1,154 lines 171 kB
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, isValidElement } from 'react'; import usePopup from "aio-popup"; import * as UT from 'aio-utils'; import AIODate from 'aio-date'; import $ from 'jquery'; import './index.css'; const AICTX = createContext({}); const AIOInput = (props) => { let type = props.type, round = props.round; let value = props.value; if (type === 'text') { if (typeof value !== 'string') { value = ''; } } else if (type === 'number') { if (typeof value !== 'number') { value = undefined; } } if (type === 'spinner') { type = 'range'; if (!round || typeof round !== 'number') { round = 1; } } else if (type === 'slider') { type = 'range'; round = 0; } else if (type === 'range') { return null; } let rootProps = Object.assign(Object.assign({}, props), { type, round, value }); if (type === 'text' && rootProps.getOptions) { return _jsx(SuggestionInput, Object.assign({}, rootProps)); } return _jsx(AIOINPUT, Object.assign({}, rootProps)); }; export default AIOInput; export const SuggestionInput = (props) => { const { getOptions, option = {}, onChange } = props; const [searchResult, SetSearchResult] = useState([]); const [value, setValue] = useState(props.value || ''); useEffect(() => { setValue(props.value); }, [props.value]); const initSearchResult = () => __awaiter(void 0, void 0, void 0, function* () { setSearchResult(value); }); useEffect(() => { initSearchResult(); }, []); function setSearchResult(newValue) { return __awaiter(this, void 0, void 0, function* () { setValue(newValue); const res = getOptions ? yield getOptions(newValue) : []; SetSearchResult(res); }); } return (_jsx(AIText, Object.assign({}, props, { value: value, options: searchResult, option: Object.assign(Object.assign({}, option), { onClick: (optionOrg, optionDetails) => { const text = GetOptionProps({ optionProp: option, key: 'text', optionDetails, optionOrg }); setSearchResult(text); if (onChange) { onChange(text, optionOrg); } } }), getOptions: undefined, onChange: (newValue) => { setSearchResult(newValue); if (onChange) { onChange(newValue); } } }))); }; function AIOINPUT(props) { let [types] = useState(getTypes(props)); let [DATE] = useState(new AIODate()); props = getDefaultProps(props, types); let { type, value, onChange, attrs = {}, rtl } = props; let [parentDom] = useState(createRef()); let [datauniqid] = useState('aiobutton' + (Math.round(Math.random() * 10000000))); let popup = usePopup({ rtl: props.rtl }); let [showPassword, SetShowPassword] = useState(false); function setShowPassword(state) { SetShowPassword(state === undefined ? !showPassword : state); } const DragOptions = UT.useDrag((fromData, toData, reOrder) => { if (typeof props.onSwap === 'function') { const { fromIndex } = fromData; const { options, toIndex } = toData; const sorted = reOrder(options, fromIndex, toIndex); props.onSwap(sorted, options[fromIndex], options[toIndex]); } }, 'aio-input-option'); function getPopover(dom) { let className = 'aio-input-popover'; className += ` aio-input-popover-${rtl ? 'rtl' : 'ltr'}`; if (types.hasOption) { className += ' aio-input-dropdown'; } if (props.type === 'time') { className += ' aio-input-time-popover'; } const popover = (props.popover || {}); let body = null; if (popover.body) { body = popover.body; } else if (type === 'date') { body = _jsx(Calendar, { onClose: popup.removeModal }); } else if (type === 'time') { body = _jsx(TimePopover, { onClose: popup.removeModal }); } else { if (context.options.optionsList.length === 0) { return; } body = _jsx(Options, {}); } let obj = Object.assign(Object.assign({}, (props.popover || {})), { position: popover.position || 'popover', fitHorizontal: ['text', 'number', 'textarea'].indexOf(type) !== -1 || (type === 'select' && !!props.multiple) || !!popover.fitHorizontal, onClose: () => closePopup(), body, getTarget: () => $(dom.current), setAttrs: (key) => { let attrs = (popover.setAttrs || (() => { return {}; }))(key); if (key === 'modal') { return UT.AddToAttrs(attrs, { className }); } return attrs; } }); return obj; } function closePopup() { popup.removeModal(); setTimeout(() => $(parentDom.current).focus(), 0); } function click(e, dom) { if (type === 'checkbox') { if (onChange) { onChange(!value, e); } } else if (types.isDropdown) { let open = !!popup.getModals().length; if (open) { return; } const popover = getPopover(dom); if (!popover) { return; } popup.addModal(popover); } else if (typeof props.onClick === 'function') { props.onClick(e); } else if (attrs.onClick) { attrs.onClick(); } } function optionClick(option) { let { attrs = {}, onClick, close } = option; if (onClick) { onClick(option.details); } else if (attrs.onClick) { attrs.onClick(option); } else if (onChange) { if (types.isInput) { /*do nothing*/ } else if (type === 'tree') { /*do nothing*/ } else if (type === 'file') { /*do nothing*/ } else if (types.isMultiple) { let { multiple } = props, newValue; if (value.indexOf(option.value) === -1) { newValue = value.concat(option.value); } else { newValue = value.filter((o) => o !== option.value); } while (typeof multiple === 'number' && newValue.length > multiple) { newValue = newValue.slice(1, newValue.length); } onChange(newValue, option.details); } else { if (option.value !== props.value) { onChange(option.value, option.details); } else if (props.deSelect === true) { onChange(undefined, option.details); } else if (typeof props.deSelect === 'function') { props.deSelect(); } } } if (close) { closePopup(); } } function getOptions() { let options = []; if (type === 'date') { if (!props.multiple) { return { optionsList: [], optionsDic: {} }; } options = [...props.value]; } else if (typeof props.options === 'function') { options = props.options(); } else if (props.options) { options = props.options; } else { options = []; } return GetOptions({ rootProps: props, types, options, optionProp: props.option || {} }); } function getContext() { let context = { options: getOptions(), popup, rootProps: Object.assign(Object.assign({}, props), { value }), datauniqid, touch: 'ontouchstart' in document.documentElement, DragOptions, click, optionClick, types, showPassword, setShowPassword, DATE }; return context; } function getRangeClassName() { let { round, vertical } = props; if (round) { return 'aio-input-range-round'; } if (vertical) { return 'aio-input-range-vertical'; } return 'aio-input-range-horizontal'; } const render = { spinner: () => null, slider: () => null, acardion: () => _jsx(Acardion, {}), tree: () => _jsx(Tree, {}), tags: () => _jsx(Layout, { properties: { text: _jsx(Tags, {}) } }), list: () => _jsx(List, {}), file: () => _jsx(File, {}), select: () => _jsx(Select, {}), checkbox: () => _jsx(Layout, {}), button: () => _jsx(Layout, {}), range: () => _jsx(Layout, { properties: { text: _jsx(Range, {}), className: getRangeClassName() } }), radio: () => _jsx(Layout, { properties: { text: _jsx(Options, {}) } }), tabs: () => _jsx(Layout, { properties: { text: _jsx(Options, {}) } }), buttons: () => _jsx(Layout, { properties: { text: _jsx(Options, {}) } }), date: () => _jsx(DateInput, {}), time: () => _jsx(Layout, { properties: { text: getTimeText(props) } }), image: () => _jsx(Image, {}), text: () => _jsx(Layout, { properties: { text: _jsx(Input, {}) } }), password: () => _jsx(Layout, { properties: { text: _jsx(Input, {}) } }), textarea: () => _jsx(Layout, { properties: { text: _jsx(Input, {}) } }), scanner: () => _jsx(ScannerInput, {}), number: () => _jsx(Layout, { properties: { text: _jsx(Input, {}) } }), color: () => _jsx(Layout, { properties: { text: _jsx(Input, {}) } }) }; if (!type || !render[type]) { return null; } const context = getContext(); return (_jsxs(AICTX.Provider, { value: context, children: [render[type](), " ", popup.render()] }, datauniqid)); } function TimePopover(props) { const { DATE, rootProps } = useContext(AICTX); const { jalali, onChange, size = 12 } = rootProps; const { onClose } = props; const [value, setValue] = useState(getTimeByUnit(rootProps)); const startYearRef = useRef(value.year ? value.year - 10 : undefined); const endYearRef = useRef(value.year ? value.year + 10 : undefined); const change = (obj) => setValue(Object.assign(Object.assign({}, value), obj)); function translate(key) { return !!jalali ? { 'year': 'سال', 'month': 'ماه', 'day': 'روز', 'hour': 'ساعت', 'minute': 'دقیقه', 'second': 'ثانیه', 'Submit': 'ثبت', 'Now': 'اکنون' }[key] : key; } function getTimeOptions(type) { var _a, _b, _c; let { year, month, day } = value; const sy = startYearRef.current, ey = endYearRef.current; if (type === 'year' && sy && ey) { return UT.GetArray(ey - sy + 1, (i) => ({ text: i + sy, value: i + sy }), (_a = rootProps.timeStep) === null || _a === void 0 ? void 0 : _a.year); } if (type === 'day' && day) { let length = !year || !month ? 31 : DATE.getMonthDaysLength([year, month]); if (day > length) { change({ day: 1 }); } return UT.GetArray(length, (i) => { return { text: i + 1, value: i + 1 }; }, (_b = rootProps.timeStep) === null || _b === void 0 ? void 0 : _b.day); } if (type === 'month') { return UT.GetArray(12, (i) => ({ text: i + 1, value: i + 1 }), (_c = rootProps.timeStep) === null || _c === void 0 ? void 0 : _c.month); } return UT.GetArray(type === 'hour' ? 24 : 60, (i) => ({ text: i, value: i }), rootProps.timeStep ? rootProps.timeStep[type] : undefined); } function layout(type) { if (typeof value[type] !== 'number') { return null; } let options = getTimeOptions(type); let p = { type: 'list', value: value[type], options, size: size * 2.5, onChange: (v) => change({ [type]: v }) }; return (_jsxs("div", { className: "aio-input-time-popover-item", children: [_jsx("div", { className: "aio-input-time-popover-item-title", children: translate(type) }), _jsx(AIOInput, Object.assign({}, p)), _jsx("div", { className: 'aio-input-time-popover-highlight' })] })); } function setValueByTimeStep(value) { return value; } function submit() { if (onChange) { onChange(setValueByTimeStep(value)); } onClose(); } function now() { setValue(getTimeByUnit(rootProps, true)); } return (_jsxs("div", { className: 'aio-input-time-popover-content aio-input-time-theme-color aio-input-time-theme-bg', style: { fontSize: size }, children: [_jsxs("div", { className: "aio-input-time-popover-body", children: [layout('year'), " ", layout('month'), " ", layout('day'), " ", layout('hour'), " ", layout('minute'), " ", layout('second')] }), _jsxs("div", { className: "aio-input-time-popover-footer", children: [_jsx("button", { onClick: submit, children: translate('Submit') }), rootProps.now !== false && _jsx("button", { onClick: () => now(), children: translate('Now') })] })] })); } const ImageCtx = createContext({}); const ImageProvider = (p) => _jsx(ImageCtx.Provider, { value: p.value, children: p.children }); const useImageCtx = () => useContext(ImageCtx); function Image() { let { rootProps } = useContext(AICTX); let { placeholder = 'placeholder', deSelect = true } = rootProps; const value = fixValue(); const popup = usePopup({ rtl: rootProps.rtl }); const editable = typeof rootProps.onChange === 'function' && !rootProps.disabled && !rootProps.loading; const [changeKey, setChangeKey] = useState(0); const [previewIndex, setPreviewIndex] = useState(0); let [urls, setUrls] = useState([]); const urlsRef = useRef(urls); urlsRef.current = urls; const piRef = useRef(previewIndex); piRef.current = previewIndex; const changePreviewIndex = (p) => { const previewIndex = piRef.current; if (p.index !== undefined) { setPreviewIndex(p.index); } if (p.dir) { let newPreviewIndex = previewIndex + p.dir; if (newPreviewIndex < 0) { newPreviewIndex = urls.length - 1; } if (newPreviewIndex >= urls.length) { newPreviewIndex = 0; } setPreviewIndex(newPreviewIndex); } }; function fixValue() { let { value = [] } = rootProps; if (!value || value === null) { value = []; } if (!Array.isArray(value)) { value = [value]; } value = value.filter((v) => !!v && v !== null); return value; } const add = (v) => __awaiter(this, void 0, void 0, function* () { if (!editable) { return; } const onChange = rootProps.onChange; setChangeKey(changeKey + 1); const newUrls = [...urls]; const files = []; for (let i = 0; i < v.length; i++) { const url = yield UT.File2Url(v[i]); if (newUrls.indexOf(url) === -1) { newUrls.push(url); files.push(v[i]); } } if (rootProps.multiple) { onChange(newUrls, files); } else { onChange(newUrls[0], files[0]); } }); const remove = (url) => __awaiter(this, void 0, void 0, function* () { if (!editable) { return; } const onChange = rootProps.onChange; setChangeKey(changeKey + 1); const newUrls = urlsRef.current.filter((o) => o !== url); if (rootProps.multiple) { onChange(newUrls, []); } else { onChange(newUrls[0], []); } }); let dom = createRef(); useEffect(() => { updateUrls(); }, [rootProps.value]); function updateUrls() { return __awaiter(this, void 0, void 0, function* () { const urls = []; for (let i = 0; i < value.length; i++) { const url = yield UT.File2Url(value[i]); urls.push(url); } setUrls(urls); }); } function openPreviewPopup(e, url) { e.stopPropagation(); e.preventDefault(); popup.addModal({ position: 'center', header: { title: '', onClose: () => popup.removeModal() }, body: _jsx("div", { className: 'aio-input-image-preview-popup', children: _jsx("img", { src: url, width: '100%', alt: '' }) }) }); } function renderDeselect(thumbnailUrl, callback) { if (!thumbnailUrl) { if (!deSelect || !editable || rootProps.multiple) { return null; } } return (_jsx("div", { onClick: (e) => { e.stopPropagation(); e.preventDefault(); remove(thumbnailUrl || urls[0]); callback && callback(); }, className: 'aio-input-image-remove', children: I('mdiClose', 1) })); } const getPreviewUrl = () => urlsRef.current[piRef.current]; function renderPreviewButton(url) { if (!rootProps.preview || rootProps.multiple || !editable) { return null; } return _jsx("div", { onClick: (e) => openPreviewPopup(e, url), className: 'aio-input-image-preview', children: I('mdiImage', 1) }); } function openMultipleModal(e) { e.stopPropagation(); e.preventDefault(); popup.addModal({ position: 'center', header: { title: '', onClose: () => popup.removeModal() }, body: _jsx(AIImageMultipleModal, {}) }); } function renderInputFile(isAddBox) { if (!editable) { return null; } if (!isAddBox && rootProps.multiple) { return null; } return (_jsx("input", Object.assign({ type: 'file', multiple: !!isAddBox, style: { width: '100%', height: '100%', padding: 0, display: 'none' }, onChange: (e) => add(e.target.files) }, rootProps.inputAttrs), changeKey)); } const attrs = UT.AddToAttrs(rootProps.attrs, { style: Object.assign({ display: 'block' }, rootProps.style), className: ['aio-input aio-input-image', rootProps.className, rootProps.disabled === true ? 'disabled' : undefined] }); const renderPreview = () => { const imageAttrs = UT.AddToAttrs(rootProps.imageAttrs, { style: { objectFit: 'contain', height: '100%' }, attrs: { ref: dom, width: '100%' } }); if (rootProps.multiple) { return (_jsx(UT.AIOSwiper, { selectedIndex: previewIndex, changeSelectedIndex: (index) => changePreviewIndex({ index }), style: { height: '100%' }, options: urls, option: { text: (o) => _jsx("img", Object.assign({}, imageAttrs, { src: o, draggable: false })), onClick: (option, index, e) => openMultipleModal(e) } })); } return (_jsx("img", Object.assign({}, imageAttrs, { src: urls[piRef.current], onClick: (e) => { if (!editable && !!rootProps.preview) { openPreviewPopup(e, urls[0]); } } }))); }; const renderPlaceholder = () => { return (_jsx("span", { className: 'aio-input-image-placeholder', onClick: (e) => { if (!rootProps.multiple) { return; } openMultipleModal(e); }, children: placeholder })); }; return (_jsxs(ImageProvider, { value: { renderInputFile, changePreviewIndex, previewIndex: piRef.current, getPreviewUrl, urls: urlsRef.current, renderDeselect }, children: [_jsxs("label", Object.assign({}, attrs, { children: [!urls.length && renderPlaceholder(), !!urls.length && _jsxs(_Fragment, { children: [renderPreview(), renderDeselect(), renderPreviewButton(urls[0])] }), renderInputFile()] })), popup.render()] })); } const AIImageMultipleModal = () => { const { renderInputFile, getPreviewUrl, urls, previewIndex, changePreviewIndex, renderDeselect } = useImageCtx(); const previewUrl = getPreviewUrl(); const renderThumbnails = () => { return (_jsx("div", { className: "aio-input-image-thubmbnail", children: urls.map((url, i) => { const active = i === previewIndex; return (_jsxs("div", { className: `aio-input-image-modal-body-item${active ? ' active' : ''}`, onClick: () => changePreviewIndex({ index: i }), children: [_jsx("img", { src: url, alt: '' }), renderDeselect(url, () => changePreviewIndex({ index: 0 }))] }, i)); }) })); }; return (_jsxs("div", { className: "aio-input-image-modal", children: [_jsxs("div", { className: "aio-input-image-modal-header", children: [_jsxs("label", { className: 'aio-input-image-modal-body-item', children: [renderInputFile(true), " ", I('mdiPlusThick', 1)] }), renderThumbnails()] }), _jsxs("div", { className: "aio-input-image-modal-preview", style: { alignItems: previewUrl === undefined ? 'center' : 'flex-start' }, children: [previewUrl !== undefined && _jsx(UT.AIOSwiper, { selectedIndex: previewIndex, changeSelectedIndex: (index) => changePreviewIndex({ index }), options: urls, option: { text: (o) => { return _jsx("img", { src: o, alt: '', width: '100%', height: '100%', style: { objectFit: 'contain' }, draggable: false }); } } }) // <img src={previewUrl} alt={''} width='100%' height='100%' style={{objectFit:'contain'}} /> , previewUrl === undefined && _jsx("svg", { viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M10,14.29L6.5,19H17.46L14.75,15.46L12.78,17.8L10,14.29M5,21V7H18.96V21H5M12,2.4L14.61,5.03H9.37L12,2.4M5,5.03C4.5,5.03 4,5.22 3.61,5.61C3.2,6 3,6.46 3,7V21C3,21.5 3.2,22 3.61,22.39C4,22.8 4.5,23 5,23H18.96C19.5,23 19.96,22.8 20.37,22.39C20.77,22 21,21.5 21,21V7C21,6.46 20.77,6 20.37,5.61C19.96,5.22 19.5,5.03 18.96,5.03H16L12,1L7.96,5.03H5Z" }) })] })] })); }; function File() { return (_jsxs("div", { className: 'aio-input-file-container', children: [_jsx(Layout, {}), _jsx(FileItems, {})] })); } function InputFile() { let { rootProps, types } = useContext(AICTX); let { value = [], onChange = () => { }, disabled, multiple, inputAttrs } = rootProps; function change(e) { let Files = e.target.files; let result; if (types.isMultiple) { result = [...value]; let names = result.map(({ name }) => name); for (let i = 0; i < Files.length; i++) { let file = Files[i]; if (names.indexOf(file.name) !== -1) { continue; } result.push({ name: file.name, size: file.size, file }); } if (typeof multiple === 'number') { while (result.length > multiple) { result = result.slice(1, result.length); } } } else { result = Files.length ? Files[0] : undefined; } onChange(result); } let props = Object.assign({ disabled: disabled === true, type: 'file', style: { display: 'none' }, multiple: types.isMultiple, onChange: (e) => change(e) }, inputAttrs); return _jsx("input", Object.assign({}, props)); } function FileItems() { let { rootProps } = useContext(AICTX); let { value, rtl } = rootProps; let files = []; if (Array.isArray(value)) { files = value; } else if (value) { files = [value]; } else { return null; } if (!files.length) { return null; } let Files = files.map((file, i) => { return _jsx(FileItem, { file: file, index: i }, i); }); return (_jsx("div", { className: 'aio-input-files', style: { direction: rtl ? 'rtl' : 'ltr' }, children: Files })); } const FileItem = (props) => { let { rootProps, types } = useContext(AICTX); let { onChange = () => { }, value = [] } = rootProps; let { file, index } = props; function getFile(file) { let filename = file.name || 'untitle'; let fileSize = file.size || 0; let nameLength = 20; try { let minName, sizeString; let lastDotIndex = filename.lastIndexOf('.'); let name = filename.slice(0, lastDotIndex); let format = filename.slice(lastDotIndex + 1, filename.length); if (name.length > nameLength) { minName = name.slice(0, Math.floor(nameLength / 2)) + '...' + name.slice(name.length - Math.floor(nameLength / 2), name.length) + '.' + format; } else { minName = filename; } let size = fileSize; if (!size) { return { minName, sizeString: false }; } let gb = size / (1024 * 1024 * 1024), mb = size / (1024 * 1024), kb = size / 1024; if (gb >= 1) { sizeString = gb.toFixed(2) + ' GB'; } else if (mb >= 1) { sizeString = mb.toFixed(2) + ' MB'; } else if (kb >= 1) { sizeString = kb.toFixed(2) + ' KB'; } else { sizeString = size + ' byte'; } return { minName, sizeString }; } catch (_a) { return { minName: 'untitle', sizeString: false }; } } function remove(e, index) { return __awaiter(this, void 0, void 0, function* () { e.stopPropagation(); e.preventDefault(); if (typeof rootProps.onRemove === 'function') { const res = yield rootProps.onRemove({ row: value[index], rowIndex: index }); if (res === false) { return; } } let newValue = []; for (let i = 0; i < value.length; i++) { if (i === index) { continue; } newValue.push(value[i]); } onChange(newValue); }); } function download() { UT.DownloadFile(file); } function getIcon() { let filePreview; if (rootProps.preview) { filePreview = UT.FilePreview(file, { onClick: () => download() }); } if (filePreview && filePreview !== null) { return filePreview; } return (_jsx("div", { className: 'aio-input-file-item-icon', onClick: () => download(), children: I('mdiAttachment', .8) })); } let { minName, sizeString } = getFile(file); let { optionsList } = GetOptions({ rootProps, types, options: [{ minName, sizeString, index }], optionProp: Object.assign(Object.assign({}, rootProps.option), { subtext: () => sizeString, text: () => minName, before: () => getIcon(), after: () => _jsx("div", { className: 'aio-input-file-item-icon', onClick: (e) => remove(e, index), children: I('mdiClose', .7) }) }) }); let option = optionsList[0]; return _jsx(Layout, { option: option }); }; const Select = () => { let { rootProps, types, options } = useContext(AICTX); let { value } = rootProps; let values = Array.isArray(value) ? [...value] : (value !== undefined ? [value] : []); function getSelectText() { if (!values.length) { return; } let option = options.optionsDic['a' + values[0]]; if (!option) { return; } return option.text; } if (types.isMultiple) { return (_jsxs("div", { className: 'aio-input-multiselect-container', children: [_jsx(Layout, {}), !rootProps.hideTags && !!values.length && _jsx(Tags, {})] })); } else { return _jsx(Layout, { properties: { text: rootProps.text || getSelectText() } }); } }; const DateInput = () => { let { rootProps, types } = useContext(AICTX); let { value, hideTags, calendarMode } = rootProps; let values = Array.isArray(value) ? [...value] : (value !== undefined ? [value] : []); function getDateText() { let { value, unit = Def('date-unit'), text, pattern: PT, jalali, placeholder } = rootProps; if (value) { text = PT !== undefined ? PT : text; let DATE = new AIODate(); let list = DATE.convertToArray(value); let [year, month = 1, day = 1, hour = 0] = list; list = [year, month, day, hour]; let splitter = DATE.getSplitter(value); let content = ''; if (text && text !== null) { content = text; } else { let pattern = '{}'; if (unit === 'month') { pattern = `{year}${splitter}{month}`; } else if (unit === 'day') { pattern = `{year}${splitter}{month}${splitter}{day}`; } else if (unit === 'hour') { pattern = `{year}${splitter}{month}${splitter}{day} - {hour} : 00`; } content = DATE.getDateByPattern(list, pattern); } return _jsx("div", { style: { direction: 'ltr', width: 'fit-content' }, children: content }); } return placeholder || (!jalali ? 'Select Date' : 'انتخاب تاریخ'); } if (calendarMode) { return _jsx(Calendar, {}); } if (types.isMultiple) { return (_jsxs("div", { className: 'aio-input-multiselect-container', children: [_jsx(Layout, { properties: { text: rootProps.text || 'Select Dates' } }), !hideTags && !!values.length && _jsx(Tags, {})] })); } else { return _jsx(Layout, { properties: { text: getDateText() } }); } }; const Tags = () => { let { rootProps, options } = useContext(AICTX); let { value = [], rtl, disabled, onChange = () => { } } = rootProps; const [searchValue, setSearchValue] = useState(''); let tags = value.map((o, i) => { let option = options.optionsDic['a' + o]; if (!!searchValue) { if (typeof option.text === 'string') { if (option.text.indexOf(searchValue) === -1) { return null; } } else { return null; } } if (option === undefined) { return null; } return (_jsx(Tag, { onClose: () => onChange(rootProps.value.filter((rpv) => rpv !== o)), attrs: option.tagAttrs, before: option.tagBefore, after: option.tagAfter, text: option.text, disabled: option.disabled }, i)); }); if (!tags.length) { return null; } const className = `aio-input-tags-container aio-input-scroll${rtl ? ' rtl' : ''}${disabled ? ' disabled' : ''}`; return (_jsxs("div", { className: className, children: [_jsx(AISearch, { value: searchValue, onChange: (searchValue) => setSearchValue(searchValue), placeholder: rootProps.tagSearch }), tags] })); }; const Tag = (props) => { let { attrs, before = I('mdiCircleMedium', 0.7), after, text, disabled, onClose = () => { } } = props; let close = disabled ? undefined : onClose; let cls = 'aio-input-tag'; let Attrs = UT.AddToAttrs(attrs, { className: [cls + ' aio-input-main-bg', disabled ? 'disabled' : undefined] }); return (_jsxs("div", Object.assign({}, Attrs, { children: [_jsx("div", { className: `${cls}-icon ${cls}-before`, children: before }), _jsx("div", { className: `${cls}-text`, children: text }), after !== undefined && _jsx("div", { className: `${cls}-icon ${cls}-after`, children: after }), _jsx("div", { className: `${cls}-icon ${cls}-remove`, onClick: close, children: I('mdiClose', 0.7) })] }))); }; const Input = () => { const { rootProps, types, showPassword, options } = useContext(AICTX); 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, reverseY: true, minY: rootProps.min, maxY: rootProps.max, dom: () => $(getRef()), 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, rootProps.onChange); } }); } } 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, onChange) { 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 && onChange) { clearTimeout(temp.btimeout); temp.btimeout = setTimeout(() => onChange(value), delay); } } function click() { if (rootProps.autoHighlight === false) { return; } if (temp.clicked) { return; } temp.clicked = true; $(getRef().current).focus().select(); } function blur(onChange) { temp.clicked = false; if (rootProps.blurChange && onChange) { onChange(value); } } 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: rootProps.onChange ? (e) => change(e.target.value, rootProps.onChange) : undefined, onBlur: () => blur(rootProps.onChange) }); 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 (!attrs.onChange) { return value; } else if (type === 'color') { return (_jsxs("label", { style: { width: '100%', height: '100%', background: value }, children: [_jsx("input", Object.assign({}, attrs, { style: { opacity: 0 } })), !!options.optionsList.length && _jsx("datalist", { id: datauniqid, children: options.optionsList.map((o) => _jsx("option", { value: o.value })) })] })); } else if (type === 'textarea') { return _jsx("textarea", Object.assign({}, attrs)); } else { return (_jsx("input", Object.assign({}, attrs))); } }; const Options = () => { let { rootProps, types, options } = useContext(AICTX); let [searchValue, setSearchValue] = useState(''); let [dom] = useState(createRef()); const hasSearch = rootProps.type !== 'tabs' && rootProps.type !== 'buttons' && !types.isInput; function getRenderOptions(options) { return options.map((option, i) => { if (searchValue) { if (option.text === undefined || option.text === '' || option.text === null) { return null; } if (option.text.indexOf(searchValue) === -1) { return null; } } let p = { option, index: i, searchValue }; return _createElement(Layout, Object.assign({}, p, { key: i })); }); } useEffect(() => { try { setTimeout(() => $(dom.current).focus(), 30); } catch (_a) { } }, []); function keyDown(e) { const code = e.keyCode; if (code === 40) { } } if (!options.optionsList.length) { return null; } let renderOptions = getRenderOptions(options.optionsList); let className = `aio-input-options aio-input-scroll aio-input-${rootProps.type}-options`; if (types.isDropdown) { className += ' aio-input-dropdown-options'; } return (_jsxs("div", { className: 'aio-input-options-container', ref: dom, tabIndex: 0, onKeyDown: (e) => keyDown(e), children: [!!hasSearch && _jsx(AISearch, { value: searchValue, onChange: (searchValue) => setSearchValue(searchValue), placeholder: rootProps.search }), _jsx("div", { className: className, children: renderOptions })] })); }; const AISearch = ({ value, onChange, placeholder }) => { if (!placeholder) { return null; } return (_jsxs("div", { className: 'aio-input-search', children: [_jsx("input", { type: 'text', value: value, placeholder: placeholder, onChange: (e) => onChange(e.target.value) }), _jsx("div", { className: 'aio-input-search-icon', onClick: () => { onChange(''); }, children: I(value ? 'mdiClose' : 'mdiMagnify', .8) })] })); }; const CheckIcon = (props) => { if (props.checked === undefined) { return null; } if (props.checkIcon) { const res = props.checkIcon({ checked: props.checked, row: props.row, rootProps: props.rootProps }); return res === false ? null : _jsx(_Fragment, { children: res }); } if (props.switch) { return (_jsx(AISwitch, Object.assign({}, props.switch, { value: props.checked }))); } return (_jsx("div", { className: 'aio-input-check-out aio-input-main-color' + (props.checked ? ' checked' : '') + (props.round ? ' aio-input-check-round' : ''), style: { background: 'none' }, children: _jsx("div", { className: 'aio-input-main-bg aio-input-check-in' }) })); }; const Layout = (props) => { let { rootProps, datauniqid, types, touch, DragOptions, click, optionClick, showPassword, setShowPassword, popup } = useContext(AICTX); let { option, index } = props; let { type, rtl } = rootProps; let [dom] = useState(createRef()); const [recognition, setRecognition] = useState(); useEffect(() => { if (!('webkitSpeechRecognition' in window)) { return; } let { onChange, voice } = rootProps; if (!voice || !onChange || !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) => { const result = event.results[0][0].transcript; if (onChange) onChange(result); }; recognition.onerror = (event) => { console.error('خطا در تشخیص گفتار: ', event.error); }; recognition.onend = () => { console.log('تشخیص گفتار پایان یافت.'); }; setRecognition(recognition); return () => { recognition.stop(); }; }, []); function getClassName() { let cls; if (option !== undefined) { cls = `aio-input-option aio-input-${type}-option`; if (types.isMultiple) { cls += ` aio-input-${type}-multiple-option`; } if (types.isDropdown) { cls += ` aio-input-dropdown-option`; } if (option.details.active === true) { cls += ' active'; if (type === 'tabs') { cls += ' aio-input-main-color'; } if (type === 'buttons') { cls += ' aio-input-main-bg'; } } } else { cls = `aio-input aio-input-${type}${touch ? ' aio-input-touch' : ''}`; if (types.isInput) { cls += ` aio-input-input`; } if (rootProps.justify) { cls += ' aio-input-justify'; } cls += rtl ? ' aio-input-rtl' : ' aio-input-ltr'; } if (type === 'tree') { let size = rootProps.size || Def('tree-size'); size = Math.round(size / 12) * 12; if (size < 24) { size = 24; } if (size > 120) { size = 120; } cls += ` aio-input-size-${size}`; } if (properties.disabled === true) { cls += ' disabled'; } if (properties.className) { cls += ' ' + properties.className; } cls += ' ' + datauniqid; return cls; } function cls(key, hasSubtext) { let className = `aio-input-${key}`; if (option) { 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, subtext, justify } = properties; if (text === undefined && placeholder !== undefined) { text = _jsx("div", { className: 'aio-input-placeholder', children: placeholder }); } if (text !== undefined) { const className = `${cls('value', !!subtext)}${justify && !types.isInput ? ' aio-input-value-justify' : ''}`; return _jsx("div", { className: className, "data-subtext": subtext, children: text }); } else { return _jsx("div", { style: { flex: 1 } }); } } function keyDown(e) { const code = e.keyCode; if (code === 13) { click(e, dom); } } function DragIcon() { if (!properties.draggable) { return null; } return (_jsx("svg", { viewBox: "8 4 10 13", role: "presentation", style: { width: 12, height: '1.8rem' }, children: _jsx("path", { d: "M9,3H11V5H9V3M13,3H15V5H13V3M9,7H11V9H9V7M13,7H15V9H13V7M9,11H11V13H9V11M13,11H15V13H13V11M9,15H11V17H9V15M13,15H15V17H13V15M9,19H11V21H9V19M13,19H15V21H13V19Z", style: { fill: 'currentcolor' } }) })); } function Caret() { if (!types.isDropdown || option || (types.isInput && !rootProps.options)) { return null; } let { caret } = rootProps; if (caret === false) { return null; } return _jsx("div", { className: 'aio-input-caret', children: caret === undefined ? I('mdiChevronDown', .8) : caret }); } function BeforeAfter(mode) { let res; if (mode === 'after' && type === 'password' && rootProps.preview) { res = _jsx("div", { className: 'aio-input-password-preview', onClick: () => setShowPassword(), children: I(showPassword ? 'mdiEyeOff' : 'mdiEye', .8) }, `layout${mode}`); } else { let v = properties[mode]; res = typeof v === 'function' ? v() : v; } if (res === undefined) { return null; } return _jsx("div", { className: cls(mode), children: res }, 'layout' + mode); } function Loading() { let { loading } = properties; let elem; if (!loading) { return null; } else if (loading === true) { elem = I('mdiLoading', 0.8, { spin: .8 }); } else { elem = loading; } return _jsx("div", { className: cls('loading'), children: elem }); } function getProps() { let { attrs, disabled, draggable, style } = properties; let zIndex = false; if (!!popup.getModals().length && !option && ['text', 'number', 'textarea'].indexOf(type) !== -1) { zIndex = true; } let onClick; //ممکنه این یک آپشن باشه باید دیزیبل پرنتش هم چک بشه تا دیزیبل بشه if (!disabled) { if (option === undefined) { onClick = (e) => { e.stopPropagation(); click(e, dom); }; } else { onClick = (e) => { e.stopPropagation(); e.preventDefault(); if ((props.properties || {}).onClick) { props.properties.onClick(); } else { optionClick(option); } }; } } attrs = UT.AddToAttrs(attrs, { className: [getClassName(), zIndex ? 'z-index-input' : undefined], style: Object.assign({}, style) }); let p = Object.assign(Object.assign({ tabIndex: option ? undefined : 1, onKeyDown: keyDown }, attrs), { onClick, ref: dom, disabled }); let options = typeof rootProps.options === 'function' ? rootProps.options() : (rootProps.options || []); if (draggable) { p = Object.assign(Object.assign(Object.assign({}, p), DragOptions.getDragAttrs({ fromIndex: index || 0 })), DragOptions.getDropAttrs({ options, toIndex: index || 0 })); } if (index) { p['data-index'] = index; } return p; } function getProperties() { let p = props.properties || {}; let obj = option || rootProps; //اگر آپشن بود از آپشن وگر نه از پروپس بخون مقادیر رو let { draggable = option ? option.draggable : false } = p; let { placeholder = !option ? rootProps.placeholder : undefined } = p; let { checked = option ? option.checked : (type === 'checkbox' ? !!rootProps.value : undefined) } = p; let { disabled = obj.disabled } = p; let { text = obj.text } = p; let { subtext = obj.subtext } = p; let { justify = obj.justify } = p; let { loading = obj.loading } = p; let { attrs = obj.attrs || {} } = p; let style = Object.assign(Object.assign({}, (obj.style || {})), p.style); let { before = obj.before } = p; let { after = obj.after } = p; let classNames = [obj.className, p.className].filter((o) => !!o); let className = classNames.length ? classNames.join(' ') : undefined; return { disabled, draggable, text, subtext, placeholder, justify, checked, loading, attrs, style, before, after, className }; } function startVoice() { recognition.start(); } function voice() { if (!recognition) { return null; } return _jsx("div", { className: 'aio-input-voice', onClick: () => startVoice(), children: I('mdiMicrophoneOutline', 0.8) }); } let pro