@flyanra/vue-core 1.2.1 → 1.3.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 (63) hide show
  1. package/dist/types/composables/index.d.ts +4 -3
  2. package/dist/types/composables/useFeatureGate/index.d.ts +1 -0
  3. package/dist/types/composables/useFeatureGate/useFeatureGate.d.ts +6 -0
  4. package/dist/types/composables/useFormHider/index.d.ts +1 -0
  5. package/dist/types/composables/useFormHider/useFormHider.d.ts +8 -0
  6. package/dist/types/composables/useLocaleInjector/index.d.ts +2 -0
  7. package/dist/types/composables/useSidebarActiveIndex/index.d.ts +1 -0
  8. package/dist/types/composables/{useSidebarActiveIndex.d.ts → useSidebarActiveIndex/useSidebarActiveIndex.d.ts} +1 -1
  9. package/package.json +2 -2
  10. package/src/components/basic/fly-button/FlyButton.types.ts +28 -28
  11. package/src/components/basic/fly-button/FlyButton.vue +178 -178
  12. package/src/components/basic/typography/FlyCollapseTitleRenderer.vue +46 -46
  13. package/src/components/feedback/tooltip/FlyInfoTooltip.vue +49 -49
  14. package/src/components/feedback/tooltip/FlyTooltip.element.scss +4 -4
  15. package/src/components/feedback/tooltip/FlyTooltip.vue +60 -60
  16. package/src/components/form/form.utils.ts +72 -72
  17. package/src/components/form/index.ts +6 -6
  18. package/src/components/form/input-renderers/boolean/FlyBoolean.vue +48 -48
  19. package/src/components/form/input-renderers/form-item-renderer/FlyFormItemRenderer.vue +48 -48
  20. package/src/components/form/input-renderers/form-item-renderer/index.ts +4 -4
  21. package/src/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.types.ts +3 -3
  22. package/src/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.utils.ts +221 -221
  23. package/src/components/form/input-renderers/form-schema-renderer/FlyFormSchemaRenderer.vue +75 -75
  24. package/src/components/form/input-renderers/form-schema-renderer/UseFormSchemaRenderer.ts +97 -97
  25. package/src/components/form/input-renderers/input-renderer/FlyInputRenderer.vue +49 -49
  26. package/src/components/form/input-renderers/input-renderer/index.ts +4 -4
  27. package/src/components/form/input-renderers/input-renderer.utils.ts +18 -18
  28. package/src/components/form/input-renderers/number/FlyNumber.vue +64 -64
  29. package/src/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.types.ts +15 -15
  30. package/src/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.vue +99 -99
  31. package/src/components/form/input-renderers/select/FlySelect.scss +1 -1
  32. package/src/components/form/input-renderers/select/FlySelect.utils.ts +37 -37
  33. package/src/components/form/input-renderers/text/FlyText.vue +70 -70
  34. package/src/components/form/input-renderers/value-unit/FlyValueUnit.vue +102 -102
  35. package/src/components/form/input-validators.ts +99 -99
  36. package/src/components/general/fly-icon-v2/FlyIconV2.types.ts +6 -6
  37. package/src/components/general/fly-icon-v2/FlyIconV2.vue +17 -17
  38. package/src/components/general/fly-icon-v2/index.ts +6 -6
  39. package/src/components/general/index.ts +5 -5
  40. package/src/components/index.ts +7 -7
  41. package/src/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebar.types.ts +8 -8
  42. package/src/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebarItem.vue +55 -55
  43. package/src/components/navigation/menu/fly-sidebar/FlySidebar.types.ts +49 -49
  44. package/src/components/navigation/menu/fly-sidebar/FlySidebar.vue +146 -146
  45. package/src/components/navigation/menu/fly-sidebar/FlySidebarNode.vue +47 -47
  46. package/src/composables/index.ts +4 -4
  47. package/src/composables/useFeatureGate/index.ts +1 -0
  48. package/src/composables/useFeatureGate/useFeatureGate.ts +19 -0
  49. package/src/composables/useFormHider/index.ts +1 -0
  50. package/src/composables/useFormHider/useFormHider.ts +37 -0
  51. package/src/composables/{UseLocaleInjector.ts → useLocaleInjector/UseLocaleInjector.ts} +37 -37
  52. package/src/composables/useLocaleInjector/index.ts +2 -0
  53. package/src/composables/useSidebarActiveIndex/index.ts +1 -0
  54. package/src/composables/{useSidebarActiveIndex.ts → useSidebarActiveIndex/useSidebarActiveIndex.ts} +103 -103
  55. package/src/styles/element/mixins/collapse.scss +61 -61
  56. package/src/styles/element/overrides/form.scss +121 -121
  57. package/src/styles/element/overrides/message-box.scss +2 -2
  58. package/src/styles/element/overrides/radio.scss +2 -2
  59. package/src/styles/element/overrides/select.scss +9 -9
  60. package/src/utils/index.ts +2 -2
  61. package/src/utils/pure-functions.ts +15 -15
  62. package/src/utils/validators.ts +81 -81
  63. /package/dist/types/composables/{UseLocaleInjector.d.ts → useLocaleInjector/UseLocaleInjector.d.ts} +0 -0
@@ -1,99 +1,99 @@
1
- <template>
2
- <div class="fly-regional-tenant-form-renderer">
3
- <el-collapse v-if="sections?.length" v-model="activeNames" accordion>
4
- <el-collapse-item :name="E_CollapsibleSections.mainForm">
5
- <template #title>
6
- <FlyCollapseTitleRenderer :title="mainFormTitle" />
7
- </template>
8
-
9
- <div style="padding: 1rem">
10
- <slot></slot>
11
- </div>
12
- </el-collapse-item>
13
-
14
- <template v-for="section in sections">
15
- <el-collapse-item v-if="section.fields?.length" :key="section.key" :name="section.key">
16
- <template #title>
17
- <FlyCollapseTitleRenderer :title="section.title" />
18
- </template>
19
- <div style="padding: 1rem">
20
- <div v-if="section.description" style="margin-bottom: 1.25rem">
21
- <p style="font-size: 0.875; line-height: 1.25rem">
22
- {{ t(section.description) }}
23
- </p>
24
- </div>
25
-
26
- <FlyFormSchemaRenderer
27
- :ref="(el) => setFormRef(el, section.key)"
28
- v-model="section.modelValue"
29
- :lookup-data="section.lookupData"
30
- :form-config="section.fields"
31
- :column-span="6"
32
- />
33
- </div>
34
- </el-collapse-item>
35
- </template>
36
- </el-collapse>
37
-
38
- <div v-else>
39
- <slot></slot>
40
- </div>
41
- </div>
42
- </template>
43
-
44
- <script setup lang="ts">
45
- import { type ComponentPublicInstance, reactive, ref } from 'vue'
46
-
47
- import { ElCollapse, ElCollapseItem } from 'element-plus'
48
-
49
- import { UseLocaleInjector } from '../../../../composables/UseLocaleInjector'
50
- import '../../../../styles/element/overrides/collapse.scss'
51
- import FlyCollapseTitleRenderer from '../../../basic/typography/FlyCollapseTitleRenderer.vue'
52
- import type { T_FlyFormSchemaRendererInstance } from '../form-schema-renderer/FlyFormSchemaRenderer.types'
53
- import FlyFormSchemaRenderer from '../form-schema-renderer/FlyFormSchemaRenderer.vue'
54
-
55
- import type { T_TenantRegionalFormProps } from './FlyRegionalTenantFormRenderer.types'
56
-
57
- enum E_CollapsibleSections {
58
- mainForm
59
- }
60
-
61
- defineProps<T_TenantRegionalFormProps>()
62
-
63
- const { t } = UseLocaleInjector()
64
-
65
- const activeNames = ref<string | number>(E_CollapsibleSections.mainForm)
66
- const formRefs = reactive<{ [K: string]: T_FlyFormSchemaRendererInstance }>({})
67
-
68
- function setFormRef(formRef: Element | ComponentPublicInstance | null, key: string) {
69
- if (formRef) {
70
- formRefs[key] = formRef as T_FlyFormSchemaRendererInstance
71
- }
72
- }
73
-
74
- async function validateForms() {
75
- const keys = Object.keys(formRefs)
76
- for (let index = 0; index < keys.length; index++) {
77
- const element = formRefs[keys[index]]
78
- const hasErrors = await element?.validateForm()
79
- if (!hasErrors) continue
80
- return hasErrors
81
- }
82
-
83
- return
84
- }
85
-
86
- defineExpose({
87
- validateForms
88
- })
89
- </script>
90
-
91
- <style lang="scss" scoped>
92
- @use '../../../../styles/element/mixins/collapse.scss' as el-collapse-mixin;
93
-
94
- .fly-regional-tenant-form-renderer {
95
- :deep(.el-collapse) {
96
- @include el-collapse-mixin.el-collapse-operation-style;
97
- }
98
- }
99
- </style>
1
+ <template>
2
+ <div class="fly-regional-tenant-form-renderer">
3
+ <el-collapse v-if="sections?.length" v-model="activeNames" accordion>
4
+ <el-collapse-item :name="E_CollapsibleSections.mainForm">
5
+ <template #title>
6
+ <FlyCollapseTitleRenderer :title="mainFormTitle" />
7
+ </template>
8
+
9
+ <div style="padding: 1rem">
10
+ <slot></slot>
11
+ </div>
12
+ </el-collapse-item>
13
+
14
+ <template v-for="section in sections">
15
+ <el-collapse-item v-if="section.fields?.length" :key="section.key" :name="section.key">
16
+ <template #title>
17
+ <FlyCollapseTitleRenderer :title="section.title" />
18
+ </template>
19
+ <div style="padding: 1rem">
20
+ <div v-if="section.description" style="margin-bottom: 1.25rem">
21
+ <p style="font-size: 0.875; line-height: 1.25rem">
22
+ {{ t(section.description) }}
23
+ </p>
24
+ </div>
25
+
26
+ <FlyFormSchemaRenderer
27
+ :ref="(el) => setFormRef(el, section.key)"
28
+ v-model="section.modelValue"
29
+ :lookup-data="section.lookupData"
30
+ :form-config="section.fields"
31
+ :column-span="6"
32
+ />
33
+ </div>
34
+ </el-collapse-item>
35
+ </template>
36
+ </el-collapse>
37
+
38
+ <div v-else>
39
+ <slot></slot>
40
+ </div>
41
+ </div>
42
+ </template>
43
+
44
+ <script setup lang="ts">
45
+ import { type ComponentPublicInstance, reactive, ref } from 'vue'
46
+
47
+ import { ElCollapse, ElCollapseItem } from 'element-plus'
48
+
49
+ import { UseLocaleInjector } from '../../../../composables/useLocaleInjector/UseLocaleInjector'
50
+ import '../../../../styles/element/overrides/collapse.scss'
51
+ import FlyCollapseTitleRenderer from '../../../basic/typography/FlyCollapseTitleRenderer.vue'
52
+ import type { T_FlyFormSchemaRendererInstance } from '../form-schema-renderer/FlyFormSchemaRenderer.types'
53
+ import FlyFormSchemaRenderer from '../form-schema-renderer/FlyFormSchemaRenderer.vue'
54
+
55
+ import type { T_TenantRegionalFormProps } from './FlyRegionalTenantFormRenderer.types'
56
+
57
+ enum E_CollapsibleSections {
58
+ mainForm
59
+ }
60
+
61
+ defineProps<T_TenantRegionalFormProps>()
62
+
63
+ const { t } = UseLocaleInjector()
64
+
65
+ const activeNames = ref<string | number>(E_CollapsibleSections.mainForm)
66
+ const formRefs = reactive<{ [K: string]: T_FlyFormSchemaRendererInstance }>({})
67
+
68
+ function setFormRef(formRef: Element | ComponentPublicInstance | null, key: string) {
69
+ if (formRef) {
70
+ formRefs[key] = formRef as T_FlyFormSchemaRendererInstance
71
+ }
72
+ }
73
+
74
+ async function validateForms() {
75
+ const keys = Object.keys(formRefs)
76
+ for (let index = 0; index < keys.length; index++) {
77
+ const element = formRefs[keys[index]]
78
+ const hasErrors = await element?.validateForm()
79
+ if (!hasErrors) continue
80
+ return hasErrors
81
+ }
82
+
83
+ return
84
+ }
85
+
86
+ defineExpose({
87
+ validateForms
88
+ })
89
+ </script>
90
+
91
+ <style lang="scss" scoped>
92
+ @use '../../../../styles/element/mixins/collapse.scss' as el-collapse-mixin;
93
+
94
+ .fly-regional-tenant-form-renderer {
95
+ :deep(.el-collapse) {
96
+ @include el-collapse-mixin.el-collapse-operation-style;
97
+ }
98
+ }
99
+ </style>
@@ -1 +1 @@
1
- @use '../../../../styles/element/overrides/select.scss';
1
+ @use '../../../../styles/element/overrides/select.scss';
@@ -1,37 +1,37 @@
1
- import { isArray, isObject } from 'lodash-es'
2
-
3
- import type {
4
- T_InputLabelValue,
5
- T_InputSelectOption,
6
- T_InputSelectOptionList
7
- } from './FlySelect.types'
8
-
9
- export function normalizeSelectOptionsToDict(
10
- options: T_InputSelectOptionList
11
- ): Record<string, T_InputLabelValue> {
12
- // already a dict: Record<string, {label,value}>
13
- if (!isArray(options)) {
14
- const out: Record<string, T_InputLabelValue> = {}
15
- Object.keys(options).forEach((k) => {
16
- const item = options[k]
17
- out[String(item.value)] = item
18
- })
19
- return out
20
- }
21
-
22
- // array: (string|number) OR {label,value}
23
- const out: Record<string, T_InputLabelValue> = {}
24
- options.forEach((opt: T_InputSelectOption) => {
25
- if (isObject(opt)) {
26
- const lv = opt as T_InputLabelValue
27
- out[String(lv.value)] = lv
28
- } else {
29
- // primitive option => label=value
30
- out[String(opt)] = {
31
- label: String(opt),
32
- value: opt
33
- }
34
- }
35
- })
36
- return out
37
- }
1
+ import { isArray, isObject } from 'lodash-es'
2
+
3
+ import type {
4
+ T_InputLabelValue,
5
+ T_InputSelectOption,
6
+ T_InputSelectOptionList
7
+ } from './FlySelect.types'
8
+
9
+ export function normalizeSelectOptionsToDict(
10
+ options: T_InputSelectOptionList
11
+ ): Record<string, T_InputLabelValue> {
12
+ // already a dict: Record<string, {label,value}>
13
+ if (!isArray(options)) {
14
+ const out: Record<string, T_InputLabelValue> = {}
15
+ Object.keys(options).forEach((k) => {
16
+ const item = options[k]
17
+ out[String(item.value)] = item
18
+ })
19
+ return out
20
+ }
21
+
22
+ // array: (string|number) OR {label,value}
23
+ const out: Record<string, T_InputLabelValue> = {}
24
+ options.forEach((opt: T_InputSelectOption) => {
25
+ if (isObject(opt)) {
26
+ const lv = opt as T_InputLabelValue
27
+ out[String(lv.value)] = lv
28
+ } else {
29
+ // primitive option => label=value
30
+ out[String(opt)] = {
31
+ label: String(opt),
32
+ value: opt
33
+ }
34
+ }
35
+ })
36
+ return out
37
+ }
@@ -1,70 +1,70 @@
1
- <template>
2
- <el-input
3
- v-model="inputProxy"
4
- v-maska="inputType === 'text' ? input?.mask : undefined"
5
- style="width: 100%"
6
- :type="inputType"
7
- v-bind="input?.attrs"
8
- :placeholder="input?.placeholder"
9
- show-word-limit
10
- @change="(val) => emit('change', castValue(val))"
11
- @blur="() => emit('blur')"
12
- @focus="() => emit('focus')"
13
- >
14
- </el-input>
15
- </template>
16
-
17
- <script setup lang="ts">
18
- import { computed, watch } from 'vue'
19
-
20
- import { ElInput } from 'element-plus'
21
-
22
- import { vMaska } from 'maska/vue'
23
-
24
- import { getInputDisplayValue } from '../input-renderer.utils'
25
-
26
- import './FlyText.scss'
27
- import type { T_InputText, T_InputTextValues } from './FlyText.types'
28
-
29
- const emit = defineEmits<{
30
- (e: 'update:modelValue', v: T_InputTextValues): void
31
- (e: 'change', v: T_InputTextValues): void
32
- (e: 'blur'): void
33
- (e: 'focus'): void
34
- }>()
35
-
36
- const props = defineProps<{
37
- modelValue?: T_InputTextValues
38
- input?: T_InputText
39
- }>()
40
-
41
- const inputType = computed(() => props.input?.attrs?.type || 'text')
42
-
43
- const inputProxy = computed({
44
- get: () => {
45
- return getInputDisplayValue(props.modelValue, 'text')
46
- },
47
- set: (v) => {
48
- const parsed = castValue(v)
49
- emit('update:modelValue', parsed)
50
- }
51
- })
52
-
53
- function castValue(v: unknown) {
54
- return v ? String(v) : ''
55
- }
56
-
57
- watch(
58
- () => props.modelValue,
59
- () => {
60
- const parsed = castValue(props.modelValue)
61
-
62
- if (parsed !== props.modelValue) {
63
- emit('update:modelValue', parsed)
64
- }
65
- },
66
- {
67
- immediate: true
68
- }
69
- )
70
- </script>
1
+ <template>
2
+ <el-input
3
+ v-model="inputProxy"
4
+ v-maska="inputType === 'text' ? input?.mask : undefined"
5
+ style="width: 100%"
6
+ :type="inputType"
7
+ v-bind="input?.attrs"
8
+ :placeholder="input?.placeholder"
9
+ show-word-limit
10
+ @change="(val) => emit('change', castValue(val))"
11
+ @blur="() => emit('blur')"
12
+ @focus="() => emit('focus')"
13
+ >
14
+ </el-input>
15
+ </template>
16
+
17
+ <script setup lang="ts">
18
+ import { computed, watch } from 'vue'
19
+
20
+ import { ElInput } from 'element-plus'
21
+
22
+ import { vMaska } from 'maska/vue'
23
+
24
+ import { getInputDisplayValue } from '../input-renderer.utils'
25
+
26
+ import './FlyText.scss'
27
+ import type { T_InputText, T_InputTextValues } from './FlyText.types'
28
+
29
+ const emit = defineEmits<{
30
+ (e: 'update:modelValue', v: T_InputTextValues): void
31
+ (e: 'change', v: T_InputTextValues): void
32
+ (e: 'blur'): void
33
+ (e: 'focus'): void
34
+ }>()
35
+
36
+ const props = defineProps<{
37
+ modelValue?: T_InputTextValues
38
+ input?: T_InputText
39
+ }>()
40
+
41
+ const inputType = computed(() => props.input?.attrs?.type || 'text')
42
+
43
+ const inputProxy = computed({
44
+ get: () => {
45
+ return getInputDisplayValue(props.modelValue, 'text')
46
+ },
47
+ set: (v) => {
48
+ const parsed = castValue(v)
49
+ emit('update:modelValue', parsed)
50
+ }
51
+ })
52
+
53
+ function castValue(v: unknown) {
54
+ return v ? String(v) : ''
55
+ }
56
+
57
+ watch(
58
+ () => props.modelValue,
59
+ () => {
60
+ const parsed = castValue(props.modelValue)
61
+
62
+ if (parsed !== props.modelValue) {
63
+ emit('update:modelValue', parsed)
64
+ }
65
+ },
66
+ {
67
+ immediate: true
68
+ }
69
+ )
70
+ </script>
@@ -1,102 +1,102 @@
1
- <template>
2
- <el-input
3
- v-model="valueProxy"
4
- style="width: 100%"
5
- :type="valueTypeIsString ? 'text' : 'number'"
6
- v-bind="input?.attrs"
7
- :placeholder="input?.placeholder"
8
- @change="(v) => emit('change', getValue(v))"
9
- @blur="() => emit('blur')"
10
- @focus="() => emit('focus')"
11
- >
12
- <template #append>
13
- <el-select
14
- v-bind="input?.unitsAttr"
15
- v-model="unitProxy"
16
- style="width: 100px"
17
- filterable
18
- :placeholder="input?.unitPlaceholder"
19
- @change="(v) => emit('change', getUnit(v))"
20
- @blur="() => emit('blur')"
21
- @focus="() => emit('focus')"
22
- >
23
- <el-option
24
- v-for="unit in options"
25
- :key="unit.value"
26
- :value="unit.value"
27
- :label="unit.label"
28
- />
29
- </el-select>
30
- </template>
31
- </el-input>
32
- </template>
33
-
34
- <script setup lang="ts">
35
- import { computed } from 'vue'
36
-
37
- import { ElInput, ElOption, ElSelect } from 'element-plus'
38
-
39
- import { getInputDisplayValue } from '../input-renderer.utils'
40
- import { displayToNumber } from '../number/FlyNumber.utils'
41
- import { normalizeSelectOptionsToDict } from '../select/FlySelect.utils'
42
-
43
- import './FlyValueUnit.scss'
44
- import type { T_InputValueUnit, T_ValueUnitValue } from './FlyValueUnit.types'
45
-
46
- const emit = defineEmits<{
47
- (e: 'update:modelValue', v: T_ValueUnitValue): void
48
- (e: 'change', v: T_ValueUnitValue): void
49
- (e: 'blur'): void
50
- (e: 'focus'): void
51
- }>()
52
-
53
- const props = defineProps<{
54
- modelValue?: T_ValueUnitValue
55
- input?: T_InputValueUnit
56
- }>()
57
-
58
- const options = computed(() => normalizeSelectOptionsToDict(props.input?.config?.options || []))
59
-
60
- const valueTypeIsString = computed(() => props.input?.config?.valueType === 'text')
61
-
62
- const valueProxy = computed({
63
- get: () => {
64
- const v = getInputDisplayValue(
65
- props.modelValue?.value,
66
- valueTypeIsString.value ? 'text' : 'number'
67
- )
68
- return v
69
- },
70
- set: (v) => {
71
- emit('update:modelValue', getValue(v))
72
- }
73
- })
74
-
75
- const unitProxy = computed({
76
- get: () => props.modelValue?.unit ?? undefined,
77
- set: (u) => {
78
- emit('update:modelValue', getUnit(u))
79
- }
80
- })
81
-
82
- function ensure(): NonNullable<T_ValueUnitValue> {
83
- return {
84
- value: props.modelValue?.value ?? undefined,
85
- unit: props.modelValue?.unit ?? undefined
86
- }
87
- }
88
-
89
- function getValue(v: string | number) {
90
- const base = ensure()
91
- const parsed = valueTypeIsString.value ? v : displayToNumber(v)
92
-
93
- const next = { ...base, value: parsed }
94
- return next
95
- }
96
-
97
- function getUnit(u: NonNullable<T_ValueUnitValue>['unit']) {
98
- const base = ensure()
99
- const next = { ...base, unit: u }
100
- return next
101
- }
102
- </script>
1
+ <template>
2
+ <el-input
3
+ v-model="valueProxy"
4
+ style="width: 100%"
5
+ :type="valueTypeIsString ? 'text' : 'number'"
6
+ v-bind="input?.attrs"
7
+ :placeholder="input?.placeholder"
8
+ @change="(v) => emit('change', getValue(v))"
9
+ @blur="() => emit('blur')"
10
+ @focus="() => emit('focus')"
11
+ >
12
+ <template #append>
13
+ <el-select
14
+ v-bind="input?.unitsAttr"
15
+ v-model="unitProxy"
16
+ style="width: 100px"
17
+ filterable
18
+ :placeholder="input?.unitPlaceholder"
19
+ @change="(v) => emit('change', getUnit(v))"
20
+ @blur="() => emit('blur')"
21
+ @focus="() => emit('focus')"
22
+ >
23
+ <el-option
24
+ v-for="unit in options"
25
+ :key="unit.value"
26
+ :value="unit.value"
27
+ :label="unit.label"
28
+ />
29
+ </el-select>
30
+ </template>
31
+ </el-input>
32
+ </template>
33
+
34
+ <script setup lang="ts">
35
+ import { computed } from 'vue'
36
+
37
+ import { ElInput, ElOption, ElSelect } from 'element-plus'
38
+
39
+ import { getInputDisplayValue } from '../input-renderer.utils'
40
+ import { displayToNumber } from '../number/FlyNumber.utils'
41
+ import { normalizeSelectOptionsToDict } from '../select/FlySelect.utils'
42
+
43
+ import './FlyValueUnit.scss'
44
+ import type { T_InputValueUnit, T_ValueUnitValue } from './FlyValueUnit.types'
45
+
46
+ const emit = defineEmits<{
47
+ (e: 'update:modelValue', v: T_ValueUnitValue): void
48
+ (e: 'change', v: T_ValueUnitValue): void
49
+ (e: 'blur'): void
50
+ (e: 'focus'): void
51
+ }>()
52
+
53
+ const props = defineProps<{
54
+ modelValue?: T_ValueUnitValue
55
+ input?: T_InputValueUnit
56
+ }>()
57
+
58
+ const options = computed(() => normalizeSelectOptionsToDict(props.input?.config?.options || []))
59
+
60
+ const valueTypeIsString = computed(() => props.input?.config?.valueType === 'text')
61
+
62
+ const valueProxy = computed({
63
+ get: () => {
64
+ const v = getInputDisplayValue(
65
+ props.modelValue?.value,
66
+ valueTypeIsString.value ? 'text' : 'number'
67
+ )
68
+ return v
69
+ },
70
+ set: (v) => {
71
+ emit('update:modelValue', getValue(v))
72
+ }
73
+ })
74
+
75
+ const unitProxy = computed({
76
+ get: () => props.modelValue?.unit ?? undefined,
77
+ set: (u) => {
78
+ emit('update:modelValue', getUnit(u))
79
+ }
80
+ })
81
+
82
+ function ensure(): NonNullable<T_ValueUnitValue> {
83
+ return {
84
+ value: props.modelValue?.value ?? undefined,
85
+ unit: props.modelValue?.unit ?? undefined
86
+ }
87
+ }
88
+
89
+ function getValue(v: string | number) {
90
+ const base = ensure()
91
+ const parsed = valueTypeIsString.value ? v : displayToNumber(v)
92
+
93
+ const next = { ...base, value: parsed }
94
+ return next
95
+ }
96
+
97
+ function getUnit(u: NonNullable<T_ValueUnitValue>['unit']) {
98
+ const base = ensure()
99
+ const next = { ...base, unit: u }
100
+ return next
101
+ }
102
+ </script>