playbook_ui 15.5.0.pre.alpha.PLAY2581aggressivevalidation12654 → 15.5.0.pre.alpha.draggableask12772
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.html.erb +31 -0
- data/app/pb_kits/playbook/pb_dialog/index.js +15 -10
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +28 -0
- data/app/pb_kits/playbook/pb_file_upload/_file_upload.scss +4 -4
- data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +34 -22
- data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.html.erb +16 -12
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_default.html.erb +1 -1
- data/app/pb_kits/playbook/pb_home_address_street/none_emphasis.html.erb +16 -12
- data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.html.erb +16 -12
- data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.scss +10 -0
- data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.tsx +66 -15
- data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.jsx +42 -0
- data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.md +1 -0
- data/app/pb_kits/playbook/pb_multiple_users/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_multiple_users/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_multiple_users/multiple_users.test.js +25 -0
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +10 -43
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +15 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +3 -0
- data/app/pb_kits/playbook/pb_typeahead/components/ClearIndicator.tsx +13 -2
- data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +6 -1
- data/app/pb_kits/playbook/pb_typeahead/components/ValueContainer.tsx +34 -7
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.html.erb +30 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.jsx +37 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.md +3 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +6 -1
- data/dist/chunks/{_typeahead-Bbgw3Q5E.js → _typeahead-B4GUo5ik.js} +2 -2
- data/dist/chunks/vendor.js +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +8 -3
|
@@ -110,25 +110,13 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
110
110
|
const inputRef = useRef<HTMLInputElement | null>(null)
|
|
111
111
|
const itiRef = useRef<any>(null);
|
|
112
112
|
const wrapperRef = useRef<HTMLDivElement | null>(null);
|
|
113
|
-
const hasBlurredRef = useRef<boolean>(false);
|
|
114
|
-
const formSubmittedRef = useRef<boolean>(false);
|
|
115
113
|
const [inputValue, setInputValue] = useState(value)
|
|
116
114
|
const [error, setError] = useState(props.error || "")
|
|
117
115
|
const [dropDownIsOpen, setDropDownIsOpen] = useState(false)
|
|
118
116
|
const [selectedData, setSelectedData] = useState()
|
|
119
117
|
const [hasTyped, setHasTyped] = useState(false)
|
|
120
|
-
const [hasBlurred, setHasBlurred] = useState(false)
|
|
121
118
|
const [formSubmitted, setFormSubmitted] = useState(false)
|
|
122
119
|
const [hasStartedValidating, setHasStartedValidating] = useState(false)
|
|
123
|
-
|
|
124
|
-
// Keep refs in sync with state for use in event listeners
|
|
125
|
-
useEffect(() => {
|
|
126
|
-
hasBlurredRef.current = hasBlurred
|
|
127
|
-
}, [hasBlurred])
|
|
128
|
-
|
|
129
|
-
useEffect(() => {
|
|
130
|
-
formSubmittedRef.current = formSubmitted
|
|
131
|
-
}, [formSubmitted])
|
|
132
120
|
|
|
133
121
|
// Only sync initial error from props, not continuous updates
|
|
134
122
|
// Once validation starts, internal validation takes over
|
|
@@ -155,8 +143,8 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
155
143
|
}
|
|
156
144
|
|
|
157
145
|
// Determine which error to display
|
|
158
|
-
// Show internal errors
|
|
159
|
-
const shouldShowInternalError = (
|
|
146
|
+
// Show internal errors on blur (hasTyped) or on form submission (formSubmitted)
|
|
147
|
+
const shouldShowInternalError = (hasTyped || formSubmitted) && required && error
|
|
160
148
|
const displayError = shouldShowInternalError ? error : ""
|
|
161
149
|
|
|
162
150
|
useEffect(() => {
|
|
@@ -271,8 +259,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
271
259
|
return
|
|
272
260
|
}
|
|
273
261
|
|
|
274
|
-
|
|
275
|
-
if (!hasBlurred && !formSubmitted) return
|
|
262
|
+
if (!hasTyped && !error) return
|
|
276
263
|
|
|
277
264
|
// Run validation checks
|
|
278
265
|
if (itiRef.current) isValid(itiRef.current.isValidNumber())
|
|
@@ -293,7 +280,6 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
293
280
|
if (phoneNumberContainer && phoneNumberContainer === wrapperRef.current) {
|
|
294
281
|
const invalidInputName = target.name || target.getAttribute('name')
|
|
295
282
|
if (invalidInputName === name) {
|
|
296
|
-
formSubmittedRef.current = true
|
|
297
283
|
setFormSubmitted(true)
|
|
298
284
|
// Trigger validation when form is submitted
|
|
299
285
|
validateErrors()
|
|
@@ -319,9 +305,6 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
319
305
|
setInputValue("")
|
|
320
306
|
setError("")
|
|
321
307
|
setHasTyped(false)
|
|
322
|
-
hasBlurredRef.current = false
|
|
323
|
-
setHasBlurred(false)
|
|
324
|
-
formSubmittedRef.current = false
|
|
325
308
|
setFormSubmitted(false)
|
|
326
309
|
setHasStartedValidating(false)
|
|
327
310
|
// Only clear validation state if field was required
|
|
@@ -339,7 +322,6 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
339
322
|
|
|
340
323
|
if (required && isEmpty) {
|
|
341
324
|
setError('Missing phone number')
|
|
342
|
-
formSubmittedRef.current = true
|
|
343
325
|
setFormSubmitted(true)
|
|
344
326
|
return 'Missing phone number'
|
|
345
327
|
}
|
|
@@ -396,7 +378,6 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
396
378
|
|
|
397
379
|
// Set the error state so the validation attribute gets added
|
|
398
380
|
setError(errorMessage)
|
|
399
|
-
formSubmittedRef.current = true
|
|
400
381
|
setFormSubmitted(true)
|
|
401
382
|
setHasTyped(true)
|
|
402
383
|
|
|
@@ -420,7 +401,6 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
420
401
|
|
|
421
402
|
// Reset form submitted state when user types
|
|
422
403
|
if (formSubmitted) {
|
|
423
|
-
formSubmittedRef.current = false
|
|
424
404
|
setFormSubmitted(false)
|
|
425
405
|
}
|
|
426
406
|
|
|
@@ -436,15 +416,11 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
436
416
|
|
|
437
417
|
setSelectedData(phoneNumberData)
|
|
438
418
|
onChange(phoneNumberData)
|
|
439
|
-
|
|
440
|
-
// Don't call isValid callback on change - only on blur or form submission
|
|
441
|
-
// This prevents triggering validation while typing
|
|
442
|
-
// Use refs to get current values in case this is called from event listener
|
|
443
|
-
if (hasBlurredRef.current || formSubmittedRef.current) {
|
|
444
|
-
isValid(itiRef.current.isValidNumber())
|
|
445
|
-
}
|
|
419
|
+
isValid(itiRef.current.isValidNumber())
|
|
446
420
|
|
|
447
|
-
//
|
|
421
|
+
// Trigger validation after onChange for React Hook Form
|
|
422
|
+
// This ensures validation state is up-to-date
|
|
423
|
+
setTimeout(() => validateErrors(), 0)
|
|
448
424
|
}
|
|
449
425
|
|
|
450
426
|
// Separating Concerns as React Docs Recommend
|
|
@@ -506,12 +482,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
506
482
|
|
|
507
483
|
setSelectedData(phoneNumberData)
|
|
508
484
|
onChange(phoneNumberData)
|
|
509
|
-
|
|
510
|
-
// Don't call isValid callback on change - only on blur or form submission
|
|
511
|
-
// Use refs to check current blur state in the event listener (closure issue)
|
|
512
|
-
if (hasBlurredRef.current || formSubmittedRef.current) {
|
|
513
|
-
isValid(telInputInit.isValidNumber())
|
|
514
|
-
}
|
|
485
|
+
isValid(telInputInit.isValidNumber())
|
|
515
486
|
})
|
|
516
487
|
}
|
|
517
488
|
}
|
|
@@ -521,16 +492,12 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
521
492
|
dark,
|
|
522
493
|
"data-phone-number": JSON.stringify(selectedData),
|
|
523
494
|
disabled,
|
|
524
|
-
error:
|
|
495
|
+
error: hasTyped ? error : props.error || displayError,
|
|
525
496
|
type: 'tel',
|
|
526
497
|
id,
|
|
527
498
|
label,
|
|
528
499
|
name,
|
|
529
|
-
onBlur:
|
|
530
|
-
hasBlurredRef.current = true
|
|
531
|
-
setHasBlurred(true)
|
|
532
|
-
validateErrors()
|
|
533
|
-
},
|
|
500
|
+
onBlur: validateErrors,
|
|
534
501
|
onChange: formatAsYouType ? undefined : handleOnChange,
|
|
535
502
|
value: inputValue
|
|
536
503
|
}
|
|
@@ -276,3 +276,18 @@ test('multi-value badges have tabIndex and focus class when focused', () => {
|
|
|
276
276
|
})
|
|
277
277
|
})
|
|
278
278
|
|
|
279
|
+
test('input display none shows number of selected items', () => {
|
|
280
|
+
render(
|
|
281
|
+
<Typeahead
|
|
282
|
+
data={{ testid: 'input-display-none-test' }}
|
|
283
|
+
defaultValue={[options[0], options[1]]}
|
|
284
|
+
inputDisplay="none"
|
|
285
|
+
isMulti
|
|
286
|
+
options={options}
|
|
287
|
+
/>
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
const kit = screen.getByTestId('input-display-none-test')
|
|
291
|
+
const inputDisplayDiv = kit.querySelector(".pb_typeahead_selection_count")
|
|
292
|
+
expect(inputDisplayDiv).toHaveTextContent("2 items selected")
|
|
293
|
+
})
|
|
@@ -43,6 +43,7 @@ type TypeaheadProps = {
|
|
|
43
43
|
error?: string,
|
|
44
44
|
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
|
45
45
|
id?: string,
|
|
46
|
+
inputDisplay?: "pills" | "none",
|
|
46
47
|
label?: string,
|
|
47
48
|
loadOptions?: string | Noop,
|
|
48
49
|
getOptionLabel?: string | (() => string),
|
|
@@ -89,6 +90,7 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
|
|
|
89
90
|
getOptionValue,
|
|
90
91
|
htmlOptions = {},
|
|
91
92
|
id,
|
|
93
|
+
inputDisplay = "pills",
|
|
92
94
|
name,
|
|
93
95
|
loadOptions = noop,
|
|
94
96
|
marginBottom = "sm",
|
|
@@ -238,6 +240,7 @@ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
|
|
|
238
240
|
getOptionValue: isString(getOptionValue) ? get(window, getOptionValue) : getOptionValue,
|
|
239
241
|
defaultOptions: true,
|
|
240
242
|
id: id || uniqueId(),
|
|
243
|
+
inputDisplay: inputDisplay,
|
|
241
244
|
inline: false,
|
|
242
245
|
isClearable: true,
|
|
243
246
|
isSearchable: true,
|
|
@@ -7,18 +7,29 @@ type ClearContainerProps = {
|
|
|
7
7
|
id: string,
|
|
8
8
|
},
|
|
9
9
|
clearValue: () => void,
|
|
10
|
+
innerProps?: any,
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
const ClearContainer = (props: ClearContainerProps): React.ReactElement => {
|
|
13
|
-
const { selectProps, clearValue } = props
|
|
13
|
+
const ClearContainer = (props: ClearContainerProps | any): React.ReactElement => {
|
|
14
|
+
const { selectProps, clearValue, innerProps } = props
|
|
14
15
|
useEffect(() => {
|
|
15
16
|
document.addEventListener(`pb-typeahead-kit-${selectProps.id}:clear`, clearValue)
|
|
16
17
|
}, [clearValue, selectProps.id])
|
|
17
18
|
|
|
19
|
+
// To stop this from bubbling up when inside a dialog or other modal
|
|
20
|
+
const handleMouseDown = (event: React.MouseEvent) => {
|
|
21
|
+
event.stopPropagation()
|
|
22
|
+
innerProps?.onMouseDown?.(event)
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
return (
|
|
19
26
|
<components.ClearIndicator
|
|
20
27
|
className="clear_indicator"
|
|
21
28
|
{...props}
|
|
29
|
+
innerProps={{
|
|
30
|
+
...innerProps,
|
|
31
|
+
onMouseDown: handleMouseDown,
|
|
32
|
+
}}
|
|
22
33
|
/>
|
|
23
34
|
)
|
|
24
35
|
}
|
|
@@ -19,7 +19,12 @@ type Props = {
|
|
|
19
19
|
const MultiValue = (props: Props) => {
|
|
20
20
|
const { removeProps, isFocused } = props
|
|
21
21
|
const { imageUrl, label } = props.data
|
|
22
|
-
const { dark, multiKit, pillColor, truncate, wrapped } = props.selectProps
|
|
22
|
+
const { dark, multiKit, pillColor, truncate, wrapped, inputDisplay } = props.selectProps
|
|
23
|
+
|
|
24
|
+
// If inputDisplay is "none", don't render the pill/badge, just return null (the count handled in ValueContainer file)
|
|
25
|
+
if (inputDisplay === 'none') {
|
|
26
|
+
return null
|
|
27
|
+
}
|
|
23
28
|
|
|
24
29
|
const formPillProps = {
|
|
25
30
|
marginRight: 'xs',
|
|
@@ -1,15 +1,42 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { components } from 'react-select'
|
|
3
|
+
import Body from '../../pb_body/_body'
|
|
3
4
|
|
|
4
5
|
type ValueContainerProps = {
|
|
5
|
-
children: React.ReactNode,
|
|
6
|
+
children: React.ReactNode | React.ReactNode[],
|
|
7
|
+
selectProps?: Record<string, unknown>,
|
|
8
|
+
hasValue?: boolean,
|
|
6
9
|
}
|
|
7
10
|
|
|
8
|
-
const ValueContainer = (props: ValueContainerProps): React.ReactElement =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
)
|
|
11
|
+
const ValueContainer = (props: ValueContainerProps | any): React.ReactElement => {
|
|
12
|
+
const { children, selectProps, hasValue } = props
|
|
13
|
+
const inputDisplay = (selectProps as any)?.inputDisplay
|
|
14
|
+
const value = (selectProps as any)?.value
|
|
15
|
+
|
|
16
|
+
// When inputDisplay is "none" and there are selected values, show count text (this is for multi-select only)
|
|
17
|
+
if (inputDisplay === 'none' && hasValue && value) {
|
|
18
|
+
const selectedCount = Array.isArray(value) ? value.length : 0
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<components.ValueContainer
|
|
22
|
+
className="text_input_value_container"
|
|
23
|
+
{...props}
|
|
24
|
+
>
|
|
25
|
+
<Body
|
|
26
|
+
className="pb_typeahead_selection_count"
|
|
27
|
+
text={`${selectedCount} item${selectedCount !== 1 ? 's' : ''} selected`}
|
|
28
|
+
/>
|
|
29
|
+
{children}
|
|
30
|
+
</components.ValueContainer>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<components.ValueContainer
|
|
36
|
+
className="text_input_value_container"
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
14
41
|
|
|
15
42
|
export default ValueContainer
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<%
|
|
2
|
+
options = [
|
|
3
|
+
{ label: 'Orange', value: '#FFA500' },
|
|
4
|
+
{ label: 'Red', value: '#FF0000' },
|
|
5
|
+
{ label: 'Green', value: '#00FF00' },
|
|
6
|
+
{ label: 'Blue', value: '#0000FF' },
|
|
7
|
+
{ label: 'Yellow', value: '#FFFF00' },
|
|
8
|
+
{ label: 'Purple', value: '#800080' },
|
|
9
|
+
{ label: 'Cyan', value: '#00FFFF' },
|
|
10
|
+
{ label: 'Magenta', value: '#FF00FF' }
|
|
11
|
+
]
|
|
12
|
+
%>
|
|
13
|
+
|
|
14
|
+
<%= pb_rails("typeahead", props: {
|
|
15
|
+
id: "typeahead-input-display-none",
|
|
16
|
+
label: "With Input Display None",
|
|
17
|
+
options: options,
|
|
18
|
+
name: :foo,
|
|
19
|
+
input_display: "none",
|
|
20
|
+
})
|
|
21
|
+
%>
|
|
22
|
+
<br/>
|
|
23
|
+
<%= pb_rails("typeahead", props: {
|
|
24
|
+
id: "typeahead-input-display-pills",
|
|
25
|
+
label: "With Input Display Pills (Default)",
|
|
26
|
+
options: options,
|
|
27
|
+
name: :foo,
|
|
28
|
+
pills: true,
|
|
29
|
+
})
|
|
30
|
+
%>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import Typeahead from '../_typeahead'
|
|
4
|
+
|
|
5
|
+
const options = [
|
|
6
|
+
{ label: 'Orange', value: '#FFA500' },
|
|
7
|
+
{ label: 'Red', value: '#FF0000' },
|
|
8
|
+
{ label: 'Green', value: '#00FF00' },
|
|
9
|
+
{ label: 'Blue', value: '#0000FF' },
|
|
10
|
+
{ label: 'Yellow', value: '#FFFF00' },
|
|
11
|
+
{ label: 'Purple', value: '#800080' },
|
|
12
|
+
{ label: 'Cyan', value: '#00FFFF' },
|
|
13
|
+
{ label: 'Magenta', value: '#FF00FF' }
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
const TypeaheadInputDisplay = (props) => {
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<Typeahead
|
|
20
|
+
inputDisplay="none"
|
|
21
|
+
isMulti
|
|
22
|
+
label="With Input Display None"
|
|
23
|
+
options={options}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
<br/>
|
|
27
|
+
<Typeahead
|
|
28
|
+
isMulti
|
|
29
|
+
label="With Input Display Pills (Default)"
|
|
30
|
+
options={options}
|
|
31
|
+
{...props}
|
|
32
|
+
/>
|
|
33
|
+
</>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default TypeaheadInputDisplay
|
|
@@ -5,6 +5,7 @@ examples:
|
|
|
5
5
|
- typeahead_default_options: With Default Options
|
|
6
6
|
- typeahead_with_context: With Context
|
|
7
7
|
- typeahead_with_pills: With Pills
|
|
8
|
+
- typeahead_input_display: Input Display
|
|
8
9
|
- typeahead_without_pills: Without Pills (Single Select)
|
|
9
10
|
- typeahead_with_pills_async: With Pills (Async Data)
|
|
10
11
|
- typeahead_with_pills_async_users: With Pills (Async Data w/ Users)
|
|
@@ -26,6 +27,7 @@ examples:
|
|
|
26
27
|
- typeahead_react_hook: React Hook
|
|
27
28
|
- typeahead_with_highlight: With Highlight
|
|
28
29
|
- typeahead_with_pills: With Pills
|
|
30
|
+
- typeahead_input_display: Input Display
|
|
29
31
|
- typeahead_with_pills_async: With Pills (Async Data)
|
|
30
32
|
- typeahead_with_pills_async_users: With Pills (Async Data w/ Users)
|
|
31
33
|
- typeahead_with_pills_async_custom_options: With Pills (Async Data w/ Custom Options)
|
|
@@ -17,4 +17,5 @@ export { default as TypeaheadReactHook } from './_typeahead_react_hook.jsx'
|
|
|
17
17
|
export { default as TypeaheadDisabled } from './_typeahead_disabled.jsx'
|
|
18
18
|
export { default as TypeaheadPreserveInput } from './_typeahead_preserve_input.jsx'
|
|
19
19
|
export { default as TypeaheadDefaultValue } from './_typeahead_default_value.jsx'
|
|
20
|
-
export { default as TypeaheadCustomOptions } from './_typeahead_custom_options.jsx'
|
|
20
|
+
export { default as TypeaheadCustomOptions } from './_typeahead_custom_options.jsx'
|
|
21
|
+
export { default as TypeaheadInputDisplay } from './_typeahead_input_display.jsx'
|
|
@@ -25,6 +25,10 @@ module Playbook
|
|
|
25
25
|
prop :is_multi, type: Playbook::Props::Boolean,
|
|
26
26
|
default: true
|
|
27
27
|
|
|
28
|
+
prop :input_display, type: Playbook::Props::Enum,
|
|
29
|
+
values: %w[none pills],
|
|
30
|
+
default: "pills"
|
|
31
|
+
|
|
28
32
|
prop :pills, type: Playbook::Props::Boolean,
|
|
29
33
|
default: false
|
|
30
34
|
|
|
@@ -78,7 +82,7 @@ module Playbook
|
|
|
78
82
|
end
|
|
79
83
|
|
|
80
84
|
def is_react?
|
|
81
|
-
pills || !is_multi || wrapped
|
|
85
|
+
pills || !is_multi || wrapped || input_display == "none"
|
|
82
86
|
end
|
|
83
87
|
|
|
84
88
|
def typeahead_react_options
|
|
@@ -91,6 +95,7 @@ module Playbook
|
|
|
91
95
|
id: id,
|
|
92
96
|
inline: inline,
|
|
93
97
|
isMulti: is_multi,
|
|
98
|
+
inputDisplay: input_display,
|
|
94
99
|
label: label,
|
|
95
100
|
marginBottom: margin_bottom,
|
|
96
101
|
multiKit: multi_kit,
|