playbook_ui 14.4.0.pre.alpha.PBNTR490multilevelselect3832 → 14.4.0.pre.alpha.PBNTR550typeaheadformpilltruncate3895
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/Components/SortIconButton.tsx +23 -4
- data/app/pb_kits/playbook/pb_contact/_contact.tsx +17 -5
- data/app/pb_kits/playbook/pb_contact/contact.html.erb +14 -6
- data/app/pb_kits/playbook/pb_contact/contact.rb +4 -0
- data/app/pb_kits/playbook/pb_contact/contact.test.js +1 -1
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +4 -3
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +1 -1
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +4 -0
- data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +6 -3
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.html.erb +1 -1
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_header_styles.scss +6 -2
- data/app/pb_kits/playbook/pb_dialog/_dialog.scss +2 -0
- data/app/pb_kits/playbook/pb_dialog/dialog_header.html.erb +1 -1
- data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +9 -1
- data/app/pb_kits/playbook/pb_map/_map_controls.tsx +7 -1
- data/app/pb_kits/playbook/pb_pagination/docs/_pagination_page_change.jsx +12 -1
- data/app/pb_kits/playbook/pb_pagination/docs/_pagination_page_change_react.md +3 -1
- data/app/pb_kits/playbook/pb_passphrase/_passphrase.tsx +10 -2
- data/app/pb_kits/playbook/pb_radio/_radio.tsx +92 -33
- data/app/pb_kits/playbook/pb_radio/docs/_radio_custom_children.jsx +59 -0
- data/app/pb_kits/playbook/pb_radio/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_radio/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx +12 -5
- data/app/pb_kits/playbook/pb_select/_select.tsx +5 -2
- data/app/pb_kits/playbook/pb_select/select.html.erb +1 -1
- data/app/pb_kits/playbook/pb_select/select.rb +4 -0
- data/app/pb_kits/playbook/pb_text_input/_text_input.scss +0 -1
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.scss +0 -1
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +14 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +7 -1
- data/app/pb_kits/playbook/pb_typeahead/components/Control.tsx +6 -5
- data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +3 -1
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_margin_bottom.html.erb +88 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_margin_bottom.jsx +60 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_typeahead/typeahead.html.erb +2 -1
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +6 -1
- data/app/pb_kits/playbook/utilities/icons/allicons.tsx +123 -0
- data/app/pb_kits/playbook/utilities/icons/angle-down.svg +3 -0
- data/app/pb_kits/playbook/utilities/icons/envelope.svg +3 -0
- data/dist/chunks/_typeahead-Ctc4yCCN.js +22 -0
- data/dist/chunks/_weekday_stacked-B4Xs5p_U.js +45 -0
- data/dist/chunks/lib-CEpcaI8y.js +29 -0
- data/dist/chunks/{pb_form_validation-zV9OpdSt.js → pb_form_validation-D9zkwt2b.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +1 -1
- 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 +11 -6
- data/dist/chunks/_typeahead-BErpxkBz.js +0 -22
- data/dist/chunks/_weekday_stacked-CGwn8Bd7.js +0 -45
- data/dist/chunks/lib-D2U4I1U6.js +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c6aac1da17236064490c7bb4ee36b45c253608e418af00cc8ce01d9704ab3b52
|
4
|
+
data.tar.gz: 579a2f877566a884c34e7ba6838bb6d45e40b3ece38cf43da3683d4f1f6c128e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3df47bbec17dcd38e0d345fd3b9d00e96af4cc45e08bb857173f88620aab7f67b21c474372922eed548cfc74a17b5fa19a43152ead0dd821d6750db0ca639626
|
7
|
+
data.tar.gz: 1d72e78a5430be2711313f1515483cd059f741d983933ec76a4bb396dfe9c7b9f19110235ee08d2cd7cafade05182e5798a742ba41afcd12629472fdc5b3407f
|
@@ -4,6 +4,7 @@ import { Header } from "@tanstack/react-table"
|
|
4
4
|
import { GenericObject } from "../../types"
|
5
5
|
|
6
6
|
import Icon from "../../pb_icon/_icon"
|
7
|
+
import { getAllIcons } from "../../utilities/icons/allicons"
|
7
8
|
|
8
9
|
import { displayIcon } from "../Utilities/IconHelpers"
|
9
10
|
|
@@ -11,21 +12,39 @@ type SortIconButtonProps = {
|
|
11
12
|
header: Header<GenericObject, unknown>
|
12
13
|
sortIcon?: string | string[]
|
13
14
|
}
|
15
|
+
|
14
16
|
export const SortIconButton = ({ header, sortIcon }: SortIconButtonProps) => {
|
15
17
|
|
18
|
+
const firstIcon = displayIcon(sortIcon)[0]
|
19
|
+
const secondIcon = displayIcon(sortIcon)[1]
|
20
|
+
const upIcon = getAllIcons()["arrowUpShortWide"].icon as unknown as { [key: string]: SVGElement }
|
21
|
+
const downIcon = getAllIcons()["arrowDownShortWide"].icon as unknown as { [key: string]: SVGElement }
|
22
|
+
|
16
23
|
return (
|
17
24
|
<>
|
18
25
|
{header.column.getIsSorted() === "desc" ? (
|
19
26
|
<div className="sort-button-icon"
|
20
|
-
key={
|
27
|
+
key={firstIcon}
|
21
28
|
>
|
22
|
-
|
29
|
+
{ firstIcon === "arrow-up-short-wide" ? (
|
30
|
+
<Icon
|
31
|
+
className="svg-inline--fa"
|
32
|
+
customIcon={upIcon}
|
33
|
+
/> ) : (
|
34
|
+
<Icon icon={firstIcon} />
|
35
|
+
)}
|
23
36
|
</div>
|
24
37
|
) : (
|
25
38
|
<div className="sort-button-icon"
|
26
|
-
key={
|
39
|
+
key={secondIcon}
|
27
40
|
>
|
28
|
-
|
41
|
+
{ secondIcon === "arrow-down-short-wide" ? (
|
42
|
+
<Icon
|
43
|
+
className="svg-inline--fa"
|
44
|
+
customIcon={downIcon}
|
45
|
+
/> ) : (
|
46
|
+
<Icon icon={secondIcon} />
|
47
|
+
)}
|
29
48
|
</div>
|
30
49
|
)}
|
31
50
|
</>
|
@@ -7,6 +7,7 @@ import { globalProps } from '../utilities/globalProps'
|
|
7
7
|
import Body from '../pb_body/_body'
|
8
8
|
import Caption from '../pb_caption/_caption'
|
9
9
|
import Icon from '../pb_icon/_icon'
|
10
|
+
import { getAllIcons } from "../utilities/icons/allicons"
|
10
11
|
|
11
12
|
const contactTypeMap: { [key: string]: string } = {
|
12
13
|
'cell': 'mobile',
|
@@ -18,6 +19,8 @@ const contactTypeMap: { [key: string]: string } = {
|
|
18
19
|
'wrong-phone': 'phone-slash',
|
19
20
|
}
|
20
21
|
|
22
|
+
const envelopeIcon = getAllIcons()["envelope"].icon as unknown as { [key: string]: SVGElement }
|
23
|
+
|
21
24
|
const formatContact = (contactString: string, contactType: string) => {
|
22
25
|
if (contactType === 'email') return contactString
|
23
26
|
|
@@ -91,11 +94,20 @@ const Contact = (props: ContactProps): React.ReactElement => {
|
|
91
94
|
dark={dark}
|
92
95
|
tag="span"
|
93
96
|
>
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
97
|
+
{contactType === 'email' ? (
|
98
|
+
<Icon
|
99
|
+
className="svg-inline--fa envelope"
|
100
|
+
customIcon={envelopeIcon}
|
101
|
+
dark={dark}
|
102
|
+
fixedWidth
|
103
|
+
/>
|
104
|
+
) : (
|
105
|
+
<Icon
|
106
|
+
dark={dark}
|
107
|
+
fixedWidth
|
108
|
+
icon={contactTypeMap[contactType] || 'phone'}
|
109
|
+
/>
|
110
|
+
)}
|
99
111
|
{` ${formatContact(contactValue, contactType)} `}
|
100
112
|
{contactDetail && (
|
101
113
|
<Caption
|
@@ -4,12 +4,20 @@
|
|
4
4
|
classname: "pb_contact_kit",
|
5
5
|
color: "light",
|
6
6
|
dark: object.dark
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
}) do %>
|
8
|
+
<% if contact_type == "email" %>
|
9
|
+
<%= pb_rails("icon", props: {
|
10
|
+
custom_icon: Playbook::Engine::root.join(envelope_path),
|
11
|
+
fixed_width: true,
|
12
|
+
dark: object.dark
|
13
|
+
}) %>
|
14
|
+
<% else %>
|
15
|
+
<%= pb_rails("icon", props: {
|
16
|
+
icon: object.contact_icon,
|
17
|
+
fixed_width: true,
|
18
|
+
dark: object.dark
|
19
|
+
}) %>
|
20
|
+
<% end %>
|
13
21
|
<%= object.formatted_contact_value if object.contact_value %>
|
14
22
|
|
15
23
|
<%= pb_rails("caption", props: {
|
@@ -79,7 +79,7 @@ test('returns correct icon', () => {
|
|
79
79
|
expect(screen.getByTestId('test-home').querySelector('.pb_icon_kit')).toHaveClass('fa-phone')
|
80
80
|
expect(screen.getByTestId('test-work').querySelector('.pb_icon_kit')).toHaveClass('fa-phone-office')
|
81
81
|
expect(screen.getByTestId('test-work-cell').querySelector('.pb_icon_kit')).toHaveClass('fa-phone-laptop')
|
82
|
-
expect(screen.getByTestId('test-email').querySelector('.
|
82
|
+
expect(screen.getByTestId('test-email').querySelector('.pb_custom_icon')).toHaveClass('envelope')
|
83
83
|
expect(screen.getByTestId('test-wrong-phone').querySelector('.pb_icon_kit')).toHaveClass('fa-phone-slash')
|
84
84
|
expect(screen.getByTestId('test-wrong-type').querySelector('.pb_icon_kit')).toHaveClass('fa-phone')
|
85
85
|
expect(screen.getByTestId('test-extension').querySelector('.pb_icon_kit')).toHaveClass('fa-phone-plus')
|
@@ -3,6 +3,7 @@ import classnames from 'classnames'
|
|
3
3
|
|
4
4
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
5
5
|
import { deprecatedProps, globalProps, GlobalProps } from '../utilities/globalProps'
|
6
|
+
import { getAllIcons } from "../utilities/icons/allicons"
|
6
7
|
|
7
8
|
import datePickerHelper from './date_picker_helper'
|
8
9
|
import Icon from '../pb_icon/_icon'
|
@@ -161,7 +162,7 @@ useEffect(() => {
|
|
161
162
|
}
|
162
163
|
return base
|
163
164
|
}
|
164
|
-
|
165
|
+
const angleDown = getAllIcons()["angleDown"].icon as unknown as { [key: string]: SVGElement }
|
165
166
|
|
166
167
|
return (
|
167
168
|
<div
|
@@ -231,8 +232,8 @@ useEffect(() => {
|
|
231
232
|
id={`${pickerId}-angle-down`}
|
232
233
|
>
|
233
234
|
<Icon
|
234
|
-
className="angle_down_icon"
|
235
|
-
|
235
|
+
className="angle_down_icon svg-inline--fa"
|
236
|
+
customIcon={angleDown}
|
236
237
|
/>
|
237
238
|
</div>
|
238
239
|
</div>
|
@@ -5,6 +5,9 @@ import monthSelectPlugin from 'flatpickr/dist/plugins/monthSelect'
|
|
5
5
|
import weekSelect from "flatpickr/dist/plugins/weekSelect/weekSelect"
|
6
6
|
import timeSelectPlugin from './plugins/timeSelect'
|
7
7
|
import quickPickPlugin from './plugins/quickPick'
|
8
|
+
import { getAllIcons } from '../utilities/icons/allicons';
|
9
|
+
|
10
|
+
const angleDown = getAllIcons().angleDown.string
|
8
11
|
|
9
12
|
const getPositionElement = (element: string | Element) => {
|
10
13
|
return (typeof element === 'string') ? document.querySelectorAll(element)[0] : element
|
@@ -256,10 +259,10 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
|
|
256
259
|
})
|
257
260
|
}
|
258
261
|
|
259
|
-
// Adding dropdown icons to year and month
|
260
|
-
dropdown.insertAdjacentHTML('afterend',
|
262
|
+
// Adding dropdown icons to year and month select
|
263
|
+
dropdown.insertAdjacentHTML('afterend', `<i class="year-dropdown-icon">${angleDown}</i>`)
|
261
264
|
if (picker.monthElements[0].parentElement) {
|
262
|
-
return picker.monthElements[0].insertAdjacentHTML('afterend',
|
265
|
+
return picker.monthElements[0].insertAdjacentHTML('afterend', `<i class="month-dropdown-icon">${angleDown}</i>`)}
|
263
266
|
// if (picker.weekElements[0].parentElement){
|
264
267
|
// return picker.weekElements[0].insertAdjacentHTML('afterend', '<i class="far fa-angle-down year-dropdown-icon" id="test-id"></i>')
|
265
268
|
// }
|
@@ -76,7 +76,11 @@
|
|
76
76
|
pointer-events: none;
|
77
77
|
color: $text_lt_light;
|
78
78
|
}
|
79
|
-
|
79
|
+
.year-dropdown-icon svg, .month-dropdown-icon svg {
|
80
|
+
width: 16px;
|
81
|
+
margin-top: 6px;
|
82
|
+
margin-left: -2px;
|
83
|
+
}
|
80
84
|
// Left - Right Arrow Styling
|
81
85
|
.flatpickr-prev-month {
|
82
86
|
display: flex;
|
@@ -113,4 +117,4 @@
|
|
113
117
|
}
|
114
118
|
}
|
115
119
|
}
|
116
|
-
}
|
120
|
+
}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<%= pb_rails("flex", props: {classname:object.classname, spacing:"between", padding:"sm", align:"center"}) do %>
|
3
3
|
<%= content.presence || object.title %>
|
4
4
|
|
5
|
-
<button class="dialog-button-class" type="button" data-close-dialog= <%= object.id %> >
|
5
|
+
<button class="dialog-button-class pb_dialog_close_icon" type="button" data-close-dialog= <%= object.id %> >
|
6
6
|
<%= pb_rails("icon", props: { custom_icon: Playbook::Engine::root.join(times_icon) }) %>
|
7
7
|
</button>
|
8
8
|
<% end %>
|
@@ -47,9 +47,13 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
|
|
47
47
|
|
48
48
|
const iconClass = icon ? "_icon" : ""
|
49
49
|
const closeIconSize = size === "small" ? "xs" : "sm"
|
50
|
+
|
51
|
+
const filteredProps: FormPillProps = {...props}
|
52
|
+
delete filteredProps.truncate
|
53
|
+
|
50
54
|
const css = classnames(
|
51
55
|
`pb_form_pill_kit_${color}${iconClass}`,
|
52
|
-
globalProps(
|
56
|
+
globalProps(filteredProps),
|
53
57
|
className,
|
54
58
|
size === 'small' ? 'small' : null,
|
55
59
|
textTransform,
|
@@ -77,6 +81,7 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
|
|
77
81
|
className="pb_form_pill_text"
|
78
82
|
size={4}
|
79
83
|
text={name}
|
84
|
+
truncate={props.truncate}
|
80
85
|
/>
|
81
86
|
</>
|
82
87
|
)}
|
@@ -92,6 +97,7 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
|
|
92
97
|
className="pb_form_pill_text"
|
93
98
|
size={4}
|
94
99
|
text={name}
|
100
|
+
truncate={props.truncate}
|
95
101
|
/>
|
96
102
|
<Icon
|
97
103
|
className="pb_form_pill_icon"
|
@@ -111,6 +117,7 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
|
|
111
117
|
className="pb_form_pill_tag"
|
112
118
|
size={4}
|
113
119
|
text={text}
|
120
|
+
truncate={props.truncate}
|
114
121
|
/>
|
115
122
|
</>
|
116
123
|
)}
|
@@ -119,6 +126,7 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
|
|
119
126
|
className="pb_form_pill_tag"
|
120
127
|
size={4}
|
121
128
|
text={text}
|
129
|
+
truncate={props.truncate}
|
122
130
|
/>
|
123
131
|
)}
|
124
132
|
<div
|
@@ -2,6 +2,7 @@ import React from "react";
|
|
2
2
|
import Button from "../pb_button/_button";
|
3
3
|
import Icon from "../pb_icon/_icon";
|
4
4
|
import Flex from "../pb_flex/_flex";
|
5
|
+
import { getAllIcons } from "../utilities/icons/allicons"
|
5
6
|
|
6
7
|
type MapControlTypes = {
|
7
8
|
zoomBtns?: boolean,
|
@@ -12,6 +13,8 @@ type MapControlTypes = {
|
|
12
13
|
children?: React.ReactNode | React.ReactNode[]
|
13
14
|
}
|
14
15
|
|
16
|
+
const eyeIcon = getAllIcons()["eye"]
|
17
|
+
|
15
18
|
const MapControls = ({
|
16
19
|
zoomBtns,
|
17
20
|
zoomInClick,
|
@@ -42,7 +45,10 @@ const MapControls = ({
|
|
42
45
|
<Button className="map-flyto-button"
|
43
46
|
onClick={flyToClick}
|
44
47
|
>
|
45
|
-
<Icon
|
48
|
+
<Icon
|
49
|
+
className="svg-inline--fa"
|
50
|
+
customIcon={eyeIcon.icon as unknown as { [key: string]: SVGElement }}
|
51
|
+
/>
|
46
52
|
</Button>
|
47
53
|
) : null}
|
48
54
|
</>
|
@@ -22,6 +22,16 @@ const PaginationPageChange = (props) => {
|
|
22
22
|
|
23
23
|
return (
|
24
24
|
<div className="App">
|
25
|
+
<Pagination
|
26
|
+
current={activePage}
|
27
|
+
key={`pagination-top-${activePage}`}
|
28
|
+
marginBottom="xs"
|
29
|
+
onChange={onPageChange}
|
30
|
+
range={5}
|
31
|
+
total={totalPages}
|
32
|
+
{...props}
|
33
|
+
/>
|
34
|
+
|
25
35
|
<Table
|
26
36
|
marginBottom="xs"
|
27
37
|
responsive="none"
|
@@ -49,7 +59,8 @@ const PaginationPageChange = (props) => {
|
|
49
59
|
</Table>
|
50
60
|
|
51
61
|
<Pagination
|
52
|
-
current={
|
62
|
+
current={activePage}
|
63
|
+
key={`pagination-bottom-${activePage}`}
|
53
64
|
onChange={onPageChange}
|
54
65
|
range={5}
|
55
66
|
total={totalPages}
|
@@ -1 +1,3 @@
|
|
1
|
-
You can use the `onChange` prop to control the data of your table. This prop is callback function that will allow you control the state.
|
1
|
+
You can use the `onChange` prop to control the data of your table. This prop is callback function that will allow you control the state.
|
2
|
+
|
3
|
+
To ensure synchronization between multiple pagination components on a single page, use unique, dynamic keys for each pagination instance. Each Pagination component should have its own dynamic key that reflects the current active page: this example uses `pagination-top-${activePage}` and `pagination-bottom-${activePage}`.
|
@@ -12,6 +12,7 @@ import Icon from '../pb_icon/_icon'
|
|
12
12
|
import PbReactPopover from '../pb_popover/_popover'
|
13
13
|
import TextInput from '../pb_text_input/_text_input'
|
14
14
|
import { GenericObject } from "../types"
|
15
|
+
import { getAllIcons } from "../utilities/icons/allicons"
|
15
16
|
|
16
17
|
type PassphraseProps = {
|
17
18
|
aria?: { [key: string]: string },
|
@@ -96,6 +97,9 @@ const Passphrase = (props: PassphraseProps): React.ReactElement => {
|
|
96
97
|
/>
|
97
98
|
)
|
98
99
|
|
100
|
+
const shieldIcon = getAllIcons()["shieldCheck"]
|
101
|
+
const eyeIcon = getAllIcons()["eye"]
|
102
|
+
|
99
103
|
return (
|
100
104
|
<div
|
101
105
|
{...ariaProps}
|
@@ -135,7 +139,8 @@ const Passphrase = (props: PassphraseProps): React.ReactElement => {
|
|
135
139
|
size="xs"
|
136
140
|
>
|
137
141
|
<Icon
|
138
|
-
|
142
|
+
className="svg-inline--fa"
|
143
|
+
customIcon={shieldIcon.icon as unknown as { [key: string]: SVGElement }}
|
139
144
|
marginRight="xs"
|
140
145
|
/>
|
141
146
|
{tip}
|
@@ -173,7 +178,10 @@ const Passphrase = (props: PassphraseProps): React.ReactElement => {
|
|
173
178
|
color="light"
|
174
179
|
dark={dark}
|
175
180
|
>
|
176
|
-
|
181
|
+
<Icon
|
182
|
+
className="svg-inline--fa"
|
183
|
+
customIcon={eyeIcon.icon as unknown as { [key: string]: SVGElement }}
|
184
|
+
/>
|
177
185
|
</Body>
|
178
186
|
</span>
|
179
187
|
</div>
|
@@ -1,28 +1,30 @@
|
|
1
|
-
/*eslint-disable react/no-multi-comp
|
1
|
+
/*eslint-disable react/no-multi-comp */
|
2
2
|
|
3
|
-
import React, { forwardRef } from 'react'
|
3
|
+
import React, { forwardRef, useRef } from 'react'
|
4
4
|
import Body from '../pb_body/_body'
|
5
|
+
import Flex from '../pb_flex/_flex'
|
5
6
|
import classnames from 'classnames'
|
6
7
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
7
8
|
import { globalProps, GlobalProps } from '../utilities/globalProps'
|
8
9
|
|
9
10
|
type RadioProps = {
|
10
|
-
aria?: {[key: string]: string},
|
11
|
+
aria?: { [key: string]: string },
|
11
12
|
alignment?: string,
|
12
13
|
checked?: boolean,
|
13
14
|
children?: React.ReactChild[] | React.ReactChild,
|
15
|
+
customChildren?: boolean,
|
14
16
|
className?: string,
|
15
17
|
dark?: boolean,
|
16
|
-
data?: {[key: string]: string},
|
18
|
+
data?: { [key: string]: string },
|
17
19
|
disabled?: boolean,
|
18
20
|
error?: boolean,
|
19
|
-
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
21
|
+
htmlOptions?: { [key: string]: string | number | boolean | (() => void) },
|
20
22
|
id?: string,
|
21
23
|
label: string,
|
22
24
|
name?: string,
|
23
25
|
value?: string,
|
24
26
|
text?: string,
|
25
|
-
onChange: (event: React.FormEvent<HTMLInputElement> | null)=>void,
|
27
|
+
onChange: (event: React.FormEvent<HTMLInputElement> | null) => void,
|
26
28
|
} & GlobalProps
|
27
29
|
|
28
30
|
const Radio = ({
|
@@ -30,10 +32,11 @@ const Radio = ({
|
|
30
32
|
alignment,
|
31
33
|
children,
|
32
34
|
className,
|
35
|
+
customChildren = false,
|
33
36
|
dark = false,
|
34
|
-
data = {},
|
35
37
|
disabled = false,
|
36
38
|
error = false,
|
39
|
+
data = {},
|
37
40
|
htmlOptions = {},
|
38
41
|
id,
|
39
42
|
label,
|
@@ -43,17 +46,28 @@ const Radio = ({
|
|
43
46
|
onChange = () => { void 0 },
|
44
47
|
...props
|
45
48
|
}: RadioProps, ref: any) => {
|
46
|
-
const
|
47
|
-
|
48
|
-
const
|
49
|
+
const radioRef = useRef(null);
|
50
|
+
|
51
|
+
const ariaProps = buildAriaProps(aria);
|
52
|
+
const dataProps = buildDataProps(data);
|
53
|
+
const htmlProps = buildHtmlProps(htmlOptions);
|
49
54
|
const classes = classnames(
|
50
|
-
buildCss('pb_radio_kit', alignment
|
51
|
-
dark ? 'dark'
|
55
|
+
buildCss('pb_radio_kit', alignment),
|
56
|
+
dark ? 'dark' : null,
|
57
|
+
error ? 'error' : null,
|
52
58
|
globalProps(props),
|
53
|
-
className
|
59
|
+
className
|
60
|
+
);
|
61
|
+
|
62
|
+
const classesCustom = classnames(
|
63
|
+
dark ? 'dark' : null,
|
64
|
+
error ? 'error' : null,
|
65
|
+
globalProps(props),
|
66
|
+
className
|
67
|
+
);
|
54
68
|
|
55
69
|
const displayRadio = (props: RadioProps & any) => {
|
56
|
-
if (children)
|
70
|
+
if (children && customChildren == false)
|
57
71
|
return (children)
|
58
72
|
else
|
59
73
|
return (
|
@@ -70,24 +84,69 @@ const Radio = ({
|
|
70
84
|
/>
|
71
85
|
)}
|
72
86
|
|
87
|
+
const handleContainerClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent> | undefined) => {
|
88
|
+
if (event) {
|
89
|
+
const target = event.target as HTMLElement;
|
90
|
+
if (
|
91
|
+
target.id === 'pb-radio-children-wrapper' ||
|
92
|
+
target.closest('#pb-radio-children-wrapper')
|
93
|
+
) {
|
94
|
+
radioRef.current?.click();
|
95
|
+
}
|
96
|
+
}
|
97
|
+
};
|
98
|
+
|
73
99
|
return (
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
100
|
+
customChildren ? (
|
101
|
+
<Flex
|
102
|
+
{...ariaProps}
|
103
|
+
{...dataProps}
|
104
|
+
{...htmlProps}
|
105
|
+
align='center'
|
106
|
+
className={classesCustom}
|
107
|
+
cursor='pointer'
|
108
|
+
htmlFor={id}
|
109
|
+
htmlOptions={{
|
110
|
+
onClick: ((event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
111
|
+
handleContainerClick(event);
|
112
|
+
}) as unknown as () => void
|
113
|
+
}}
|
114
|
+
id="radio-container"
|
115
|
+
>
|
116
|
+
<label className={buildCss('pb_radio_kit', alignment)}>
|
117
|
+
<input
|
118
|
+
disabled={disabled}
|
119
|
+
id={id}
|
120
|
+
name={name}
|
121
|
+
onChange={onChange}
|
122
|
+
ref={radioRef}
|
123
|
+
type="radio"
|
124
|
+
value={value}
|
125
|
+
{...props}
|
126
|
+
/>
|
127
|
+
<span className="pb_radio_button" />
|
128
|
+
</label>
|
129
|
+
<div id="pb-radio-children-wrapper"> {children} </div>
|
130
|
+
</Flex>
|
131
|
+
) : (
|
132
|
+
<label
|
133
|
+
{...ariaProps}
|
134
|
+
{...dataProps}
|
135
|
+
{...htmlProps}
|
136
|
+
className={classes}
|
137
|
+
htmlFor={id}
|
138
|
+
>
|
139
|
+
<>{displayRadio(props)}</>
|
140
|
+
<span className="pb_radio_button" />
|
141
|
+
<Body
|
142
|
+
dark={dark}
|
143
|
+
status={error ? 'negative' : null}
|
144
|
+
text={label}
|
145
|
+
variant={null}
|
146
|
+
/>
|
147
|
+
</label>
|
148
|
+
)
|
149
|
+
);
|
150
|
+
};
|
92
151
|
|
93
|
-
export default forwardRef(Radio)
|
152
|
+
export default forwardRef(Radio);
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import Radio from '../_radio'
|
3
|
+
import Select from '../../pb_select/_select'
|
4
|
+
import Typeahead from '../../pb_typeahead/_typeahead'
|
5
|
+
import Title from '../../pb_title/_title'
|
6
|
+
|
7
|
+
const RadioChildren = (props) => {
|
8
|
+
|
9
|
+
|
10
|
+
const options = [
|
11
|
+
{ label: 'Orange', value: 'Orange' },
|
12
|
+
{ label: 'Red', value: 'Red' },
|
13
|
+
{ label: 'Green', value: 'Green' },
|
14
|
+
{ label: 'Blue', value: 'Blue' },
|
15
|
+
]
|
16
|
+
|
17
|
+
return (
|
18
|
+
<div>
|
19
|
+
<Radio
|
20
|
+
customChildren
|
21
|
+
label="Select"
|
22
|
+
name="Group1"
|
23
|
+
tabIndex={0}
|
24
|
+
value="Select"
|
25
|
+
{...props}
|
26
|
+
>
|
27
|
+
<Select
|
28
|
+
minWidth="xs"
|
29
|
+
options={options}
|
30
|
+
/>
|
31
|
+
</Radio>
|
32
|
+
<Radio
|
33
|
+
customChildren
|
34
|
+
label="Typeahead"
|
35
|
+
name="Group1"
|
36
|
+
tabIndex={0}
|
37
|
+
value="Typeahead"
|
38
|
+
{...props}
|
39
|
+
>
|
40
|
+
<Typeahead
|
41
|
+
minWidth="xs"
|
42
|
+
options={options}
|
43
|
+
/>
|
44
|
+
</Radio>
|
45
|
+
<br />
|
46
|
+
<Radio
|
47
|
+
customChildren
|
48
|
+
defaultChecked={false}
|
49
|
+
label="Typography"
|
50
|
+
name="Group1"
|
51
|
+
value="Typography"
|
52
|
+
{...props}
|
53
|
+
>
|
54
|
+
<Title text="Custom Typography" />
|
55
|
+
</Radio>
|
56
|
+
</div>
|
57
|
+
)
|
58
|
+
}
|
59
|
+
export default RadioChildren
|