playbook_ui 14.13.0.pre.alpha.play1851checkboxreacthook6083 → 14.13.0.pre.alpha.play1852reacthookformsupportradio6213

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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +0 -1
  3. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +3 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +6 -5
  5. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +8 -1
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_headers_custom_cell.jsx +75 -0
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props.html.erb +1 -1
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_rails.md +3 -1
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_react.md +1 -1
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.html.erb +33 -0
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_rails.md +3 -0
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +2 -0
  13. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -1
  14. data/app/pb_kits/playbook/pb_bar_graph/BarGraphStyles.scss +58 -0
  15. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_pb_styles.jsx +64 -0
  16. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_pb_styles.md +1 -0
  17. data/app/pb_kits/playbook/pb_bar_graph/docs/example.yml +1 -0
  18. data/app/pb_kits/playbook/pb_bar_graph/docs/index.js +1 -0
  19. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table.html.erb +2 -2
  20. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table.md +4 -1
  21. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table_react.jsx +90 -0
  22. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table_react.md +5 -0
  23. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +2 -0
  24. data/app/pb_kits/playbook/pb_draggable/docs/index.js +2 -1
  25. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableContainer.tsx +7 -4
  26. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +6 -3
  27. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.html.erb +1 -6
  28. data/app/pb_kits/playbook/pb_nav/item.html.erb +7 -19
  29. data/app/pb_kits/playbook/pb_nav/nav.html.erb +3 -8
  30. data/app/pb_kits/playbook/pb_online_status/online_status.html.erb +1 -6
  31. data/app/pb_kits/playbook/pb_overlay/_overlay.tsx +4 -0
  32. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.jsx +37 -0
  33. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional_react.md +1 -0
  34. data/app/pb_kits/playbook/pb_overlay/docs/example.yml +1 -0
  35. data/app/pb_kits/playbook/pb_overlay/docs/index.js +1 -0
  36. data/app/pb_kits/playbook/pb_overlay/subcomponents/_overlay_token.tsx +48 -10
  37. data/app/pb_kits/playbook/pb_popover/popover.html.erb +1 -6
  38. data/app/pb_kits/playbook/pb_progress_pills/_progress_pills.scss +6 -1
  39. data/app/pb_kits/playbook/pb_progress_pills/_progress_pills.tsx +7 -5
  40. data/app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_default.html.erb +1 -0
  41. data/app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_default.jsx +7 -0
  42. data/app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_default.md +1 -0
  43. data/app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_full_width.html.erb +1 -0
  44. data/app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_full_width.jsx +18 -0
  45. data/app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_full_width_rails.md +1 -0
  46. data/app/pb_kits/playbook/pb_progress_pills/docs/_progress_pills_full_width_react.md +1 -0
  47. data/app/pb_kits/playbook/pb_progress_pills/docs/example.yml +2 -0
  48. data/app/pb_kits/playbook/pb_progress_pills/docs/index.js +1 -0
  49. data/app/pb_kits/playbook/pb_progress_pills/progress_pills.html.erb +2 -7
  50. data/app/pb_kits/playbook/pb_progress_pills/progress_pills.rb +6 -0
  51. data/app/pb_kits/playbook/pb_progress_pills/progress_pills.test.js +26 -1
  52. data/app/pb_kits/playbook/pb_progress_simple/progress_simple.html.erb +1 -5
  53. data/app/pb_kits/playbook/pb_progress_step/progress_step.html.erb +1 -5
  54. data/app/pb_kits/playbook/pb_progress_step/progress_step_item.html.erb +1 -5
  55. data/app/pb_kits/playbook/pb_radio/_radio.tsx +85 -73
  56. data/app/pb_kits/playbook/pb_radio/docs/_radio_react_hook.jsx +60 -0
  57. data/app/pb_kits/playbook/pb_radio/docs/_radio_react_hook.md +1 -0
  58. data/app/pb_kits/playbook/pb_radio/docs/example.yml +2 -1
  59. data/app/pb_kits/playbook/pb_radio/docs/index.js +1 -0
  60. data/app/pb_kits/playbook/pb_radio/radio.html.erb +6 -11
  61. data/app/pb_kits/playbook/pb_radio/radio.test.js +16 -0
  62. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible.jsx +1 -1
  63. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_click.html.erb +51 -0
  64. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_click_rails.md +2 -0
  65. data/app/pb_kits/playbook/pb_table/docs/example.yml +1 -0
  66. data/app/pb_kits/playbook/pb_table/index.ts +41 -9
  67. data/app/pb_kits/playbook/pb_table/styles/_collapsible.scss +4 -0
  68. data/app/pb_kits/playbook/pb_table/subcomponents/_table_body.tsx +29 -2
  69. data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +31 -3
  70. data/app/pb_kits/playbook/pb_table/table_body.html.erb +13 -7
  71. data/app/pb_kits/playbook/pb_table/table_body.rb +2 -0
  72. data/app/pb_kits/playbook/pb_table/table_row.html.erb +14 -7
  73. data/app/pb_kits/playbook/pb_table/table_row.rb +14 -1
  74. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_mask.html.erb +14 -0
  75. data/app/pb_kits/playbook/pb_text_input/index.js +9 -0
  76. data/app/pb_kits/playbook/pb_text_input/text_input.rb +5 -2
  77. data/dist/chunks/_typeahead-BdE70xxu.js +36 -0
  78. data/dist/chunks/_weekday_stacked-Dze0K01W.js +45 -0
  79. data/dist/chunks/{lib-WQEeEj3t.js → lib-D3us1bGD.js} +1 -1
  80. data/dist/chunks/{pb_form_validation-Cq64l4zn.js → pb_form_validation-BpihMSOQ.js} +1 -1
  81. data/dist/chunks/vendor.js +1 -1
  82. data/dist/menu.yml +0 -7
  83. data/dist/playbook-doc.js +1 -1
  84. data/dist/playbook-rails-react-bindings.js +1 -1
  85. data/dist/playbook-rails.js +1 -1
  86. data/dist/playbook.css +1 -1
  87. data/lib/playbook/version.rb +1 -1
  88. metadata +26 -23
  89. data/app/pb_kits/playbook/pb_avatar_action_button/_avatar_action_button.scss +0 -66
  90. data/app/pb_kits/playbook/pb_avatar_action_button/_avatar_action_button.tsx +0 -98
  91. data/app/pb_kits/playbook/pb_avatar_action_button/avatar_action_button.html.erb +0 -28
  92. data/app/pb_kits/playbook/pb_avatar_action_button/avatar_action_button.rb +0 -42
  93. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_actions.html.erb +0 -19
  94. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_actions.jsx +0 -26
  95. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_default.html.erb +0 -10
  96. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_default.jsx +0 -17
  97. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_on_click.jsx +0 -19
  98. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_onclick.html.erb +0 -16
  99. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_placement.html.erb +0 -35
  100. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_placement.jsx +0 -42
  101. data/app/pb_kits/playbook/pb_avatar_action_button/docs/_avatar_action_button_tooltip.html.erb +0 -13
  102. data/app/pb_kits/playbook/pb_avatar_action_button/docs/example.yml +0 -15
  103. data/app/pb_kits/playbook/pb_avatar_action_button/docs/index.js +0 -4
  104. data/app/pb_kits/playbook/pb_avatar_action_button/pb_avatar_action_button.test.js +0 -31
  105. data/dist/chunks/_typeahead-CR2Xkt-o.js +0 -36
  106. data/dist/chunks/_weekday_stacked-9LU-xxnS.js +0 -45
  107. /data/app/pb_kits/playbook/pb_table/docs/{_table_with_collapsible_with_custom_click.md → _table_with_collapsible_with_custom_click_react.md} +0 -0
@@ -1,6 +1,4 @@
1
- /*eslint-disable react/no-multi-comp */
2
-
3
- import React, { forwardRef, useRef } from 'react'
1
+ import React, { useRef, forwardRef } from 'react'
4
2
  import Body from '../pb_body/_body'
5
3
  import Flex from '../pb_flex/_flex'
6
4
  import classnames from 'classnames'
@@ -24,10 +22,10 @@ type RadioProps = {
24
22
  name?: string,
25
23
  value?: string,
26
24
  text?: string,
27
- onChange: (event: React.FormEvent<HTMLInputElement> | null) => void,
25
+ onChange?: (event: React.FormEvent<HTMLInputElement> | null) => void,
28
26
  } & GlobalProps
29
27
 
30
- const Radio = ({
28
+ const Radio = forwardRef<HTMLInputElement, RadioProps>(({
31
29
  aria = {},
32
30
  alignment,
33
31
  children,
@@ -43,110 +41,124 @@ const Radio = ({
43
41
  name = 'radio_name',
44
42
  text = 'Radio Text',
45
43
  value = 'radio_text',
44
+ checked = false,
46
45
  onChange = () => { void 0 },
47
46
  ...props
48
- }: RadioProps, ref: any) => {
49
- const radioRef = useRef(null);
47
+ }, ref) => {
48
+ const internalRef = useRef<HTMLInputElement>(null)
49
+ const setRefs = (el: HTMLInputElement) => {
50
+ internalRef.current = el
51
+ if (typeof ref === 'function') {
52
+ ref(el)
53
+ } else if (ref) {
54
+ (ref as React.MutableRefObject<HTMLInputElement | null>).current = el
55
+ }
56
+ }
57
+
58
+ // Since we're using defaultChecked for uncontrolled input,
59
+ // we no longer need to sync the checked state with useEffect.
60
+
61
+ const ariaProps = buildAriaProps(aria)
62
+ const dataProps = buildDataProps(data)
63
+ const htmlProps = buildHtmlProps(htmlOptions)
50
64
 
51
- const ariaProps = buildAriaProps(aria);
52
- const dataProps = buildDataProps(data);
53
- const htmlProps = buildHtmlProps(htmlOptions);
54
65
  const classes = classnames(
55
66
  buildCss('pb_radio_kit', alignment),
56
67
  dark ? 'dark' : null,
57
68
  error ? 'error' : null,
58
69
  globalProps(props),
59
70
  className
60
- );
71
+ )
61
72
 
62
73
  const classesCustom = classnames(
63
74
  dark ? 'dark' : null,
64
75
  error ? 'error' : null,
65
76
  globalProps(props),
66
77
  className
67
- );
78
+ )
68
79
 
69
- const displayRadio = (props: RadioProps & any) => {
70
- if (children && customChildren == false)
71
- return (children)
80
+ const displayRadio = (inputProps: any) => {
81
+ if (children && customChildren === false)
82
+ return children
72
83
  else
73
- return (
74
- <input
75
- disabled={disabled}
76
- id={id}
77
- name={name}
78
- onChange={onChange}
79
- ref={ref}
80
- text={text}
81
- type="radio"
82
- value={value}
83
- {...props}
84
- />
85
- )}
84
+ return (
85
+ <input
86
+ defaultChecked={checked}
87
+ disabled={disabled}
88
+ id={id}
89
+ name={name}
90
+ onChange={onChange}
91
+ ref={setRefs}
92
+ type="radio"
93
+ value={value}
94
+ {...inputProps}
95
+ />
96
+ )
97
+ }
86
98
 
87
99
  const handleContainerClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent> | undefined) => {
88
100
  if (event) {
89
- const target = event.target as HTMLElement;
101
+ const target = event.target as HTMLElement
90
102
  if (
91
103
  target.id === 'pb-radio-children-wrapper' ||
92
104
  target.closest('#pb-radio-children-wrapper')
93
105
  ) {
94
- radioRef.current?.click();
106
+ internalRef.current?.click()
95
107
  }
96
108
  }
97
- };
109
+ }
98
110
 
99
- return (
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)}>
111
+ return customChildren ? (
112
+ <Flex
113
+ {...ariaProps}
114
+ {...dataProps}
115
+ {...htmlProps}
116
+ align="center"
117
+ className={classesCustom}
118
+ cursor="pointer"
119
+ htmlFor={id}
120
+ htmlOptions={{
121
+ onClick: ((event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
122
+ handleContainerClick(event)
123
+ }) as unknown as () => void
124
+ }}
125
+ id="radio-container"
126
+ >
127
+ <label className={buildCss('pb_radio_kit', alignment)}>
117
128
  <input
129
+ defaultChecked={checked}
118
130
  disabled={disabled}
119
131
  id={id}
120
132
  name={name}
121
133
  onChange={onChange}
122
- ref={radioRef}
134
+ ref={setRefs}
123
135
  type="radio"
124
136
  value={value}
125
137
  {...props}
126
138
  />
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
139
  <span className="pb_radio_button" />
141
- <Body
142
- dark={dark}
143
- status={error ? 'negative' : null}
144
- text={label}
145
- variant={null}
146
- />
147
140
  </label>
148
- )
149
- );
150
- };
141
+ <div id="pb-radio-children-wrapper"> {children} </div>
142
+ </Flex>
143
+ ) : (
144
+ <label
145
+ {...ariaProps}
146
+ {...dataProps}
147
+ {...htmlProps}
148
+ className={classes}
149
+ htmlFor={id}
150
+ >
151
+ {displayRadio(props)}
152
+ <span className="pb_radio_button" />
153
+ <Body
154
+ dark={dark}
155
+ status={error ? 'negative' : null}
156
+ text={label}
157
+ variant={null}
158
+ />
159
+ </label>
160
+ )
161
+ })
151
162
 
152
- export default forwardRef(Radio);
163
+ Radio.displayName = "Radio"
164
+ export default Radio
@@ -0,0 +1,60 @@
1
+ import React from "react"
2
+ import { useForm } from "react-hook-form"
3
+ import { Radio, Flex, Body } from "playbook-ui"
4
+
5
+ const RadioReactHook = () => {
6
+ const { register, watch } = useForm({
7
+ defaultValues: {
8
+ size: "Small",
9
+ },
10
+ })
11
+
12
+ const selectedSize = watch("size", "Small")
13
+
14
+ return (
15
+ <Flex orientation="row">
16
+ <Flex
17
+ align="start"
18
+ orientation="column"
19
+ paddingRight="lg"
20
+ >
21
+ <Radio
22
+ alignment="left"
23
+ label="Small"
24
+ marginBottom='sm'
25
+ name="size"
26
+ value="Small"
27
+ {...register("size")}
28
+ />
29
+ <br />
30
+ <Radio
31
+ alignment="left"
32
+ label="Medium"
33
+ marginBottom='sm'
34
+ name="size"
35
+ value="Medium"
36
+ {...register("size")}
37
+ />
38
+ <br />
39
+ <Radio
40
+ alignment="left"
41
+ label="Large"
42
+ marginBottom='sm'
43
+ name="size"
44
+ value="Large"
45
+ {...register("size")}
46
+ />
47
+ </Flex>
48
+ <Flex
49
+ align="start"
50
+ orientation="column"
51
+ >
52
+ <Body
53
+ text={`Selected Size: ${selectedSize}`}
54
+ />
55
+ </Flex>
56
+ </Flex>
57
+ )
58
+ }
59
+
60
+ export default RadioReactHook
@@ -0,0 +1 @@
1
+ You can pass react hook props to the radio kit.
@@ -16,6 +16,7 @@ examples:
16
16
  - radio_alignment: Alignment
17
17
  - radio_disabled: Disabled
18
18
  - radio_custom_children: Custom Children
19
+ - radio_react_hook: React Hook Form
19
20
 
20
21
  swift:
21
22
  - radio_default_swift: Default
@@ -26,4 +27,4 @@ examples:
26
27
  - radio_spacing_swift: Spacing
27
28
  - radio_padding_swift: Padding
28
29
  - radio_subtitle_swift: Subtitle
29
- - radio_props_swift: ""
30
+ - radio_props_swift: ""
@@ -4,3 +4,4 @@ export { default as RadioError } from './_radio_error.jsx'
4
4
  export { default as RadioAlignment } from './_radio_alignment.jsx'
5
5
  export { default as RadioDisabled } from './_radio_disabled.jsx'
6
6
  export { default as RadioCustomChildren } from './_radio_custom_children.jsx'
7
+ export { default as RadioReactHook } from './_radio_react_hook.jsx'
@@ -7,26 +7,21 @@
7
7
  data: object.data,
8
8
  **combined_html_options
9
9
  }) do %>
10
- <%= content_tag(:label,
10
+ <%= pb_content_tag(:label,
11
11
  'data-pb-radio-children': 'true',
12
12
  checked: object.checked,
13
- class: object.classname,
14
- id: object.id,
15
- value: object.value) do %>
13
+ value: object.value
14
+ ) do %>
16
15
  <%= input %>
17
16
  <span class="pb_radio_button"></span>
18
17
  <% end %>
19
18
  <div data-pb-radio-children-wrapper="true"> <%= content %> </div>
20
19
  <% end %>
21
20
  <% else %>
22
- <%= content_tag(:label,
23
- aria: object.aria,
21
+ <%= pb_content_tag(:label,
24
22
  checked: object.checked,
25
- class: object.classname,
26
- data: object.data,
27
- id: object.id,
28
23
  value: object.value,
29
- **combined_html_options) do %>
24
+ ) do %>
30
25
 
31
26
  <% if content.present? %>
32
27
  <%= content %>
@@ -37,4 +32,4 @@
37
32
  <span class="pb_radio_button"></span>
38
33
  <%= pb_rails("body", props: { status: object.body_status, text: object.text, dark: object.dark }) %>
39
34
  <% end %>
40
- <% end %>
35
+ <% end %>
@@ -86,3 +86,19 @@ test('has disabled attribute', () => {
86
86
  expect(input).toHaveAttribute('disabled')
87
87
  })
88
88
 
89
+
90
+ test('has ref in the input element', () => {
91
+ const ref = React.createRef()
92
+ render(
93
+ <Radio
94
+ data={{ testid: testId }}
95
+ name="Radio-name"
96
+ ref={ref}
97
+ text="Radio"
98
+ value="radio value"
99
+ />
100
+ )
101
+
102
+ expect(ref.current).not.toBeNull()
103
+ expect(ref.current?.tagName).toBe('INPUT')
104
+ })
@@ -16,7 +16,7 @@ const TableWithCollapsible = (props) => {
16
16
  );
17
17
  };
18
18
 
19
- return (
19
+ return (
20
20
  <Table
21
21
  size="sm"
22
22
  {...props}
@@ -0,0 +1,51 @@
1
+ <% content = capture do %>
2
+ <%= pb_rails("card", props: { border_none: true, border_radius: "none", padding: "md" }) do %>
3
+ <%= pb_rails("body", props: { text: "Nested content inside a Table Row" }) %>
4
+ <% end %>
5
+ <% end %>
6
+
7
+ <%= pb_rails("table", props: { size: "sm" }) do %>
8
+ <%= pb_rails("table/table_head") do %>
9
+ <%= pb_rails("table/table_row") do %>
10
+ <%= pb_rails("table/table_header", props: { text: "Column 1"}) %>
11
+ <%= pb_rails("table/table_header", props: { text: "Column 2"}) %>
12
+ <%= pb_rails("table/table_header", props: { text: "Column 3"}) %>
13
+ <%= pb_rails("table/table_header", props: { text: "Column 4"}) %>
14
+ <%= pb_rails("table/table_header", props: { text: "Column 5"}) %>
15
+ <%= pb_rails("table/table_header", props: { text: ""}) %>
16
+ <% end %>
17
+ <% end %>
18
+ <%= pb_rails("table/table_body") do %>
19
+ <%= pb_rails("table/table_row", props: { collapsible: true, collapsible_content: content, collapsible_side_highlight: true, toggle_cell_id: "cell-1", id: "5" }) do %>
20
+ <%= pb_rails("table/table_cell", props: { text: "Value 1"}) %>
21
+ <%= pb_rails("table/table_cell", props: { text: "Value 2"}) %>
22
+ <%= pb_rails("table/table_cell", props: { text: "Value 3"}) %>
23
+ <%= pb_rails("table/table_cell", props: { text: "Value 4"}) %>
24
+ <%= pb_rails("table/table_cell", props: { text: "Value 5"}) %>
25
+ <%= pb_rails("table/table_cell", props: { text_align: "right", id: "cell-1", cursor: "pointer" }) do %>
26
+ <%= pb_rails("icon", props: { icon: "chevron-down", fixed_width: true, color: "primary" }) %>
27
+ <% end %>
28
+ <% end %>
29
+ <%= pb_rails("table/table_row", props: { collapsible: true, collapsible_content: content, collapsible_side_highlight: true, toggle_cell_id: "cell-2", id: "6" }) do %>
30
+ <%= pb_rails("table/table_cell", props: { text: "Value 1"}) %>
31
+ <%= pb_rails("table/table_cell", props: { text: "Value 2"}) %>
32
+ <%= pb_rails("table/table_cell", props: { text: "Value 3"}) %>
33
+ <%= pb_rails("table/table_cell", props: { text: "Value 4"}) %>
34
+ <%= pb_rails("table/table_cell", props: { text: "Value 5"}) %>
35
+ <%= pb_rails("table/table_cell", props: { text_align: "right", id: "cell-2", cursor: "pointer" }) do %>
36
+ <%= pb_rails("icon", props: { icon: "chevron-down", fixed_width: true, color: "primary" }) %>
37
+ <% end %>
38
+ <% end %>
39
+ <%= pb_rails("table/table_row", props: { collapsible: true, collapsible_content: content, collapsible_side_highlight: true, toggle_cell_id: "cell-3", id: "7" }) do %>
40
+ <%= pb_rails("table/table_cell", props: { text: "Value 1"}) %>
41
+ <%= pb_rails("table/table_cell", props: { text: "Value 2"}) %>
42
+ <%= pb_rails("table/table_cell", props: { text: "Value 3"}) %>
43
+ <%= pb_rails("table/table_cell", props: { text: "Value 4"}) %>
44
+ <%= pb_rails("table/table_cell", props: { text: "Value 5"}) %>
45
+ <%= pb_rails("table/table_cell", props: { text_align: "right", id: "cell-3", cursor: "pointer" }) do %>
46
+ <%= pb_rails("icon", props: { icon: "chevron-down", fixed_width: true, color: "primary" }) %>
47
+ <% end %>
48
+ <% end %>
49
+ <% end %>
50
+ <% end %>
51
+
@@ -0,0 +1,2 @@
1
+ When using the `collapsible` prop, the default functionality is that the entire Row will be clickable to toggle the Row. To limit the click event to a specific Table Cell, you can use the `toggle_cell_id` prop to pass in the id of the Cell you want to use as the trigger.
2
+ __NOTE__: `toggle_cell_id` and the `id` on the Cell you want to use as the trigger MUST be the same. Please also be aware that you will need to pass in an `id` to any Table Rows you want to be collapsible. Make sure every `id` is unique if you are using multipe collapsibles.
@@ -31,6 +31,7 @@ examples:
31
31
  - table_with_subcomponents_as_divs: Table with Sub Components (Divs)
32
32
  - table_outer_padding: Outer Padding
33
33
  - table_with_collapsible: Table with Collapsible
34
+ - table_with_collapsible_with_custom_click: Table with Collapsible with Custom Click
34
35
  - table_with_collapsible_with_custom_content_rails: Table with Collapsible with Custom Content
35
36
  - table_with_collapsible_with_nested_rows_rails: Table with Collapsible with Nested Rows
36
37
  - table_with_collapsible_with_nested_table_rails: Table with Collapsible with Nested Table
@@ -2,6 +2,7 @@ import PbEnhancedElement from '../pb_enhanced_element'
2
2
 
3
3
  const TABLE_WRAPPER_SELECTOR = "[data-pb-table-wrapper]";
4
4
  const TABLE_COLLAPSIBLE_WRAPPER_SELECTOR = "[data-pb-table-collapsible-wrapper]";
5
+ const TABLE_COLLAPSIBLE_CELL_SELECTOR = "[data-pb-table-collapsible-cell-id]";
5
6
 
6
7
  export default class PbTable extends PbEnhancedElement {
7
8
  stickyLeftColumns: string[] = [];
@@ -158,18 +159,49 @@ export default class PbTable extends PbEnhancedElement {
158
159
  }
159
160
 
160
161
  handleCollapsibleClick() {
162
+ const cells = this.element.querySelectorAll(TABLE_COLLAPSIBLE_CELL_SELECTOR);
161
163
  const collapsibleElements = this.element.querySelectorAll(TABLE_COLLAPSIBLE_WRAPPER_SELECTOR);
162
- collapsibleElements.forEach((collapsibleElement) => {
163
- collapsibleElement.addEventListener('click', (event) => {
164
- document.dispatchEvent(new CustomEvent(`collapsed-toggle${(event.currentTarget as HTMLElement).id}`))
165
-
166
- const toggleElements = this.element.querySelectorAll(`.collapsible_border_toggle${(event.currentTarget as HTMLElement).id}`);
167
- toggleElements.forEach(element => {
168
- element.classList.toggle('no-border');
169
- element.classList.toggle('border-active');
164
+
165
+ if (cells.length > 0) {
166
+ cells.forEach((cell) => {
167
+ const cellId = (cell as HTMLElement).dataset.pbTableCollapsibleCellId;
168
+
169
+ Array.from(cell.children).forEach((child) => {
170
+ if (child.id === cellId) {
171
+ Array.from(child.children).forEach((svgChild) => {
172
+ svgChild.id = cellId; // Assign cellId to SVG child
173
+ Array.from(svgChild.children).forEach((pathChild) => {
174
+ pathChild.id = cellId; // Assign cellId to path child
175
+ });
176
+ });
177
+ }
178
+ });
179
+ cell.addEventListener('click', (event) => {
180
+ if ((event.target as HTMLElement).id) {
181
+ document.dispatchEvent(new CustomEvent(`collapsed-toggle${(event.currentTarget as HTMLElement).id}`));
182
+
183
+ const toggleElements = this.element.querySelectorAll(`.collapsible_border_toggle${(event.currentTarget as HTMLElement).id}`);
184
+ toggleElements.forEach((element) => {
185
+ element.classList.toggle('no-border');
186
+ element.classList.toggle('border-active');
187
+ });
188
+ }
170
189
  });
190
+ });
191
+
192
+ } else {
193
+ collapsibleElements.forEach((collapsibleElement) => {
194
+ collapsibleElement.addEventListener('click', (event) => {
195
+ document.dispatchEvent(new CustomEvent(`collapsed-toggle${(event.currentTarget as HTMLElement).id}`))
196
+
197
+ const toggleElements = this.element.querySelectorAll(`.collapsible_border_toggle${(event.currentTarget as HTMLElement).id}`);
198
+ toggleElements.forEach(element => {
199
+ element.classList.toggle('no-border');
200
+ element.classList.toggle('border-active');
201
+ });
202
+ })
171
203
  })
172
- })
204
+ }
173
205
  }
174
206
 
175
207
  handleCollapsibleRow() {
@@ -37,6 +37,10 @@
37
37
  cursor: pointer;
38
38
  }
39
39
 
40
+ .collapsible_cell {
41
+ cursor: default;
42
+ }
43
+
40
44
  .no-border {
41
45
  border-bottom: none !important;
42
46
  }
@@ -7,11 +7,14 @@ import {
7
7
  } from "../../utilities/props";
8
8
  import { globalProps } from "../../utilities/globalProps";
9
9
 
10
+ import Draggable from "../../pb_draggable/_draggable"
11
+
10
12
  type TableBodyPropTypes = {
11
13
  aria?: { [key: string]: string };
12
14
  children: React.ReactNode[] | React.ReactNode;
13
15
  className: string;
14
16
  data?: { [key: string]: string };
17
+ draggableContainer?: boolean;
15
18
  htmlOptions?: { [key: string]: string | number | boolean | (() => void) };
16
19
  id?: string;
17
20
  tag?: "table" | "div";
@@ -23,6 +26,7 @@ const TableBody = (props: TableBodyPropTypes): React.ReactElement => {
23
26
  children,
24
27
  className,
25
28
  data = {},
29
+ draggableContainer = false,
26
30
  htmlOptions = {},
27
31
  id,
28
32
  tag = "table",
@@ -37,7 +41,30 @@ const TableBody = (props: TableBodyPropTypes): React.ReactElement => {
37
41
  return (
38
42
  <>
39
43
  {isTableTag ? (
40
- <tbody
44
+ draggableContainer ? (
45
+ <Draggable.Container
46
+ {...ariaProps}
47
+ {...dataProps}
48
+ {...htmlProps}
49
+ className={classes}
50
+ id={id}
51
+ tag="tbody"
52
+ >
53
+ {children}
54
+ </Draggable.Container>
55
+ ) : (
56
+ <tbody
57
+ {...ariaProps}
58
+ {...dataProps}
59
+ {...htmlProps}
60
+ className={classes}
61
+ id={id}
62
+ >
63
+ {children}
64
+ </tbody>
65
+ )
66
+ ) : draggableContainer ? (
67
+ <Draggable.Container
41
68
  {...ariaProps}
42
69
  {...dataProps}
43
70
  {...htmlProps}
@@ -45,7 +72,7 @@ const TableBody = (props: TableBodyPropTypes): React.ReactElement => {
45
72
  id={id}
46
73
  >
47
74
  {children}
48
- </tbody>
75
+ </Draggable.Container>
49
76
  ) : (
50
77
  <div
51
78
  {...ariaProps}
@@ -9,6 +9,7 @@ import {
9
9
  import { globalProps } from "../../utilities/globalProps";
10
10
  import Collapsible from "../../pb_collapsible/_collapsible";
11
11
  import useCollapsible from "../../pb_collapsible/useCollapsible";
12
+ import Draggable from "../../pb_draggable/_draggable";
12
13
 
13
14
  type TableRowPropTypes = {
14
15
  aria?: { [key: string]: string };
@@ -19,6 +20,8 @@ type TableRowPropTypes = {
19
20
  collapsibleSideHighlight?: boolean;
20
21
  data?: { [key: string]: string };
21
22
  dark?: boolean;
23
+ dragId?: string;
24
+ draggableItem?: boolean;
22
25
  htmlOptions?: { [key: string]: string | number | boolean | (() => void) };
23
26
  id?: string;
24
27
  toggleCellId?: string;
@@ -36,6 +39,8 @@ const TableRow = (props: TableRowPropTypes): React.ReactElement => {
36
39
  className,
37
40
  data = {},
38
41
  dark = false,
42
+ dragId,
43
+ draggableItem = false,
39
44
  htmlOptions = {},
40
45
  id,
41
46
  toggleCellId,
@@ -152,15 +157,38 @@ const TableRow = (props: TableRowPropTypes): React.ReactElement => {
152
157
  </>
153
158
  )
154
159
  ) : isTableTag ? (
155
- <tr
160
+ draggableItem ? (
161
+ <Draggable.Item
162
+ {...ariaProps}
163
+ {...dataProps}
164
+ {...htmlProps}
165
+ className={classes}
166
+ dragId={dragId}
167
+ tag="tr"
168
+ >
169
+ {children}
170
+ </Draggable.Item>
171
+ ) : (
172
+ <tr
173
+ {...ariaProps}
174
+ {...dataProps}
175
+ {...htmlProps}
176
+ className={classes}
177
+ id={id}
178
+ >
179
+ {children}
180
+ </tr>
181
+ )
182
+ ) : draggableItem ? (
183
+ <Draggable.Item
156
184
  {...ariaProps}
157
185
  {...dataProps}
158
186
  {...htmlProps}
159
187
  className={classes}
160
- id={id}
188
+ dragId={dragId}
161
189
  >
162
190
  {children}
163
- </tr>
191
+ </Draggable.Item>
164
192
  ) : (
165
193
  <div
166
194
  {...ariaProps}
@@ -1,11 +1,17 @@
1
1
  <% if object.tag == "table" %>
2
- <%= content_tag(:tbody,
3
- aria: object.aria,
4
- class: object.classname,
5
- data: object.data,
6
- id: object.id,
7
- **combined_html_options) do %>
8
- <%= content.presence %>
2
+ <% if object.draggable_container %>
3
+ <%= pb_rails("draggable/draggable_container", props: { tag: "tbody", classname: object.classname, data: object.data }) do %>
4
+ <%= content.presence %>
5
+ <% end %>
6
+ <% else %>
7
+ <%= content_tag(:tbody,
8
+ aria: object.aria,
9
+ class: object.classname,
10
+ data: object.data,
11
+ id: object.id,
12
+ **combined_html_options) do %>
13
+ <%= content.presence %>
14
+ <% end %>
9
15
  <% end %>
10
16
  <% else %>
11
17
  <%= content_tag(:div,