srcdev-nuxt-forms 2.4.23 → 3.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 (85) hide show
  1. package/nuxt.config.ts +3 -0
  2. package/package.json +2 -2
  3. package/assets/styles/ally/_utils.css +0 -20
  4. package/assets/styles/ally/_variables.css +0 -8
  5. package/assets/styles/ally/index.css +0 -2
  6. package/assets/styles/forms/index.css +0 -2
  7. package/assets/styles/forms/themes/_error.css +0 -85
  8. package/assets/styles/forms/themes/_ghost.css +0 -85
  9. package/assets/styles/forms/themes/_input-action-underlined.css +0 -20
  10. package/assets/styles/forms/themes/_input-action.css +0 -20
  11. package/assets/styles/forms/themes/_primary.css +0 -90
  12. package/assets/styles/forms/themes/_secondary.css +0 -85
  13. package/assets/styles/forms/themes/_success.css +0 -85
  14. package/assets/styles/forms/themes/_tertiary.css +0 -85
  15. package/assets/styles/forms/themes/_warning.css +0 -85
  16. package/assets/styles/forms/themes/index.css +0 -9
  17. package/assets/styles/forms/variables/_sizes.css +0 -71
  18. package/assets/styles/forms/variables/_theme.css +0 -11
  19. package/assets/styles/forms/variables/index.css +0 -2
  20. package/assets/styles/main.css +0 -5
  21. package/assets/styles/typography/index.css +0 -2
  22. package/assets/styles/typography/utils/_font-classes.css +0 -190
  23. package/assets/styles/typography/utils/_weights.css +0 -69
  24. package/assets/styles/typography/utils/index.css +0 -2
  25. package/assets/styles/typography/variables/_colors.css +0 -14
  26. package/assets/styles/typography/variables/_reponsive-font-size.css +0 -10
  27. package/assets/styles/typography/variables/index.css +0 -2
  28. package/assets/styles/utils/_margin-helpers.css +0 -334
  29. package/assets/styles/utils/_padding-helpers.css +0 -308
  30. package/assets/styles/utils/_page.css +0 -36
  31. package/assets/styles/utils/index.css +0 -3
  32. package/assets/styles/variables/colors/_blue.css +0 -15
  33. package/assets/styles/variables/colors/_gray.css +0 -16
  34. package/assets/styles/variables/colors/_green.css +0 -15
  35. package/assets/styles/variables/colors/_orange.css +0 -15
  36. package/assets/styles/variables/colors/_red.css +0 -15
  37. package/assets/styles/variables/colors/_yellow.css +0 -15
  38. package/assets/styles/variables/colors/colors.css +0 -6
  39. package/assets/styles/variables/index.css +0 -1
  40. package/components/forms/c12/prop-validators/index.ts +0 -38
  41. package/components/forms/c12/utils.ts +0 -14
  42. package/components/forms/form-errors/InputError.vue +0 -172
  43. package/components/forms/form-errors/tests/InputError.spec.ts +0 -67
  44. package/components/forms/input-button/InputButtonCore.vue +0 -191
  45. package/components/forms/input-button/variants/InputButtonConfirm.vue +0 -66
  46. package/components/forms/input-button/variants/InputButtonSubmit.vue +0 -62
  47. package/components/forms/input-checkbox/MultipleCheckboxes.vue +0 -203
  48. package/components/forms/input-checkbox/SingleCheckbox.vue +0 -169
  49. package/components/forms/input-checkbox/tests/MultipleCheckboxes.spec.ts +0 -98
  50. package/components/forms/input-checkbox/tests/data/tags.json +0 -67
  51. package/components/forms/input-checkbox-radio/InputCheckboxRadioButton.vue +0 -214
  52. package/components/forms/input-checkbox-radio/InputCheckboxRadioCore.vue +0 -191
  53. package/components/forms/input-checkbox-radio/InputCheckboxRadioWithLabel.vue +0 -111
  54. package/components/forms/input-number/InputNumberCore.vue +0 -203
  55. package/components/forms/input-number/variants/InputNumberDefault.vue +0 -154
  56. package/components/forms/input-radio/MultipleRadiobuttons.vue +0 -201
  57. package/components/forms/input-radio/tests/MultipleRadioButtons.spec.ts +0 -89
  58. package/components/forms/input-radio/tests/data/tags.json +0 -67
  59. package/components/forms/input-range/InputRangeCore.vue +0 -274
  60. package/components/forms/input-range/variants/InputRangeDefault.vue +0 -156
  61. package/components/forms/input-range-fancy/InputRangeFancyCore.vue +0 -450
  62. package/components/forms/input-range-fancy/InputRangeFancyWithLabel.vue +0 -124
  63. package/components/forms/input-text/InputTextCore.vue +0 -331
  64. package/components/forms/input-text/variants/InputPasswordWithLabel.vue +0 -130
  65. package/components/forms/input-text/variants/InputTextAsNumberWithLabel.vue +0 -187
  66. package/components/forms/input-text/variants/InputTextWithLabel.vue +0 -298
  67. package/components/forms/input-textarea/InputTextareaCore.vue +0 -234
  68. package/components/forms/input-textarea/variants/InputTextareaWithLabel.vue +0 -267
  69. package/components/forms/toggle-switch/ToggleSwitchCore.vue +0 -216
  70. package/components/forms/toggle-switch/variants/ToggleSwitchWithLabel.vue +0 -105
  71. package/components/forms/toggle-switch/variants/ToggleSwitchWithLabelInline.vue +0 -102
  72. package/components/forms/ui/FormField.vue +0 -78
  73. package/components/forms/ui/FormWrapper.vue +0 -35
  74. package/components/utils/colour-scheme-select/ColourSchemeSelect.vue +0 -270
  75. package/components/utils/colour-scheme-select/ColourSchemeSelectOld.vue +0 -225
  76. package/components/utils/dark-mode-switcher/DarkModeSwitcher.vue +0 -47
  77. package/composables/useApiRequest.ts +0 -25
  78. package/composables/useColourScheme.ts +0 -25
  79. package/composables/useErrorMessages.ts +0 -59
  80. package/composables/useFormControl.ts +0 -248
  81. package/composables/useSleep.ts +0 -5
  82. package/composables/useStyleClassPassthrough.ts +0 -30
  83. package/composables/useZodValidation.ts +0 -148
  84. package/types/types.forms.ts +0 -216
  85. package/types/types.zodFormControl.ts +0 -21
@@ -1,214 +0,0 @@
1
- <template>
2
- <div class="input-checkbox-radio-button-button" :data-form-theme="formTheme" :data-size="size" :class="[size, elementClasses, optionsLayout, { error: fieldHasError }]">
3
- <InputCheckboxRadioCore :isButton="true" :type :id :name :required v-model="modelValue" :size :trueValue :falseValue :fieldHasError :theme :ariaDescribedby>
4
- <template #checkedIcon>
5
- <slot name="checkedIcon"></slot>
6
- </template>
7
- </InputCheckboxRadioCore>
8
- <label v-if="hasLabelContent" class="input-checkbox-radio-button-label" :for="id">
9
- <slot name="labelContent"></slot>
10
- </label>
11
- <label v-else class="input-checkbox-radio-button-label" :for="id">{{ label }}</label>
12
- <div class="item-icon">
13
- <slot name="itemIcon">
14
- <Icon name="material-symbols:add-2" class="icon" />
15
- </slot>
16
- </div>
17
- </div>
18
- </template>
19
-
20
- <script setup lang="ts">
21
- import propValidators from '../c12/prop-validators';
22
-
23
- const props = defineProps({
24
- type: {
25
- type: String as PropType<'checkbox' | 'radio'>,
26
- required: true,
27
- },
28
- id: {
29
- type: String,
30
- required: true,
31
- },
32
- name: {
33
- type: String,
34
- required: true,
35
- },
36
- label: {
37
- type: String,
38
- required: true,
39
- },
40
- required: {
41
- type: Boolean,
42
- default: false,
43
- },
44
- fieldHasError: {
45
- type: Boolean,
46
- default: false,
47
- },
48
- trueValue: {
49
- type: [String, Number, Boolean],
50
- default: true,
51
- },
52
- falseValue: {
53
- type: [String, Number, Boolean],
54
- default: false,
55
- },
56
- size: {
57
- type: String as PropType<string>,
58
- default: 'medium',
59
- validator(value: string) {
60
- return propValidators.size.includes(value);
61
- },
62
- },
63
- optionsLayout: {
64
- type: String as PropType<string>,
65
- default: 'equal-widths',
66
- validator(value: string) {
67
- return propValidators.optionsLayout.includes(value);
68
- },
69
- },
70
- styleClassPassthrough: {
71
- type: Array as PropType<string[]>,
72
- default: () => [],
73
- },
74
- theme: {
75
- type: String as PropType<string>,
76
- default: 'primary',
77
- validator(value: string) {
78
- return propValidators.theme.includes(value);
79
- },
80
- },
81
- direction: {
82
- type: String as PropType<'row' | 'row-reverse'>,
83
- default: 'row',
84
- validator(value: string) {
85
- return ['row', 'row-reverse'].includes(value);
86
- },
87
- },
88
- ariaDescribedby: {
89
- type: String,
90
- default: null,
91
- },
92
- });
93
-
94
- const slots = useSlots();
95
- const hasLabelContent = computed(() => slots.labelContent !== undefined);
96
- const { elementClasses, updateElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
97
-
98
- const modelValue = defineModel();
99
-
100
- const formTheme = computed(() => {
101
- return props.fieldHasError ? 'error' : props.theme;
102
- });
103
-
104
- const flexDirection = ref(props.direction);
105
- </script>
106
-
107
- <style lang="css">
108
- .input-checkbox-radio-button-button {
109
- /* --_checkbox-size: initial; */
110
- --_background-color: var(--theme-checkbox-radio-button-bg-default);
111
- --_outline-width: var(--form-element-outline-width);
112
- --_border-color: var(--theme-checkbox-radio-button-border-default);
113
- --_outline-color: var(--theme-checkbox-radio-button-outline-default);
114
- --_label-color: var(--theme-checkbox-radio-button-label-default);
115
- --_box-shadow: var(--theme-checkbox-radio-button-shadow);
116
- --_white-space: wrap;
117
- --_gap: 0.4rem;
118
- /* --_border-radius: 2.2rem; */
119
- --_padding-block: 0.4rem;
120
- --_padding-inline: 1.2rem;
121
-
122
- display: flex;
123
- flex-direction: v-bind(flexDirection);
124
- align-items: center;
125
- justify-content: space-between;
126
- gap: var(--_gap);
127
-
128
- background-color: var(--_background-color);
129
- border-radius: calc(var(--form-element-line-height) / 1);
130
- border: var(--theme-checkbox-radio-button-border-width) solid var(--_border-color);
131
- outline: var(--theme-checkbox-radio-button-outline-width) solid var(--_outline-color);
132
- box-shadow: 0.1rem 0.1rem 0.8rem 0.1rem var(--_box-shadow);
133
- padding-block: var(--_padding-block);
134
- padding-inline: var(--_padding-inline);
135
-
136
- &.inline {
137
- --_white-space: nowrap;
138
- }
139
-
140
- /* &:focus-within {
141
- --_box-shadow: var(--theme-checkbox-radio-button-shadow-focus);
142
- --_outline-color: var(--theme-checkbox-radio-button-outline-focus);
143
- } */
144
-
145
- &:has(.input-checkbox-radio-core:focus-visible) {
146
- --_box-shadow: var(--theme-checkbox-radio-button-shadow-focus);
147
- --_outline-color: var(--theme-checkbox-radio-button-outline-focus);
148
- }
149
-
150
- /* Sizes */
151
- &.x-small {
152
- /* --_checkbox-size: 2rem; */
153
- --_gap: 1rem;
154
- /* --_border-radius: 2rem; */
155
- --_padding-block: 0.2rem;
156
- --_padding-inline: 1.6rem;
157
- }
158
- &.small {
159
- /* --_checkbox-size: 2.2rem; */
160
- --_gap: 1.2rem;
161
- /* --_border-radius: 1.8rem; */
162
- --_padding-block: 0rem;
163
- --_padding-inline: 1.2rem;
164
- }
165
- &.normal {
166
- /* --_checkbox-size: 3.4rem; */
167
- --_gap: 1rem;
168
- /* --_border-radius: 2rem; */
169
- --_padding-block: 0.4rem;
170
- --_padding-inline: 1.2rem;
171
- }
172
- &.medium {
173
- /* --_checkbox-size: 3.4rem; */
174
- --_gap: 1rem;
175
- /* --_border-radius: 2rem; */
176
- --_padding-block: 0.4rem;
177
- --_padding-inline: 1.2rem;
178
- }
179
- &.large {
180
- /* --_checkbox-size: 3.4rem; */
181
- --_gap: 1rem;
182
- /* --_border-radius: 2rem; */
183
- --_padding-block: 0.4rem;
184
- --_padding-inline: 1.2rem;
185
- }
186
- }
187
-
188
- .input-checkbox-radio-button-label {
189
- display: flex;
190
- flex-grow: 1;
191
- color: var(--_label-color);
192
- font-size: var(--form-element-font-size);
193
- width: 100%;
194
- height: var(--form-element-line-height);
195
- align-items: center;
196
- justify-content: center;
197
- margin-block: 0.8rem;
198
- padding-inline: 0.8rem;
199
- white-space: var(--_white-space);
200
-
201
- &:hover {
202
- cursor: pointer;
203
- }
204
- }
205
-
206
- .item-icon {
207
- display: flex;
208
- align-items: center;
209
- justify-content: center;
210
- color: var(--_border-color);
211
- height: var(--form-input-checkbox-radio-button-size);
212
- width: var(--form-input-checkbox-radio-button-size);
213
- }
214
- </style>
@@ -1,191 +0,0 @@
1
- <template>
2
- <div class="input-checkbox-radio-wrapper" :data-form-theme="formTheme" :data-theme="size" :class="[type, size, elementClasses, { error: fieldHasError }, { button: isButton }]">
3
- <slot name="checkedIcon" v-if="isChecked">
4
- <Icon :name="defaultIcon" class="input-checked-icon" />
5
- </slot>
6
-
7
- <input
8
- :type
9
- :true-value
10
- :false-value
11
- :id
12
- :name
13
- :required="required && !multipleOptions"
14
- :value="trueValue"
15
- class="input-checkbox-radio-core"
16
- :class="[size, { error: fieldHasError }, { 'is-button': isButton }]"
17
- v-model="modelValue"
18
- ref="inputField"
19
- :aria-checked="isChecked"
20
- :aria-describedby
21
- :aria-invalid="fieldHasError"
22
- />
23
- </div>
24
- </template>
25
-
26
- <script setup lang="ts">
27
- import propValidators from '../c12/prop-validators';
28
- const props = defineProps({
29
- isButton: {
30
- type: Boolean,
31
- default: false,
32
- },
33
- type: {
34
- type: String as PropType<'checkbox' | 'radio'>,
35
- required: true,
36
- },
37
- id: {
38
- type: String,
39
- required: true,
40
- },
41
- name: {
42
- type: String,
43
- required: true,
44
- },
45
- required: {
46
- type: Boolean,
47
- value: false,
48
- },
49
- trueValue: {
50
- type: [String, Number, Boolean],
51
- default: true,
52
- },
53
- falseValue: {
54
- type: [String, Number, Boolean],
55
- default: false,
56
- },
57
- multipleOptions: {
58
- type: Boolean,
59
- default: false,
60
- },
61
- theme: {
62
- type: String as PropType<string>,
63
- default: 'primary',
64
- validator(value: string) {
65
- return propValidators.theme.includes(value);
66
- },
67
- },
68
- size: {
69
- type: String as PropType<string>,
70
- default: 'medium',
71
- validator(value: string) {
72
- return propValidators.size.includes(value);
73
- },
74
- },
75
- fieldHasError: {
76
- type: Boolean,
77
- default: false,
78
- },
79
- styleClassPassthrough: {
80
- type: Array as PropType<string[]>,
81
- default: () => [],
82
- },
83
- ariaDescribedby: {
84
- type: String,
85
- default: null,
86
- },
87
- });
88
-
89
- const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
90
-
91
- const formTheme = computed(() => {
92
- return props.fieldHasError ? 'error' : props.theme;
93
- });
94
-
95
- const modelValue = defineModel<any>();
96
-
97
- const inputField = ref<HTMLInputElement | null>(null);
98
-
99
- const defaultIcon = computed(() => {
100
- return props.type === 'checkbox' ? 'material-symbols:check-small' : 'material-symbols:circle';
101
- });
102
-
103
- const isArray = Array.isArray(modelValue.value);
104
-
105
- const isChecked = computed(() => {
106
- if (isArray) {
107
- return modelValue.value.includes(props.trueValue);
108
- } else {
109
- return modelValue.value === props.trueValue;
110
- }
111
- });
112
- </script>
113
-
114
- <style lang="css">
115
- .input-checkbox-radio-wrapper {
116
- --_outline-width: 0.1rem;
117
- --_border-width: 0.1rem;
118
- --_border-radius: 50%;
119
- --_background-color: var(--theme-form-checkbox-bg);
120
- --_box-shadow: none;
121
-
122
- --_icon-size: var(--form-input-checkbox-radio-button-size);
123
-
124
- &:not(.button) {
125
- --_icon-size: var(--form-toggle-symbol-size);
126
- --_outline-width: var(--form-element-outline-width);
127
- --_border-width: var(--form-element-border-width);
128
- &.checkbox {
129
- --_background-color: var(--theme-form-checkbox-bg);
130
- --_border-color: var(--theme-form-checkbox-border);
131
- --_border-radius: 0.4rem;
132
- --_outline-color: var(--theme-form-checkbox-outline);
133
- }
134
-
135
- &.radio {
136
- --_background-color: var(--theme-form-radio-bg);
137
- --_border-color: var(--theme-form-radio-border);
138
- --_border-radius: 50%;
139
- --_outline-color: var(--theme-form-radio-outline);
140
- }
141
- }
142
-
143
- display: grid;
144
- grid-template-areas: 'element-stack';
145
- place-content: center;
146
-
147
- background-color: var(--_background-color);
148
- border: var(--_border-width) solid var(--_border-color);
149
- border-radius: var(--_border-radius);
150
- outline: 0.1rem solid var(--_outline-color);
151
- box-shadow: var(--_box-shadow);
152
-
153
- height: var(--_icon-size);
154
- width: var(--_icon-size);
155
-
156
- transition: all 0.2s ease-in-out;
157
-
158
- &:not(.button):has(.input-checkbox-radio-core:focus-visible) {
159
- --_box-shadow: var(--form-focus-box-shadow);
160
- }
161
-
162
- .input-checked-icon {
163
- grid-area: element-stack;
164
- color: var(--theme-form-checkbox-symbol);
165
- height: var(--_icon-size);
166
- width: var(--_icon-size);
167
- box-shadow: var(--_box-shadow);
168
- }
169
-
170
- .input-checkbox-radio-core {
171
- grid-area: element-stack;
172
- appearance: none;
173
- margin: 0;
174
- overflow: hidden;
175
- opacity: 0;
176
-
177
- height: var(--_icon-size);
178
- width: var(--_icon-size);
179
-
180
- &:hover {
181
- cursor: pointer;
182
- }
183
-
184
- &:not(.is-button) {
185
- &:focus-visible {
186
- --_box-shadow: var(--form-focus-box-shadow);
187
- }
188
- }
189
- }
190
- }
191
- </style>
@@ -1,111 +0,0 @@
1
- <template>
2
- <div class="input-checkbox-radio-with-label" :data-size="size" :class="[elementClasses, optionsLayout, { error: fieldHasError }]">
3
- <InputCheckboxRadioCore :type :id :name :required v-model="modelValue" :size :trueValue :falseValue :fieldHasError :theme :ariaDescribedby>
4
- <template #checkedIcon>
5
- <slot name="checkedIcon"></slot>
6
- </template>
7
- </InputCheckboxRadioCore>
8
- <label v-if="hasLabelContent" class="input-checkbox-radio-label body-normal" :for="id">
9
- <slot name="labelContent"></slot>
10
- </label>
11
- <label v-else class="input-checkbox-radio-label body-normal-semibold" :for="id">{{ label }}</label>
12
- </div>
13
- </template>
14
-
15
- <script setup lang="ts">
16
- import propValidators from '../c12/prop-validators';
17
-
18
- const props = defineProps({
19
- type: {
20
- type: String as PropType<'checkbox' | 'radio'>,
21
- required: true,
22
- },
23
- name: {
24
- type: String,
25
- required: true,
26
- },
27
- label: {
28
- type: String,
29
- required: true,
30
- },
31
- required: {
32
- type: Boolean,
33
- default: false,
34
- },
35
- fieldHasError: {
36
- type: Boolean,
37
- default: false,
38
- },
39
- trueValue: {
40
- type: [String, Number, Boolean],
41
- default: true,
42
- },
43
- falseValue: {
44
- type: [String, Number, Boolean],
45
- default: false,
46
- },
47
- size: {
48
- type: String as PropType<string>,
49
- default: 'medium',
50
- validator(value: string) {
51
- return propValidators.size.includes(value);
52
- },
53
- },
54
- optionsLayout: {
55
- type: String as PropType<string>,
56
- default: 'equal-widths',
57
- validator(value: string) {
58
- return propValidators.optionsLayout.includes(value);
59
- },
60
- },
61
- styleClassPassthrough: {
62
- type: Array as PropType<string[]>,
63
- default: () => [],
64
- },
65
- theme: {
66
- type: String as PropType<string>,
67
- default: 'primary',
68
- validator(value: string) {
69
- return propValidators.theme.includes(value);
70
- },
71
- },
72
- ariaDescribedby: {
73
- type: String,
74
- default: null,
75
- },
76
- });
77
-
78
- const slots = useSlots();
79
- const hasLabelContent = computed(() => slots.labelContent !== undefined);
80
- const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
81
-
82
- const modelValue = defineModel();
83
- const id = useId();
84
- </script>
85
-
86
- <style lang="css">
87
- .input-checkbox-radio-with-label {
88
- --_white-space: wrap;
89
-
90
- display: flex;
91
- align-items: center;
92
-
93
- &.inline {
94
- --_white-space: nowrap;
95
- }
96
-
97
- .input-checkbox-radio-label {
98
- display: flex;
99
- width: 100%;
100
- height: 100%;
101
- align-items: center;
102
- margin-block: 0.8rem;
103
- padding-inline: 0.8rem;
104
- white-space: var(--_white-space);
105
-
106
- &:hover {
107
- cursor: pointer;
108
- }
109
- }
110
- }
111
- </style>
@@ -1,203 +0,0 @@
1
- <template>
2
- <div class="input-number-wrapper" :data-form-theme="formTheme" :data-size="size">
3
- <div v-if="hasLeftContent" class="slot left">
4
- <slot name="left"></slot>
5
- </div>
6
-
7
- <div class="input-number-container">
8
- <input
9
- type="number"
10
- :id
11
- :name
12
- :required
13
- :min
14
- :max
15
- :step
16
- :class="[elementClasses, 'input-number-core', `input-number--${theme}`, `input-number--${size}`, `input-number--${weight}`]"
17
- v-model="modelValue"
18
- ref="inputField"
19
- inputmode="numeric"
20
- pattern="[0-9]+"
21
- />
22
- </div>
23
- <div v-if="hasRightContent" class="slot right">
24
- <slot name="right"></slot>
25
- </div>
26
- </div>
27
- </template>
28
-
29
- <script setup lang="ts">
30
- import propValidators from '../c12/prop-validators';
31
-
32
- const props = defineProps({
33
- id: {
34
- type: String,
35
- required: true,
36
- },
37
- name: {
38
- type: String,
39
- required: true,
40
- },
41
- min: {
42
- type: Number,
43
- required: true,
44
- },
45
- max: {
46
- type: Number,
47
- required: true,
48
- },
49
- step: {
50
- type: Number,
51
- default: 1,
52
- },
53
- placeholder: {
54
- type: String,
55
- default: '',
56
- },
57
- required: {
58
- type: Boolean,
59
- default: false,
60
- },
61
- theme: {
62
- type: String as PropType<string>,
63
- default: 'primary',
64
- validator(value: string) {
65
- return propValidators.theme.includes(value);
66
- },
67
- },
68
- size: {
69
- type: String as PropType<string>,
70
- default: 'medium',
71
- validator(value: string) {
72
- return propValidators.size.includes(value);
73
- },
74
- },
75
- weight: {
76
- type: String as PropType<string>,
77
- default: 'wght-400',
78
- validator(value: string) {
79
- return propValidators.weight.includes(value);
80
- },
81
- },
82
- fieldHasError: {
83
- type: Boolean,
84
- default: false,
85
- },
86
- styleClassPassthrough: {
87
- type: Array as PropType<string[]>,
88
- default: () => [],
89
- },
90
- });
91
-
92
- const slots = useSlots();
93
- const hasLeftContent = computed(() => slots.left !== undefined);
94
- const hasRightContent = computed(() => slots.right !== undefined);
95
-
96
- const formTheme = computed(() => {
97
- return props.fieldHasError ? 'error' : props.theme;
98
- });
99
-
100
- const modelValue = defineModel<number | readonly number[]>();
101
-
102
- const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
103
- const minLength = computed(() => `${props.max.toString().length + 1}em`);
104
- </script>
105
-
106
- <style lang="css">
107
- .input-number-wrapper {
108
- --_focus-box-shadow: var(--box-shadow-off);
109
- --_min-width: v-bind(minLength);
110
-
111
- display: flex;
112
- align-items: center;
113
-
114
- width: fit-content;
115
-
116
- background-color: var(--theme-form-input-bg-normal);
117
- border-radius: var(--form-element-border-width);
118
- border: var(--form-element-border-width) solid var(--theme-form-input-border);
119
- outline: var(--form-element-outline-width) solid var(--theme-form-input-outline);
120
- box-shadow: var(--_focus-box-shadow);
121
-
122
- .slot {
123
- display: inline-block;
124
-
125
- .icon {
126
- font-weight: 900;
127
- }
128
- }
129
-
130
- &.has-left-slot {
131
- .left-slot {
132
- display: flex;
133
- align-items: center;
134
- }
135
- }
136
-
137
- &.has-right-slot {
138
- .right-slot {
139
- display: flex;
140
- align-items: center;
141
- }
142
- }
143
-
144
- .input-number-core {
145
- background-color: transparent;
146
- border: none;
147
- outline: none;
148
- box-shadow: none;
149
-
150
- background-color: var(--theme-form-input-bg-normal);
151
- color: var(--theme-form-input-text-color-normal);
152
- font-family: var(--font-family);
153
- font-size: var(--form-element-font-size);
154
- line-height: var(--form-element-line-height);
155
-
156
- padding-inline: var(--form-text-padding-inline);
157
- padding-block-start: var(--form-element-padding-block-start);
158
- padding-block-end: var(--form-element-padding-block-end);
159
- text-align: center;
160
- min-width: var(--_min-width);
161
-
162
- &:focus-visible {
163
- --_focus-box-shadow: var(--box-shadow-on);
164
- }
165
-
166
- &::placeholder,
167
- &::-webkit-input-placeholder {
168
- font-family: var(--font-family);
169
- font-size: var(--font-size);
170
- font-style: italic;
171
- font-weight: 400;
172
- }
173
- }
174
-
175
- &:has(.has-left-button),
176
- &:has(.has-right-button) {
177
- .slot {
178
- .input-button-core {
179
- border: initial;
180
- border-radius: 0;
181
- outline: initial;
182
- box-shadow: unset;
183
- }
184
- }
185
-
186
- .left-slot {
187
- margin-inline-end: 0;
188
- border-right: 2px solid var(--theme-btn-bg-hover);
189
- }
190
-
191
- .right-slot {
192
- margin-inline-end: 0;
193
- border-left: 2px solid var(--theme-btn-bg-hover);
194
- }
195
- }
196
- }
197
-
198
- input[type='number']::-webkit-inner-spin-button,
199
- input[type='number']::-webkit-outer-spin-button {
200
- -webkit-appearance: none;
201
- margin: 0;
202
- }
203
- </style>