@flyanra/vue-core 0.3.0 → 1.0.0

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 (118) hide show
  1. package/dist/types/components/basic/fly-button/FlyButton.types.d.ts +2 -3
  2. package/dist/types/components/basic/typography/FlyCollapseTitleRenderer.vue.d.ts +16 -0
  3. package/dist/types/components/feedback/tooltip/FlyInfoTooltip.vue.d.ts +36 -0
  4. package/dist/types/components/feedback/tooltip/FlyTooltip.vue.d.ts +1 -0
  5. package/dist/types/components/form/form.utils.d.ts +11 -0
  6. package/dist/types/components/form/index.d.ts +5 -0
  7. package/dist/types/components/form/input-renderers/boolean/FlyBoolean.types.d.ts +14 -0
  8. package/dist/types/components/form/input-renderers/boolean/FlyBoolean.vue.d.ts +15 -0
  9. package/dist/types/components/form/input-renderers/date-time/FlyDateTime.types.d.ts +20 -0
  10. package/dist/types/components/form/input-renderers/date-time/FlyDateTime.vue.d.ts +19 -0
  11. package/dist/types/components/form/input-renderers/form-item-renderer/FlyFormItemRenderer.vue.d.ts +19 -0
  12. package/dist/types/components/form/input-renderers/form-item-renderer/index.d.ts +3 -0
  13. package/dist/types/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.types.d.ts +2 -0
  14. package/dist/types/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.utils.d.ts +21 -0
  15. package/dist/types/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.vue.d.ts +17 -0
  16. package/dist/types/components/form/input-renderers/form-schema-renderer/UseFormSchemaRenderer.d.ts +25 -0
  17. package/dist/types/components/form/input-renderers/form-schema.types.d.ts +77 -0
  18. package/dist/types/components/form/input-renderers/input-renderer/FlyInputRenderer.vue.d.ts +18 -0
  19. package/dist/types/components/form/input-renderers/input-renderer/index.d.ts +3 -0
  20. package/dist/types/components/form/input-renderers/input-renderer.types.d.ts +30 -0
  21. package/dist/types/components/form/input-renderers/input-renderer.utils.d.ts +2 -0
  22. package/dist/types/components/form/input-renderers/number/FlyNumber.types.d.ts +13 -0
  23. package/dist/types/components/form/input-renderers/number/FlyNumber.utils.d.ts +1 -0
  24. package/dist/types/components/form/input-renderers/number/FlyNumber.vue.d.ts +19 -0
  25. package/dist/types/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.types.d.ts +13 -0
  26. package/dist/types/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.vue.d.ts +20 -0
  27. package/dist/types/components/form/input-renderers/select/FlySelect.types.d.ts +22 -0
  28. package/dist/types/components/form/input-renderers/select/FlySelect.utils.d.ts +2 -0
  29. package/dist/types/components/form/input-renderers/select/FlySelect.vue.d.ts +19 -0
  30. package/dist/types/components/form/input-renderers/text/FlyText.types.d.ts +18 -0
  31. package/dist/types/components/form/input-renderers/text/FlyText.vue.d.ts +19 -0
  32. package/dist/types/components/form/input-renderers/value-unit/FlyValueUnit.types.d.ts +23 -0
  33. package/dist/types/components/form/input-renderers/value-unit/FlyValueUnit.vue.d.ts +19 -0
  34. package/dist/types/components/form/input-validators.d.ts +12 -0
  35. package/dist/types/components/general/fly-icon-v2/FlyIconV2.types.d.ts +5 -0
  36. package/dist/types/components/general/fly-icon-v2/FlyIconV2.vue.d.ts +4 -0
  37. package/dist/types/components/general/fly-icon-v2/index.d.ts +4 -0
  38. package/dist/types/components/general/index.d.ts +2 -0
  39. package/dist/types/components/index.d.ts +1 -4
  40. package/dist/types/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebar.types.d.ts +2 -2
  41. package/dist/types/components/navigation/menu/fly-sidebar/FlySidebar.types.d.ts +2 -2
  42. package/dist/types/composables/UseLocaleInjector.d.ts +8 -0
  43. package/dist/types/composables/index.d.ts +1 -0
  44. package/dist/types/utils/pure-functions.d.ts +1 -0
  45. package/dist/types/utils/validators.d.ts +8 -0
  46. package/package.json +26 -8
  47. package/src/components/basic/fly-button/FlyButton.types.ts +2 -3
  48. package/src/components/basic/fly-button/FlyButton.vue +4 -6
  49. package/src/components/basic/typography/FlyCollapseTitleRenderer.vue +46 -0
  50. package/src/components/feedback/tooltip/FlyInfoTooltip.vue +49 -0
  51. package/src/components/feedback/tooltip/FlyTooltip.element.scss +1 -1
  52. package/src/components/feedback/tooltip/FlyTooltip.vue +1 -0
  53. package/src/components/form/form.utils.ts +72 -0
  54. package/src/components/form/index.ts +6 -0
  55. package/src/components/form/input-renderers/boolean/FlyBoolean.scss +1 -0
  56. package/src/components/form/input-renderers/boolean/FlyBoolean.types.ts +16 -0
  57. package/src/components/form/input-renderers/boolean/FlyBoolean.vue +48 -0
  58. package/src/components/form/input-renderers/date-time/FlyDateTime.scss +1 -0
  59. package/src/components/form/input-renderers/date-time/FlyDateTime.types.ts +21 -0
  60. package/src/components/form/input-renderers/date-time/FlyDateTime.vue +85 -0
  61. package/src/components/form/input-renderers/form-item-renderer/FlyFormItemRenderer.scss +4 -0
  62. package/src/components/form/input-renderers/form-item-renderer/FlyFormItemRenderer.vue +48 -0
  63. package/src/components/form/input-renderers/form-item-renderer/index.ts +4 -0
  64. package/src/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.types.ts +3 -0
  65. package/src/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.utils.ts +221 -0
  66. package/src/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.vue +75 -0
  67. package/src/components/form/input-renderers/form-schema-renderer/UseFormSchemaRenderer.ts +97 -0
  68. package/src/components/form/input-renderers/form-schema.types.ts +95 -0
  69. package/src/components/form/input-renderers/input-renderer/FlyInputRenderer.vue +49 -0
  70. package/src/components/form/input-renderers/input-renderer/index.ts +4 -0
  71. package/src/components/form/input-renderers/input-renderer.types.ts +49 -0
  72. package/src/components/form/input-renderers/input-renderer.utils.ts +18 -0
  73. package/src/components/form/input-renderers/number/FlyNumber.scss +1 -0
  74. package/src/components/form/input-renderers/number/FlyNumber.types.ts +13 -0
  75. package/src/components/form/input-renderers/number/FlyNumber.utils.ts +6 -0
  76. package/src/components/form/input-renderers/number/FlyNumber.vue +64 -0
  77. package/src/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.types.ts +15 -0
  78. package/src/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.vue +99 -0
  79. package/src/components/form/input-renderers/select/FlySelect.scss +1 -0
  80. package/src/components/form/input-renderers/select/FlySelect.types.ts +25 -0
  81. package/src/components/form/input-renderers/select/FlySelect.utils.ts +37 -0
  82. package/src/components/form/input-renderers/select/FlySelect.vue +48 -0
  83. package/src/components/form/input-renderers/text/FlyText.scss +1 -0
  84. package/src/components/form/input-renderers/text/FlyText.types.ts +20 -0
  85. package/src/components/form/input-renderers/text/FlyText.vue +70 -0
  86. package/src/components/form/input-renderers/value-unit/FlyValueUnit.scss +2 -0
  87. package/src/components/form/input-renderers/value-unit/FlyValueUnit.types.ts +28 -0
  88. package/src/components/form/input-renderers/value-unit/FlyValueUnit.vue +102 -0
  89. package/src/components/form/input-validators.ts +99 -0
  90. package/src/components/general/fly-icon-v2/FlyIconV2.types.ts +6 -0
  91. package/src/components/general/fly-icon-v2/FlyIconV2.vue +17 -0
  92. package/src/components/general/fly-icon-v2/index.ts +6 -0
  93. package/src/components/general/index.ts +3 -0
  94. package/src/components/index.ts +2 -6
  95. package/src/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebar.types.ts +2 -2
  96. package/src/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebarItem.vue +2 -2
  97. package/src/components/navigation/menu/fly-sidebar/FlySidebar.types.ts +2 -2
  98. package/src/components/navigation/menu/fly-sidebar/FlySidebar.vue +5 -4
  99. package/src/components/navigation/menu/fly-sidebar/FlySidebarNode.vue +3 -3
  100. package/src/styles/element/mixins/collapse.scss +2 -2
  101. package/src/styles/element/overrides/date-time.scss +11 -0
  102. package/src/styles/element/overrides/form.scss +26 -12
  103. package/src/styles/element/overrides/message-box.scss +2 -0
  104. package/src/styles/element/overrides/radio.scss +2 -0
  105. package/src/styles/element/overrides/select.scss +9 -0
  106. package/dist/types/components/AppButton/AppButton.types.d.ts +0 -8
  107. package/dist/types/components/AppButton/AppButton.vue.d.ts +0 -20
  108. package/dist/types/components/AppButton/index.d.ts +0 -4
  109. package/dist/types/components/AppCard/AppCard.types.d.ts +0 -5
  110. package/dist/types/components/AppCard/AppCard.vue.d.ts +0 -17
  111. package/dist/types/components/AppCard/index.d.ts +0 -4
  112. package/src/components/AppButton/AppButton.element.scss +0 -2
  113. package/src/components/AppButton/AppButton.types.ts +0 -10
  114. package/src/components/AppButton/AppButton.vue +0 -65
  115. package/src/components/AppButton/index.ts +0 -6
  116. package/src/components/AppCard/AppCard.types.ts +0 -5
  117. package/src/components/AppCard/AppCard.vue +0 -58
  118. package/src/components/AppCard/index.ts +0 -6
@@ -0,0 +1,4 @@
1
+ import FlyIconV2 from './FlyIconV2.vue';
2
+ export default FlyIconV2;
3
+ export { FlyIconV2 };
4
+ export type { T_FlyIconV2Props } from './FlyIconV2.types.ts';
@@ -1,2 +1,4 @@
1
1
  export { default as FlyIcon } from './fly-icon';
2
2
  export type * from './fly-icon';
3
+ export { default as T_FlyIconV2 } from './fly-icon-v2';
4
+ export type * from './fly-icon-v2';
@@ -1,8 +1,5 @@
1
- export { default as AppButton } from './AppButton';
2
- export type * from './AppButton';
3
- export { default as AppCard } from './AppCard';
4
- export type * from './AppCard';
5
1
  export * from './navigation';
6
2
  export * from './basic';
7
3
  export * from './feedback';
8
4
  export * from './general';
5
+ export * from './form';
@@ -1,7 +1,7 @@
1
- import type { T_FlyIconProps } from '../../../general/fly-icon';
1
+ import type { T_FlyIconV2Props } from '../../../general/fly-icon-v2/FlyIconV2.types';
2
2
  export type T_FlyMiniSidebarItem = {
3
3
  key: string | number;
4
4
  label: string;
5
5
  path: string;
6
- icon: T_FlyIconProps;
6
+ icon: T_FlyIconV2Props['icon'];
7
7
  };
@@ -1,8 +1,8 @@
1
- import type { T_FlyIconProps } from '../../../general/fly-icon/FlyIcon.types';
1
+ import type { T_FlyIconV2Props } from '../../../general';
2
2
  export type T_FlySidebarBase = {
3
3
  index: string;
4
4
  label?: string;
5
- icon?: T_FlyIconProps;
5
+ icon?: T_FlyIconV2Props['icon'];
6
6
  disabled?: boolean;
7
7
  };
8
8
  export type T_FlySidebarItem = T_FlySidebarBase & {
@@ -0,0 +1,8 @@
1
+ import type { Locale } from '@flyanra/js-utils/locales';
2
+ import type { ComposerTranslation } from 'vue-i18n';
3
+ type T_LocaleInjector = {
4
+ t: ComposerTranslation;
5
+ locale: Locale;
6
+ };
7
+ export declare function UseLocaleInjector(): T_LocaleInjector;
8
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export declare function checkRange(value: unknown, min?: number, max?: number): boolean;
@@ -0,0 +1,8 @@
1
+ import type { FormItemRule } from 'element-plus';
2
+ export declare const isRequiredError: (languageKey: string) => string;
3
+ type RangeObject = {
4
+ min?: number;
5
+ max?: number;
6
+ };
7
+ export declare const checkInputRange: (languageKey: string | undefined, range: RangeObject, valueTypeLanguageKey?: string, errorMessage?: string) => FormItemRule["validator"];
8
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flyanra/vue-core",
3
- "version": "0.3.0",
3
+ "version": "1.0.0",
4
4
  "private": false,
5
5
  "description": "Source-distributed Vue component library for Vite and Nuxt consumers.",
6
6
  "sideEffects": false,
@@ -30,6 +30,14 @@
30
30
  "types": "./dist/types/components/*/index.d.ts",
31
31
  "import": "./src/components/*/index.ts"
32
32
  },
33
+ "./composables": {
34
+ "types": "./dist/types/composables/index.d.ts",
35
+ "import": "./src/composables/index.ts"
36
+ },
37
+ "./composables/*": {
38
+ "types": "./dist/types/composables/*/index.d.ts",
39
+ "import": "./src/composables/*/index.ts"
40
+ },
33
41
  "./package.json": "./package.json"
34
42
  },
35
43
  "types": "./dist/types/index.d.ts",
@@ -79,13 +87,15 @@
79
87
  "devDependencies": {
80
88
  "@changesets/cli": "^2.30.0",
81
89
  "@eslint/js": "^10.0.1",
90
+ "@flyanra/js-utils": "^1.3.2",
91
+ "@iconify-json/ri": "^1.2.10",
82
92
  "@jamescoyle/vue-icon": "^0.1.2",
83
93
  "@mdi/js": "^7.4.47",
84
94
  "@remixicon/vue": "^4.9.0",
85
- "@storybook/addon-a11y": "^10.3.5",
86
- "@storybook/addon-docs": "^10.3.5",
87
- "@storybook/addon-vitest": "^10.3.5",
88
- "@storybook/vue3-vite": "^10.3.5",
95
+ "@storybook/addon-a11y": "^10.3.6",
96
+ "@storybook/addon-docs": "^10.3.6",
97
+ "@storybook/addon-vitest": "^10.3.6",
98
+ "@storybook/vue3-vite": "^10.3.6",
89
99
  "@tailwindcss/vite": "^4.2.2",
90
100
  "@trivago/prettier-plugin-sort-imports": "^6.0.2",
91
101
  "@types/node": "^24.12.2",
@@ -93,33 +103,41 @@
93
103
  "@vitest/browser-playwright": "^4.1.4",
94
104
  "@vitest/coverage-v8": "^4.1.4",
95
105
  "@vue/tsconfig": "^0.9.1",
106
+ "dompurify": "^3.4.2",
96
107
  "element-plus": "^2.13.7",
97
108
  "eslint": "^10.2.0",
98
109
  "eslint-config-prettier": "^10.1.8",
99
- "eslint-plugin-storybook": "^10.3.5",
110
+ "eslint-plugin-storybook": "^10.3.6",
100
111
  "eslint-plugin-vue": "^10.8.0",
101
112
  "globals": "^17.5.0",
102
113
  "husky": "^9.1.7",
103
114
  "lint-staged": "^16.4.0",
115
+ "lodash-es": "^4.18.1",
116
+ "maska": "^3.2.0",
104
117
  "playwright": "^1.59.1",
105
118
  "prettier": "^3.8.3",
106
119
  "prettier-plugin-packagejson": "^3.0.2",
107
120
  "sass": "^1.99.0",
108
- "storybook": "^10.3.5",
121
+ "storybook": "^10.3.6",
109
122
  "storybook-vue3-router": "^7.0.0",
110
123
  "tailwindcss": "^4.2.2",
111
124
  "typescript": "~6.0.2",
112
125
  "typescript-eslint": "^8.58.2",
126
+ "unplugin-icons": "^23.0.1",
113
127
  "vite": "^8.0.4",
114
128
  "vitest": "^4.1.4",
115
129
  "vue": "^3.5.32",
116
130
  "vue-eslint-parser": "^10.4.0",
131
+ "vue-i18n": "^11.4.0",
117
132
  "vue-tsc": "^3.2.6"
118
133
  },
119
134
  "peerDependencies": {
135
+ "@flyanra/js-utils": "^1.3.2",
120
136
  "@jamescoyle/vue-icon": "^0.1.2",
121
137
  "element-plus": "^2.13.7",
122
- "vue": "^3.5.32"
138
+ "maska": "^3.2.0",
139
+ "vue": "^3.5.32",
140
+ "vue-i18n": "^11.4.0"
123
141
  },
124
142
  "volta": {
125
143
  "node": "24.12.0",
@@ -1,6 +1,6 @@
1
1
  import type { ButtonType, ElButton, UseTooltipProps } from 'element-plus'
2
2
 
3
- import type { T_FlyIconTypes } from '../../general/fly-icon/FlyIcon.types'
3
+ import type { T_FlyIconV2Props } from '../../general'
4
4
 
5
5
  export type FlyButtonIconPosition = 'left' | 'right'
6
6
 
@@ -16,9 +16,8 @@ export type FlyButtonProps = {
16
16
  */
17
17
  clipRound?: boolean
18
18
  full?: boolean
19
- icon?: string | object
19
+ icon?: T_FlyIconV2Props['icon']
20
20
  iconPosition?: FlyButtonIconPosition
21
- iconType?: T_FlyIconTypes
22
21
  imageUrl?: string
23
22
  label?: string
24
23
  size?: FlyButtonSizes
@@ -13,18 +13,16 @@
13
13
  :class="[{ active, 'aspect-1': aspect1 }]"
14
14
  @click="handleClick"
15
15
  >
16
- <FlyIcon
16
+ <FlyIconV2
17
17
  v-if="icon && resolvedIconPosition === 'left'"
18
- :type="iconType"
19
18
  :icon="icon"
20
19
  :class="[{ 'left-icon': slots.default }]"
21
20
  />
22
21
 
23
22
  <slot></slot>
24
23
 
25
- <FlyIcon
24
+ <FlyIconV2
26
25
  v-if="icon && resolvedIconPosition === 'right'"
27
- :type="iconType"
28
26
  :icon="icon"
29
27
  :class="[{ 'right-icon': slots.default }]"
30
28
  />
@@ -42,10 +40,10 @@ import { computed, useAttrs, useSlots } from 'vue'
42
40
 
43
41
  import { ElButton } from 'element-plus'
44
42
 
45
- import { isEmpty } from 'lodash'
43
+ import { isEmpty } from 'lodash-es'
46
44
 
47
45
  import FlyTooltip from '../../feedback/tooltip/FlyTooltip.vue'
48
- import FlyIcon from '../../general/fly-icon/FlyIcon.vue'
46
+ import FlyIconV2 from '../../general/fly-icon-v2/FlyIconV2.vue'
49
47
 
50
48
  import './FlyButton.element.scss'
51
49
  import type { FlyButtonIconPosition, FlyButtonProps } from './FlyButton.types'
@@ -0,0 +1,46 @@
1
+ <template>
2
+ <div class="fly-collapse-title-renderer">
3
+ <div class="fly-collapse-title-renderer__inner">
4
+ <p class="fly-collapse-title-renderer__title">
5
+ {{ t(title) }}
6
+ </p>
7
+
8
+ <slot></slot>
9
+ </div>
10
+ </div>
11
+ </template>
12
+
13
+ <script lang="ts" setup>
14
+ import { UseLocaleInjector } from '../../../composables/UseLocaleInjector'
15
+
16
+ defineProps<{
17
+ title: string
18
+ }>()
19
+
20
+ const { t } = UseLocaleInjector()
21
+ </script>
22
+
23
+ <style lang="scss" scoped>
24
+ .fly-collapse-title-renderer {
25
+ display: flex;
26
+ gap: 0.25rem;
27
+ align-items: center;
28
+ text-align: left;
29
+ flex-grow: 1;
30
+
31
+ &__inner {
32
+ display: flex;
33
+ padding-left: 0.5rem;
34
+ padding-right: 0.5rem;
35
+ flex-grow: 1;
36
+ align-items: center;
37
+ }
38
+
39
+ &__title {
40
+ font-size: 0.875rem;
41
+ line-height: 1.25rem;
42
+ font-weight: 500;
43
+ flex-grow: 1;
44
+ }
45
+ }
46
+ </style>
@@ -0,0 +1,49 @@
1
+ <template>
2
+ <span class="fly-info-tooltip">
3
+ <FlyTooltip
4
+ v-if="content"
5
+ :tooltip="{
6
+ content: DOMPurify.sanitize(content)
7
+ }"
8
+ >
9
+ <slot name="trigger">
10
+ <FlyIcon class="tw-cursor-pointer" :icon="mdiInformationSlabBoxOutline" />
11
+ </slot>
12
+ <template #content>
13
+ <!-- eslint-disable-next-line vue/no-v-html -->
14
+ <div v-if="html" v-html="DOMPurify.sanitize(content)"></div>
15
+ <slot v-else></slot>
16
+ </template>
17
+ </FlyTooltip>
18
+ </span>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ import { mdiInformationSlabBoxOutline } from '@mdi/js'
23
+ import DOMPurify from 'dompurify'
24
+
25
+ import FlyIcon from '../../general/fly-icon/FlyIcon.vue'
26
+
27
+ import FlyTooltip from './FlyTooltip.vue'
28
+
29
+ defineProps({
30
+ content: {
31
+ type: String,
32
+ default: ''
33
+ },
34
+ html: {
35
+ type: Boolean,
36
+ default: false
37
+ }
38
+ })
39
+ </script>
40
+
41
+ <style lang="scss" scoped>
42
+ .fly-info-tooltip {
43
+ :deep(.app-icon) {
44
+ svg {
45
+ display: inline;
46
+ }
47
+ }
48
+ }
49
+ </style>
@@ -1,4 +1,4 @@
1
- @use '../../../../styles/element/common.scss' as *;
1
+ @use '../../../styles//element/common.scss' as *;
2
2
 
3
3
  @use 'element-plus/theme-chalk/src/popper.scss' as *;
4
4
  @use 'element-plus/theme-chalk/src/tooltip.scss' as *;
@@ -19,6 +19,7 @@ import { computed } from 'vue'
19
19
 
20
20
  import { ElTooltip, type UseTooltipProps } from 'element-plus'
21
21
 
22
+ import './FlyTooltip.element.scss'
22
23
  import type { T_FlyTooltipProps } from './FlyTooltip.types'
23
24
 
24
25
  const props = defineProps<T_FlyTooltipProps>()
@@ -0,0 +1,72 @@
1
+ import type { FormInstance } from 'element-plus'
2
+
3
+ import { UseLocaleInjector } from '../../composables/UseLocaleInjector'
4
+
5
+ export type ValidateFieldsError = { [K: string]: { message?: string }[] }
6
+
7
+ /**
8
+ * @returns Translated error message based on active locale
9
+ */
10
+ export function formFieldErrorMessageFormatter(errors: ValidateFieldsError) {
11
+ const { t, locale } = UseLocaleInjector()
12
+ const keys = Object.keys(errors)
13
+
14
+ if (keys.length) {
15
+ const requiredFieldNames: (string | undefined)[] = []
16
+ const otherErrors: (string | undefined)[] = []
17
+ let formFieldErrorMessage = ''
18
+
19
+ keys.forEach((k) => {
20
+ const msg = errors[k][0].message
21
+ const index = msg?.indexOf(t ? t('validation.isRequired') : 'validation.isRequired')
22
+
23
+ if (index && index >= 0) {
24
+ requiredFieldNames.push(msg?.slice(0, index)?.trim())
25
+ } else {
26
+ otherErrors.push(msg)
27
+ }
28
+ })
29
+
30
+ const requiredFieldsLength = requiredFieldNames.length
31
+ const otherErrorsLength = otherErrors.length
32
+
33
+ if (requiredFieldsLength >= 1) {
34
+ const joinedList = new Intl.ListFormat(locale, {
35
+ style: 'long',
36
+ type: 'conjunction'
37
+ }).format(requiredFieldNames.filter((item): item is string => Boolean(item)))
38
+
39
+ formFieldErrorMessage = t
40
+ ? t('validation.requiredFields', {
41
+ field: joinedList,
42
+ count: requiredFieldNames.length
43
+ })
44
+ : joinedList
45
+ }
46
+
47
+ if (otherErrorsLength) {
48
+ if (formFieldErrorMessage) formFieldErrorMessage += ' || ' // temporary
49
+ otherErrors.forEach((e, i) => {
50
+ formFieldErrorMessage += e + `${i === otherErrorsLength - 1 ? '' : ' || '}` // temporary
51
+ })
52
+ }
53
+
54
+ return formFieldErrorMessage
55
+ }
56
+
57
+ return t ? t('validation.someInputsInvalid') : 'validation.someInputsInvalid'
58
+ }
59
+
60
+ export async function genericFormValidator(formRef: FormInstance): Promise<true> {
61
+ return new Promise((resolve, reject) => {
62
+ formRef.validate((valid, errors) => {
63
+ if (!valid) {
64
+ if (errors) {
65
+ return reject(formFieldErrorMessageFormatter(errors))
66
+ }
67
+ } else {
68
+ return resolve(true)
69
+ }
70
+ })
71
+ })
72
+ }
@@ -0,0 +1,6 @@
1
+ export * from './input-renderers/form-item-renderer'
2
+ export * from './input-renderers/input-renderer'
3
+
4
+ export type { T_InputRendererBase } from './input-renderers/input-renderer.types'
5
+ export * from './input-validators'
6
+ export * from './form.utils'
@@ -0,0 +1 @@
1
+ @use 'element-plus/theme-chalk/src/switch.scss' as *;
@@ -0,0 +1,16 @@
1
+ export type T_InputBooleanValues = string | number | boolean | undefined
2
+
3
+ export type T_InputBooleanBase = T_InputBoolean & {
4
+ type: 'boolean'
5
+ placeholder?: string
6
+ }
7
+
8
+ export type T_InputBoolean = {
9
+ /**
10
+ * Attrs are passed directly to the input element as props
11
+ */
12
+ attrs?: {
13
+ activeText?: string
14
+ inactiveText?: string
15
+ }
16
+ }
@@ -0,0 +1,48 @@
1
+ <template>
2
+ <el-switch
3
+ v-model="inputProxy"
4
+ v-bind="input?.attrs"
5
+ @change="(v) => emit('change', v)"
6
+ ></el-switch>
7
+ </template>
8
+
9
+ <script setup lang="ts">
10
+ import { computed, watch } from 'vue'
11
+
12
+ import { ElSwitch } from 'element-plus'
13
+
14
+ import './FlyBoolean.scss'
15
+ import type { T_InputBoolean, T_InputBooleanValues } from './FlyBoolean.types'
16
+
17
+ const emit = defineEmits<{
18
+ (e: 'update:modelValue', v: T_InputBooleanValues): void
19
+ (e: 'change', v: T_InputBooleanValues): void
20
+ }>()
21
+
22
+ const props = defineProps<{
23
+ modelValue?: T_InputBooleanValues
24
+ input?: T_InputBoolean
25
+ }>()
26
+
27
+ const inputProxy = computed({
28
+ get: () => {
29
+ return Boolean(props.modelValue)
30
+ },
31
+ set: (v) => {
32
+ emit('update:modelValue', Boolean(v))
33
+ }
34
+ })
35
+
36
+ watch(
37
+ () => props.modelValue,
38
+ () => {
39
+ const parsed = Boolean(props.modelValue)
40
+ if (parsed !== props.modelValue) {
41
+ emit('update:modelValue', parsed)
42
+ }
43
+ },
44
+ {
45
+ immediate: true
46
+ }
47
+ )
48
+ </script>
@@ -0,0 +1 @@
1
+ @use '../../../../styles/element/overrides/date-time.scss';
@@ -0,0 +1,21 @@
1
+ export type T_DateTimeRawValue = Date | [Date, Date] | undefined
2
+ export type T_DateTimeValues = string | string[] | undefined
3
+
4
+ export type T_DateInputTypes = 'date' | 'dateTime' | 'dateRange' | 'dateTimeRange'
5
+
6
+ export type T_InputDateTimeBase = T_InputDateTime & {
7
+ type: 'dateTime'
8
+ }
9
+
10
+ export type T_InputDateTime = {
11
+ placeholder?: string
12
+ startPlaceholder?: string
13
+ endPlaceholder?: string
14
+ /**
15
+ * Attrs are passed directly to the input element as props
16
+ */
17
+ attrs?: { [K: string]: unknown }
18
+ config?: {
19
+ inputType?: T_DateInputTypes // defaults to dateTime
20
+ }
21
+ }
@@ -0,0 +1,85 @@
1
+ <template>
2
+ <el-date-picker
3
+ v-model="inputProxy"
4
+ style="width: 100%"
5
+ :type="inputTypeMap[input?.config?.inputType || 'dateTime']"
6
+ :popper-options="{
7
+ modifiers: [
8
+ {
9
+ name: 'preventOverflow',
10
+ options: {
11
+ padding: 8
12
+ }
13
+ }
14
+ ]
15
+ }"
16
+ :placeholder="input?.placeholder"
17
+ :start-placeholder="input?.startPlaceholder"
18
+ :end-placeholder="input?.endPlaceholder"
19
+ @change="(val: T_DateTimeRawValue) => emit('change', parseValueForEmit(val))"
20
+ @blur="() => emit('blur')"
21
+ @focus="() => emit('focus')"
22
+ />
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ import { computed } from 'vue'
27
+
28
+ import { type DatePickerProps, ElDatePicker } from 'element-plus'
29
+
30
+ import './FlyDateTime.scss'
31
+ import type { T_DateTimeRawValue, T_DateTimeValues, T_InputDateTime } from './FlyDateTime.types'
32
+
33
+ const emit = defineEmits<{
34
+ (e: 'update:modelValue', v: T_DateTimeValues): void
35
+ (e: 'change', v: T_DateTimeValues): void
36
+ (e: 'blur'): void
37
+ (e: 'focus'): void
38
+ }>()
39
+
40
+ const props = defineProps<{
41
+ modelValue?: T_DateTimeValues
42
+ input?: T_InputDateTime
43
+ }>()
44
+
45
+ const inputTypeMap: Record<string, DatePickerProps['type']> = {
46
+ date: 'date',
47
+ dateTime: 'datetime',
48
+ dateRange: 'daterange',
49
+ dateTimeRange: 'datetimerange'
50
+ }
51
+
52
+ const isRange = computed(
53
+ () =>
54
+ props.input?.config?.inputType === 'dateRange' ||
55
+ props.input?.config?.inputType === 'dateTimeRange'
56
+ )
57
+
58
+ const inputProxy = computed({
59
+ get: (): T_DateTimeRawValue => {
60
+ if (!props.modelValue) return undefined
61
+
62
+ if (isRange.value && Array.isArray(props.modelValue)) {
63
+ const d = props.modelValue.map((d) => new Date(d))
64
+ return [d[0], d[1]]
65
+ }
66
+
67
+ return new Date(props.modelValue as string)
68
+ },
69
+ set: (v) => {
70
+ emit('update:modelValue', parseValueForEmit(v))
71
+ }
72
+ })
73
+
74
+ function parseValueForEmit(v: T_DateTimeRawValue) {
75
+ if (!v) {
76
+ return undefined
77
+ }
78
+
79
+ if (isRange.value && Array.isArray(v)) {
80
+ return v.map((d: Date) => d.toISOString())
81
+ }
82
+
83
+ return (v as Date).toISOString()
84
+ }
85
+ </script>
@@ -0,0 +1,4 @@
1
+ @use 'element-plus/theme-chalk/src/form.scss';
2
+ @use 'element-plus/theme-chalk/src/form-item.scss';
3
+
4
+ @use 'element-plus/theme-chalk/src/icon.scss';
@@ -0,0 +1,48 @@
1
+ <template>
2
+ <el-form-item :prop="input.prop || input.key">
3
+ <template #label>
4
+ <FlyInfoTooltip v-if="input.tooltip" :content="input.tooltip" />
5
+ {{ t(input.label) }}
6
+ </template>
7
+
8
+ <FlyInputRenderer
9
+ v-model="modelProxy"
10
+ :input="input"
11
+ @change="(val: unknown) => emit('change', val)"
12
+ @blur="() => emit('blur')"
13
+ @focus="() => emit('focus')"
14
+ />
15
+ </el-form-item>
16
+ </template>
17
+
18
+ <script setup lang="ts">
19
+ import { computed } from 'vue'
20
+
21
+ import { ElFormItem } from 'element-plus'
22
+
23
+ import { UseLocaleInjector } from '../../../../composables/UseLocaleInjector'
24
+ import FlyInfoTooltip from '../../../feedback/tooltip/FlyInfoTooltip.vue'
25
+ import type { T_InputRendererBase } from '../input-renderer.types'
26
+ import FlyInputRenderer from '../input-renderer/FlyInputRenderer.vue'
27
+
28
+ import './FlyFormItemRenderer.scss'
29
+
30
+ const props = defineProps<{
31
+ modelValue: unknown
32
+ input: T_InputRendererBase
33
+ }>()
34
+
35
+ const emit = defineEmits<{
36
+ (e: 'update:modelValue', value: unknown): void
37
+ (e: 'change', value: unknown): void
38
+ (e: 'blur'): void
39
+ (e: 'focus'): void
40
+ }>()
41
+
42
+ const { t } = UseLocaleInjector()
43
+
44
+ const modelProxy = computed({
45
+ get: () => props.modelValue,
46
+ set: (val) => emit('update:modelValue', val)
47
+ })
48
+ </script>
@@ -0,0 +1,4 @@
1
+ import FlyFormItemRenderer from './FlyFormItemRenderer.vue'
2
+
3
+ export default FlyFormItemRenderer
4
+ export { FlyFormItemRenderer }
@@ -0,0 +1,3 @@
1
+ import type FlyFormSchemaRenderer from './FlyFormSchemaRenderer.vue'
2
+
3
+ export type T_FlyFormSchemaRendererInstance = InstanceType<typeof FlyFormSchemaRenderer> | null