pixel-react 1.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/lib/components/Charts/DashboardDonutChart/DashboardDonutChart.d.ts +5 -0
  3. package/lib/components/Charts/DashboardDonutChart/DashboardDonutChart.stories.d.ts +7 -0
  4. package/lib/components/Charts/DashboardDonutChart/index.d.ts +1 -0
  5. package/lib/components/Charts/DashboardDonutChart/types.d.ts +21 -0
  6. package/lib/components/Charts/PieChart/PieChart.d.ts +5 -0
  7. package/lib/components/Charts/PieChart/PieChart.stories.d.ts +7 -0
  8. package/lib/components/Charts/PieChart/index.d.ts +1 -0
  9. package/lib/components/Charts/PieChart/types.d.ts +27 -0
  10. package/lib/components/FF_Captcha/Recaptcha.d.ts +5 -0
  11. package/lib/components/FF_Captcha/captcha.stories.d.ts +8 -0
  12. package/lib/components/FF_Captcha/types.d.ts +20 -0
  13. package/lib/components/MultiSelect/MultiSelect.d.ts +1 -1
  14. package/lib/components/MultiSelect/MultiSelectTypes.d.ts +1 -1
  15. package/lib/components/NLPInput/NlpInput.d.ts +4 -0
  16. package/lib/components/NLPInput/NlpInput.stories.d.ts +7 -0
  17. package/lib/components/NLPInput/components/NlpDropDown/NlpDropDownType.d.ts +19 -0
  18. package/lib/components/NLPInput/components/NlpDropDown/NlpDropdown.d.ts +4 -0
  19. package/lib/components/NLPInput/index.d.ts +1 -0
  20. package/lib/components/NLPInput/type.d.ts +70 -0
  21. package/lib/components/Table/Table.d.ts +1 -1
  22. package/lib/index.d.ts +96 -19
  23. package/lib/index.esm.js +2951 -249
  24. package/lib/index.esm.js.map +1 -1
  25. package/lib/index.js +2953 -247
  26. package/lib/index.js.map +1 -1
  27. package/lib/tsconfig.tsbuildinfo +1 -1
  28. package/lib/utils/getEncryptedData/getEncryptedData.d.ts +2 -0
  29. package/lib/utils/getEncryptedData/getEncryptedData.stories.d.ts +6 -0
  30. package/package.json +6 -2
  31. package/src/StyleGuide/ColorPalette/ColorPalette.tsx +2 -4
  32. package/src/StyleGuide/ColorPalette/colorPaletteList.ts +95 -20
  33. package/src/assets/Themes/BaseTheme.scss +2 -3
  34. package/src/assets/Themes/DarkTheme.scss +9 -8
  35. package/src/assets/icons/wswb_delete_icon.svg +4 -0
  36. package/src/assets/icons/wswb_plus_icon.svg +5 -0
  37. package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.scss +145 -0
  38. package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.stories.tsx +52 -0
  39. package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.tsx +335 -0
  40. package/src/components/Charts/DashboardDonutChart/index.ts +1 -0
  41. package/src/components/Charts/DashboardDonutChart/types.ts +33 -0
  42. package/src/components/Charts/PieChart/PieChart.scss +39 -0
  43. package/src/components/Charts/PieChart/PieChart.stories.tsx +46 -0
  44. package/src/components/Charts/PieChart/PieChart.tsx +193 -0
  45. package/src/components/Charts/PieChart/index.ts +1 -0
  46. package/src/components/Charts/PieChart/types.ts +28 -0
  47. package/src/components/FF_Captcha/Recaptcha.scss +11 -0
  48. package/src/components/FF_Captcha/Recaptcha.tsx +41 -0
  49. package/src/components/FF_Captcha/captcha.stories.tsx +40 -0
  50. package/src/components/FF_Captcha/index.ts +0 -0
  51. package/src/components/FF_Captcha/types.ts +22 -0
  52. package/src/components/Icon/iconList.ts +6 -0
  53. package/src/components/Modal/modal.scss +1 -1
  54. package/src/components/MultiSelect/MultiSelect.stories.tsx +2 -3
  55. package/src/components/MultiSelect/MultiSelect.tsx +35 -23
  56. package/src/components/MultiSelect/MultiSelectTypes.ts +1 -1
  57. package/src/components/NLPInput/NLPInput.scss +246 -0
  58. package/src/components/NLPInput/NlpInput.stories.tsx +136 -0
  59. package/src/components/NLPInput/NlpInput.tsx +374 -0
  60. package/src/components/NLPInput/components/NlpDropDown/NlpDropDownType.ts +60 -0
  61. package/src/components/NLPInput/components/NlpDropDown/NlpDropdown.scss +83 -0
  62. package/src/components/NLPInput/components/NlpDropDown/NlpDropdown.tsx +180 -0
  63. package/src/components/NLPInput/index.ts +1 -0
  64. package/src/components/NLPInput/type.tsx +124 -0
  65. package/src/components/Table/Table.scss +5 -0
  66. package/src/components/Table/Table.stories.tsx +12 -0
  67. package/src/components/Table/Table.tsx +25 -14
  68. package/src/components/TextArea/Textarea.scss +1 -1
  69. package/src/index.ts +8 -1
  70. package/src/utils/getEncryptedData/getEncryptedData.stories.tsx +55 -0
  71. package/src/utils/getEncryptedData/getEncryptedData.ts +10 -0
  72. package/lib/components/AddButton/AddButton.d.ts +0 -5
  73. package/lib/components/AddButton/AddButton.stories.d.ts +0 -6
  74. package/lib/components/AddButton/index.d.ts +0 -1
  75. package/lib/components/AddButton/types.d.ts +0 -4
@@ -0,0 +1,41 @@
1
+ import { useState, forwardRef } from 'react';
2
+ import ReCAPTCHA from 'react-google-recaptcha';
3
+ import { RecaptchaProps } from './types';
4
+ import './Recaptcha.scss';
5
+ import classNames from 'classnames';
6
+ import Typography from '../Typography';
7
+
8
+ const Recaptcha = forwardRef<ReCAPTCHA, RecaptchaProps>(
9
+ ({ onVerify, className = '', error: externalError, sitekey, ...props }, ref) => {
10
+ const [internalError, setInternalError] = useState<string | null>(null);
11
+
12
+ const handleChange = (token: string | null) => {
13
+ if (token) {
14
+ setInternalError(null);
15
+ onVerify(token);
16
+ } else {
17
+ setInternalError('Please complete the CAPTCHA');
18
+ }
19
+ };
20
+
21
+ const error = externalError || internalError;
22
+
23
+ return (
24
+ <div className={classNames('ff-recaptcha-wrapper', className)}>
25
+ <ReCAPTCHA
26
+ ref={ref}
27
+ sitekey={sitekey}
28
+ onChange={handleChange}
29
+ {...props}
30
+ />
31
+ {error && (
32
+ <div className="ff-recaptcha-error">
33
+ <Typography fontSize={12}>{error}</Typography>
34
+ </div>
35
+ )}
36
+ </div>
37
+ );
38
+ }
39
+ );
40
+
41
+ export default Recaptcha;
@@ -0,0 +1,40 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import Recaptcha from './Recaptcha';
3
+
4
+ const meta: Meta<typeof Recaptcha> = {
5
+ title: 'Components/Recaptcha',
6
+ component: Recaptcha,
7
+ parameters: {
8
+ layout: 'centered',
9
+ },
10
+ tags: ['autodocs'],
11
+ };
12
+
13
+ type Story = StoryObj<typeof Recaptcha>;
14
+
15
+ const defaultArgs = {
16
+ sitekey: '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI', // Test key
17
+ onVerify: () => {},
18
+ };
19
+
20
+ export const Default: Story = {
21
+ args: {
22
+ ...defaultArgs,
23
+ },
24
+ };
25
+
26
+ export const WithError: Story = {
27
+ args: {
28
+ ...defaultArgs,
29
+ error: 'Custom error message',
30
+ },
31
+ };
32
+
33
+ export const WithCustomTheme: Story = {
34
+ args: {
35
+ ...defaultArgs,
36
+ theme: 'dark',
37
+ },
38
+ };
39
+
40
+ export default meta;
File without changes
@@ -0,0 +1,22 @@
1
+ import { ComponentProps } from 'react';
2
+ import ReCAPTCHA from 'react-google-recaptcha';
3
+
4
+ export interface RecaptchaProps extends Omit<ComponentProps<typeof ReCAPTCHA>, 'onChange'> {
5
+ /**
6
+ * Callback function that receives the verification token
7
+ */
8
+ onVerify: (token: string | null) => void;
9
+ /**
10
+ * Optional CSS class name
11
+ */
12
+ className?: string;
13
+ /**
14
+ * Optional error message to display
15
+ */
16
+ error?: string | null;
17
+ /**
18
+ * reCAPTCHA site key
19
+ */
20
+ sitekey: string;
21
+ }
22
+
@@ -65,6 +65,10 @@ import AndroidIcon from '../../assets/icons/android_icon.svg?react';
65
65
 
66
66
  import SwitchLicenseIcon from '../../assets/icons/switch_license_icon.svg?react';
67
67
  import FireflinkLogo from '../../assets/icons/fireflink_logo.svg?react';
68
+ import WSWBDeleteIcon from '../../assets/icons/wswb_delete_icon.svg?react'
69
+ import WSWBPlusIcon from '../../assets/icons/wswb_plus_icon.svg?react'
70
+
71
+
68
72
  //icons
69
73
  Components['delete_info'] = DeleteInfoIcon;
70
74
  Components['success'] = ToastSuccessIcon;
@@ -130,5 +134,7 @@ Components['android_icon'] = AndroidIcon;
130
134
 
131
135
  Components['select_license'] = SwitchLicenseIcon;
132
136
  Components['fireflink-logo'] = FireflinkLogo;
137
+ Components['wswb_delete_icon'] = WSWBDeleteIcon;
138
+ Components['wswb_plus_icon'] = WSWBPlusIcon;
133
139
 
134
140
  export default Components;
@@ -15,7 +15,7 @@
15
15
  background: var(--ff-mini-modal-border);
16
16
  position: relative;
17
17
  max-width: 100%;
18
- border-radius: 12px 12px 0 0;
18
+ border-radius: 12px;
19
19
  padding: 16px;
20
20
 
21
21
  .ff-modal-header {
@@ -60,14 +60,14 @@ export const EmailGroup: Story = {
60
60
  ]);
61
61
  const [selectedOptions, setSelectedOptions] = useState<
62
62
  { label?: string; value?: string }[]
63
- >([{ label: 'Sample1@gmail.com', value: 'sample1@gmail.com'}]);
63
+ >([{ label: 'Sample1@gmail.com', value: 'sample1@gmail.com' }]);
64
64
  const onChange = (options: { label?: string; value?: string }[]) => {
65
65
  setSelectedOptions(options);
66
66
  };
67
67
  return (
68
68
  <MultiSelect
69
69
  label={'Enter Email'}
70
- type='email'
70
+ type="email"
71
71
  required
72
72
  options={options}
73
73
  selectedOptions={selectedOptions}
@@ -101,7 +101,6 @@ export const Controlled: Story = {
101
101
  };
102
102
  return (
103
103
  <MultiSelect
104
- // disabled
105
104
  label={'Fruits'}
106
105
  required
107
106
  options={options}
@@ -29,8 +29,8 @@ const ChipElement = ({
29
29
  return null;
30
30
  };
31
31
  const MultiSelect = ({
32
- options,
33
- type = "text",
32
+ options = [],
33
+ type = 'text',
34
34
  selectedOptions = [],
35
35
  onChange = () => {},
36
36
  acceptNewOption = false,
@@ -42,7 +42,7 @@ const MultiSelect = ({
42
42
  errorMessage = 'Fill this field',
43
43
  withSelectButton = false,
44
44
  onSelect = () => {},
45
- displayCount = false
45
+ displayCount = false,
46
46
  }: MultiSelectProps) => {
47
47
  const [isOpen, setIsOpen] = useState<boolean>(false);
48
48
  const [allOptions, setAllOptions] = useState(options);
@@ -50,7 +50,7 @@ const MultiSelect = ({
50
50
  const [searchedKeyword, setSearchedKeyword] = useState('');
51
51
  const [isSelectFocusedOnce, setIsSelectFocusedOnce] =
52
52
  useState<boolean>(false);
53
- const [inputError, setInputError] = useState<string>('')
53
+ const [inputError, setInputError] = useState<string>('');
54
54
 
55
55
  const [dropdownPosition, setDropdownPosition] = useState<{
56
56
  top: number;
@@ -110,13 +110,13 @@ const MultiSelect = ({
110
110
  handleOptionChange(option, false);
111
111
  };
112
112
  const handleKeyEnter = (e: React.KeyboardEvent<HTMLDivElement>) => {
113
- if (acceptNewOption && e.key === "Enter") {
113
+ if (acceptNewOption && e.key === 'Enter') {
114
114
  setInputError('');
115
- if (type === "email") {
115
+ if (type === 'email') {
116
116
  const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
117
117
  if (!emailPattern.test(searchedKeyword)) {
118
118
  setIsOpen(false);
119
- setInputError("Please enter a valid email address.");
119
+ setInputError('Please enter a valid email address.');
120
120
  return;
121
121
  }
122
122
  }
@@ -126,11 +126,16 @@ const MultiSelect = ({
126
126
  value: searchedKeyword.toLowerCase(),
127
127
  isChecked: true,
128
128
  };
129
- const filteredOptions = [...allOptions].filter(option => option.isChecked === true);
129
+ const filteredOptions = [...allOptions].filter(
130
+ (option) => option.isChecked === true
131
+ );
130
132
 
131
133
  setAllOptions([...allOptions, newOption]);
132
134
  setSearchedKeyword('');
133
- onChange?.([...filteredOptions, { label: searchedKeyword, value: searchedKeyword.toLocaleLowerCase() }]);
135
+ onChange?.([
136
+ ...filteredOptions,
137
+ { label: searchedKeyword, value: searchedKeyword.toLocaleLowerCase() },
138
+ ]);
134
139
  setIsOpen(false);
135
140
  }
136
141
  };
@@ -148,6 +153,17 @@ const MultiSelect = ({
148
153
  });
149
154
  }
150
155
  };
156
+ const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
157
+ if (!isOpen) {
158
+ setIsOpen(true);
159
+ }
160
+ const input = e.target.value;
161
+ setSearchedKeyword(input);
162
+ const filteredOptions = options.filter((option) =>
163
+ option.value?.toLowerCase().includes(input.toLowerCase())
164
+ );
165
+ onSearch?.(input, filteredOptions.length);
166
+ };
151
167
  useEffect(() => {
152
168
  if (isOpen) {
153
169
  calculatePosition();
@@ -192,7 +208,7 @@ const MultiSelect = ({
192
208
  !dropdownRef.current.contains(event?.target as Node) &&
193
209
  !selectWrapper.current.contains(event?.target as Node)
194
210
  ) {
195
- setInputError('')
211
+ setInputError('');
196
212
  setIsOpen(false);
197
213
  if (!isSelectFocusedOnce) {
198
214
  setIsSelectFocusedOnce(true);
@@ -213,7 +229,8 @@ const MultiSelect = ({
213
229
  className={classNames('ff-multiselect-wrapper', {
214
230
  'ff-multiselect-wrapper--with-options': selectedOptions?.length,
215
231
  'ff-multiselect-wrapper--opened-dropdown': isOpen,
216
- 'ff-multiselect-wrapper--error': (isFieldSkipped && required) || inputError,
232
+ 'ff-multiselect-wrapper--error':
233
+ (isFieldSkipped && required) || inputError,
217
234
  'ff-multiselect-wrapper--disabled': disabled,
218
235
  })}
219
236
  >
@@ -231,7 +248,7 @@ const MultiSelect = ({
231
248
  {label}
232
249
  </span>
233
250
  <div className="ff-multiselect-chip-container">
234
- {displayCount ?
251
+ {displayCount ? (
235
252
  <>
236
253
  {selectedOptions.slice(0, maxVisibleChips).map((option) => (
237
254
  <ChipElement
@@ -240,7 +257,8 @@ const MultiSelect = ({
240
257
  onChipCloseClick={(e) => handleChipCloseClick(option, e)}
241
258
  />
242
259
  ))}
243
- </> :
260
+ </>
261
+ ) : (
244
262
  selectedOptions.map((option) => (
245
263
  <ChipElement
246
264
  key={option?.label}
@@ -248,7 +266,7 @@ const MultiSelect = ({
248
266
  onChipCloseClick={(e) => handleChipCloseClick(option, e)}
249
267
  />
250
268
  ))
251
- }
269
+ )}
252
270
  <div className="ff-multiselect-input-container">
253
271
  <input
254
272
  value={searchedKeyword}
@@ -256,13 +274,7 @@ const MultiSelect = ({
256
274
  autoComplete="off"
257
275
  placeholder="search..."
258
276
  ref={inputRef}
259
- onChange={(e) => {
260
- if (!isOpen) {
261
- setIsOpen(true);
262
- }
263
- setSearchedKeyword(e.target.value);
264
- onSearch?.(e.target.value);
265
- }}
277
+ onChange={handleSearch}
266
278
  onKeyDown={handleKeyEnter}
267
279
  id="input-ele"
268
280
  className="ff-select-input"
@@ -295,7 +307,7 @@ const MultiSelect = ({
295
307
  </div>
296
308
  <div ref={dropdownWrapper}>
297
309
  {(inputError || (isFieldSkipped && required && errorMessage)) && (
298
- <div className="error-text">{inputError || errorMessage }</div>
310
+ <div className="error-text">{inputError || errorMessage}</div>
299
311
  )}
300
312
  {isOpen &&
301
313
  createPortal(
@@ -317,4 +329,4 @@ const MultiSelect = ({
317
329
  );
318
330
  };
319
331
 
320
- export default MultiSelect;
332
+ export default MultiSelect;
@@ -10,7 +10,7 @@ interface MultiSelectProps {
10
10
  label: string;
11
11
  selectedOptions?: Option[];
12
12
  disabled?: boolean;
13
- onSearch?: (searchedKeyword: string) => void;
13
+ onSearch?: (searchedKeyword: string, resultsLength: number) => void;
14
14
  onChange?: (selectedOptions: Option[]) => void;
15
15
  acceptNewOption?: boolean;
16
16
  zIndex?: number;
@@ -0,0 +1,246 @@
1
+ @use '../../assets/styles/fonts';
2
+
3
+ @mixin transition-all($time: 0.3s) {
4
+ transition: opacity $time ease-out, transform $time ease-out,
5
+ font-size $time ease-out, padding $time ease-out;
6
+ }
7
+
8
+ @mixin absolute-position($top: auto, $right: auto, $bottom: auto, $left: auto) {
9
+ position: absolute;
10
+ top: $top;
11
+ right: $right;
12
+ bottom: $bottom;
13
+ left: $left;
14
+ }
15
+
16
+ @mixin opacity-style($opacity: 1, $color: null, $border-color-arg: null) {
17
+ opacity: $opacity;
18
+
19
+ @if $color {
20
+ color: $color;
21
+ }
22
+
23
+ @if $border-color-arg {
24
+ border-color: $border-color-arg;
25
+ }
26
+ }
27
+
28
+ .ff-nlp-input-wrapper {
29
+ position: relative;
30
+
31
+ .ff-nlp-input {
32
+ @extend .fontSm;
33
+ margin: 0;
34
+ padding: 0;
35
+ box-sizing: border-box;
36
+ min-height: 32px;
37
+ min-width: 489px;
38
+ display: flex;
39
+ align-items: end;
40
+ position: relative;
41
+
42
+ &-fieldset {
43
+ margin: 0;
44
+ padding: 25px 0px 0px 8px;
45
+ border: 1px solid transparent;
46
+ box-sizing: border-box;
47
+ height: 100%;
48
+ width: 100%;
49
+ border-radius: 4px;
50
+ display: block;
51
+
52
+ &--border-radius {
53
+ border-radius: 0px 4px 4px 0px;
54
+ }
55
+
56
+ &--no-label {
57
+ padding: 30px 0px 0px 8px;
58
+ }
59
+
60
+ &--default {
61
+ @include opacity-style(0, null, var(--ff-nlp-input-border-color));
62
+ }
63
+
64
+ &--active {
65
+ @include opacity-style(1, null, var(--ff-nlp-input-brand-color));
66
+ }
67
+
68
+ &--option {
69
+ opacity: 1;
70
+ }
71
+
72
+ &--no-border {
73
+ border-color: transparent;
74
+ }
75
+
76
+ &--error {
77
+ border-color: var(--error-light);
78
+ }
79
+
80
+ .ff-nlp-input-legend {
81
+ @extend .font-size-8;
82
+ padding: 0 2px;
83
+ letter-spacing: 0.5px;
84
+
85
+ &--default {
86
+ @include transition-all(0.3s);
87
+ opacity: 0;
88
+ }
89
+
90
+ &--active {
91
+ @include transition-all(0.25s);
92
+ @include opacity-style(1, var(--ff-nlp-input-brand-color));
93
+ }
94
+
95
+ &--option {
96
+ @include opacity-style(1, var(--ff-nlp-input-default-color));
97
+ }
98
+
99
+ &--error {
100
+ color: var(--error-light);
101
+ }
102
+
103
+ &--required {
104
+ margin-right: 2px;
105
+ }
106
+ }
107
+ }
108
+
109
+ &-input {
110
+ @extend .fontSm;
111
+ @include absolute-position(6px, auto, auto, auto);
112
+ width: calc(100% - 38px);
113
+ min-height: calc(100% - 8px);
114
+ padding: 0 28px 0 8px;
115
+ border-radius: 4px;
116
+ border: 1px solid transparent;
117
+ z-index: 100;
118
+ background: transparent;
119
+ outline: none;
120
+ color: var(--ff-nlp-input-text-color);
121
+
122
+ &:hover {
123
+ ~ .ff-nlp-input-label {
124
+ color: var(--ff-nlp-input-text-hover-color);
125
+ }
126
+ }
127
+
128
+ &--border-radius {
129
+ border-radius: 0px 4px 4px 0px;
130
+ }
131
+
132
+ &--default {
133
+ @include opacity-style(1, null, var(--ff-nlp-input-border-color));
134
+
135
+ &:hover {
136
+ border-color: var(--ff-nlp-input-text-color);
137
+
138
+ ~ .ff-nlp-input-fieldset--option {
139
+ border-color: var(--ff-nlp-input-text-color);
140
+
141
+ .ff-nlp-input-legend--option {
142
+ color: var(--ff-nlp-input-text-color);
143
+ }
144
+ }
145
+ }
146
+ }
147
+
148
+ &--no-label {
149
+ min-height: calc(100% - 2px);
150
+ margin-top: 0px;
151
+ top: 0px;
152
+ }
153
+
154
+ &--active {
155
+ border-color: transparent;
156
+
157
+ &:hover {
158
+ border-color: transparent;
159
+ }
160
+ }
161
+
162
+ &--no-border {
163
+ border: none;
164
+ border-color: transparent;
165
+
166
+ &:hover {
167
+ border-color: transparent;
168
+
169
+ ~ .ff-nlp-input-fieldset--no-border {
170
+ border-color: transparent;
171
+ }
172
+ }
173
+ }
174
+
175
+ &--disable {
176
+ border-color: var(--ff-nlp-input-border-color);
177
+
178
+ &:hover {
179
+ border-color: var(--ff-nlp-input-border-color);
180
+
181
+ ~ .ff-nlp-input-label--default {
182
+ color: var(--ff-nlp-input-default-color);
183
+ }
184
+ }
185
+ }
186
+
187
+ &--error {
188
+ border-color: var(--error-light);
189
+
190
+ &:hover {
191
+ border-color: var(--error-light);
192
+ }
193
+ }
194
+ }
195
+
196
+ &-label {
197
+ @include absolute-position(13px, auto, auto, 8px);
198
+ z-index: 1;
199
+ font-size: 12px;
200
+ top: 60%;
201
+ padding-left: 8px;
202
+
203
+ &--default {
204
+ @include transition-all;
205
+ @include opacity-style(1, var(--ff-nlp-input-default-color));
206
+
207
+ transform: translateY(-50%);
208
+ }
209
+
210
+ &--active {
211
+ @extend .font-size-8;
212
+ @include transition-all;
213
+ opacity: 0;
214
+ transform: translateY(-150%);
215
+ padding: 0 6px;
216
+ }
217
+
218
+ &--required {
219
+ margin-right: 2px;
220
+ }
221
+ }
222
+
223
+ &-arrow {
224
+ position: absolute;
225
+ top: 60%;
226
+ height: 100%;
227
+ right: 10px;
228
+ transform: rotateX(180deg) translateY(50%);
229
+ cursor: pointer;
230
+
231
+ &--no-label {
232
+ top: 50%;
233
+ }
234
+
235
+ &--down {
236
+ transform: rotateX(0deg) translateY(-50%);
237
+ z-index: 101;
238
+ }
239
+ }
240
+ }
241
+
242
+ &-error-text {
243
+ @include absolute-position(auto, auto, -14px, 12px);
244
+ white-space: nowrap;
245
+ }
246
+ }