@platformatic/ui-components 0.2.16 → 0.2.18

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@platformatic/ui-components",
3
3
  "description": "Platformatic UI Components",
4
- "version": "0.2.16",
4
+ "version": "0.2.18",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -3,6 +3,6 @@ import Button from './Button'
3
3
 
4
4
  export default function LoginButton ({ iconName, label, onClick, ...props }) {
5
5
  return (
6
- <Button backgroundColor='main-green' alt={label} label={label} platformaticIcon={{ iconName, size: 'medium', color: 'main-dark-blue' }} data-testid='login-button' size='extra-large' onClick={onClick} {...props} bold />
6
+ <Button backgroundColor='main-green' alt={label} label={label} platformaticIcon={{ iconName, size: 'medium', color: 'main-dark-blue' }} data-testid='login-button' size='extra-large' onClick={onClick} {...props} />
7
7
  )
8
8
  }
@@ -13,7 +13,6 @@ function TooltipV2 ({ tooltipClassName, text, visible, alignment, elementClassNa
13
13
  if (visible) {
14
14
  setClassName(visibleClassName())
15
15
  if (ref.current) {
16
- console.log('elementClassName', elementClassName)
17
16
  const referenceBoundingClientRect = document.getElementsByClassName(elementClassName)[0]?.getBoundingClientRect()
18
17
  if (referenceBoundingClientRect) {
19
18
  const topPosition = referenceBoundingClientRect.y - (referenceBoundingClientRect.height)
@@ -17,12 +17,9 @@ function Select ({
17
17
  borderColor,
18
18
  borderListColor,
19
19
  errorMessage,
20
- onChange,
21
20
  onSelect,
22
- onClear,
23
21
  disabled,
24
22
  mainColor,
25
- optionSelected,
26
23
  dataAttrName,
27
24
  dataAttrValue,
28
25
  backgroundColor,
@@ -30,6 +27,7 @@ function Select ({
30
27
  }) {
31
28
  const inputRef = useRef()
32
29
  const [showOptions, setShowOptions] = useState(false)
30
+ // eslint-disable-next-line no-unused-vars
33
31
  const [isSelected, setIsSelected] = useState(false)
34
32
  const [isOnFocus, setIsOnFocus] = useState(false)
35
33
 
@@ -41,6 +39,7 @@ function Select ({
41
39
  let optionsClassName = `${styles.options} ${defaultOptionsClassName} `
42
40
  inputClassName += ' ' + commonStyles[`background-color-${backgroundColor}`]
43
41
  optionsClassName += commonStyles[`background-color-${backgroundColor}`]
42
+ const optionSelectedClassName = styles.optionSelected
44
43
 
45
44
  if (borderListColor) {
46
45
  optionsClassName += ' ' + styles['bordered-options']
@@ -94,20 +93,11 @@ function Select ({
94
93
  }
95
94
 
96
95
  useEffect(() => {
97
- if (value.length > 0 && !showOptions && !isSelected) {
98
- setShowOptions(true)
99
- }
100
96
  if (value.length === 0) {
101
97
  setIsSelected(false)
102
98
  }
103
99
  }, [value])
104
100
 
105
- useEffect(() => {
106
- if (optionSelected) {
107
- setSelected(optionSelected)
108
- }
109
- }, [optionSelected])
110
-
111
101
  useEffect(() => {
112
102
  if (disabled) {
113
103
  const className = normalClassName() + ' ' + commonStyles['apply-opacity-30']
@@ -117,10 +107,10 @@ function Select ({
117
107
  }
118
108
  }, [disabled])
119
109
 
120
- function renderLi (option, index) {
110
+ function renderLi (option, index, isOptionSelected) {
121
111
  return (
122
112
  <li
123
- key={index} className={singleOptionClassName} onClick={() => {
113
+ key={index} className={`${isOptionSelected ? optionSelectedClassName : singleOptionClassName}`} onClick={() => {
124
114
  if (option.notSelectable) {
125
115
  return handleNotSelectable(option.onClick && option.onClick())
126
116
  }
@@ -137,34 +127,15 @@ function Select ({
137
127
  }
138
128
 
139
129
  function renderOptions () {
140
- if (value.length === 0) {
141
- return (
142
- <ul className={optionsClassName}>
143
- {options.length > 0 ? options.map((option, index) => renderLi(option, index)) : <li className={singleOptionClassName}><div className={styles.liContent}><span className={commonStyles[`text--${mainColor}`]}>No data found</span></div></li>}
144
- </ul>
145
- )
146
- }
147
130
  const notFilterableOptions = options.filter(option => option.notFilterable)
148
- const filteredOptions = options.filter(option => !option.notFilterable).filter(option => option.label.toLowerCase().includes(value.toLowerCase()))
149
-
150
131
  return (
151
132
  <ul className={optionsClassName}>
152
- {filteredOptions.length > 0 ? filteredOptions.map((option, index) => renderLi(option, index)) : <li className={singleOptionClassName}><div className={styles.liContent}><span className={commonStyles[`text--${mainColor}`]}>No data found</span></div></li>}
153
133
  {notFilterableOptions.length > 0 && notFilterableOptions.map((option, index) => renderLi(option, index))}
134
+ {options.length > 0 ? options.map((option, index) => renderLi(option, index, option.label === value)) : <li className={singleOptionClassName}><div className={styles.liContent}><span className={commonStyles[`text--${mainColor}`]}>No data found</span></div></li>}
154
135
  </ul>
155
136
  )
156
137
  }
157
138
 
158
- // https://stackoverflow.com/questions/23892547/what-is-the-best-way-to-trigger-change-or-input-event-in-react-js
159
- function clearValue () {
160
- const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set
161
- nativeInputValueSetter.call(inputRef.current, '')
162
- const ev2 = new Event('input', { bubbles: true })
163
- ev2.simulated = true
164
- inputRef.current.dispatchEvent(ev2)
165
- onClear()
166
- }
167
-
168
139
  function handleFocus () {
169
140
  if (!isOnFocus) {
170
141
  setIsOnFocus(true)
@@ -177,7 +148,7 @@ function Select ({
177
148
  event.preventDefault()
178
149
  setTimeout(() => {
179
150
  if (showOptions) {
180
- setShowOptions(false)
151
+ // setShowOptions(false)
181
152
  setIsOnFocus(false)
182
153
  setWrapperClassName(normalClassName())
183
154
  }
@@ -187,9 +158,8 @@ function Select ({
187
158
  return (
188
159
  <div className={containerClassName} {...dataProps}>
189
160
  <div className={styles.selectContainer}>
190
- <input type='text' name={name} value={value} className={wrapperClassName} ref={inputRef} onChange={onChange} disabled={disabled} placeholder={placeholder} onFocus={() => handleFocus()} onBlur={(e) => handleBlur(e)} />
161
+ <input type='text' name={name} value={value} className={wrapperClassName} ref={inputRef} disabled={disabled} placeholder={placeholder} onFocus={() => handleFocus()} onBlur={(e) => handleBlur(e)} readOnly />
191
162
  <div className={styles.icons}>
192
- {value?.length > 0 && !disabled && <PlatformaticIcon iconName='CircleCloseIcon' color={borderColor} onClick={() => clearValue()} size={SMALL} />}
193
163
  <PlatformaticIcon iconName={showOptions ? 'ArrowUpIcon' : 'ArrowDownIcon'} color={borderColor} disabled={disabled} onClick={() => setShowOptions(!showOptions)} size={SMALL} />
194
164
  </div>
195
165
  </div>
@@ -252,18 +222,10 @@ Select.propTypes = {
252
222
  * color of border UL
253
223
  */
254
224
  borderListColor: PropTypes.oneOf([MAIN_GREEN, MAIN_DARK_BLUE, WHITE]),
255
- /**
256
- * onChange
257
- */
258
- onChange: PropTypes.func,
259
225
  /**
260
226
  * onSelect
261
227
  */
262
228
  onSelect: PropTypes.func,
263
- /**
264
- * onClear
265
- */
266
- onClear: PropTypes.func,
267
229
  /**
268
230
  * Disabled
269
231
  */
@@ -272,16 +234,6 @@ Select.propTypes = {
272
234
  * mainColor
273
235
  */
274
236
  mainColor: PropTypes.oneOf([MAIN_DARK_BLUE, WHITE]),
275
- /**
276
- * optionSelected
277
- */
278
- optionSelected: PropTypes.shape({
279
- label: PropTypes.string,
280
- value: PropTypes.oneOfType([
281
- PropTypes.string,
282
- PropTypes.number
283
- ])
284
- }),
285
237
  /**
286
238
  * dataAttrName
287
239
  */
@@ -312,12 +264,9 @@ Select.defaultProps = {
312
264
  borderColor: MAIN_GREEN,
313
265
  borderListColor: '',
314
266
  errorMessage: '',
315
- onChange: () => {},
316
267
  onSelect: () => {},
317
- onClear: () => {},
318
268
  disabled: false,
319
269
  mainColor: MAIN_DARK_BLUE,
320
- optionSelected: null,
321
270
  dataAttrName: '',
322
271
  dataAttrValue: '',
323
272
  backgroundColor: WHITE,
@@ -17,7 +17,7 @@
17
17
  @apply outline-none;
18
18
  }
19
19
  .options {
20
- @apply absolute left-0 top-[42px] w-full max-h-[216px] overflow-y-scroll z-20;
20
+ @apply absolute left-0 top-[42px] w-[calc(100%-1rem)] max-h-[216px] overflow-y-auto z-20 p-2;
21
21
  }
22
22
  .bordered-options {
23
23
  @apply border border-solid rounded
@@ -25,6 +25,9 @@
25
25
  .option {
26
26
  @apply font-light cursor-pointer z-10 flex flex-row justify-between items-center px-4;
27
27
  }
28
+ .optionSelected {
29
+ @apply font-light cursor-pointer z-10 flex flex-row justify-between items-center px-4 bg-white/15;
30
+ }
28
31
  .bordered-bottom {
29
32
  @apply border-b
30
33
  }
@@ -33,7 +36,7 @@
33
36
  transform: translateY(-50%);
34
37
  }
35
38
  .liContent {
36
- @apply py-2 flex items-center gap-x-1 relative z-[-1] w-auto basis-2/3;
39
+ @apply py-2 flex items-center gap-x-1 relative z-[-1] w-full;
37
40
  }
38
41
  .descriptionValue {
39
42
  @apply opacity-70
@@ -0,0 +1,327 @@
1
+ 'use strict'
2
+ import React, { useState, useEffect, useRef } from 'react'
3
+ import PropTypes from 'prop-types'
4
+ import styles from './SelectWithInput.module.css'
5
+ import commonStyles from '../Common.module.css'
6
+ import { MAIN_DARK_BLUE, MAIN_GREEN, RICH_BLACK, SMALL, WHITE } from '../constants'
7
+ import PlatformaticIcon from '../PlatformaticIcon'
8
+
9
+ function SelectWithInput ({
10
+ defaultContainerClassName,
11
+ placeholder,
12
+ name,
13
+ value,
14
+ options,
15
+ defaultOptionsClassName,
16
+ optionsBorderedBottom,
17
+ borderColor,
18
+ borderListColor,
19
+ errorMessage,
20
+ onChange,
21
+ onSelect,
22
+ onClear,
23
+ disabled,
24
+ mainColor,
25
+ optionSelected,
26
+ dataAttrName,
27
+ dataAttrValue,
28
+ backgroundColor,
29
+ inputTextClassName
30
+ }) {
31
+ const inputRef = useRef()
32
+ const [showOptions, setShowOptions] = useState(false)
33
+ const [isSelected, setIsSelected] = useState(false)
34
+ const [isOnFocus, setIsOnFocus] = useState(false)
35
+
36
+ const showError = errorMessage.length > 0
37
+ const containerClassName = `${styles.container} ${defaultContainerClassName} `
38
+ let inputClassName = `${commonStyles.fullWidth} ${styles.select} ${inputTextClassName}`
39
+ inputClassName += ' ' + styles[`select-${mainColor}`]
40
+ inputClassName += ' ' + commonStyles[`text--${borderColor}`]
41
+ let optionsClassName = `${styles.options} ${defaultOptionsClassName} `
42
+ inputClassName += ' ' + commonStyles[`background-color-${backgroundColor}`]
43
+ optionsClassName += commonStyles[`background-color-${backgroundColor}`]
44
+
45
+ if (borderListColor) {
46
+ optionsClassName += ' ' + styles['bordered-options']
47
+ optionsClassName += ' ' + commonStyles[`bordered--${borderListColor}-30`]
48
+ }
49
+ let singleOptionClassName = `${styles.option} ` + commonStyles[`bordered--${mainColor}-70`] + ' ' + commonStyles[`hover-background-color-opaque-${mainColor}`]
50
+ if (optionsBorderedBottom) {
51
+ singleOptionClassName += ` ${styles['bordered-bottom']}`
52
+ }
53
+
54
+ const optionSpanClassName = commonStyles[`text--${mainColor}`]
55
+
56
+ const [wrapperClassName, setWrapperClassName] = useState(normalClassName())
57
+
58
+ function onFocusClassName () {
59
+ return inputClassName + ' ' + commonStyles[`bordered--${borderColor}-100`]
60
+ }
61
+
62
+ function normalClassName () {
63
+ const baseClassName = inputClassName
64
+ if (showError) {
65
+ inputClassName += ' ' + commonStyles['bordered--error-red']
66
+ } else {
67
+ inputClassName += ' ' + commonStyles[`bordered--${borderColor}-70`]
68
+ }
69
+ if (disabled) inputClassName += ' ' + commonStyles['apply-opacity-30']
70
+ return baseClassName
71
+ }
72
+
73
+ const dataProps = {}
74
+ if (dataAttrName && dataAttrValue) {
75
+ dataProps[`data-${dataAttrName}`] = dataAttrValue
76
+ }
77
+
78
+ function handleNotSelectable (callback = () => {}) {
79
+ setIsSelected(true)
80
+ setShowOptions(false)
81
+ callback()
82
+ }
83
+ function setSelected ({ label, value }) {
84
+ setIsSelected(true)
85
+ setShowOptions(false)
86
+ /* eslint-disable-next-line no-undef */
87
+ onSelect(new CustomEvent('valueSelected', {
88
+ detail: {
89
+ name,
90
+ label,
91
+ value
92
+ }
93
+ }))
94
+ }
95
+
96
+ useEffect(() => {
97
+ if (value.length > 0 && !showOptions && !isSelected) {
98
+ setShowOptions(true)
99
+ }
100
+ if (value.length === 0) {
101
+ setIsSelected(false)
102
+ }
103
+ }, [value])
104
+
105
+ useEffect(() => {
106
+ if (optionSelected) {
107
+ setSelected(optionSelected)
108
+ }
109
+ }, [optionSelected])
110
+
111
+ useEffect(() => {
112
+ if (disabled) {
113
+ const className = normalClassName() + ' ' + commonStyles['apply-opacity-30']
114
+ setWrapperClassName(className)
115
+ } else {
116
+ setWrapperClassName(normalClassName())
117
+ }
118
+ }, [disabled])
119
+
120
+ function renderLi (option, index) {
121
+ return (
122
+ <li
123
+ key={index} className={singleOptionClassName} onClick={() => {
124
+ if (option.notSelectable) {
125
+ return handleNotSelectable(option.onClick && option.onClick())
126
+ }
127
+ return setSelected(option)
128
+ }}
129
+ >
130
+ <div className={styles.liContent}>
131
+ {option.iconName && <PlatformaticIcon iconName={option.iconName} color={option.iconColor || mainColor} size={option.iconSize ?? SMALL} onClick={null} />}
132
+ <span className={optionSpanClassName}>{option.label}</span>
133
+ </div>
134
+ {option.descriptionValue && <span className={`${optionSpanClassName} ${styles.descriptionValue}`}>{option.descriptionValue}</span>}
135
+ </li>
136
+ )
137
+ }
138
+
139
+ function renderOptions () {
140
+ if (value.length === 0) {
141
+ return (
142
+ <ul className={optionsClassName}>
143
+ {options.length > 0 ? options.map((option, index) => renderLi(option, index)) : <li className={singleOptionClassName}><div className={styles.liContent}><span className={commonStyles[`text--${mainColor}`]}>No data found</span></div></li>}
144
+ </ul>
145
+ )
146
+ }
147
+ const notFilterableOptions = options.filter(option => option.notFilterable)
148
+ const filteredOptions = options.filter(option => !option.notFilterable).filter(option => option.label.toLowerCase().includes(value.toLowerCase()))
149
+
150
+ return (
151
+ <ul className={optionsClassName}>
152
+ {filteredOptions.length > 0 ? filteredOptions.map((option, index) => renderLi(option, index)) : <li className={singleOptionClassName}><div className={styles.liContent}><span className={commonStyles[`text--${mainColor}`]}>No data found</span></div></li>}
153
+ {notFilterableOptions.length > 0 && notFilterableOptions.map((option, index) => renderLi(option, index))}
154
+ </ul>
155
+ )
156
+ }
157
+
158
+ // https://stackoverflow.com/questions/23892547/what-is-the-best-way-to-trigger-change-or-input-event-in-react-js
159
+ function clearValue () {
160
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set
161
+ nativeInputValueSetter.call(inputRef.current, '')
162
+ const ev2 = new Event('input', { bubbles: true })
163
+ ev2.simulated = true
164
+ inputRef.current.dispatchEvent(ev2)
165
+ onClear()
166
+ }
167
+
168
+ function handleFocus () {
169
+ if (!isOnFocus) {
170
+ setIsOnFocus(true)
171
+ setWrapperClassName(onFocusClassName())
172
+ }
173
+ setShowOptions(true)
174
+ }
175
+
176
+ function handleBlur (event) {
177
+ event.preventDefault()
178
+ setTimeout(() => {
179
+ if (showOptions) {
180
+ setShowOptions(false)
181
+ setIsOnFocus(false)
182
+ setWrapperClassName(normalClassName())
183
+ }
184
+ }, 250)
185
+ }
186
+
187
+ return (
188
+ <div className={containerClassName} {...dataProps}>
189
+ <div className={styles.selectContainer}>
190
+ <input type='text' name={name} value={value} className={wrapperClassName} ref={inputRef} onChange={onChange} disabled={disabled} placeholder={placeholder} onFocus={() => handleFocus()} onBlur={(e) => handleBlur(e)} />
191
+ <div className={styles.icons}>
192
+ {value?.length > 0 && !disabled && <PlatformaticIcon iconName='CircleCloseIcon' color={borderColor} onClick={() => clearValue()} size={SMALL} />}
193
+ <PlatformaticIcon iconName={showOptions ? 'ArrowUpIcon' : 'ArrowDownIcon'} color={borderColor} disabled={disabled} onClick={() => setShowOptions(!showOptions)} size={SMALL} />
194
+ </div>
195
+ </div>
196
+ {showOptions && !showError && renderOptions()}
197
+ {showError && <span className={commonStyles['error-message']}>{errorMessage}</span>}
198
+ </div>
199
+ )
200
+ }
201
+
202
+ SelectWithInput.propTypes = {
203
+ /**
204
+ * defaultContainerClassName
205
+ */
206
+ defaultContainerClassName: PropTypes.string,
207
+ /**
208
+ * placeholder
209
+ */
210
+ placeholder: PropTypes.string,
211
+ /**
212
+ * name
213
+ */
214
+ name: PropTypes.oneOfType([
215
+ PropTypes.string,
216
+ PropTypes.number
217
+ ]),
218
+ /**
219
+ * value
220
+ */
221
+ value: PropTypes.string,
222
+ /**
223
+ * options
224
+ */
225
+ options: PropTypes.arrayOf(PropTypes.shape({
226
+ label: PropTypes.string,
227
+ value: PropTypes.oneOfType([
228
+ PropTypes.string,
229
+ PropTypes.number
230
+ ]),
231
+ iconName: PropTypes.string,
232
+ iconSize: PropTypes.string,
233
+ iconColor: PropTypes.string,
234
+ notSelectable: PropTypes.bool,
235
+ notFilterable: PropTypes.bool,
236
+ onClick: PropTypes.func,
237
+ descriptionValue: PropTypes.string
238
+ })),
239
+ /**
240
+ * defaultOptionsClassName
241
+ */
242
+ defaultOptionsClassName: PropTypes.string,
243
+ /**
244
+ * optionsBorderedBottom
245
+ */
246
+ optionsBorderedBottom: PropTypes.bool,
247
+ /**
248
+ * color of border
249
+ */
250
+ borderColor: PropTypes.oneOf([MAIN_GREEN, MAIN_DARK_BLUE, WHITE]),
251
+ /**
252
+ * color of border UL
253
+ */
254
+ borderListColor: PropTypes.oneOf([MAIN_GREEN, MAIN_DARK_BLUE, WHITE]),
255
+ /**
256
+ * onChange
257
+ */
258
+ onChange: PropTypes.func,
259
+ /**
260
+ * onSelect
261
+ */
262
+ onSelect: PropTypes.func,
263
+ /**
264
+ * onClear
265
+ */
266
+ onClear: PropTypes.func,
267
+ /**
268
+ * Disabled
269
+ */
270
+ disabled: PropTypes.bool,
271
+ /**
272
+ * mainColor
273
+ */
274
+ mainColor: PropTypes.oneOf([MAIN_DARK_BLUE, WHITE]),
275
+ /**
276
+ * optionSelected
277
+ */
278
+ optionSelected: PropTypes.shape({
279
+ label: PropTypes.string,
280
+ value: PropTypes.oneOfType([
281
+ PropTypes.string,
282
+ PropTypes.number
283
+ ])
284
+ }),
285
+ /**
286
+ * dataAttrName
287
+ */
288
+ dataAttrName: PropTypes.string,
289
+ /**
290
+ * dataAttrValue
291
+ */
292
+ dataAttrValue: PropTypes.string,
293
+ /**
294
+ * backgroundColor
295
+ */
296
+ backgroundColor: PropTypes.oneOf([MAIN_DARK_BLUE, WHITE, RICH_BLACK]),
297
+ /**
298
+ * inputTextClassName
299
+ */
300
+ inputTextClassName: PropTypes.string
301
+ }
302
+
303
+ SelectWithInput.defaultProps = {
304
+ defaultContainerClassName: '',
305
+ placeholder: 'this is the default',
306
+ name: '',
307
+ value: '',
308
+ id: '',
309
+ options: [],
310
+ defaultOptionsClassName: '',
311
+ optionsBorderedBottom: true,
312
+ borderColor: MAIN_GREEN,
313
+ borderListColor: '',
314
+ errorMessage: '',
315
+ onChange: () => {},
316
+ onSelect: () => {},
317
+ onClear: () => {},
318
+ disabled: false,
319
+ mainColor: MAIN_DARK_BLUE,
320
+ optionSelected: null,
321
+ dataAttrName: '',
322
+ dataAttrValue: '',
323
+ backgroundColor: WHITE,
324
+ inputTextClassName: ''
325
+ }
326
+
327
+ export default SelectWithInput
@@ -0,0 +1,40 @@
1
+ .container {
2
+ @apply flex flex-col w-full relative
3
+ }
4
+ .selectContainer {
5
+ @apply w-full flex items-center relative z-10;
6
+ }
7
+ .select {
8
+ @apply py-1.5 px-2 md:px-3 md:py-[10.5px] h-full border border-solid box-border rounded;
9
+ }
10
+
11
+ .select-main-dark-blue.active,
12
+ .select-main-dark-blue:focus {
13
+ @apply shadow-main-dark-blue outline-none;
14
+ }
15
+ .select-white.active,
16
+ .select-white:focus {
17
+ @apply outline-none;
18
+ }
19
+ .options {
20
+ @apply absolute left-0 top-[42px] w-full max-h-[216px] overflow-y-scroll z-20;
21
+ }
22
+ .bordered-options {
23
+ @apply border border-solid rounded
24
+ }
25
+ .option {
26
+ @apply font-light cursor-pointer z-10 flex flex-row justify-between items-center px-4;
27
+ }
28
+ .bordered-bottom {
29
+ @apply border-b
30
+ }
31
+ .icons {
32
+ @apply absolute top-[50%] right-[0.5rem] flex gap-x-2;
33
+ transform: translateY(-50%);
34
+ }
35
+ .liContent {
36
+ @apply py-2 flex items-center gap-x-1 relative z-[-1] w-auto basis-2/3;
37
+ }
38
+ .descriptionValue {
39
+ @apply opacity-70
40
+ }
@@ -5,6 +5,7 @@ import Password from './Password'
5
5
  import Preview from './Preview'
6
6
  import RadioGroup from './RadioGroup'
7
7
  import Select from './Select'
8
+ import SelectWithInput from './SelectWithInput'
8
9
  import TextArea from './TextArea'
9
10
  import ToggleSwitch from './ToggleSwitch'
10
11
 
@@ -16,6 +17,7 @@ export default {
16
17
  Preview,
17
18
  RadioGroup,
18
19
  Select,
20
+ SelectWithInput,
19
21
  TextArea,
20
22
  ToggleSwitch
21
23
  }
@@ -35,18 +35,13 @@ Default.args = {
35
35
  const TemplateBorderMainDarkBlue = (args) => {
36
36
  const [value, setValue] = useState('')
37
37
 
38
- function handleChange (event) {
39
- setValue(event.target.value)
40
- }
41
-
42
38
  function handleSelect (event) {
43
39
  setValue(event.detail.label)
44
40
  }
45
41
 
46
42
  return (
47
43
  <div style={{ backgroundColor: 'white', padding: '20px 10px' }}>
48
- <p>Value of the input {value}</p>
49
- <Select {...args} value={value} onChange={handleChange} onSelect={handleSelect} />
44
+ <Select {...args} value={value} onSelect={handleSelect} />
50
45
  </div>
51
46
  )
52
47
  }
@@ -54,10 +49,6 @@ const TemplateBorderMainDarkBlue = (args) => {
54
49
  const TemplateBorderMainDarkBlue2 = (args) => {
55
50
  const [value, setValue] = useState('')
56
51
 
57
- function handleChange (event) {
58
- setValue(event.target.value)
59
- }
60
-
61
52
  function handleSelect (event) {
62
53
  setValue(event.detail.label)
63
54
  }
@@ -66,7 +57,7 @@ const TemplateBorderMainDarkBlue2 = (args) => {
66
57
  <>
67
58
  <div style={{ backgroundColor: 'white', padding: '20px 10px' }}>
68
59
  <p>Value of the input {value}</p>
69
- <Select {...args} value={value} onChange={handleChange} onSelect={handleSelect} />
60
+ <Select {...args} value={value} onSelect={handleSelect} />
70
61
  <br />
71
62
  <Select placeholder='Disabled' disabled />
72
63
 
@@ -146,10 +137,6 @@ githubRepoExample.args = {
146
137
  const TemplateTransparent = (args) => {
147
138
  const [value, setValue] = useState('')
148
139
 
149
- function handleChange (event) {
150
- setValue(event.target.value)
151
- }
152
-
153
140
  function handleSelect (event) {
154
141
  setValue(event.detail.label)
155
142
  }
@@ -157,7 +144,7 @@ const TemplateTransparent = (args) => {
157
144
  return (
158
145
  <div style={{ padding: '20px 10px' }}>
159
146
  <p>Value of the input {value}</p>
160
- <Select {...args} value={value} onChange={handleChange} onSelect={handleSelect} />
147
+ <Select {...args} value={value} onSelect={handleSelect} />
161
148
  </div>
162
149
  )
163
150
  }
@@ -0,0 +1,176 @@
1
+ 'use strict'
2
+ import React, { useState } from 'react'
3
+ import SelectWithInput from '../../components/forms/SelectWithInput'
4
+ import { MAIN_DARK_BLUE, MAIN_GREEN, RICH_BLACK, WHITE } from '../../components/constants'
5
+
6
+ const divStyle = {
7
+ width: '100%',
8
+ height: 'auto',
9
+ padding: '20px',
10
+ backgroundColor: 'transparent'
11
+ }
12
+
13
+ export default {
14
+ title: 'Platformatic/Forms/SelectWithInput',
15
+ component: SelectWithInput,
16
+ decorators: [
17
+ (Story) => (
18
+ <div style={divStyle}>
19
+ <Story />
20
+ </div>
21
+ )
22
+ ]
23
+ }
24
+
25
+ const Template = (args) => <SelectWithInput {...args} />
26
+
27
+ export const Default = Template.bind({})
28
+
29
+ Default.args = {
30
+ name: 'test',
31
+ placeholder: 'Platformatic empty select',
32
+ borderColor: MAIN_GREEN
33
+ }
34
+
35
+ const TemplateBorderMainDarkBlue = (args) => {
36
+ const [value, setValue] = useState('')
37
+
38
+ function handleChange (event) {
39
+ setValue(event.target.value)
40
+ }
41
+
42
+ function handleSelect (event) {
43
+ setValue(event.detail.label)
44
+ }
45
+
46
+ return (
47
+ <div style={{ backgroundColor: 'white', padding: '20px 10px' }}>
48
+ <p>Value of the input {value}</p>
49
+ <SelectWithInput {...args} value={value} onChange={handleChange} onSelect={handleSelect} />
50
+ </div>
51
+ )
52
+ }
53
+
54
+ const TemplateBorderMainDarkBlue2 = (args) => {
55
+ const [value, setValue] = useState('')
56
+
57
+ function handleChange (event) {
58
+ setValue(event.target.value)
59
+ }
60
+
61
+ function handleSelect (event) {
62
+ setValue(event.detail.label)
63
+ }
64
+
65
+ return (
66
+ <>
67
+ <div style={{ backgroundColor: 'white', padding: '20px 10px' }}>
68
+ <p>Value of the input {value}</p>
69
+ <SelectWithInput {...args} value={value} onChange={handleChange} onSelect={handleSelect} />
70
+ <br />
71
+ <SelectWithInput placeholder='Disabled' disabled />
72
+
73
+ </div>
74
+ </>
75
+ )
76
+ }
77
+
78
+ export const BorderMainDarkBlue = TemplateBorderMainDarkBlue.bind({})
79
+
80
+ BorderMainDarkBlue.args = {
81
+ name: 'test',
82
+ placeholder: 'Defaul option',
83
+ options: [...Array(20).keys()].map(ele => ({ label: `Option ${ele}`, value: `Value${ele}`, iconName: 'SocialGitHubIcon' })),
84
+ borderColor: MAIN_DARK_BLUE
85
+ }
86
+
87
+ export const DefaultInvalid = TemplateBorderMainDarkBlue.bind({})
88
+
89
+ DefaultInvalid.args = {
90
+ name: 'test',
91
+ placeholder: 'Platformatic empty select',
92
+ options: [{ label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }, { label: 'Option 3', value: '3' }],
93
+ borderColor: MAIN_GREEN,
94
+ errorMessage: 'This is an error message'
95
+ }
96
+
97
+ export const withDifferentOptions = TemplateBorderMainDarkBlue2.bind({})
98
+
99
+ withDifferentOptions.args = {
100
+ name: 'test',
101
+ placeholder: 'Platformatic',
102
+ options: [...Array(20).keys()].map(ele => ({
103
+ label: `Option ${ele}`,
104
+ value: `Value${ele}`,
105
+ iconName: 'SocialGitHubIcon'
106
+ })).concat({
107
+ label: 'Last but not least',
108
+ iconName: 'AddIcon',
109
+ value: 123123,
110
+ notSelectable: true,
111
+ onClick: () => alert('you clicked last but not least')
112
+ }).concat({
113
+ label: 'Play',
114
+ iconName: 'PlayIcon',
115
+ value: 123123,
116
+ notSelectable: true
117
+ }),
118
+ borderColor: MAIN_DARK_BLUE
119
+ }
120
+
121
+ export const githubRepoExample = TemplateBorderMainDarkBlue2.bind({})
122
+
123
+ githubRepoExample.args = {
124
+ name: 'test',
125
+ placeholder: 'Platformatic',
126
+ options: [...Array(4).keys()].map(ele => ({
127
+ label: `GitHub Repo ${ele}`,
128
+ value: `Value${ele}`,
129
+ iconName: 'SocialGitHubIcon'
130
+ })).concat({
131
+ label: 'this is an option that is not selectable',
132
+ iconName: 'AddIcon',
133
+ value: 123123,
134
+ notSelectable: true,
135
+ onClick: () => alert('you clicked last but not least')
136
+ }).concat({
137
+ label: 'Add Github repo',
138
+ iconName: 'PlayIcon',
139
+ value: 123123,
140
+ notSelectable: true,
141
+ notFilterable: true
142
+ }),
143
+ borderColor: MAIN_DARK_BLUE
144
+ }
145
+
146
+ const TemplateTransparent = (args) => {
147
+ const [value, setValue] = useState('')
148
+
149
+ function handleChange (event) {
150
+ setValue(event.target.value)
151
+ }
152
+
153
+ function handleSelect (event) {
154
+ setValue(event.detail.label)
155
+ }
156
+
157
+ return (
158
+ <div style={{ padding: '20px 10px' }}>
159
+ <p>Value of the input {value}</p>
160
+ <SelectWithInput {...args} value={value} onChange={handleChange} onSelect={handleSelect} />
161
+ </div>
162
+ )
163
+ }
164
+
165
+ export const TemplateBackgroundTransparent = TemplateTransparent.bind({})
166
+
167
+ TemplateBackgroundTransparent.args = {
168
+ name: 'test',
169
+ placeholder: 'Defaul option',
170
+ optionsBorderedBottom: false,
171
+ options: [...Array(20).keys()].map(ele => ({ label: `Option ${ele}`, value: `Value${ele}`, iconName: 'OrganizationIcon' })),
172
+ borderColor: WHITE,
173
+ mainColor: WHITE,
174
+ backgroundColor: RICH_BLACK,
175
+ borderListColor: WHITE
176
+ }