This commit is contained in:
Nadar
2026-03-17 13:24:22 +03:00
commit 82e5ac9d81
554 changed files with 29637 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
import { useField } from 'vee-validate'
import { computed, ref, toRef } from 'vue'
import type { ComponentInternalInstance } from 'vue'
interface Props {
id: string
label?: string
disabled?: boolean
modelValue?: boolean | string | number
trueValue?: boolean | string | number
falseValue?: boolean | string | number
required?: boolean
}
export default (props: Props, slots: ComponentInternalInstance['slots']) => {
const { checked, errorMessage, handleChange } = useField(
toRef(props, 'id'),
computed(() => ({
required: props.required,
})),
{
type: 'checkbox',
initialValue: props.modelValue,
checkedValue: props.trueValue ?? true,
uncheckedValue: props.falseValue ?? false,
syncVModel: true,
},
)
const focused = ref(false)
const active = computed(() => !props.disabled)
const invalid = computed(() => active.value && !!errorMessage.value)
const hasLabel = computed(() => !!props.label || slots.default)
return {
focused,
checked,
active,
invalid,
hasLabel,
handleChange,
}
}

View File

@@ -0,0 +1,63 @@
const namespace = 'ui'
const statePrefix = 'is-'
function _bem(namespace: string, block: string, blockSuffix: string, element: string, modifier: string) {
let cls = `${block}`
if (blockSuffix)
cls += `-${blockSuffix}`
if (element)
cls += `__${element}`
if (modifier)
cls += `--${modifier}`
return cls
}
export default (block: string) => {
const b = (blockSuffix: string = '') => _bem(namespace, block, blockSuffix, '', '')
const e = (element: string) =>
element ? _bem(namespace, block, '', element, '') : ''
const m = (modifier: string) =>
modifier ? _bem(namespace, block, '', '', modifier) : ''
const be = (blockSuffix: string, element: string) =>
blockSuffix && element
? _bem(namespace, block, blockSuffix, element, '')
: ''
const em = (element: string, modifier: string) =>
element && modifier ? _bem(namespace, block, '', element, modifier) : ''
const bm = (blockSuffix: string, modifier: string) =>
blockSuffix && modifier
? _bem(namespace, block, blockSuffix, '', modifier)
: ''
const bem = (blockSuffix: string, element: string, modifier: string) =>
blockSuffix && element && modifier
? _bem(namespace, block, blockSuffix, element, modifier)
: ''
const is = (name: string, ...args: any[]) => {
const state = args.length >= 1 ? args[0] : true
return name && state ? `${statePrefix}${name}` : ''
}
const has = (name: string, ...args: any[]) => {
const state = args.length >= 1 ? args[0] : true
return name && state ? `has-${name}` : ''
}
const exp = (condition: boolean, trueState: string, falseState: string = '') => {
return condition ? trueState : falseState
}
return {
namespace,
b,
e,
m,
be,
em,
bm,
bem,
is,
has,
exp,
}
}

View File

@@ -0,0 +1,56 @@
import Fuse from 'fuse.js'
import { isRef, ref, unref, watch } from 'vue'
export default (items, options, term) => {
const fuse = ref(null)
const result = ref(unref(items))
watch(items, (value) => {
if (fuse.value) {
fuse.value.setCollection(unref(value))
result.value = unref(items)
}
})
watch(
() => options,
(value) => {
fuse.value = new Fuse(unref(items), { minMatchCharLength: 2, ...value })
},
{ immediate: true },
)
if (isRef(term)) {
watch(term, (value) => {
search(value)
})
}
const search = (term = '') => {
if (!fuse.value)
return
term = term.trim()
if (term.length < 2) {
result.value = unref(items)
return
}
const documents = fuse.value.search(term)
result.value = documents.map(doc => doc.item)
}
const reset = () => {
result.value = unref(items)
}
return {
fuse,
result,
search,
reset,
}
}

View File

@@ -0,0 +1,27 @@
import { computed, getCurrentInstance, inject, provide, unref } from 'vue'
import type { MaybeRef, Ref } from 'vue'
export function useGlobalConfig(
key: string,
defaultValue: unknown = undefined,
): Ref<unknown> {
const config = inject('GLOBAL_CONFIG') as MaybeRef<unknown>
if (key)
return computed(() => unref(config)?.[key] ?? defaultValue)
else
return config
}
export function provideGlobalConfig(config, app) {
const inSetup = !!getCurrentInstance()
const provideFn = app?.provide ?? (inSetup ? provide : undefined)
if (!provideFn)
return
provideFn('GLOBAL_CONFIG', config)
return config
}

View File

@@ -0,0 +1,3 @@
import notify from '../components/notification/notify'
export default () => notify

View File

@@ -0,0 +1,40 @@
import { useField } from 'vee-validate'
import { computed, ref, toRef } from 'vue'
import type { ComponentInternalInstance } from 'vue'
interface Props {
id: string
value: string | number
label?: string
disabled?: boolean
modelValue?: string | number
required?: boolean
}
export default (props: Props, slots: ComponentInternalInstance['slots']) => {
const { checked, handleChange } = useField(
toRef(props, 'id'),
computed(() => ({
required: props.required,
})),
{
type: 'radio',
initialValue: props.modelValue,
checkedValue: props.value,
syncVModel: true,
},
)
const focused = ref(false)
const active = computed(() => !props.disabled)
const hasLabel = computed(() => !!props.label || slots.default)
return {
focused,
active,
checked,
hasLabel,
handleChange,
}
}

View File

@@ -0,0 +1,61 @@
import { computed, onMounted, onUnmounted, ref, unref, watch } from 'vue'
export default function useTimer(expirationTime) {
const now = ref(Date.now())
const remainingTime = ref(calcRemainingTime())
const requestId = ref()
const isPaused = computed(() => !requestId.value)
const isPassed = computed(() => remainingTime.value === 0)
function calcRemainingTime() {
return Math.max(Math.ceil((unref(expirationTime) - now.value) / 1000), 0)
}
function update() {
now.value = Date.now()
const newRemainingTime = calcRemainingTime()
if (newRemainingTime !== remainingTime.value)
remainingTime.value = newRemainingTime
if (remainingTime.value > 0)
requestId.value = window.requestAnimationFrame(update)
}
function start() {
requestId.value = requestAnimationFrame(update)
}
function stop() {
cancelAnimationFrame(requestId.value)
requestId.value = null
}
watch(expirationTime, () => {
if (!isPaused.value) {
remainingTime.value = calcRemainingTime()
stop()
start()
}
})
onMounted(() => {
start()
})
onUnmounted(() => {
stop()
})
return {
remainingTime,
isPaused,
isPassed,
start,
stop,
}
}