@globalbrain/sefirot 0.71.0 → 2.0.0-draft.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/CHANGELOG.md +6 -804
  2. package/README.md +1 -1
  3. package/lib/assets/styles/bootstrap.css +1 -2
  4. package/lib/assets/styles/variables.css +14 -47
  5. package/lib/components/SAvatar.vue +9 -18
  6. package/lib/components/SButton.vue +35 -48
  7. package/lib/components/SDialog.vue +16 -34
  8. package/lib/components/SDropdown.vue +36 -55
  9. package/lib/components/SDropdownItem.vue +27 -39
  10. package/lib/components/SDropdownItemText.vue +4 -9
  11. package/lib/components/SDropdownItemUser.vue +4 -12
  12. package/lib/components/SInputBase.vue +33 -45
  13. package/lib/components/SInputCheckbox.vue +19 -35
  14. package/lib/components/SInputDropdown.vue +109 -171
  15. package/lib/components/SInputDropdownItem.vue +26 -32
  16. package/lib/components/SInputDropdownItemText.vue +6 -11
  17. package/lib/components/SInputDropdownItemTextTag.vue +10 -17
  18. package/lib/components/SInputDropdownItemUser.vue +5 -13
  19. package/lib/components/SInputDropdownItemUserTag.vue +9 -16
  20. package/lib/components/SInputFile.vue +38 -53
  21. package/lib/components/SInputHMS.vue +91 -114
  22. package/lib/components/SInputNumber.vue +27 -106
  23. package/lib/components/SInputRadio.vue +23 -33
  24. package/lib/components/SInputRadios.vue +37 -47
  25. package/lib/components/SInputText.vue +72 -628
  26. package/lib/components/SInputTextarea.vue +54 -113
  27. package/lib/components/SInputYMD.vue +94 -105
  28. package/lib/components/SLink.vue +16 -52
  29. package/lib/components/SModal.vue +53 -90
  30. package/lib/components/SPortalModals.vue +37 -53
  31. package/lib/components/SPortalSnackbars.vue +9 -24
  32. package/lib/components/SSheet.vue +10 -23
  33. package/lib/components/SSheetFooter.vue +0 -2
  34. package/lib/components/SSheetFooterAction.vue +9 -14
  35. package/lib/components/SSheetFooterActions.vue +1 -3
  36. package/lib/components/SSheetHeader.vue +9 -24
  37. package/lib/components/SSheetHeaderTitle.vue +1 -3
  38. package/lib/components/SSheetMedium.vue +13 -25
  39. package/lib/components/SSnackbar.vue +18 -28
  40. package/lib/composables/Dialog.ts +9 -17
  41. package/lib/composables/Dropdown.ts +2 -2
  42. package/lib/composables/{Menu.ts → Flyout.ts} +11 -4
  43. package/lib/composables/Form.ts +42 -44
  44. package/lib/composables/Modal.ts +9 -9
  45. package/lib/composables/Snackbar.ts +18 -0
  46. package/lib/composables/Validation.ts +28 -0
  47. package/lib/mixins/Sheet.ts +3 -3
  48. package/lib/store/Sefirot.ts +8 -13
  49. package/lib/store/dialog/index.ts +20 -10
  50. package/lib/store/modal/index.ts +11 -13
  51. package/lib/store/snackbars/index.ts +3 -4
  52. package/lib/support/{Util.ts → Utils.ts} +0 -2
  53. package/lib/types/Utils.ts +0 -7
  54. package/lib/types/vue-shims.d.ts +7 -0
  55. package/lib/validation/rules/checked.ts +6 -10
  56. package/lib/validation/rules/fileExtension.ts +9 -9
  57. package/lib/validation/rules/hms.ts +9 -9
  58. package/lib/validation/rules/index.ts +10 -74
  59. package/lib/validation/rules/maxLength.ts +10 -9
  60. package/lib/validation/rules/minLength.ts +12 -0
  61. package/lib/validation/rules/required.ts +2 -10
  62. package/lib/validation/rules/requiredHms.ts +11 -0
  63. package/lib/validation/rules/requiredIf.ts +3 -11
  64. package/lib/validation/rules/requiredYmd.ts +11 -0
  65. package/lib/validation/rules/ymd.ts +11 -0
  66. package/lib/validation/validators/checked.ts +1 -1
  67. package/lib/validation/validators/fileExtension.ts +1 -1
  68. package/lib/validation/validators/hms.ts +5 -5
  69. package/lib/validation/validators/requiredHms.ts +17 -0
  70. package/lib/validation/validators/requiredYmd.ts +7 -0
  71. package/lib/validation/validators/ymd.ts +41 -0
  72. package/package.json +45 -50
  73. package/lib/components/SAction.vue +0 -37
  74. package/lib/components/SActionAvatar.vue +0 -25
  75. package/lib/components/SActionButton.vue +0 -40
  76. package/lib/components/SActionPill.vue +0 -35
  77. package/lib/components/SActionSwitch.vue +0 -37
  78. package/lib/components/SAlert.vue +0 -145
  79. package/lib/components/SButtonGroup.vue +0 -160
  80. package/lib/components/SCard.vue +0 -111
  81. package/lib/components/SCardFooter.vue +0 -74
  82. package/lib/components/SCardHeader.vue +0 -213
  83. package/lib/components/SGrid.vue +0 -237
  84. package/lib/components/SGridActionLink.vue +0 -53
  85. package/lib/components/SGridActionMulti.vue +0 -139
  86. package/lib/components/SGridActionSingle.vue +0 -64
  87. package/lib/components/SHeader.vue +0 -180
  88. package/lib/components/SInputCheckboxes.vue +0 -83
  89. package/lib/components/SInputDate.vue +0 -192
  90. package/lib/components/SInputDay.vue +0 -87
  91. package/lib/components/SInputMonth.vue +0 -86
  92. package/lib/components/SInputSelect.vue +0 -282
  93. package/lib/components/SInputSwitch.vue +0 -212
  94. package/lib/components/SInputSwitches.vue +0 -108
  95. package/lib/components/SInputTime.vue +0 -255
  96. package/lib/components/SInputYear.vue +0 -60
  97. package/lib/components/SMarkdown.vue +0 -56
  98. package/lib/components/SPlaceholderBlank.vue +0 -113
  99. package/lib/components/SPlaceholderImage.vue +0 -83
  100. package/lib/components/SPortalScreens.vue +0 -62
  101. package/lib/components/SProgressBar.vue +0 -89
  102. package/lib/components/SResponsive.vue +0 -46
  103. package/lib/components/SScreen.vue +0 -81
  104. package/lib/components/SStep.vue +0 -107
  105. package/lib/components/SSteps.vue +0 -75
  106. package/lib/components/STag.vue +0 -67
  107. package/lib/components/STooltip.vue +0 -134
  108. package/lib/components/SWindow.vue +0 -158
  109. package/lib/composables/Action.ts +0 -141
  110. package/lib/composables/Alert.ts +0 -50
  111. package/lib/composables/Card.ts +0 -46
  112. package/lib/composables/FormValidation.ts +0 -150
  113. package/lib/composables/Header.ts +0 -72
  114. package/lib/composables/InputDropdown.ts +0 -6
  115. package/lib/composables/Markdown.ts +0 -138
  116. package/lib/composables/Router.ts +0 -20
  117. package/lib/composables/Step.ts +0 -7
  118. package/lib/composables/Store.ts +0 -9
  119. package/lib/composables/Tag.ts +0 -32
  120. package/lib/composables/Tooltip.ts +0 -91
  121. package/lib/composables/Utils.ts +0 -115
  122. package/lib/composables/markdown/LinkPlugin.ts +0 -45
  123. package/lib/compositions/useForm.ts +0 -17
  124. package/lib/compositions/useResizeObserver.ts +0 -25
  125. package/lib/compositions/useTime.ts +0 -26
  126. package/lib/store/alert/index.ts +0 -32
  127. package/lib/store/screen/index.ts +0 -46
  128. package/lib/types/v-calendar.d.ts +0 -5
  129. package/lib/validation/Validation.ts +0 -151
  130. package/lib/validation/rules/day.ts +0 -11
  131. package/lib/validation/rules/email.ts +0 -11
  132. package/lib/validation/rules/every.ts +0 -38
  133. package/lib/validation/rules/include.ts +0 -11
  134. package/lib/validation/rules/includeSome.ts +0 -11
  135. package/lib/validation/rules/integer.ts +0 -11
  136. package/lib/validation/rules/maxValue.ts +0 -11
  137. package/lib/validation/rules/minValue.ts +0 -11
  138. package/lib/validation/rules/month.ts +0 -11
  139. package/lib/validation/rules/not.ts +0 -10
  140. package/lib/validation/rules/regex.ts +0 -11
  141. package/lib/validation/rules/requiredHMS.ts +0 -11
  142. package/lib/validation/rules/requiredMonthDate.ts +0 -11
  143. package/lib/validation/rules/requiredYearMonth.ts +0 -11
  144. package/lib/validation/rules/requiredYearMonthDate.ts +0 -11
  145. package/lib/validation/rules/rule.ts +0 -5
  146. package/lib/validation/rules/sameAs.ts +0 -11
  147. package/lib/validation/rules/url.ts +0 -11
  148. package/lib/validation/rules/validateIf.ts +0 -27
  149. package/lib/validation/rules/year.ts +0 -11
  150. package/lib/validation/rules/yearMonth.ts +0 -11
  151. package/lib/validation/rules/yearMonthDate.ts +0 -11
  152. package/lib/validation/validators/day.ts +0 -29
  153. package/lib/validation/validators/email.ts +0 -5
  154. package/lib/validation/validators/include.ts +0 -5
  155. package/lib/validation/validators/includeSome.ts +0 -5
  156. package/lib/validation/validators/index.ts +0 -51
  157. package/lib/validation/validators/integer.ts +0 -6
  158. package/lib/validation/validators/maxLength.ts +0 -3
  159. package/lib/validation/validators/maxValue.ts +0 -3
  160. package/lib/validation/validators/minValue.ts +0 -3
  161. package/lib/validation/validators/month.ts +0 -3
  162. package/lib/validation/validators/monthDate.ts +0 -20
  163. package/lib/validation/validators/regex.ts +0 -3
  164. package/lib/validation/validators/required.ts +0 -27
  165. package/lib/validation/validators/requiredHMS.ts +0 -17
  166. package/lib/validation/validators/requiredMonthDate.ts +0 -8
  167. package/lib/validation/validators/requiredYearMonth.ts +0 -8
  168. package/lib/validation/validators/requiredYearMonthDate.ts +0 -9
  169. package/lib/validation/validators/sameAs.ts +0 -5
  170. package/lib/validation/validators/url.ts +0 -5
  171. package/lib/validation/validators/year.ts +0 -3
  172. package/lib/validation/validators/yearMonth.ts +0 -20
  173. package/lib/validation/validators/yearMonthDate.ts +0 -21
@@ -1,91 +0,0 @@
1
- import { Ref, ref } from '@vue/composition-api'
2
-
3
- export type Position = 'top' | 'right' | 'bottom' | 'left'
4
-
5
- const SCREEN_PADDING = 16
6
-
7
- /**
8
- * Prevent tooltip going off-screen by adjusting the position depending on
9
- * the current window size. This only applies to position `top` and
10
- * `bottom` since we only care about left and right of the screen.
11
- */
12
- export function useTooltip(
13
- content: Ref<HTMLElement | null>,
14
- tip: Ref<HTMLElement | null>,
15
- position: Position
16
- ) {
17
- const on = ref(false)
18
-
19
- function show(): void {
20
- setPosition()
21
- setTimeout(() => { on.value = true })
22
- }
23
-
24
- function hide(): void {
25
- setTimeout(() => { on.value = false })
26
- }
27
-
28
- function setPosition(): void {
29
- if (shouldPosition()) {
30
- doSetPosition()
31
- }
32
- }
33
-
34
- function doSetPosition(): void {
35
- // Reset position first so that we can get the original position.
36
- resetPosition()
37
-
38
- // Temporally show tip to get its size.
39
- tip.value!.style.display = 'block'
40
-
41
- const contentRect = content.value!.getBoundingClientRect()
42
- const tipRect = tip.value!.getBoundingClientRect()
43
-
44
- const contentRightX = contentRect.x + contentRect.width
45
- const tipRightX = tipRect.x + tipRect.width
46
-
47
- if (tipRect.x < 0) {
48
- adjustLeftPosition(contentRect.x)
49
- } else if (tipRightX > window.outerWidth) {
50
- adjustRightPosition(contentRightX)
51
- }
52
-
53
- tip.value!.style.display = 'none'
54
- }
55
-
56
- function adjustLeftPosition(contentRectX: number): void {
57
- tip.value!.style.left = '0'
58
- tip.value!.style.right = 'auto'
59
- setTransform(-contentRectX + SCREEN_PADDING)
60
- }
61
-
62
- function adjustRightPosition(contentRightX: number): void {
63
- tip.value!.style.left = 'auto'
64
- tip.value!.style.right = '0'
65
- setTransform((window.outerWidth - contentRightX) - SCREEN_PADDING)
66
- }
67
-
68
- function resetPosition(): void {
69
- tip.value!.style.left = ''
70
- tip.value!.style.right = ''
71
- tip.value!.style.transform = ''
72
- }
73
-
74
- function setTransform(x: number): void {
75
- tip.value!.style.transform = `translate(${x}px, ${position === 'top' ? -100 : 100}%)`
76
- }
77
-
78
- function shouldPosition(): boolean {
79
- if (!tip.value || !content.value) {
80
- return false
81
- }
82
-
83
- return position === 'top' || position === 'bottom'
84
- }
85
-
86
- return {
87
- on,
88
- show,
89
- hide
90
- }
91
- }
@@ -1,115 +0,0 @@
1
- import {
2
- Ref,
3
- ComputedRef,
4
- WatchSource,
5
- shallowRef,
6
- computed,
7
- watch,
8
- isRef
9
- } from '@vue/composition-api'
10
-
11
- export type Refish<T = any> = T | Ref<T> | ComputedRef<T>
12
-
13
- export type Source<S> = Ref<S> | ComputedRef<S>
14
-
15
- export function get<T>(refish: Refish<T> | (() => T)): T {
16
- if (isRef(refish)) {
17
- return refish.value
18
- }
19
-
20
- if (refish instanceof Function) {
21
- return refish()
22
- }
23
-
24
- return refish
25
- }
26
-
27
- export function computedOnly<T, S>(
28
- source: WatchSource<S>,
29
- fn: (value: S, oldValue?: S) => T
30
- ): Ref<T> {
31
- const value = shallowRef() as Ref<T>
32
-
33
- watch(source, (newValue, oldValue) => {
34
- value.value = fn(newValue, oldValue)
35
- }, { immediate: true })
36
-
37
- return value
38
- }
39
-
40
- export function computedIf<T, R, E>(
41
- refish: Refish<T | null>,
42
- callback: (value: T) => R,
43
- empty: E
44
- ): ComputedRef<R | E> {
45
- return computed(() => {
46
- const value = get(refish)
47
-
48
- return value ? callback(value) : empty
49
- })
50
- }
51
-
52
- export function computedIfOnly<T, E, S>(
53
- source: WatchSource<S>,
54
- fn: (value: Exclude<S, undefined | null | false>) => T,
55
- empty: E
56
- ): Ref<T | E> {
57
- return computedOnly(source, (value) => {
58
- return value
59
- ? fn(value as Exclude<S, undefined | null | false>)
60
- : empty
61
- })
62
- }
63
-
64
- export function computedArray<T>(callback: (carry: T) => void): ComputedRef<T> {
65
- return computed(() => {
66
- const carry = [] as any
67
-
68
- callback(carry)
69
-
70
- return carry
71
- })
72
- }
73
-
74
- export function computedArrayOnly<T extends any[], S>(
75
- source: Source<S>,
76
- callback: (carry: T) => void
77
- ): Ref<T> {
78
- return computedOnly(source, () => {
79
- const carry = [] as any
80
-
81
- callback(carry)
82
-
83
- return carry
84
- })
85
- }
86
-
87
- export function computedArrayIf<T, D extends any[]>(
88
- refish: Refish<T | null>,
89
- callback: (carry: D, value: T) => void
90
- ): ComputedRef<D> {
91
- return computed(() => {
92
- const carry = [] as any
93
-
94
- const value = get(refish)
95
-
96
- value && callback(carry, value)
97
-
98
- return carry
99
- })
100
- }
101
-
102
- export function computedArrayIfNot<T, D extends any[]>(
103
- refish: Refish<T | null>,
104
- callback: (carry: D) => void
105
- ): ComputedRef<D> {
106
- return computed(() => {
107
- const carry = [] as any
108
-
109
- const value = get(refish)
110
-
111
- value || callback(carry)
112
-
113
- return carry
114
- })
115
- }
@@ -1,45 +0,0 @@
1
- import MarkdownIt from 'markdown-it'
2
-
3
- export type LinkAttrs = Record<string, string>
4
-
5
- const EXTERNAL_REGEX = /^https?:/
6
- const CALLBACK_REGEX = /\{([\d}]+)\}/
7
- const CALLBACK_HREF = '#callback'
8
-
9
- export function linkPlugin(md: MarkdownIt, linkAttrs: LinkAttrs = {}): void {
10
- md.renderer.rules.link_open = (tokens, idx, options, _env, self) => {
11
- const token = tokens[idx]
12
- const hrefIndex = token.attrIndex('href')
13
-
14
- if (hrefIndex >= 0) {
15
- const hrefAttr = token.attrs![hrefIndex]
16
- const url = decodeURIComponent(hrefAttr[1])
17
-
18
- if (isExternalUrl(url)) {
19
- Object.entries(linkAttrs).forEach(([key, val]) => {
20
- token.attrSet(key, val)
21
- })
22
- }
23
-
24
- if (isCallbackUrl(url)) {
25
- const matched = url.match(CALLBACK_REGEX)![1]
26
-
27
- token.attrSet('data-callback-id', matched)
28
-
29
- hrefAttr[1] = CALLBACK_HREF
30
- }
31
-
32
- token.attrSet('class', 'SMarkdown-link')
33
- }
34
-
35
- return self.renderToken(tokens, idx, options)
36
- }
37
- }
38
-
39
- export function isExternalUrl(url: string): boolean {
40
- return EXTERNAL_REGEX.test(url)
41
- }
42
-
43
- export function isCallbackUrl(url: string): boolean {
44
- return url === CALLBACK_HREF || CALLBACK_REGEX.test(decodeURIComponent(url))
45
- }
@@ -1,17 +0,0 @@
1
- import { reactive, markRaw } from '@vue/composition-api'
2
- import { createValidation, Data, Rules } from '../validation/Validation'
3
-
4
- export interface FormDefinition {
5
- data: Data
6
- rules: Rules
7
- }
8
-
9
- export default function useForm(definition: FormDefinition) {
10
- const data = reactive(definition.data)
11
- const validation = markRaw(createValidation(data, definition.rules))
12
-
13
- return {
14
- data,
15
- validation
16
- }
17
- }
@@ -1,25 +0,0 @@
1
- import { ResizeObserver } from '@juggle/resize-observer'
2
- import { reactive, toRefs, onMounted, onUnmounted, Ref } from '@vue/composition-api'
3
-
4
- export interface EL {
5
- w: number
6
- h: number
7
- }
8
-
9
- export default function useResizeObserver(target: Ref<HTMLElement | null>) {
10
- const el = reactive({ w: 0, h: 0 })
11
-
12
- const ro = new ResizeObserver((entries) => {
13
- const entry = entries[0]
14
- el.w = entry.contentBoxSize[0].inlineSize
15
- el.h = entry.contentBoxSize[0].blockSize
16
- })
17
-
18
- onMounted(() => { ro.observe(target.value!) })
19
- onUnmounted(() => { ro.disconnect() })
20
-
21
- return {
22
- el: toRefs(el),
23
- ro
24
- }
25
- }
@@ -1,26 +0,0 @@
1
- function pad(n: number, width: number): string {
2
- const number = String(n)
3
- return number.length >= width ? number : new Array(width - number.length + 1).join('0') + number
4
- }
5
-
6
- function createTimes(from: number, to: number): string[] {
7
- const hours: string[] = []
8
-
9
- for (let h = from; h <= to; h++) {
10
- hours.push(pad(h, 2))
11
- }
12
-
13
- return hours
14
- }
15
-
16
- export default function useTime() {
17
- const hours = createTimes(0, 23)
18
- const minutes = createTimes(0, 59)
19
- const seconds = createTimes(0, 59)
20
-
21
- return {
22
- hours,
23
- minutes,
24
- seconds
25
- }
26
- }
@@ -1,32 +0,0 @@
1
- import { ActionTree, ActionContext } from 'vuex'
2
- import SAlert from '../../components/SAlert.vue'
3
- import { Alert } from '../../composables/Alert'
4
- import { State as RootState } from '../Sefirot'
5
-
6
- export type AlertPayload = Alert & { uid?: number }
7
-
8
- export const actions: ActionTree<any, RootState> = {
9
- open(context: ActionContext<any, RootState>, alert: AlertPayload): void {
10
- const { uid } = alert
11
-
12
- delete alert.uid
13
-
14
- context.dispatch('modal/open', {
15
- uid,
16
- component: SAlert,
17
- data: alert,
18
- options: {
19
- closable: false
20
- }
21
- }, { root: true })
22
- },
23
-
24
- close(context: ActionContext<any, RootState>, uid?: number): void {
25
- context.dispatch('modal/close', uid, { root: true })
26
- }
27
- }
28
-
29
- export default {
30
- namespaced: true,
31
- actions
32
- }
@@ -1,46 +0,0 @@
1
- import { ActionTree, ActionContext, MutationTree } from 'vuex'
2
- import { State as RootState } from '../Sefirot'
3
-
4
- export interface State {
5
- name: string | null
6
- data: Record<string, any>
7
- }
8
-
9
- export interface PayloadOpen {
10
- name: string
11
- data?: Record<string, any>
12
- }
13
-
14
- export function state(): State {
15
- return {
16
- name: null,
17
- data: {}
18
- }
19
- }
20
-
21
- export const actions: ActionTree<State, RootState> = {
22
- open(context: ActionContext<State, RootState>, { name, data }: PayloadOpen): void {
23
- context.commit('set', { name, data })
24
- },
25
-
26
- close(context: ActionContext<State, RootState>): void {
27
- context.commit('set', {
28
- name: null,
29
- data: {}
30
- })
31
- }
32
- }
33
-
34
- export const mutations: MutationTree<State> = {
35
- set(state: State, { name, data = {} }: PayloadOpen): void {
36
- state.name = name
37
- state.data = data
38
- }
39
- }
40
-
41
- export default {
42
- namespaced: true,
43
- state,
44
- actions,
45
- mutations
46
- }
@@ -1,5 +0,0 @@
1
- declare module 'v-calendar' {
2
- const VCalendar: any
3
-
4
- export default VCalendar
5
- }
@@ -1,151 +0,0 @@
1
- import { ref, computed, toRefs, Ref } from '@vue/composition-api'
2
- import { Rule } from './rules'
3
-
4
- export interface Validation {
5
- _isValidation: boolean
6
- $data: Ref<any>
7
- $initData: any
8
- $isDirty: Ref<boolean>
9
- $isValid: Ref<boolean>
10
- $errors: Ref<readonly Error[]>
11
- $touch: () => void
12
- $reset: () => void
13
- $init: () => void
14
- $validate: () => boolean
15
- [name: string]: MaybeValidation
16
- }
17
-
18
- export type Data = Record<string, any>
19
- export type Rules = Record<string, Rule[] | Record<string, any>>
20
- export type InitData = any
21
- export type Error = [string, string]
22
- export type MaybeValidation = any | boolean | Ref<boolean> | Ref<readonly Error[]> | Function | Validation
23
-
24
- export function createValidation(data: Data, rules: Rules, rootData?: Data): Validation {
25
- const validation = createInitialValidation()
26
- setNestedValidations(validation, data, rootData ?? data, rules)
27
- setValidation(validation)
28
- return validation
29
- }
30
-
31
- function createInitialValidation(): Validation {
32
- return {
33
- _isValidation: true,
34
- $data: ref(null),
35
- $initData: null,
36
- $isDirty: ref(false),
37
- $isValid: ref(false),
38
- $errors: ref([]),
39
- $touch: () => {},
40
- $reset: () => {},
41
- $init: () => {},
42
- $validate: () => false
43
- }
44
- }
45
-
46
- function createNestedValidation(name: string, data: Data, rootData: Data, validators: Rule[]): Validation {
47
- const initData = data[name]
48
- const dataRef = toRefs(data)[name]
49
-
50
- const isDirty = ref(false)
51
-
52
- const errors = computed(() => {
53
- return validators.reduce<Error[]>((errors, validator) => {
54
- const d = data[name]
55
-
56
- if (validator.optional && (d === undefined || d === null || d === '')) {
57
- return errors
58
- }
59
-
60
- if (!validator.validate(d, rootData)) {
61
- errors.push([validator.name, validator.message])
62
- }
63
-
64
- return errors
65
- }, [])
66
- })
67
-
68
- const isValid = computed(() => errors.value.length === 0)
69
-
70
- const touch = () => { isDirty.value = true }
71
- const reset = () => { isDirty.value = false }
72
-
73
- const init = () => {
74
- reset()
75
- dataRef.value = initData
76
- }
77
-
78
- const validate = () => {
79
- touch()
80
- return isValid.value
81
- }
82
-
83
- return {
84
- _isValidation: true,
85
- $data: dataRef,
86
- $initData: initData,
87
- $isDirty: isDirty,
88
- $errors: errors,
89
- $isValid: isValid,
90
- $touch: touch,
91
- $reset: reset,
92
- $init: init,
93
- $validate: validate
94
- }
95
- }
96
-
97
- function setValidation(validation: Validation): void {
98
- const isDirty = computed(() => {
99
- return Object.keys(validation).every((field) => {
100
- const v = validation[field]
101
- return isValidation(v) ? v.$isDirty.value : true
102
- }, [])
103
- })
104
-
105
- const errors = computed(() => {
106
- return Object.keys(validation).reduce<Error[]>((errors, field) => {
107
- const v = validation[field]
108
- return isValidation(v) ? errors.concat(v.$errors.value) : errors
109
- }, [])
110
- })
111
-
112
- const isValid = computed(() => errors.value.length === 0)
113
-
114
- const touch = () => { callAll(validation, 'touch') }
115
- const reset = () => { callAll(validation, 'reset') }
116
- const init = () => { callAll(validation, 'init') }
117
-
118
- const validate = () => {
119
- touch()
120
- return isValid.value
121
- }
122
-
123
- validation.$isDirty = isDirty
124
- validation.$errors = errors
125
- validation.$isValid = isValid
126
- validation.$touch = touch
127
- validation.$reset = reset
128
- validation.$init = init
129
- validation.$validate = validate
130
- }
131
-
132
- function setNestedValidations(validation: Validation, data: Data, rootData: Data, rules: Rules): void {
133
- for (const name in rules) {
134
- const validators = rules[name]
135
-
136
- validation[name] = Array.isArray(validators)
137
- ? createNestedValidation(name, data, rootData, validators)
138
- : createValidation(data[name], validators, rootData)
139
- }
140
- }
141
-
142
- function callAll(validation: Validation, method: 'touch' | 'reset' | 'init'): void {
143
- for (const field in validation) {
144
- const v = validation[field]
145
- isValidation(v) && v[`$${method}`]()
146
- }
147
- }
148
-
149
- function isValidation(value: MaybeValidation): value is Validation {
150
- return value !== null && typeof value === 'object' && !Array.isArray(value) && value._isValidation
151
- }
@@ -1,11 +0,0 @@
1
- import { day as baseDay } from '../validators'
2
- import { Rule } from './'
3
-
4
- export default function day(year?: string, month?: string, message?: string): Rule {
5
- return {
6
- name: 'day',
7
- message: message ?? 'The Date is invalid.',
8
- optional: true,
9
- validate: (value, data) => baseDay(value, data[year!], data[month!])
10
- }
11
- }
@@ -1,11 +0,0 @@
1
- import { email as baseEmail } from '../validators'
2
- import { Rule } from './'
3
-
4
- export default function email(message?: string): Rule {
5
- return {
6
- name: 'email',
7
- message: message ?? 'The Email address is invalid.',
8
- optional: true,
9
- validate: baseEmail
10
- }
11
- }
@@ -1,38 +0,0 @@
1
- import { Rule } from './'
2
-
3
- interface Options {
4
- [name: string]: Rule[]
5
- }
6
-
7
- export default function every(options: Options): Rule {
8
- return {
9
- name: 'each',
10
- message: 'Error found in items.',
11
- optional: true,
12
- validate(value: Record<string, any>[], data): boolean {
13
- return value.every(item => check(options, item, data))
14
- }
15
- }
16
- }
17
-
18
- function check(
19
- options: Options,
20
- item: Record<string, any>,
21
- data: any
22
- ): boolean {
23
- for (const key in item) {
24
- const rules = options[key]
25
-
26
- if (!rules) {
27
- continue
28
- }
29
-
30
- const result = rules.every(rule => rule.validate(item[key], data))
31
-
32
- if (!result) {
33
- return false
34
- }
35
- }
36
-
37
- return true
38
- }
@@ -1,11 +0,0 @@
1
- import { include as baseInclude } from '../validators'
2
- import { Rule } from './'
3
-
4
- export default function required(other: string, message?: string): Rule {
5
- return {
6
- name: 'include',
7
- message: message ?? `The value must include ${other}.`,
8
- optional: true,
9
- validate: (value, data) => baseInclude(value, data[other])
10
- }
11
- }
@@ -1,11 +0,0 @@
1
- import { includeSome as baseIncludeSome } from '../validators'
2
- import { Rule } from './'
3
-
4
- export default function required(other: string, message?: string): Rule {
5
- return {
6
- name: 'includeSome',
7
- message: message ?? `The value must include some of ${other}.`,
8
- optional: true,
9
- validate: (value, data) => baseIncludeSome(value, data[other])
10
- }
11
- }
@@ -1,11 +0,0 @@
1
- import { integer as baseInteger } from '../validators'
2
- import { Rule } from './'
3
-
4
- export default function integer(message?: string): Rule {
5
- return {
6
- name: 'maxValue',
7
- message: message ?? 'The value must not contain decimals.',
8
- optional: true,
9
- validate: baseInteger
10
- }
11
- }
@@ -1,11 +0,0 @@
1
- import { maxValue as baseMaxValue } from '../validators'
2
- import { Rule } from './'
3
-
4
- export default function maxValue(max: number, message?: string): Rule {
5
- return {
6
- name: 'maxValue',
7
- message: message ?? `The value must be ${max} or less.`,
8
- optional: true,
9
- validate: value => baseMaxValue(value, max)
10
- }
11
- }
@@ -1,11 +0,0 @@
1
- import { minValue as baseMinValue } from '../validators'
2
- import { Rule } from './'
3
-
4
- export default function minValue(min: number, message?: string): Rule {
5
- return {
6
- name: 'minValue',
7
- message: message ?? `The value must be ${min} or more.`,
8
- optional: true,
9
- validate: value => baseMinValue(value, min)
10
- }
11
- }
@@ -1,11 +0,0 @@
1
- import { month as baseMonth } from '../validators'
2
- import { Rule } from './'
3
-
4
- export default function month(message?: string): Rule {
5
- return {
6
- name: 'month',
7
- message: message ?? 'The month is invalid.',
8
- optional: true,
9
- validate: baseMonth
10
- }
11
- }