playbook_ui 14.9.0.pre.alpha.PBNTR686advancedtablepaginationpoc4747 → 14.9.0.pre.alpha.PLAY16264818
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_select/_select.tsx +19 -14
- data/app/pb_kits/playbook/pb_select/docs/_select_form.jsx +108 -0
- data/app/pb_kits/playbook/pb_select/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_select/docs/index.js +1 -0
- data/app/pb_kits/playbook/utilities/hookFormProps.ts +16 -0
- data/dist/chunks/{_weekday_stacked-DSEuqOLN.js → _weekday_stacked-DxlPBh55.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd75b9e4b0f7ce117dbd06fd2a726c2c365b6e5bf64cb203f030ba83659ae448
|
4
|
+
data.tar.gz: 4973b4425fac4133d09a37743f38638af91d63ac3a720555846ca286b0358635
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdd757f0e267dede1c878c35a04a53cc26fb39568a802ae979477d938c6fc3e23f4e48150ec4d549717febb1daf69ae8d60285582c1ef58cd539b819ac47ab08
|
7
|
+
data.tar.gz: 9a2776ad808a0e04c2f152e64975d48b02911c3edd4cda0be6d317571fd92553d29cd6e8159444d392d2a48815e4ee1318b4eaabaf5c17bdba9c9c89ff22538b
|
@@ -1,8 +1,10 @@
|
|
1
1
|
import React, { forwardRef } from 'react'
|
2
2
|
import classnames from 'classnames'
|
3
|
+
import { FieldValues } from 'react-hook-form'
|
3
4
|
|
4
5
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
5
6
|
import { globalProps, GlobalProps, domSafeProps } from '../utilities/globalProps'
|
7
|
+
import { HookFormProps, withHookForm } from '../utilities/hookFormProps'
|
6
8
|
import type { InputCallback } from '../types'
|
7
9
|
import { getAllIcons } from "../utilities/icons/allicons"
|
8
10
|
|
@@ -16,7 +18,7 @@ type SelectOption = {
|
|
16
18
|
disabled?: boolean,
|
17
19
|
}
|
18
20
|
|
19
|
-
type SelectProps = {
|
21
|
+
type SelectProps<T extends FieldValues = FieldValues> = {
|
20
22
|
aria?: { [key: string]: string },
|
21
23
|
blankSelection?: string,
|
22
24
|
children?: Node,
|
@@ -30,16 +32,17 @@ type SelectProps = {
|
|
30
32
|
includeBlank?: string,
|
31
33
|
inline?: boolean,
|
32
34
|
label?: string,
|
33
|
-
margin
|
35
|
+
margin?: string,
|
34
36
|
marginBottom: string,
|
37
|
+
marginTop: string,
|
35
38
|
multiple?: boolean,
|
36
39
|
name?: string,
|
37
|
-
onChange
|
40
|
+
onChange?: InputCallback<HTMLSelectElement>,
|
38
41
|
options: SelectOption[],
|
39
42
|
required?: boolean,
|
40
43
|
showArrow?: boolean,
|
41
44
|
value?: string,
|
42
|
-
} & GlobalProps
|
45
|
+
} & GlobalProps & Partial<HookFormProps<T>>
|
43
46
|
|
44
47
|
const createOptions = (options: SelectOption[]) => options.map((option, index) => (
|
45
48
|
<option
|
@@ -51,7 +54,7 @@ const createOptions = (options: SelectOption[]) => options.map((option, index) =
|
|
51
54
|
</option>
|
52
55
|
))
|
53
56
|
|
54
|
-
const Select = ({
|
57
|
+
const Select = <T extends FieldValues = FieldValues>({
|
55
58
|
aria = {},
|
56
59
|
blankSelection,
|
57
60
|
children,
|
@@ -65,17 +68,20 @@ const Select = ({
|
|
65
68
|
inline = false,
|
66
69
|
multiple = false,
|
67
70
|
name,
|
68
|
-
onChange
|
71
|
+
onChange,
|
69
72
|
options = [],
|
73
|
+
register,
|
70
74
|
required = false,
|
75
|
+
rules,
|
71
76
|
showArrow = false,
|
72
77
|
value,
|
73
78
|
...props
|
74
|
-
}: SelectProps
|
79
|
+
}: SelectProps<T>, ref: React.LegacyRef<HTMLSelectElement>) => {
|
75
80
|
const ariaProps = buildAriaProps(aria)
|
76
81
|
const dataProps = buildDataProps(data)
|
77
82
|
const htmlProps = buildHtmlProps(htmlOptions)
|
78
83
|
const optionsList = createOptions(options)
|
84
|
+
const hookFormProps = name ? withHookForm({ register, name, rules }) : {}
|
79
85
|
|
80
86
|
const inlineClass = inline ? 'inline' : null
|
81
87
|
const compactClass = compact ? 'compact' : null
|
@@ -91,21 +97,22 @@ const Select = ({
|
|
91
97
|
compactClass
|
92
98
|
);
|
93
99
|
|
94
|
-
const
|
100
|
+
const icons = getAllIcons()
|
101
|
+
const angleDown = icons?.angleDown?.icon as { [key: string]: SVGElement }
|
95
102
|
|
96
103
|
const selectWrapperClass = classnames(buildCss('pb_select_kit_wrapper'), { error }, className)
|
97
104
|
const selectBody =(() =>{
|
98
105
|
if (children) return children
|
99
106
|
return (
|
100
107
|
<select
|
101
|
-
{...htmlOptions}
|
102
108
|
{...domSafeProps(props)}
|
109
|
+
{...hookFormProps}
|
103
110
|
disabled={disabled}
|
104
111
|
id={name}
|
105
112
|
multiple={multiple}
|
106
113
|
name={name}
|
107
|
-
onChange={onChange}
|
108
|
-
ref={ref}
|
114
|
+
onChange={onChange || hookFormProps.onChange}
|
115
|
+
ref={ref || hookFormProps.ref}
|
109
116
|
required={required}
|
110
117
|
value={value}
|
111
118
|
>
|
@@ -135,14 +142,12 @@ const Select = ({
|
|
135
142
|
htmlFor={name}
|
136
143
|
>
|
137
144
|
{selectBody}
|
138
|
-
{ multiple !== true
|
145
|
+
{ multiple !== true && angleDown &&
|
139
146
|
<Icon
|
140
147
|
className="pb_select_kit_caret svg-inline--fa"
|
141
148
|
customIcon={angleDown}
|
142
149
|
fixedWidth
|
143
150
|
/>
|
144
|
-
:
|
145
|
-
null
|
146
151
|
}
|
147
152
|
{error &&
|
148
153
|
<Body
|
@@ -0,0 +1,108 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { useForm } from 'react-hook-form'
|
3
|
+
import { Select, Card, Body, Button } from 'playbook-ui'
|
4
|
+
|
5
|
+
const SelectForm = (props) => {
|
6
|
+
const {
|
7
|
+
register,
|
8
|
+
handleSubmit,
|
9
|
+
formState: { errors },
|
10
|
+
watch,
|
11
|
+
} = useForm({
|
12
|
+
defaultValues: {
|
13
|
+
favoriteFood: '',
|
14
|
+
mealType: '',
|
15
|
+
dietaryRestrictions: '',
|
16
|
+
}
|
17
|
+
})
|
18
|
+
|
19
|
+
const onSubmit = (data) => {
|
20
|
+
console.log('Form submitted:', data)
|
21
|
+
}
|
22
|
+
|
23
|
+
// Watch form values for real-time display
|
24
|
+
const formValues = watch()
|
25
|
+
|
26
|
+
const foodOptions = [
|
27
|
+
{ value: 'pizza', text: 'Pizza' },
|
28
|
+
{ value: 'burger', text: 'Burger' },
|
29
|
+
{ value: 'sushi', text: 'Sushi' },
|
30
|
+
{ value: 'salad', text: 'Salad' },
|
31
|
+
]
|
32
|
+
|
33
|
+
const mealTypes = [
|
34
|
+
{ value: 'breakfast', text: 'Breakfast' },
|
35
|
+
{ value: 'lunch', text: 'Lunch' },
|
36
|
+
{ value: 'dinner', text: 'Dinner' },
|
37
|
+
]
|
38
|
+
|
39
|
+
const dietaryOptions = [
|
40
|
+
{ value: 'none', text: 'No Restrictions' },
|
41
|
+
{ value: 'vegetarian', text: 'Vegetarian' },
|
42
|
+
{ value: 'vegan', text: 'Vegan' },
|
43
|
+
{ value: 'glutenFree', text: 'Gluten Free' },
|
44
|
+
]
|
45
|
+
|
46
|
+
return (
|
47
|
+
<div>
|
48
|
+
<Card>
|
49
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
50
|
+
<Select
|
51
|
+
error={errors.favoriteFood?.message}
|
52
|
+
label="What's your favorite food?"
|
53
|
+
name="favoriteFood"
|
54
|
+
options={foodOptions}
|
55
|
+
register={register}
|
56
|
+
rules={{
|
57
|
+
required: 'Please select your favorite food',
|
58
|
+
}}
|
59
|
+
{...props}
|
60
|
+
/>
|
61
|
+
<Select
|
62
|
+
blankSelection="Choose a meal type..."
|
63
|
+
error={errors.mealType?.message}
|
64
|
+
label="Preferred meal time"
|
65
|
+
marginTop="md"
|
66
|
+
name="mealType"
|
67
|
+
options={mealTypes}
|
68
|
+
register={register}
|
69
|
+
rules={{
|
70
|
+
required: 'Please select a meal type',
|
71
|
+
}}
|
72
|
+
{...props}
|
73
|
+
/>
|
74
|
+
<Select
|
75
|
+
label="Dietary Restrictions"
|
76
|
+
marginTop="md"
|
77
|
+
name="dietaryRestrictions"
|
78
|
+
options={dietaryOptions}
|
79
|
+
register={register}
|
80
|
+
{...props}
|
81
|
+
/>
|
82
|
+
|
83
|
+
<Button
|
84
|
+
marginTop="lg"
|
85
|
+
text="Submit"
|
86
|
+
type="submit"
|
87
|
+
variant="primary"
|
88
|
+
|
89
|
+
/>
|
90
|
+
</form>
|
91
|
+
<Card marginTop="lg">
|
92
|
+
<Body
|
93
|
+
text="Current Form Values:"
|
94
|
+
variant="bold"
|
95
|
+
/>
|
96
|
+
<pre style={{ marginTop: '8px', color: "white" }}>
|
97
|
+
{JSON.stringify(formValues, null, 2)}
|
98
|
+
</pre>
|
99
|
+
</Card>
|
100
|
+
</Card>
|
101
|
+
</div>
|
102
|
+
)
|
103
|
+
}
|
104
|
+
|
105
|
+
export default SelectForm
|
106
|
+
|
107
|
+
|
108
|
+
|
@@ -10,3 +10,4 @@ export { default as SelectInline } from './_select_inline.jsx'
|
|
10
10
|
export { default as SelectInlineShowArrow } from './_select_inline_show_arrow.jsx'
|
11
11
|
export { default as SelectInlineCompact } from './_select_inline_compact.jsx'
|
12
12
|
export { default as SelectMultiple } from './_select_multiple.jsx'
|
13
|
+
export { default as SelectForm } from './_select_form.jsx'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { UseFormRegister, FieldValues, RegisterOptions } from 'react-hook-form'
|
2
|
+
|
3
|
+
export type HookFormProps<T extends FieldValues = FieldValues> = {
|
4
|
+
register?: UseFormRegister<T>
|
5
|
+
rules?: RegisterOptions
|
6
|
+
name: string
|
7
|
+
}
|
8
|
+
|
9
|
+
export const withHookForm = <T extends FieldValues = FieldValues>(
|
10
|
+
props: HookFormProps<T>
|
11
|
+
) => {
|
12
|
+
const { register, name, rules } = props
|
13
|
+
if (!register) return {}
|
14
|
+
|
15
|
+
return register(name, rules)
|
16
|
+
}
|