@globalbrain/sefirot 2.0.0-draft.8 → 2.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 (97) hide show
  1. package/README.md +6 -6
  2. package/lib/components/SAvatar.vue +17 -17
  3. package/lib/components/SButton.vue +512 -267
  4. package/lib/components/SButtonGroup.vue +149 -0
  5. package/lib/components/SDropdown.vue +26 -150
  6. package/lib/components/SDropdownSection.vue +48 -0
  7. package/lib/components/SDropdownSectionFilter.vue +189 -0
  8. package/lib/components/SDropdownSectionFilterItem.vue +21 -0
  9. package/lib/components/SDropdownSectionFilterItemAvatar.vue +31 -0
  10. package/lib/components/SDropdownSectionFilterItemText.vue +20 -0
  11. package/lib/components/SDropdownSectionMenu.vue +39 -0
  12. package/lib/components/SIcon.vue +13 -0
  13. package/lib/components/SInputBase.vue +31 -31
  14. package/lib/components/SInputCheckbox.vue +1 -1
  15. package/lib/components/SInputCheckboxes.vue +74 -0
  16. package/lib/components/SInputDate.vue +182 -0
  17. package/lib/components/SInputDropdown.vue +158 -157
  18. package/lib/components/SInputDropdownItem.vue +46 -48
  19. package/lib/components/{SInputDropdownItemUserTag.vue → SInputDropdownItemAvatar.vue} +43 -44
  20. package/lib/components/SInputDropdownItemText.vue +79 -16
  21. package/lib/components/SInputFile.vue +55 -60
  22. package/lib/components/SInputHMS.vue +120 -110
  23. package/lib/components/SInputNumber.vue +38 -9
  24. package/lib/components/SInputRadio.vue +39 -36
  25. package/lib/components/SInputRadios.vue +40 -53
  26. package/lib/components/SInputSelect.vue +3 -3
  27. package/lib/components/SInputSwitch.vue +193 -0
  28. package/lib/components/SInputSwitches.vue +88 -0
  29. package/lib/components/SInputText.vue +206 -62
  30. package/lib/components/SInputTextarea.vue +46 -32
  31. package/lib/components/SInputYMD.vue +123 -126
  32. package/lib/components/SMarkdown.vue +52 -0
  33. package/lib/components/SModal.vue +25 -63
  34. package/lib/components/SMount.vue +19 -0
  35. package/lib/components/SSheet.vue +49 -55
  36. package/lib/components/SSheetFooter.vue +1 -1
  37. package/lib/components/SSheetFooterAction.vue +24 -17
  38. package/lib/components/SSheetFooterActions.vue +1 -4
  39. package/lib/components/SSheetForm.vue +15 -0
  40. package/lib/components/SSheetMedium.vue +8 -10
  41. package/lib/components/SSheetTitle.vue +7 -14
  42. package/lib/components/SSnackbar.vue +55 -45
  43. package/lib/components/{SPortalSnackbars.vue → SSnackbars.vue} +17 -20
  44. package/lib/components/SStep.vue +106 -0
  45. package/lib/components/SSteps.vue +59 -0
  46. package/lib/components/STable.vue +241 -0
  47. package/lib/components/STableCell.vue +82 -0
  48. package/lib/components/STableCellAvatar.vue +69 -0
  49. package/lib/components/STableCellAvatars.vue +93 -0
  50. package/lib/components/STableCellDay.vue +40 -0
  51. package/lib/components/STableCellPill.vue +84 -0
  52. package/lib/components/STableCellText.vue +102 -0
  53. package/lib/components/STableColumn.vue +255 -0
  54. package/lib/components/STableFooter.vue +115 -0
  55. package/lib/components/STableHeader.vue +74 -0
  56. package/lib/components/STableItem.vue +38 -0
  57. package/lib/components/STooltip.vue +112 -0
  58. package/lib/composables/Dropdown.ts +40 -99
  59. package/lib/composables/Form.ts +21 -18
  60. package/lib/composables/Grid.ts +117 -0
  61. package/lib/composables/Markdown.ts +138 -0
  62. package/lib/composables/Step.ts +7 -0
  63. package/lib/composables/Table.ts +103 -0
  64. package/lib/composables/Tooltip.ts +91 -0
  65. package/lib/composables/Validation.ts +5 -9
  66. package/lib/composables/markdown/LinkPlugin.ts +45 -0
  67. package/lib/mixins/Sheet.ts +5 -3
  68. package/lib/stores/Snackbars.ts +48 -0
  69. package/lib/{assets/styles → styles}/base.css +0 -0
  70. package/lib/{assets/styles → styles}/bootstrap.css +1 -0
  71. package/lib/{assets/styles → styles}/variables.css +55 -48
  72. package/lib/support/Day.ts +8 -0
  73. package/lib/support/Num.ts +3 -0
  74. package/lib/support/Time.ts +5 -2
  75. package/lib/support/Utils.ts +4 -3
  76. package/lib/types/shims.d.ts +3 -0
  77. package/lib/validation/validators/requiredYmd.ts +1 -1
  78. package/lib/validation/validators/ymd.ts +4 -4
  79. package/package.json +57 -37
  80. package/CHANGELOG.md +0 -47
  81. package/lib/.DS_Store +0 -0
  82. package/lib/components/.DS_Store +0 -0
  83. package/lib/components/SDialog.vue +0 -140
  84. package/lib/components/SDropdownItem.vue +0 -78
  85. package/lib/components/SDropdownItemText.vue +0 -22
  86. package/lib/components/SDropdownItemUser.vue +0 -40
  87. package/lib/components/SInputDropdownItemTextTag.vue +0 -94
  88. package/lib/components/SInputDropdownItemUser.vue +0 -41
  89. package/lib/components/SPortalModals.vue +0 -74
  90. package/lib/components/icons/.DS_Store +0 -0
  91. package/lib/composables/Dialog.ts +0 -38
  92. package/lib/composables/Modal.ts +0 -34
  93. package/lib/composables/Snackbar.ts +0 -18
  94. package/lib/store/Sefirot.ts +0 -17
  95. package/lib/store/dialog/index.ts +0 -42
  96. package/lib/store/modal/index.ts +0 -61
  97. package/lib/store/snackbars/index.ts +0 -70
@@ -1,28 +1,91 @@
1
+ <script setup lang="ts">
2
+ import SIconX from './icons/SIconX.vue'
3
+
4
+ defineProps<{
5
+ label: string
6
+ value: string | number | boolean
7
+ disabled: boolean
8
+ }>()
9
+
10
+ defineEmits<{
11
+ (e: 'remove', value: string | number | boolean): void
12
+ }>()
13
+ </script>
14
+
1
15
  <template>
2
- <div class="SInputDropdownItemText" :class="{ mute, disabled }">
3
- <p class="text">{{ item.text }}</p>
16
+ <div class="SInputDropdownItemText" :class="{ disabled }">
17
+ <p class="text">{{ label }}</p>
18
+
19
+ <div v-if="!disabled" class="remove" role="button" @click.stop="$emit('remove', value)">
20
+ <div class="remove-box">
21
+ <SIconX class="remove-icon" />
22
+ </div>
23
+ </div>
4
24
  </div>
5
25
  </template>
6
26
 
7
- <script setup lang="ts">
8
- import { PropType } from 'vue'
27
+ <style lang="postcss" scoped>
28
+ .SInputDropdownItemText {
29
+ display: flex;
30
+ border: 1px solid var(--c-divider-light);
31
+ border-radius: 14px;
32
+ padding: 0 0 0 12px;
33
+ background-color: var(--c-bg-mute);
34
+ }
9
35
 
10
- const props = defineProps({
11
- mute: { type: Boolean, default: false },
12
- item: { type: Object as PropType<any>, required: true },
13
- disabled: { type: Boolean, default: false }
14
- })
15
- </script>
36
+ .SInputDropdownItemText.disabled {
37
+ padding: 0 10px 0;
38
+ background-color: var(--c-gray-light-4);
16
39
 
17
- <style lang="postcss" scoped>
18
- .SInputDropdownItemText.mute .text {
19
- color: var(--input-placeholder);
40
+ .text {
41
+ color: var(--c-text-2);
42
+ }
43
+ }
44
+
45
+ .dark .SInputDropdownItemText.disabled {
46
+ background-color: var(--c-gray-dark-2);
20
47
  }
21
48
 
22
49
  .text {
23
50
  margin: 0;
24
- padding: 0 8px;
25
- font-size: 14px;
26
- font-weight: 400;
51
+ line-height: 26px;
52
+ font-size: 12px;
53
+ font-weight: 500;
54
+ white-space: nowrap;
55
+ }
56
+
57
+ .remove {
58
+ display: flex;
59
+ justify-content: center;
60
+ align-items: center;
61
+ width: 26px;
62
+ height: 26px;
63
+ }
64
+
65
+ .remove-box {
66
+ display: flex;
67
+ justify-content: center;
68
+ align-items: center;
69
+ border-radius: 50%;
70
+ width: 20px;
71
+ height: 20px;
72
+ color: var(--c-text-2);
73
+ transition: color 0.25s, background-color 0.25s;
74
+
75
+ .remove:hover & {
76
+ color: var(--c-text-1);
77
+ background-color: var(--c-gray-light-3)
78
+ }
79
+
80
+ .dark .remove:hover & {
81
+ color: var(--c-text-1);
82
+ background-color: var(--c-gray-dark-3)
83
+ }
84
+ }
85
+
86
+ .remove-icon {
87
+ width: 12px;
88
+ height: 12px;
89
+ fill: currentColor;
27
90
  }
28
91
  </style>
@@ -1,3 +1,47 @@
1
+ <script setup lang="ts">
2
+ import { ref, computed } from 'vue'
3
+ import { Validatable } from '../composables/Validation'
4
+ import SInputBase from './SInputBase.vue'
5
+
6
+ export type Size = 'mini' | 'small' | 'medium'
7
+
8
+ const props = defineProps<{
9
+ size?: Size
10
+ label?: string
11
+ text?: string
12
+ note?: string
13
+ help?: string
14
+ placeholder?: string
15
+ modelValue: File | null
16
+ hideError?: boolean
17
+ validation?: Validatable
18
+ }>()
19
+
20
+ const emit = defineEmits<{
21
+ (e: 'update:modelValue', file: File | null): void
22
+ }>()
23
+
24
+ const input = ref<HTMLInputElement | null>(null)
25
+
26
+ const classes = computed(() => [props.size ?? 'small'])
27
+
28
+ const fileName = computed(() => {
29
+ return props.modelValue ? props.modelValue.name : null
30
+ })
31
+
32
+ function open(): void {
33
+ input.value!.click()
34
+ }
35
+
36
+ function handleChange(e: Event): void {
37
+ const file = (e.target as any).files[0]
38
+
39
+ emit('update:modelValue', file ?? null)
40
+
41
+ file && props.validation?.$touch()
42
+ }
43
+ </script>
44
+
1
45
  <template>
2
46
  <SInputBase
3
47
  class="SInputFile"
@@ -5,7 +49,7 @@
5
49
  :label="label"
6
50
  :note="note"
7
51
  :help="help"
8
- :error-message="errorMessage"
52
+ :hide-error="hideError"
9
53
  :validation="validation"
10
54
  >
11
55
  <input
@@ -18,7 +62,7 @@
18
62
  <div class="box" role="button" @click="open">
19
63
  <div class="action">
20
64
  <button class="button">
21
- {{ text }}
65
+ {{ text ?? 'Choose File' }}
22
66
  </button>
23
67
  </div>
24
68
 
@@ -30,48 +74,6 @@
30
74
  </SInputBase>
31
75
  </template>
32
76
 
33
- <script setup lang="ts">
34
- import { PropType, ref, computed } from 'vue'
35
- import { Validation, Validatable } from '../composables/Validation'
36
- import SInputBase from './SInputBase.vue'
37
-
38
- type Size = 'mini' | 'small' | 'medium'
39
-
40
- const props = defineProps({
41
- size: { type: String as PropType<Size>, default: 'small' },
42
- label: { type: String, default: null },
43
- note: { type: String, default: null },
44
- text: { type: String, default: 'Choose File' },
45
- help: { type: String, default: null },
46
- placeholder: { type: String, default: null },
47
- errorMessage: { type: Boolean, default: true },
48
- modelValue: { type: Object as PropType<File | null>, default: null },
49
- validation: { type: Object as PropType<Validatable>, default: null }
50
- })
51
-
52
- const emit = defineEmits(['update:modelValue'])
53
-
54
- const input = ref<HTMLInputElement | null>(null)
55
-
56
- const classes = computed(() => [props.size])
57
-
58
- const fileName = computed(() => {
59
- return props.modelValue ? props.modelValue.name : null
60
- })
61
-
62
- function open(): void {
63
- input.value!.click()
64
- }
65
-
66
- function handleChange(e: Event): void {
67
- const file = (e.target as any).files[0]
68
-
69
- emit('update:modelValue', file ?? null)
70
-
71
- file && props.validation?.$touch()
72
- }
73
- </script>
74
-
75
77
  <style lang="postcss" scoped>
76
78
  .SInputFile.mini {
77
79
  .action {
@@ -152,25 +154,22 @@ function handleChange(e: Event): void {
152
154
 
153
155
  .box {
154
156
  display: flex;
155
- border: 1px solid var(--input-border);
157
+ border: 1px solid var(--c-divider);
156
158
  border-radius: 4px;
159
+ background-color: var(--c-bg);
157
160
  cursor: pointer;
158
161
  transition: border-color .25s;
159
162
 
160
163
  &:hover {
161
- border-color: var(--input-focus-border);
164
+ border-color: var(--c-black);
162
165
 
163
166
  .button {
164
- background-color: var(--c-gray-light-4);
167
+ background-color: var(--c-bg-soft);
165
168
  }
166
169
  }
167
- }
168
170
 
169
- .dark .box {
170
- &:hover {
171
- .button {
172
- background-color: var(--c-gray-dark-3);
173
- }
171
+ .dark &:hover {
172
+ border-color: var(--c-gray);
174
173
  }
175
174
  }
176
175
 
@@ -182,17 +181,13 @@ function handleChange(e: Event): void {
182
181
  border: 1px solid var(--c-divider-light);
183
182
  border-radius: 4px;
184
183
  color: var(--c-text-1);
185
- background-color: var(--c-white-mute);
186
- transition: background-color .25s;
187
- }
188
-
189
- .dark .button {
190
- background-color: var(--c-black-mute);
184
+ background-color: var(--c-bg-mute);
191
185
  transition: background-color .25s;
192
186
  }
193
187
 
194
188
  .text {
195
189
  flex-grow: 1;
190
+ font-weight: 500;
196
191
  overflow: hidden;
197
192
  }
198
193
 
@@ -207,6 +202,6 @@ function handleChange(e: Event): void {
207
202
  }
208
203
 
209
204
  .placeholder {
210
- color: var(--input-placeholder);
205
+ color: var(--c-text-2);
211
206
  }
212
207
  </style>
@@ -1,86 +1,37 @@
1
- <template>
2
- <SInputBase
3
- class="SInputHMS"
4
- :class="[size, { disabled }]"
5
- :label="label"
6
- :note="note"
7
- :help="help"
8
- :error-message="errorMessage"
9
- :validation="validation"
10
- >
11
- <div class="container">
12
- <input
13
- v-if="hour"
14
- class="input hour"
15
- :value="modelValue?.hour ?? null"
16
- placeholder="00"
17
- :disabled="disabled"
18
- @blur="updateHour"
19
- >
20
- <div v-if="hour && minute" class="separator" />
21
- <input
22
- v-if="minute"
23
- class="input minute"
24
- :value="modelValue?.minute ?? null"
25
- placeholder="00"
26
- :disabled="disabled"
27
- @blur="updateMinute"
28
- >
29
- <div v-if="minute && second" class="separator" />
30
- <input
31
- v-if="second"
32
- class="input second"
33
- :value="modelValue?.second ?? null"
34
- placeholder="00"
35
- :disabled="disabled"
36
- @blur="updateSecond"
37
- >
38
- </div>
39
-
40
- <template #before-help>
41
- <slot name="before-help" />
42
- </template>
43
- </SInputBase>
44
- </template>
45
-
46
1
  <script setup lang="ts">
47
- import { PropType } from 'vue'
48
- import { SyntheticInputEvent } from '../types/Utils'
2
+ import { ref } from 'vue'
49
3
  import { Validatable } from '../composables/Validation'
50
4
  import SInputBase from './SInputBase.vue'
51
5
 
52
- type Size = 'mini' | 'small' | 'medium'
6
+ export type Size = 'mini' | 'small' | 'medium'
53
7
 
54
- interface Value {
55
- hour?: string
56
- minute?: string
57
- second?: string
8
+ export interface Value {
9
+ hour: string | null
10
+ minute: string | null
11
+ second: string | null
58
12
  }
59
13
 
60
- type ValueType = 'hour' | 'minute' | 'second'
14
+ export type ValueType = 'hour' | 'minute' | 'second'
61
15
 
62
- interface Fields {
63
- hour?: boolean
64
- minute?: boolean
65
- second?: boolean
66
- }
16
+ const props = defineProps<{
17
+ size?: Size
18
+ label?: string
19
+ note?: string
20
+ help?: string
21
+ noHour?: boolean
22
+ noMinute?: boolean
23
+ noSecond?: boolean
24
+ disabled?: boolean
25
+ hideError?: boolean
26
+ modelValue: Value
27
+ validation?: Validatable
28
+ }>()
67
29
 
68
- const props = defineProps({
69
- size: { type: String as PropType<Size>, default: 'small' },
70
- label: { type: String, default: null },
71
- note: { type: String, default: null },
72
- help: { type: String, default: null },
73
- placeholder: { type: String, default: null },
74
- hour: { type: Boolean, default: true },
75
- minute: { type: Boolean, default: true },
76
- second: { type: Boolean, default: true },
77
- disabled: { type: Boolean, default: false },
78
- errorMessage: { type: Boolean, default: true },
79
- modelValue: { type: Object as PropType<Value>, default: null },
80
- validation: { type: Object as PropType<Validatable>, default: null }
81
- })
82
-
83
- const emit = defineEmits(['update:modelValue'])
30
+ const emit = defineEmits<{
31
+ (e: 'update:modelValue', value: Value): void
32
+ }>()
33
+
34
+ const isFocused = ref(false)
84
35
 
85
36
  const touched = {
86
37
  hour: false,
@@ -88,53 +39,45 @@ const touched = {
88
39
  second: false
89
40
  }
90
41
 
91
- function updateHour(e: FocusEvent): void {
92
- const value = getValue((e.target as HTMLInputElement).value)
42
+ function onFocus() {
43
+ isFocused.value = true
44
+ }
93
45
 
94
- update('hour', value)
46
+ function blur() {
47
+ isFocused.value = false
95
48
  }
96
49
 
97
- function updateMinute(e: FocusEvent): void {
98
- const value = getValue((e.target as HTMLInputElement).value)
50
+ function updateHour(e: FocusEvent): void {
51
+ update('hour', getValue((e.target as HTMLInputElement).value))
52
+ }
99
53
 
100
- update('minute', value ? value.padStart(2, '0') : undefined)
54
+ function updateMinute(e: FocusEvent): void {
55
+ update('minute', getValue((e.target as HTMLInputElement).value))
101
56
  }
102
57
 
103
58
  function updateSecond(e: FocusEvent): void {
104
- const value = getValue((e.target as HTMLInputElement).value)
105
-
106
- update('second', value ? value.padStart(2, '0') : undefined)
59
+ update('second', getValue((e.target as HTMLInputElement).value))
107
60
  }
108
61
 
109
- function update(type: ValueType, value?: string): void {
110
- const data = { ...props.modelValue } as Value
111
-
112
- setValue(data, type, value)
113
-
114
- data.hour === undefined && data.minute === undefined && data.second === undefined
115
- ? emit('update:modelValue', null)
116
- : emit('update:modelValue', data)
62
+ function update(type: ValueType, value: string | null) {
63
+ emit('update:modelValue', {
64
+ ...props.modelValue,
65
+ [type]: value !== null ? value.padStart(2, '0') : null
66
+ })
117
67
 
118
68
  emitTouch(type)
69
+
70
+ blur()
119
71
  }
120
72
 
121
- function getValue(value: string): string | undefined {
73
+ function getValue(value: string): string | null {
122
74
  if (value === '') {
123
- return undefined
75
+ return null
124
76
  }
125
77
 
126
78
  const input = Number(value)
127
79
 
128
- return isNaN(input) ? undefined : String(input)
129
- }
130
-
131
- function setValue(data: Value, type: ValueType, value?: string): void {
132
- if (value === undefined) {
133
- delete data[type]
134
- return
135
- }
136
-
137
- data[type] = value
80
+ return isNaN(input) ? null : String(input)
138
81
  }
139
82
 
140
83
  function emitTouch(type: ValueType): void {
@@ -153,7 +96,7 @@ function createRequiredTouched(): boolean[] {
153
96
  const requiredTouched = [] as boolean[]
154
97
 
155
98
  for (const key in touched) {
156
- if ((props as any)[key]) {
99
+ if (!(props as any)[`no${key.charAt(0).toUpperCase() + key.slice(1)}`]) {
157
100
  requiredTouched.push((touched as any)[key])
158
101
  }
159
102
  }
@@ -162,6 +105,54 @@ function createRequiredTouched(): boolean[] {
162
105
  }
163
106
  </script>
164
107
 
108
+ <template>
109
+ <SInputBase
110
+ class="SInputHMS"
111
+ :class="[size, { disabled }]"
112
+ :label="label"
113
+ :note="note"
114
+ :help="help"
115
+ :hide-error="hideError"
116
+ :validation="validation"
117
+ >
118
+ <div class="container" :class="{ focus: isFocused }">
119
+ <input
120
+ v-if="!noHour"
121
+ class="input hour"
122
+ :value="modelValue.hour"
123
+ placeholder="00"
124
+ :disabled="disabled"
125
+ @focus="onFocus"
126
+ @blur="updateHour"
127
+ >
128
+ <div v-if="!noHour && !noMinute" class="separator" />
129
+ <input
130
+ v-if="!noMinute"
131
+ class="input minute"
132
+ :value="modelValue.minute"
133
+ placeholder="00"
134
+ :disabled="disabled"
135
+ @focus="onFocus"
136
+ @blur="updateMinute"
137
+ >
138
+ <div v-if="!noMinute && !noSecond" class="separator" />
139
+ <input
140
+ v-if="!noSecond"
141
+ class="input second"
142
+ :value="modelValue.second"
143
+ placeholder="00"
144
+ :disabled="disabled"
145
+ @focus="onFocus"
146
+ @blur="updateSecond"
147
+ >
148
+ </div>
149
+
150
+ <template #before-help>
151
+ <slot name="before-help" />
152
+ </template>
153
+ </SInputBase>
154
+ </template>
155
+
165
156
  <style lang="postcss" scoped>
166
157
  .SInputHMS.mini {
167
158
  .container {
@@ -253,22 +244,41 @@ function createRequiredTouched(): boolean[] {
253
244
 
254
245
  .container {
255
246
  display: inline-flex;
256
- border: 1px solid var(--input-border);
257
- border-radius: 4px;
258
- transition: border-color .25s;
247
+ border: 1px solid var(--c-divider);
248
+ border-radius: 6px;
249
+ background-color: var(--c-bg);
250
+ transition: border-color 0.25s;
259
251
 
260
252
  &:hover {
261
- border-color: var(--input-focus-border);
253
+ border-color: var(--c-black);
254
+ }
255
+
256
+ &.focus,
257
+ &:hover.focus {
258
+ border-color: var(--c-info);
259
+ }
260
+
261
+ .dark &:hover {
262
+ border-color: var(--c-gray);
263
+ }
264
+
265
+ .dark &.focus,
266
+ .dark &:hover.focus {
267
+ border-color: var(--c-info);
262
268
  }
263
269
  }
264
270
 
265
271
  .input {
266
- margin: 0;
267
272
  background-color: transparent;
273
+
274
+ &::placeholder {
275
+ font-weight: 500;
276
+ color: var(--c-text-3);
277
+ }
268
278
  }
269
279
 
270
280
  .separator::before {
271
- color: var(--c-text-2);
281
+ color: var(--c-text-3);
272
282
  content: ":";
273
283
  }
274
284
  </style>
@@ -1,34 +1,45 @@
1
1
  <template>
2
2
  <SInputText
3
3
  class="SInputNumber"
4
+ :name="name"
4
5
  :size="size"
5
6
  type="number"
6
7
  :label="label"
7
8
  :note="note"
8
9
  :help="help"
10
+ :align="align"
9
11
  :placeholder="placeholder"
10
12
  :disabled="disabled"
11
13
  :error-message="errorMessage"
12
- :model-value="modelValue"
14
+ :display-value="displayValue"
15
+ :model-value="String(modelValue)"
13
16
  :validation="validation"
14
17
  @update:model-value="emitUpdate"
15
- />
18
+ >
19
+ <template #before-help>
20
+ <p v-if="helpFormat" class="help-text">
21
+ {{ valueWithSeparator }}
22
+ </p>
23
+ </template>
24
+ </SInputText>
16
25
  </template>
17
26
 
18
27
  <script setup lang="ts">
19
- import { PropType } from 'vue'
28
+ import { computed, PropType } from 'vue'
29
+ import { Validatable } from '../composables/Validation'
20
30
  import { isNullish } from '../support/Utils'
21
- import { Validation, Validatable } from '../composables/Validation'
22
- import SInputText from './SInputText.vue'
31
+ import SInputText, { Size, Align } from './SInputText.vue'
23
32
 
24
- type Size = 'mini' | 'small' | 'medium'
25
-
26
- defineProps({
33
+ const props = defineProps({
27
34
  size: { type: String as PropType<Size>, default: 'small' },
35
+ name: { type: String, default: null },
28
36
  label: { type: String, default: null },
29
37
  note: { type: String, default: null },
30
38
  help: { type: String, default: null },
31
39
  placeholder: { type: String, default: null },
40
+ align: { type: String as PropType<Align>, default: null },
41
+ separator: { type: Boolean, default: false },
42
+ helpFormat: { type: Boolean, default: false },
32
43
  disabled: { type: Boolean, default: false },
33
44
  errorMessage: { type: Boolean, default: true },
34
45
  modelValue: { type: Number as PropType<number | null>, default: null },
@@ -37,7 +48,25 @@ defineProps({
37
48
 
38
49
  const emit = defineEmits(['update:modelValue'])
39
50
 
51
+ const valueWithSeparator = computed(() => {
52
+ if (isNullish(props.modelValue)) {
53
+ return '0'
54
+ }
55
+
56
+ return props.modelValue >= 100000000000000000000
57
+ ? 'The number is too big'
58
+ : props.modelValue.toLocaleString('en-US', { maximumSignificantDigits: 20 })
59
+ })
60
+
61
+ const displayValue = computed(() => {
62
+ if (!props.separator || valueWithSeparator.value === '0') {
63
+ return null
64
+ }
65
+
66
+ return valueWithSeparator.value
67
+ })
68
+
40
69
  function emitUpdate(value: string | null): void {
41
- emit('update:modelValue', value ? Number(value): null)
70
+ emit('update:modelValue', value ? Number(value) : null)
42
71
  }
43
72
  </script>