UNPKG

@mythpe/js-helpers

Version:

Library of plugins & shortcuts that use JavaScript, also includes the Vue3 plugin with quasar apps

175 lines (164 loc) 6.1 kB
/* * MyTh Ahmed Faiz Copyright © 2016-2024 All rights reserved. * Email: mythpe@gmail.com * Mobile: +966590470092 * Website: https://www.4myth.com * Github: https://github.com/mythpe */ import lodash from 'lodash' import { computed, MaybeRefOrGetter, toValue } from 'vue' import { extend, useSplitAttrs } from 'quasar' import { useI18n } from 'vue-i18n' import { MythOptionsConfig as MOC } from '../types' import { useMyth } from '../vue3' import { useFieldError, useFieldValue, useSetFieldError, useSetFieldValue } from 'vee-validate' type G = { name: string; } & Record<string, any>; type OptsContext = { choose?: boolean; }; export const useInputHelper = <P extends G = G> (Props: MaybeRefOrGetter<P>, key: keyof MOC, Opts: MaybeRefOrGetter<OptsContext> = {}) => { const { messages, locale } = useI18n({ useScope: 'global' }) const { __, options } = useMyth() const { attributes: attrs } = useSplitAttrs() const props = toValue<P>(Props) const opts = toValue<OptsContext>(Opts) const inputOptions = computed(() => (k: keyof MOC) => options[k] || {}) const inputProps = computed<MOC[typeof key] & P>(() => extend(!0, {}, inputOptions.value(key), props)) const hasTopLabel = computed(() => inputProps.value.topLabel === !0) const getLabel = computed<string | undefined>(() => { const k = props.label === undefined ? props.name : props.label return k ? (__(k) || undefined) : undefined }) const getPlaceholder = computed<string | undefined>(() => { if (props.placeholder === undefined) { const k = props.label !== undefined ? props.label : props.name return __(`replace.${opts?.choose ? 'choose' : 'enter'}`, { name: __(k) }) } return __(props.placeholder) || undefined // if (inputProps.value.hidePlaceholder === !0) { // return props.placeholder !== undefined ? (__(props.placeholder) || undefined) : undefined // } }) const getAutocompleteAttribute = computed<string | null | undefined>(() => { const opt = inputOptions.value(key) const autocomplete = 'autocomplete' in opt && opt?.autocomplete !== undefined ? opt?.autocomplete : props.autocomplete if (autocomplete !== undefined) { if (autocomplete === !0 || autocomplete === '') { return lodash.kebabCase(props.name) } else if (autocomplete === !1) { return 'off' } else if (autocomplete?.length > 0) { return autocomplete } } return undefined }) const accepts = computed(() => { const l = [] if (props.accept) { l.push(props.accept) } if (props.images) { l.push('image/png,image/jpg,image/jpeg') } if (props.svg) { l.push('image/svg+xml') } if (props.video) { l.push('video/mp4,video/x-m4v,video/*') } if (props.pdf) { l.push('application/pdf') } if (props.excel) { l.push('.csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') } return l }) const isNumeric = (str: any) => !isNaN(str) && !isNaN(parseFloat(str)) const convertRules = (rules: any) => { if (!rules) { return {} } let values: Record<string, any> = {} const list: any[] = typeof rules === 'string' ? rules.split('|') : (Array.isArray(rules) ? rules : [rules]) for (const rule of list) { // console.log(rule) if (!rule) { continue } if (typeof rule === 'object' && !Array.isArray(rule)) { values = { ...values, ...rule } continue } if (Array.isArray(rule)) { values = { ...values, ...rule } } const [name, value] = rule.split(':') if (!name) { continue } values[name] = !value ? !0 : /,/g.test(value) ? value.split(',').map((e: any) => isNumeric(e) ? parseInt(e) : e) : (isNumeric(value) ? parseInt(value) : value) } if (values.color && props.required) { values.requiredColor = values.color delete values.color } return values } const publicRules = ['required', 'email', 'numeric', 'integer', 'float', 'color'] const validations = (messages.value as any)?.[locale.value]?.validation?.messages || {} const getRules = computed<Record<string, any>>(() => { if (props.viewMode) { return {} } const rules: any = { ...convertRules(toValue(props.rules)) } // const attrs = toValue(opts.attrs) || {} const keys = lodash.uniq<string>([...publicRules, ...(options.inputRules ?? []), ...Object.keys(validations)]) for (const k of keys) { if (['mobile', '_default', 'default'].includes(k)) { continue } const cases = [k, lodash.snakeCase(k), lodash.camelCase(k), lodash.kebabCase(k)] mainFor: for (const c of cases) { for (const b of [attrs.value, props]) { if (c in b && (b[c] === !0 || b[c] === '')) { rules[lodash.snakeCase(k)] = b[c] === !0 || b[c] === '' ? !0 : b[c] break mainFor } } } } const mobile = attrs.value?.mobile !== undefined ? attrs.value.mobile : props.mobile if (mobile !== undefined) { const defLen = 10 rules.digits = typeof mobile === 'boolean' ? defLen : (mobile || defLen) } return Object.values(rules).filter(e => !!e).length > 0 ? rules : undefined }) return { getRules, accepts, hasTopLabel, getLabel, getPlaceholder, getAutocompleteAttribute, inputOptions, inputProps } } export const useValue = <T = any> (name: MaybeRefOrGetter<string>) => { const [value, setValue] = [useFieldValue<T>(name), useSetFieldValue<T>(name)] const field = computed<T>({ get: () => value.value, set: (v: T) => setValue(v) }) return { field, value, setValue } } export const useError = (name: MaybeRefOrGetter<string>) => { const [error, setErrors] = [useFieldError(name), useSetFieldError(name)] const errors = computed<string | string[] | undefined>({ get: () => error.value, set: (v: string | string[] | undefined) => setErrors(v) }) return { errors, error, setErrors } }