22 <div
33 :class =" {
44 'h-select': true,
5+ [`h-select--behavior-invalid`]: state.internalInvalid,
56 [`h-select--behavior-block`]: block,
6- [`h-select--behavior-has-value`]: hasValue,
7- [`h-select--size-${size}`]: size,
7+ [`h-select--behavior-has-value`]: state.hasValue,
88 }"
99 >
10+ <label
11+ v-if =" label"
12+ class =" h-select__label"
13+ >
14+ {{ label }}
15+ </label >
16+
1017 <select
1118 class =" h-select__field"
1219 v-bind =" $attrs"
13- :value =" internalValue"
14- @change.stop =" handlerChange($event?.target?.value)"
20+ :value =" state.internalValue"
21+ :name =" state.name"
22+ @change.stop =" handlerChange"
1523 >
1624 <option
1725 v-if =" placeholder"
2836 v-for =" (option, index) in options"
2937 :key =" option.value || index"
3038 class =" h-select__field-option"
31- :value =" option.value || option "
39+ :value =" getOption( option, 'value') "
3240 >
33- {{ option.text || option }}
41+ {{ getOption( option, 'text') }}
3442 </option >
3543 </select >
44+
45+ <h-text
46+ v-if =" helperTextActive"
47+ class =" h-select__helper-text"
48+ size =" extra-small"
49+ weight =" medium"
50+ emphasis =" high"
51+ >
52+ <template v-if =" state .helperTextVisible " >
53+ {{ state.internalTextValue }}
54+ </template >
55+ </h-text >
3656 </div >
3757</template >
3858
@@ -41,11 +61,30 @@ import { shouldBeOneOf } from '@utils/validations';
4161import {
4262 selectSizes ,
4363} from ' @assets/constants' ;
64+ import { HFormKey } from ' @components/molecules/form' ;
65+ import {
66+ computed ,
67+ reactive ,
68+ ref ,
69+ onMounted ,
70+ watch ,
71+ inject ,
72+ toRef ,
73+ } from ' vue' ;
74+ import { Validate } from ' @utils/validations/validate' ;
4475
4576export default {
4677 name: ' HSelect' ,
4778 inheritAttrs: false ,
4879 props: {
80+ label: {
81+ type: String ,
82+ default: null ,
83+ },
84+ name: {
85+ type: String ,
86+ default: null ,
87+ },
4988 block: {
5089 type: Boolean ,
5190 default: false ,
@@ -73,82 +112,133 @@ export default {
73112 type: [Object , String ],
74113 default: null ,
75114 },
76- },
77- emits: [' input' , ' change' , ' select' , ' update:modelValue' ],
78- computed: {
79- internalValue () {
80- return this .value || this .modelValue ;
115+ invalid: {
116+ type: Boolean ,
117+ default: false ,
118+ },
119+ helperTextActive: {
120+ type: Boolean ,
121+ default: true ,
81122 },
82- hasValue () {
83- return Boolean (this .internalValue );
123+ helperText: {
124+ type: String ,
125+ default: null ,
84126 },
85- },
86- methods: {
87- handlerChange (value ) {
88- this .$emit (' input' , value);
89- this .$emit (' change' , value);
90- this .$emit (' select' , value);
91- this .$emit (' update:modelValue' , value);
127+ rules: {
128+ type: Object ,
129+ default: null ,
92130 },
93131 },
132+ emits: [' input' , ' change' , ' select' , ' update:modelValue' ],
133+ setup ($props , { emit: $emit }) {
134+ const HForm = inject (HFormKey, undefined );
135+
136+ const state = reactive ({
137+ internalValue: computed (() => $props .value || $props .modelValue ),
138+ hasValue: computed (() => Boolean (state .internalValue )),
139+ validationMessages: null ,
140+ validationActive: true ,
141+ helperTextVisible: computed (() => $props .helperText || state .invalid ),
142+ invalid: computed (() => Boolean (state .validationActive && state .validationMessages ? .length )),
143+ internalTextValue: computed (() => state .validationMessages ? .[0 ]? .message || $props .helperText ),
144+ internalInvalid: computed (() => $props .invalid || state .invalid ),
145+ name: computed (() => $props .name || $props .label || ' Campo' ),
146+ currentValidation: computed (() => ({
147+ name: state .name ,
148+ value: state .internalValue ,
149+ tag: ' select' ,
150+ type: ' simple' ,
151+ messages: state .validationMessages ,
152+ })),
153+ });
154+
155+ const checkValidation = (validationActive ) => {
156+ if (! $props .rules ) return ;
157+ state .validationActive = Boolean (validationActive);
158+ state .validationMessages = Validate (state .internalValue , $props .rules );
159+ };
160+
161+ const getOption = (option , key ) => (Object .prototype .hasOwnProperty .call (option, key)
162+ ? option[key]
163+ : option);
164+
165+ const handlerChange = ($event ) => {
166+ const value = $event? .target ? .value ;
167+ console .log (value);
168+ $emit (' input' , value);
169+ $emit (' change' , value);
170+ $emit (' select' , value);
171+ $emit (' update:modelValue' , value);
172+ };
173+
174+ const currentValidation = toRef (state, ' currentValidation' );
175+
176+ watch (() => state .internalValue , () => checkValidation (true ));
177+
178+ onMounted (() => {
179+ if ($props .rules ) checkValidation ($props? .rules ? .startValidating );
180+ if (HForm) HForm .registerField (currentValidation);
181+ });
182+
183+ return {
184+ state,
185+ handlerChange,
186+ getOption,
187+ };
188+ },
94189};
95190< / script>
96191
97192< style lang= " scss" >
98193: root {
99- --h-select --border-color : var (--color-theme-primary );
100- --h-select --border-radius : var (--border-radius-normal );
101- --h-select --border-style : solid ;
102- --h-select --border-width : var (--size-base-micro );
194+ -- h- select__field -- border- color: var (-- color- theme- primary);
195+ -- h- select__field -- border- radius: var (-- border- radius- normal);
196+ -- h- select__field -- border- style: solid;
197+ -- h- select__field -- border- width: var (-- size- base- micro);
103198 -- h- select__field-- color: var (-- color- theme- primary);
104199 -- h- select__field-- background- color: var (-- color- theme- white);
200+
201+ -- h- select- width: 250px ;
202+
203+ -- h- select__label- font- weight: 500 ;
204+ -- h- select__label- margin- bottom: var (-- size- base- small);
205+ -- h- select__field-- height: 44px ;
206+
207+ -- h- select__helper- text- color: var (-- color- theme- grey);
208+ -- h- select__helper- text- color-- invalid: var (-- color- theme- danger);
209+ -- h- select__helper- text- height: var (-- size- base- medium);
105210}
106211
107212.h - select {
108- border-color : var (--h-select--border-color );
109- border-radius : var (--h-select--border-radius );
110- border-style : var (--h-select--border-style );
111- border-width : var (--h-select--border-width );
112-
113- display : inline-flex ;
213+ display: inline- block;
114214 font- family: ' Red Hat Text' , sans- serif;
115215 height: fit- content;
116216 position: relative;
117- width : 303px ;
118-
119- & --size {
120- & -small {
121- & > .h-select__field {
122- min-height : var (--size-base-extra-large );
123- font-size : var (--size-scalable-micro );
124- }
125- }
126- & -medium {
127- & > .h-select__field {
128- min-height : var (--size-base-jumbo );
129- font-size : var (--size-scalable-extra-small );
130- }
131- }
132- }
217+ width: var (-- h- select- width);
133218
134219 & -- behavior {
135220 & - block {
136221 width: 100 % ;
137222 }
138223 & - has- value {
139- --h-select__field--background-color : var (--color-blue-grey-scale-100 );
224+ -- h- select__field-- background- color: var (-- color- blue- grey- scale- 050 );
225+ }
226+ & - invalid {
227+ -- h- select__field-- border- color: var (-- color- pink- scale- alpha- 400 );
228+ -- h- select__helper- text- color: var (-- h- select__helper- text- color-- invalid);
140229 }
141230 }
142231
143232 & __field {
233+ border- color: var (-- h- select__field-- border- color);
234+ border- radius: var (-- h- select__field-- border- radius);
235+ border- style: var (-- h- select__field-- border- style);
236+ border- width: var (-- h- select__field-- border- width);
144237 background- color: var (-- h- select__field-- background- color);
145- border-radius : var (--border-radius-normal );
146- border : none ;
147238 color: var (-- h- select__field-- color);
148- flex : 1 ;
149239 font- family: ' Red Hat Text' , sans- serif;
150240 font- weight: 500 ;
151- height : 100 % ;
241+ height: var ( -- h - select__field -- height) ;
152242 left: 0 ;
153243 padding- left: var (-- size- base- medium);
154244 padding- right: var (-- size- base- medium);
@@ -158,10 +248,23 @@ export default {
158248 }
159249}
160250
251+ .h - select__label {
252+ font- weight: var (-- h- select__label- font- weight);
253+ margin- bottom: var (-- h- select__label- margin- bottom);
254+ display: inline- block;
255+ }
256+
161257.h - select__field-- placeholder {
162258 color: var (-- color- blue- grey- scale- 300 );
163259 font- weight: 500 ;
164260 font- style: italic;
165261}
166262
263+ .h - select__helper- text {
264+ -- h- text-- color: var (-- h- select__helper- text- color);
265+ margin- top: var (-- size- base- extra- small);
266+ padding- left: var (-- size- base- small);
267+ padding- right: var (-- size- base- small);
268+ min- height: var (-- h- select__helper- text- height);
269+ }
167270< / style>
0 commit comments