playbook_ui 14.13.0.pre.alpha.PLAY1873rails86087 → 14.13.0.pre.alpha.PLAY1873rails86115

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table.html.erb +2 -2
  3. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table.md +4 -1
  4. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table_react.jsx +90 -0
  5. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table_react.md +5 -0
  6. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +2 -0
  7. data/app/pb_kits/playbook/pb_draggable/docs/index.js +2 -1
  8. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableContainer.tsx +7 -4
  9. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +6 -3
  10. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.html.erb +1 -6
  11. data/app/pb_kits/playbook/pb_nav/item.html.erb +7 -19
  12. data/app/pb_kits/playbook/pb_nav/nav.html.erb +3 -8
  13. data/app/pb_kits/playbook/pb_online_status/online_status.html.erb +1 -6
  14. data/app/pb_kits/playbook/pb_popover/popover.html.erb +1 -6
  15. data/app/pb_kits/playbook/pb_table/subcomponents/_table_body.tsx +29 -2
  16. data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +31 -3
  17. data/app/pb_kits/playbook/pb_table/table_body.html.erb +13 -7
  18. data/app/pb_kits/playbook/pb_table/table_body.rb +2 -0
  19. data/app/pb_kits/playbook/pb_table/table_row.html.erb +13 -7
  20. data/app/pb_kits/playbook/pb_table/table_row.rb +4 -0
  21. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_mask.html.erb +14 -0
  22. data/app/pb_kits/playbook/pb_text_input/index.js +9 -0
  23. data/app/pb_kits/playbook/pb_text_input/text_input.rb +5 -2
  24. data/app/pb_kits/playbook/pb_user_badge/user_badge.rb +1 -1
  25. data/dist/chunks/{_typeahead-DQTwAd_2.js → _typeahead-C_q1qAtC.js} +4 -4
  26. data/dist/chunks/_weekday_stacked-DCeouuO3.js +45 -0
  27. data/dist/chunks/vendor.js +1 -1
  28. data/dist/playbook-doc.js +1 -1
  29. data/dist/playbook-rails-react-bindings.js +1 -1
  30. data/dist/playbook-rails.js +1 -1
  31. data/lib/playbook/version.rb +1 -1
  32. metadata +6 -4
  33. data/dist/chunks/_weekday_stacked-ei-exO-N.js +0 -45
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e08365da5253269e56718df0229fb325a9904ae790a197f4d9498972990d5e20
4
- data.tar.gz: 2fd146a0b22bd09f5b4dbe54a16a3b438a7a24bb360f3a476c307645e8b6fc5b
3
+ metadata.gz: d811b9febcfdbd9d1a4ff04bb496d39054a3a6293187c260ab2e637c5557c03e
4
+ data.tar.gz: 60834f6893edac9324ef5149968ab1d7102302e2fbf3847c71d8aab6ed46b44d
5
5
  SHA512:
6
- metadata.gz: 79d14e319ea738d2959955de82a9eac69637d27eba8efad3549f520b7c9ce95ee4ed704e4e7451f8aca6ffc633cccab31a1306bd03ca8b6127eaceeb3f16a01c
7
- data.tar.gz: 734cff649221dc31c3a2eb03c73d9bc27df9aa28642bb0e190f41317ef0896fd8b9decc85e2e6587d7c2f7a660e1cefd2f7a151dd4ec4264652e6eb44f610557
6
+ metadata.gz: 7c32fbdf124c3161e10e402cf779213202c0f1cec288515513e4dc5591aa2e4e5ef3cd2a296444d9d15a8bdbde3f99a2222317b9fcb771f8213a349768f61b16
7
+ data.tar.gz: 0eff9ea691089a5f0a7fece2aa80fa402f790e86e957a8af768df90ab22c6dd974413a85996998e374dbc72ee017a5621e857443390d2a49f5e160e3f51fe8fe
@@ -43,9 +43,9 @@
43
43
  <% end %>
44
44
  <% end %>
45
45
 
46
- <%= pb_rails("draggable/draggable_container", props: {tag:"tbody"}) do %>
46
+ <%= pb_rails("table/table_body", props: {draggable_container: true}) do %>
47
47
  <% initial_items.each do |item| %>
48
- <%= pb_rails("draggable/draggable_item", props:{drag_id: item[:id], tag:"tr"}) do %>
48
+ <%= pb_rails("table/table_row", props:{drag_id: item[:id], draggable_item: true}) do %>
49
49
  <%= pb_rails("table/table_cell", props: { text: item[:id]}) %>
50
50
  <%= pb_rails("table/table_cell") do %>
51
51
  <%= pb_rails("flex", props:{align:"center"}) do %>
@@ -1 +1,4 @@
1
- The draggable kit can also be used in conjunction with the table kit to create draggable table rows. To do this, make use of the `tag` prop on the draggable_container to set it to 'tbody' and the same prop on the draggable_item to set that to 'tr'. This will create the functionality seen here.
1
+ The draggable kit can also be used in conjunction with the table kit to create draggable table rows. To do this:
2
+
3
+ - use the `draggable_container` prop on the table/table_body to designate it as the Draggable Container
4
+ - use the `draggable_item` prop on the table/table_row to designate it as the Draggable Item. Make sure to also pass id to the `drag_id` prop here.
@@ -0,0 +1,90 @@
1
+ import React, { useState } from "react";
2
+ import { Flex, Table, Body, Avatar, DraggableProvider } from "playbook-ui";
3
+
4
+ // Initial items to be dragged
5
+ const data = [
6
+ {
7
+ id: "1",
8
+ task: "Task 1",
9
+ assignee_name: "Terry Miles",
10
+ assignee_img: "https://randomuser.me/api/portraits/men/44.jpg",
11
+ },
12
+ {
13
+ id: "2",
14
+ task: "Task 2",
15
+ assignee_name: "Sophia Miles",
16
+ assignee_img: "https://randomuser.me/api/portraits/women/8.jpg",
17
+ },
18
+ {
19
+ id: "3",
20
+ task: "Task 3",
21
+ assignee_name: "Alice Jones",
22
+ assignee_img: "https://randomuser.me/api/portraits/women/10.jpg",
23
+ },
24
+ {
25
+ id: "4",
26
+ task: "Task 4",
27
+ assignee_name: "Mike James",
28
+ assignee_img: "https://randomuser.me/api/portraits/men/8.jpg",
29
+ },
30
+ {
31
+ id: "5",
32
+ task: "Task 5",
33
+ assignee_name: "James Guy",
34
+ assignee_img: "https://randomuser.me/api/portraits/men/18.jpg",
35
+ }
36
+ ];
37
+
38
+ const DraggableWithTableReact = (props) => {
39
+ const [initialState, setInitialState] = useState(data);
40
+
41
+ return (
42
+ <>
43
+ <DraggableProvider initialItems={data}
44
+ onReorder={(items) => setInitialState(items)}
45
+ >
46
+ <Table
47
+ responsive="none"
48
+ size="sm"
49
+ {...props}
50
+ >
51
+ <Table.Head>
52
+ <Table.Row>
53
+ <Table.Header>{"id"}</Table.Header>
54
+ <Table.Header>{"name"}</Table.Header>
55
+ <Table.Header>{"task number"}</Table.Header>
56
+ </Table.Row>
57
+ </Table.Head>
58
+ <Table.Body draggableContainer>
59
+ {initialState.map(({ id, task, assignee_name, assignee_img }) => (
60
+ <Table.Row
61
+ dragId={id}
62
+ draggableItem
63
+ key={id}
64
+ >
65
+ <Table.Cell>{id}</Table.Cell>
66
+ <Table.Cell>
67
+ <Flex align="center">
68
+ <Avatar
69
+ imageUrl={assignee_img}
70
+ size="xs"
71
+ />
72
+ <Body
73
+ paddingLeft="xxs"
74
+ text={assignee_name}
75
+ {...props}
76
+ />
77
+ </Flex>
78
+ </Table.Cell>
79
+ <Table.Cell>{task}</Table.Cell>
80
+ </Table.Row>
81
+ ))}
82
+ </Table.Body>
83
+ </Table>
84
+ </DraggableProvider>
85
+ </>
86
+
87
+ );
88
+ };
89
+
90
+ export default DraggableWithTableReact;
@@ -0,0 +1,5 @@
1
+ The draggable kit can also be used in conjunction with the table kit to create draggable table rows. To do this:
2
+
3
+ - Wrap the Table with the `DraggableProvider` and manage state as shown.
4
+ - use the `draggableContainer` prop on the Table.Body to designate it as the Draggable Container
5
+ - use the `draggableItem` prop on the Table.Row to designate it as the Draggable Item. Make sure to also pass id to the `dragId` prop here.
@@ -4,7 +4,9 @@ examples:
4
4
  - draggable_with_list: Draggable with List Kit
5
5
  - draggable_with_selectable_list: Draggable with SelectableList Kit
6
6
  - draggable_with_cards: Draggable with Cards
7
+ - draggable_with_table_react: Draggable with Table
7
8
  - draggable_multiple_containers: Dragging Across Multiple Containers
9
+
8
10
  rails:
9
11
  - draggable_default_rails: Default
10
12
  - draggable_with_list_rails: Draggable with List Kit
@@ -2,4 +2,5 @@ export { default as DraggableDefault } from './_draggable_default.jsx'
2
2
  export { default as DraggableWithCards } from './_draggable_with_cards.jsx'
3
3
  export { default as DraggableWithList } from './_draggable_with_list.jsx'
4
4
  export { default as DraggableWithSelectableList } from './_draggable_with_selectable_list.jsx'
5
- export { default as DraggableMultipleContainers } from './_draggable_multiple_containers.jsx'
5
+ export { default as DraggableMultipleContainers } from './_draggable_multiple_containers.jsx'
6
+ export { default as DraggableWithTableReact } from './_draggable_with_table_react.jsx'
@@ -17,10 +17,11 @@ type DraggableContainerProps = {
17
17
  data?: { [key: string]: string };
18
18
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
19
19
  id?: string;
20
+ tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div' | 'tr' | 'th' | 'td' | 'thead' | 'col' | 'tbody',
20
21
  };
21
22
 
22
23
  const DraggableContainer = (props: DraggableContainerProps) => {
23
- const { aria = {}, children, className, container, data = {}, htmlOptions = {}, id } = props;
24
+ const { aria = {}, children, className, container, data = {}, htmlOptions = {}, id, tag="div" } = props;
24
25
 
25
26
  const { handleDragOver, handleDrop, activeContainer } = DraggableContext();
26
27
 
@@ -28,6 +29,8 @@ const DraggableContainer = (props: DraggableContainerProps) => {
28
29
  const dataProps = buildDataProps(data);
29
30
  const htmlProps = buildHtmlProps(htmlOptions);
30
31
 
32
+ const Tag: React.ReactElement | any = `${tag}`;
33
+
31
34
  const classes = classnames(
32
35
  buildCss("pb_draggable_container"),
33
36
  `${activeContainer === container ? "active" : ""}`,
@@ -36,18 +39,18 @@ const DraggableContainer = (props: DraggableContainerProps) => {
36
39
  );
37
40
 
38
41
  return (
39
- <div
42
+ <Tag
40
43
  {...ariaProps}
41
44
  {...dataProps}
42
45
  {...htmlProps}
43
46
  className={classes}
44
47
  id={id}
45
48
  key={container}
46
- onDragOver={(e) => handleDragOver(e, container)}
49
+ onDragOver={(e: Event) => handleDragOver(e, container)}
47
50
  onDrop={() => handleDrop(container)}
48
51
  >
49
52
  {children}
50
- </div>
53
+ </Tag>
51
54
  );
52
55
  };
53
56
 
@@ -18,10 +18,11 @@ type DraggableItemProps = {
18
18
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
19
19
  id?: string;
20
20
  dragId?: string;
21
+ tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div' | 'tr' | 'th' | 'td' | 'thead' | 'col' | 'tbody',
21
22
  };
22
23
 
23
24
  const DraggableItem = (props: DraggableItemProps) => {
24
- const { aria = {}, children, className, container, data = {}, htmlOptions = {}, id, dragId } = props;
25
+ const { aria = {}, children, className, container, data = {}, htmlOptions = {}, id, dragId, tag="div" } = props;
25
26
 
26
27
  const { isDragging, handleDragStart, handleDragEnter, handleDragEnd } =
27
28
  DraggableContext();
@@ -30,6 +31,8 @@ const DraggableItem = (props: DraggableItemProps) => {
30
31
  const dataProps = buildDataProps(data);
31
32
  const htmlProps = buildHtmlProps(htmlOptions);
32
33
 
34
+ const Tag: React.ReactElement | any = `${tag}`;
35
+
33
36
  const classes = classnames(
34
37
  buildCss("pb_draggable_item"),
35
38
  `${isDragging === dragId ? "is_dragging" : ""}`,
@@ -38,7 +41,7 @@ const DraggableItem = (props: DraggableItemProps) => {
38
41
  );
39
42
 
40
43
  return (
41
- <div
44
+ <Tag
42
45
  {...ariaProps}
43
46
  {...dataProps}
44
47
  {...htmlProps}
@@ -51,7 +54,7 @@ const DraggableItem = (props: DraggableItemProps) => {
51
54
  onDragStart={() => handleDragStart(dragId, container)}
52
55
  >
53
56
  {children}
54
- </div>
57
+ </Tag>
55
58
  );
56
59
  };
57
60
 
@@ -1,8 +1,3 @@
1
- <%= content_tag(:div,
2
- aria: object.aria,
3
- data: object.data,
4
- id: object.id,
5
- class: object.classname,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
7
2
  <%= react_component("MultiLevelSelect", object.multi_level_select_options) %>
8
3
  <% end %>
@@ -1,15 +1,9 @@
1
1
  <% if object.collapsible %>
2
2
  <%= pb_rails("collapsible", props: { name: "collapsible-nav-example", classname: object.collapsible_nav_classname }) do %>
3
3
  <%= pb_rails("collapsible/collapsible_main", props: { name: "default-collapsible-nav", icon: object.collapsible_icons, size: "xs", dark: object.dark, classname:object.margin_classes }) do %>
4
- <%= content_tag(object.tag,
5
- aria: object.aria,
6
- class: object.classname,
7
- data: object.data,
8
- dark: object.dark,
9
- id: object.id,
10
- href: object.link && object.link,
11
- target: object.link && object.target,
12
- **combined_html_options
4
+ <%= pb_content_tag( object.tag,
5
+ href: object.link && object.link,
6
+ target: object.link && object.target
13
7
  ) do %>
14
8
  <% if object.image_url %>
15
9
  <%= pb_rails("image", props: { url: object.image_url, classname: "pb_nav_img_wrapper_collapsible" }) %>
@@ -20,22 +14,16 @@
20
14
  <span class="pb_nav_list_item_text_collapsible">
21
15
  <%= object.text %>
22
16
  </span>
23
- <% end %>
17
+ <% end %>
24
18
  <% end %>
25
19
  <%= pb_rails("collapsible/collapsible_content", props: {collapsed: object.collapsed}) do %>
26
20
  <%= content.presence %>
27
21
  <% end %>
28
22
  <% end %>
29
23
  <% else %>
30
- <%= content_tag(object.tag,
31
- aria: object.aria,
32
- class: object.classname,
33
- **combined_html_options,
34
- data: object.data,
35
- dark: object.dark,
36
- id: object.id,
37
- href: object.link && object.link,
38
- target: object.link && object.target
24
+ <%= pb_content_tag( object.tag,
25
+ href: object.link && object.link,
26
+ target: object.link && object.target
39
27
  ) do %>
40
28
  <% if object.image_url %>
41
29
  <%= pb_rails("image", props: { url: object.image_url, classname: "pb_nav_img_wrapper" }) %>
@@ -1,12 +1,7 @@
1
- <%= content_tag(:nav,
2
- aria: object.aria,
3
- class: object.classname,
4
- data: object.data,
5
- id: object.id,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag(:nav) do %>
7
2
  <% if object.title %>
8
- <%= content_tag(:div, class: "pb_nav_list_title") do %>
9
- <%= content_tag(:a, class: "pb_nav_list_item_link_text", href: object.link) do %>
3
+ <%= pb_content_tag do %>
4
+ <%= pb_content_tag(:a) do %>
10
5
  <%= pb_rails("caption", props: { text: object.title, dark: dark }) %>
11
6
  <% end %>
12
7
  <% end %>
@@ -1,7 +1,2 @@
1
- <%= content_tag(:div,
2
- aria: object.aria.merge!(label: object.status),
3
- class: object.classname,
4
- data: object.data,
5
- id: object.id,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
7
2
  <% end %>
@@ -1,9 +1,4 @@
1
- <%= content_tag(:div,
2
- aria: object.aria,
3
- class: object.classname,
4
- data: object.data,
5
- id: object.id,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
7
2
  <div class="pb_popover_tooltip hide" id="<%= object.tooltip_id %>" role="tooltip" style="<%= object.z_index_helper %>">
8
3
  <div class="pb_popover_body <%= object.width_height_class_helper %> <%= object.popover_spacing_helper %>" style="<%= object.width_height_helper %>">
9
4
  <%= content.presence %>
@@ -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,
@@ -6,6 +6,8 @@ module Playbook
6
6
  prop :tag, type: Playbook::Props::Enum,
7
7
  values: %w[table div],
8
8
  default: "table"
9
+ prop :draggable_container, type: Playbook::Props::Boolean,
10
+ default: false
9
11
 
10
12
  def classname
11
13
  generate_classname("pb_table_tbody")
@@ -18,13 +18,19 @@
18
18
  <% end %>
19
19
  </tr>
20
20
  <% elsif object.tag == "table" %>
21
- <%= content_tag(:tr,
22
- aria: object.aria,
23
- class: object.classname,
24
- data: object.data,
25
- id: object.id,
26
- **combined_html_options) do %>
27
- <%= content.presence %>
21
+ <% if object.draggable_item %>
22
+ <%= pb_rails("draggable/draggable_item", props:{ drag_id: object.drag_id, tag: "tr", classname: object.classname, data: object.data }) do %>
23
+ <%= content.presence %>
24
+ <% end %>
25
+ <% else %>
26
+ <%= content_tag(:tr,
27
+ aria: object.aria,
28
+ class: object.classname,
29
+ data: object.data,
30
+ id: object.id,
31
+ **combined_html_options) do %>
32
+ <%= content.presence %>
33
+ <% end %>
28
34
  <% end %>
29
35
  <% else %>
30
36
  <%= content_tag(:div,
@@ -13,6 +13,10 @@ module Playbook
13
13
  prop :collapsible_content
14
14
  prop :collapsible_side_highlight, type: Playbook::Props::Boolean,
15
15
  default: true
16
+ prop :draggable_item, type: Playbook::Props::Boolean,
17
+ default: false
18
+ prop :drag_id, type: Playbook::Props::String,
19
+ default: nil
16
20
 
17
21
  def classname
18
22
  generate_classname("pb_table_row_kit", side_highlight_class) + tag_class
@@ -27,6 +27,20 @@
27
27
  placeholder: "123-45-6789"
28
28
  }) %>
29
29
 
30
+ <%= pb_rails("text_input", props: {
31
+ label: "Credit Card",
32
+ mask: "credit_card",
33
+ margin_bottom: "md",
34
+ placeholder: "1234 5678 9012 3456"
35
+ }) %>
36
+
37
+ <%= pb_rails("text_input", props: {
38
+ label: "CVV",
39
+ mask: "cvv",
40
+ margin_bottom: "md",
41
+ placeholder: "123"
42
+ }) %>
43
+
30
44
  <%= pb_rails("title" , props: {
31
45
  text: "Hidden Input Under The Hood",
32
46
  padding_bottom: "sm"
@@ -27,6 +27,8 @@ export default class PbTextInput extends PbEnhancedElement {
27
27
  ssn: 'ssn',
28
28
  postal_code: 'postalCode',
29
29
  zip_code: 'zipCode',
30
+ credit_card: 'creditCard',
31
+ cvv: 'cvv',
30
32
  }[maskType];
31
33
 
32
34
  if (maskKey && INPUTMASKS[maskKey]) {
@@ -45,6 +47,9 @@ export default class PbTextInput extends PbEnhancedElement {
45
47
  case "currency":
46
48
  sanitizedInput.value = sanitizeCurrency(formattedValue);
47
49
  break;
50
+ case "credit_card":
51
+ sanitizedInput.value = sanitizeCreditCard(formattedValue);
52
+ break;
48
53
  default:
49
54
  sanitizedInput.value = formattedValue;
50
55
  }
@@ -63,6 +68,10 @@ function sanitizeCurrency(input) {
63
68
  return input.replace(/[$,]/g, "");
64
69
  }
65
70
 
71
+ function sanitizeCreditCard(input) {
72
+ return input.replace(/\D/g, "");
73
+ }
74
+
66
75
  function setCursorPosition(inputElement, cursorPosition, rawValue, formattedValue) {
67
76
  const difference = formattedValue.length - rawValue.length;
68
77
  const newPosition = Math.max(0, cursorPosition + difference);
@@ -4,13 +4,15 @@
4
4
  module Playbook
5
5
  module PbTextInput
6
6
  class TextInput < Playbook::KitBase
7
- VALID_MASKS = %w[currency zipCode postalCode ssn].freeze
7
+ VALID_MASKS = %w[currency zip_code postal_code ssn credit_card cvv].freeze
8
8
 
9
9
  MASK_PATTERNS = {
10
10
  "currency" => '^\$\d{1,3}(?:,\d{3})*(?:\.\d{2})?$',
11
11
  "zip_code" => '\d{5}',
12
12
  "postal_code" => '\d{5}-\d{4}',
13
13
  "ssn" => '\d{3}-\d{2}-\d{4}',
14
+ "credit_card" => '\d{4} \d{4} \d{4} \d{4}',
15
+ "cvv" => '\d{3,4}',
14
16
  }.freeze
15
17
 
16
18
  prop :autocomplete, type: Playbook::Props::Boolean,
@@ -34,7 +36,8 @@ module Playbook
34
36
  prop :add_on, type: Playbook::Props::NestedProps,
35
37
  nested_kit: Playbook::PbTextInput::AddOn
36
38
 
37
- prop :mask, type: Playbook::Props::String,
39
+ prop :mask, type: Playbook::Props::Enum,
40
+ values: ["currency", "zip_code", "postal_code", "ssn", "credit_card", "cvv", nil],
38
41
  default: nil
39
42
 
40
43
  def classname
@@ -17,7 +17,7 @@ module Playbook
17
17
  def display_badge
18
18
  @display_badge ||= begin
19
19
  badge_path = File.join(
20
- File.dirname(self.class.source_location),
20
+ File.dirname(self.class.instance_method(:display_badge).source_location.first),
21
21
  "badges",
22
22
  "#{badge}.svg"
23
23
  )