playbook_ui 14.12.0.pre.alpha.PBNTR456fixedconftoastrailsautoclose5673 → 14.12.0.pre.alpha.PBNTR456fixedconftoastrailsautoclose5728
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/_playbook.scss +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/CustomCell.tsx +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +8 -13
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_loading.html.erb +33 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_loading_rails.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_loading.md → _advanced_table_loading_react.md} +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +3 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +9 -5
- data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +2 -0
- data/app/pb_kits/playbook/pb_avatar/_avatar.scss +5 -0
- data/app/pb_kits/playbook/pb_copy_button/_copy_button.scss +3 -0
- data/app/pb_kits/playbook/pb_copy_button/_copy_button.tsx +92 -0
- data/app/pb_kits/playbook/pb_copy_button/copy_button.test.jsx +64 -0
- data/app/pb_kits/playbook/pb_copy_button/docs/_copy_button_default.jsx +21 -0
- data/app/pb_kits/playbook/pb_copy_button/docs/_copy_button_from.jsx +45 -0
- data/app/pb_kits/playbook/pb_copy_button/docs/_copy_button_from.md +1 -0
- data/app/pb_kits/playbook/pb_copy_button/docs/example.yml +8 -0
- data/app/pb_kits/playbook/pb_copy_button/docs/index.js +2 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/index.js +13 -36
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_content.jsx +12 -8
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_content_rails.html.erb +52 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_content_rails.md +0 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_rows_rails.html.erb +52 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_rows_rails.md +3 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table_rails.html.erb +80 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table_rails.md +1 -0
- data/app/pb_kits/playbook/pb_table/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_table/table_row.rb +1 -1
- data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +3 -1
- data/dist/chunks/{_typeahead-BWwaAo_0.js → _typeahead-BIhRQo8Q.js} +3 -3
- data/dist/chunks/_weekday_stacked-VKMYuo6-.js +45 -0
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +6 -0
- 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/pb_forms_global_props_helper.rb +136 -0
- data/lib/playbook/pb_forms_helper.rb +13 -4
- data/lib/playbook/version.rb +1 -1
- metadata +22 -5
- data/dist/chunks/_weekday_stacked-zyBCd1s8.js +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 443f924259452e15c0bb8bc2ea0d94645d77fa9b42fb76564d273f42f42db997
|
4
|
+
data.tar.gz: 354744c87e2be85504715e8b1c695754f99ce6a2776b4c738a5e2f1408a4c5d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af9311e0d5f5a9f5ee66ea6483baca4152dfcadb4903ec31120b90a4c2b0af51e4621403924979557844fa9db39121bcfebf1775733b4c6475f6edde8ce324e0
|
7
|
+
data.tar.gz: d027b8c7e30f6c2d3a0bcf7cf8dd3910917f6aea83e9a1fb92977dbcda20d05276d1bc89bc52a62a9076036b3ddfed510c5b75e795191d364d7073964232b57b
|
@@ -15,6 +15,7 @@
|
|
15
15
|
@import 'pb_circle_chart/circle_chart';
|
16
16
|
@import 'pb_circle_icon_button/circle_icon_button';
|
17
17
|
@import 'pb_collapsible/collapsible';
|
18
|
+
@import 'pb_copy_button/copy_button';
|
18
19
|
@import 'pb_contact/contact';
|
19
20
|
@import 'pb_currency/currency';
|
20
21
|
@import 'pb_dashboard_value/dashboard_value';
|
@@ -39,7 +39,7 @@ export const TableHeaderCell = ({
|
|
39
39
|
sortIcon,
|
40
40
|
table
|
41
41
|
}: TableHeaderCellProps) => {
|
42
|
-
const { sortControl, responsive, selectableRows, hasAnySubRows, showActionsBar } =
|
42
|
+
const { sortControl, responsive, selectableRows, hasAnySubRows, showActionsBar, inlineRowLoading } =
|
43
43
|
useContext(AdvancedTableContext);
|
44
44
|
|
45
45
|
type justifyTypes = "none" | "center" | "start" | "end" | "between" | "around" | "evenly"
|
@@ -91,7 +91,7 @@ const isToggleExpansionEnabled =
|
|
91
91
|
|
92
92
|
let justifyHeader:justifyTypes;
|
93
93
|
|
94
|
-
if (header?.index === 0 && hasAnySubRows) {
|
94
|
+
if (header?.index === 0 && hasAnySubRows || (header?.index === 0 && inlineRowLoading)) {
|
95
95
|
justifyHeader = enableSorting ? "between" : "start";
|
96
96
|
} else {
|
97
97
|
justifyHeader = isLeafColumn ? "end" : "center";
|
@@ -1,15 +1,10 @@
|
|
1
1
|
<%= pb_content_tag do %>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
table_data: object.table_data,
|
11
|
-
column_definitions: object.column_definitions,
|
12
|
-
responsive: object.responsive }) %>
|
13
|
-
<% end %>
|
14
|
-
<% end %>
|
2
|
+
<%= pb_rails("table", props: { size: "sm", data_table: true, number_spacing:"tabular", responsive:"none", dark: dark, classname: object.loading ? "content-loading" : "" }.merge(object.table_props)) do %>
|
3
|
+
<% if content.present? %>
|
4
|
+
<% content.presence %>
|
5
|
+
<% else %>
|
6
|
+
<%= pb_rails("advanced_table/table_header", props: { column_definitions: object.column_definitions, enable_toggle_expansion: object.enable_toggle_expansion, responsive: object.responsive, loading: object.loading }) %>
|
7
|
+
<%= pb_rails("advanced_table/table_body", props: { id: object.id, table_data: object.table_data, column_definitions: object.column_definitions, responsive: object.responsive, loading: object.loading }) %>
|
8
|
+
<% end %>
|
9
|
+
<% end %>
|
15
10
|
<% end %>
|
@@ -10,6 +10,8 @@ module Playbook
|
|
10
10
|
prop :enable_toggle_expansion, type: Playbook::Props::Enum,
|
11
11
|
values: %w[all header none],
|
12
12
|
default: "header"
|
13
|
+
prop :loading, type: Playbook::Props::Boolean,
|
14
|
+
default: false
|
13
15
|
prop :responsive, type: Playbook::Props::Enum,
|
14
16
|
values: %w[none scroll],
|
15
17
|
default: "scroll"
|
@@ -245,7 +245,7 @@ test("toggleExpansionAll button exists and toggles subrows open and closed", asy
|
|
245
245
|
})
|
246
246
|
|
247
247
|
|
248
|
-
test("loading state +
|
248
|
+
test("loading state + initialLoadingRowsCount prop", () => {
|
249
249
|
render(
|
250
250
|
<AdvancedTable
|
251
251
|
columnDefinitions={columnDefinitions}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<% column_definitions = [
|
2
|
+
{
|
3
|
+
accessor: "year",
|
4
|
+
label: "Year",
|
5
|
+
cellAccessors: ["quarter", "month", "day"],
|
6
|
+
},
|
7
|
+
{
|
8
|
+
accessor: "newEnrollments",
|
9
|
+
label: "New Enrollments",
|
10
|
+
},
|
11
|
+
{
|
12
|
+
accessor: "scheduledMeetings",
|
13
|
+
label: "Scheduled Meetings",
|
14
|
+
},
|
15
|
+
{
|
16
|
+
accessor: "attendanceRate",
|
17
|
+
label: "Attendance Rate",
|
18
|
+
},
|
19
|
+
{
|
20
|
+
accessor: "completedClasses",
|
21
|
+
label: "Completed Classes",
|
22
|
+
},
|
23
|
+
{
|
24
|
+
accessor: "classCompletionRate",
|
25
|
+
label: "Class Completion Rate",
|
26
|
+
},
|
27
|
+
{
|
28
|
+
accessor: "graduatedStudents",
|
29
|
+
label: "Graduated Students",
|
30
|
+
}
|
31
|
+
] %>
|
32
|
+
|
33
|
+
<%= pb_rails("advanced_table", props: { id: "beta_table", table_data: @table_data, column_definitions: column_definitions, loading: true }) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
The optional `loading` prop takes a boolean value that can be managed using state. If loading is true, the table will display the loading skeleton and once loading is false, the table will render with the data provided.
|
@@ -1,3 +1,3 @@
|
|
1
|
-
|
1
|
+
The optional `loading` prop takes a boolean value that can be managed using state. If loading is true, the table will display the loading skeleton and once loading is false, the table will render with the data provided.
|
2
2
|
|
3
|
-
By default, the inital row count of the loading skeleton is set to 10. If you want more control over this initial row count, the optional `
|
3
|
+
By default, the inital row count of the loading skeleton is set to 10. If you want more control over this initial row count, the optional `initialLoadingRowsCount` prop can be used to pass in a number. __NOTE__: This is only for the first render of the table, subsequent loading skeleton row count logic is handled within the kit itself.
|
@@ -1,6 +1,7 @@
|
|
1
1
|
examples:
|
2
2
|
rails:
|
3
3
|
- advanced_table_beta: Default (Required Props)
|
4
|
+
- advanced_table_loading: Loading State
|
4
5
|
- advanced_table_beta_subrow_headers: SubRow Headers
|
5
6
|
- advanced_table_collapsible_trail_rails: Collapsible Trail
|
6
7
|
- advanced_table_table_props: Table Props
|
@@ -16,6 +16,8 @@ module Playbook
|
|
16
16
|
default: []
|
17
17
|
prop :collapsible_trail, type: Playbook::Props::Boolean,
|
18
18
|
default: true
|
19
|
+
prop :loading, type: Playbook::Props::Boolean,
|
20
|
+
default: false
|
19
21
|
prop :responsive, type: Playbook::Props::Enum,
|
20
22
|
values: %w[none scroll],
|
21
23
|
default: "scroll"
|
@@ -54,7 +56,7 @@ module Playbook
|
|
54
56
|
current_data_attributes = current_depth.zero? ? { row_depth: 0 } : table_data_attributes
|
55
57
|
|
56
58
|
# Additional class and data attributes needed for toggle logic
|
57
|
-
output << pb_rails("advanced_table/table_row", props: { id: id, row: row, column_definitions: leaf_columns, depth: current_depth, collapsible_trail: collapsible_trail, classname: additional_classes, table_data_attributes: current_data_attributes, responsive: responsive })
|
59
|
+
output << pb_rails("advanced_table/table_row", props: { id: id, row: row, column_definitions: leaf_columns, depth: current_depth, collapsible_trail: collapsible_trail, classname: additional_classes, table_data_attributes: current_data_attributes, responsive: responsive, loading: loading })
|
58
60
|
|
59
61
|
if row[:children].present?
|
60
62
|
row[:children].each do |child_row|
|
@@ -6,11 +6,15 @@
|
|
6
6
|
<%= pb_rails("table/table_header", props: { id: header_id, colspan: cell[:colspan], classname: [object.th_classname(is_first_column: cell_index.zero?), ('last-header-cell' if cell[:is_last_in_group] && cell_index != 0)].compact.join(' '), sort_menu: cell[:accessor] ? cell[:sort_menu] : nil }) do %>
|
7
7
|
<%= pb_rails("flex", props: { align: "center", justify: cell_index.zero? ? "start" : row_index === header_rows.size - 1 ? "end" : "center", text_align: "end" }) do %>
|
8
8
|
<% if cell_index.zero? && (object.enable_toggle_expansion == "header" || object.enable_toggle_expansion == "all") && row_index === header_rows.size - 1 %>
|
9
|
-
|
10
|
-
class="
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
<% if loading %>
|
10
|
+
<div class="<%= object.loading ? 'loading-toggle-icon' : '' %>"></div>
|
11
|
+
<% else %>
|
12
|
+
<button
|
13
|
+
class="gray-icon toggle-all-icon"
|
14
|
+
onclick="expandAllRows(this); event.preventDefault();">
|
15
|
+
<%= pb_rails("icon", props: { icon: "arrows-from-line", cursor: "pointer", fixed_width: true, padding_right: "xs" }) %>
|
16
|
+
</button>
|
17
|
+
<% end %>
|
14
18
|
<% end %>
|
15
19
|
<%= cell[:label] %>
|
16
20
|
<% end %>
|
@@ -8,6 +8,8 @@ module Playbook
|
|
8
8
|
prop :enable_toggle_expansion, type: Playbook::Props::Enum,
|
9
9
|
values: %w[all header none],
|
10
10
|
default: "header"
|
11
|
+
prop :loading, type: Playbook::Props::Boolean,
|
12
|
+
default: false
|
11
13
|
prop :responsive, type: Playbook::Props::Enum,
|
12
14
|
values: %w[none scroll],
|
13
15
|
default: "scroll"
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<% object.column_definitions.each_with_index do |column, index| %>
|
3
3
|
<% next unless column[:accessor].present? %>
|
4
4
|
<%= pb_rails("table/table_cell", props: { classname:object.td_classname(column, index)}) do %>
|
5
|
-
<%= pb_rails("flex", props:{ align: "center", justify: index.zero? ? "start" : "end" }) do %>
|
5
|
+
<%= pb_rails("flex", props:{ align: "center", justify: index.zero? ? "start" : "end", classname: object.loading ? "loading-cell" : "" }) do %>
|
6
6
|
<% if collapsible_trail && index.zero? %>
|
7
7
|
<% (1..depth).each do |i| %>
|
8
8
|
<% additional_offset = i > 1 ? (i - 1) * 0.25 : 0 %>
|
@@ -13,6 +13,8 @@ module Playbook
|
|
13
13
|
default: true
|
14
14
|
prop :table_data_attributes, type: Playbook::Props::HashProp,
|
15
15
|
default: {}
|
16
|
+
prop :loading, type: Playbook::Props::Boolean,
|
17
|
+
default: false
|
16
18
|
prop :responsive, type: Playbook::Props::Enum,
|
17
19
|
values: %w[none scroll],
|
18
20
|
default: "scroll"
|
@@ -0,0 +1,92 @@
|
|
1
|
+
|
2
|
+
import React, { useState } from 'react'
|
3
|
+
import classnames from 'classnames'
|
4
|
+
import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
|
5
|
+
import { globalProps } from '../utilities/globalProps'
|
6
|
+
|
7
|
+
import Button from '../pb_button/_button'
|
8
|
+
import Tooltip from '../pb_tooltip/_tooltip'
|
9
|
+
|
10
|
+
type CopyButtonProps = {
|
11
|
+
aria?: { [key: string]: string },
|
12
|
+
className?: string,
|
13
|
+
data?: { [key: string]: string },
|
14
|
+
id?: string,
|
15
|
+
from?: string,
|
16
|
+
text?: string,
|
17
|
+
tooltipPlacement?: "top" | "right" | "bottom" | "left",
|
18
|
+
tooltipText?: string,
|
19
|
+
value?: string,
|
20
|
+
}
|
21
|
+
|
22
|
+
const CopyButton = (props: CopyButtonProps) => {
|
23
|
+
const {
|
24
|
+
aria = {},
|
25
|
+
className,
|
26
|
+
data = {},
|
27
|
+
from = '',
|
28
|
+
id,
|
29
|
+
text= 'Copy',
|
30
|
+
tooltipPlacement= 'bottom',
|
31
|
+
tooltipText = 'Copied!',
|
32
|
+
value = '',
|
33
|
+
} = props
|
34
|
+
|
35
|
+
const [copied, setCopied] = useState(false)
|
36
|
+
|
37
|
+
const ariaProps = buildAriaProps(aria)
|
38
|
+
const dataProps = buildDataProps(data)
|
39
|
+
const classes = classnames(buildCss('pb_copy_button_kit'), globalProps(props), className)
|
40
|
+
|
41
|
+
const copy = () => {
|
42
|
+
if (!from && !value) {
|
43
|
+
return
|
44
|
+
}
|
45
|
+
|
46
|
+
if (value) {
|
47
|
+
navigator.clipboard.writeText(value)
|
48
|
+
} else if (from) {
|
49
|
+
const copyElement = document.getElementById(from);
|
50
|
+
let copyText = copyElement?.innerText
|
51
|
+
|
52
|
+
if (copyElement instanceof HTMLTextAreaElement || copyElement instanceof HTMLInputElement) {
|
53
|
+
copyText = copyElement.value;
|
54
|
+
}
|
55
|
+
|
56
|
+
if (copyText) {
|
57
|
+
navigator.clipboard.writeText(copyText)
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
setCopied(true)
|
62
|
+
|
63
|
+
setTimeout(() => {
|
64
|
+
setCopied(false)
|
65
|
+
}, 1000);
|
66
|
+
}
|
67
|
+
|
68
|
+
return (
|
69
|
+
<div
|
70
|
+
{...ariaProps}
|
71
|
+
{...dataProps}
|
72
|
+
className={classes}
|
73
|
+
id={id}
|
74
|
+
>
|
75
|
+
<Tooltip
|
76
|
+
forceOpenTooltip={copied}
|
77
|
+
placement={tooltipPlacement}
|
78
|
+
showTooltip={false}
|
79
|
+
text={tooltipText}
|
80
|
+
>
|
81
|
+
<Button
|
82
|
+
icon='copy'
|
83
|
+
onClick={copy}
|
84
|
+
>
|
85
|
+
{ text }
|
86
|
+
</Button>
|
87
|
+
</Tooltip>
|
88
|
+
</div>
|
89
|
+
)
|
90
|
+
}
|
91
|
+
|
92
|
+
export default CopyButton
|
@@ -0,0 +1,64 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { CopyButton } from 'playbook-ui'
|
3
|
+
import { ensureAccessible, renderKit, render, fireEvent, screen } from '../utilities/test-utils'
|
4
|
+
|
5
|
+
const props = {
|
6
|
+
data: { testid: 'default', value: 'copy' }
|
7
|
+
}
|
8
|
+
|
9
|
+
test('returns namespaced class name', () => {
|
10
|
+
const kit = renderKit(CopyButton, props)
|
11
|
+
expect(kit).toBeInTheDocument()
|
12
|
+
expect(kit).toHaveClass('pb_copy_button_kit')
|
13
|
+
})
|
14
|
+
|
15
|
+
it('should be accessible', async () => {
|
16
|
+
ensureAccessible(CopyButton, props)
|
17
|
+
})
|
18
|
+
|
19
|
+
// It's difficult to actually use navigator.clipboard.readText, so we mock
|
20
|
+
it('copies the value to clipboard and pastes it into an input', async () => {
|
21
|
+
Object.defineProperty(global, 'navigator', {
|
22
|
+
value: {
|
23
|
+
clipboard: {
|
24
|
+
writeText: jest.fn().mockResolvedValueOnce(undefined),
|
25
|
+
},
|
26
|
+
},
|
27
|
+
writable: true,
|
28
|
+
})
|
29
|
+
|
30
|
+
render(<CopyButton {...props} />)
|
31
|
+
|
32
|
+
const copyButton = screen.getByTestId('default')
|
33
|
+
fireEvent.click(copyButton)
|
34
|
+
|
35
|
+
await navigator.clipboard.writeText('copy')
|
36
|
+
|
37
|
+
expect(navigator.clipboard.writeText).toHaveBeenCalledWith("copy");
|
38
|
+
})
|
39
|
+
|
40
|
+
test('passes text and tooltip props to button', () => {
|
41
|
+
render(
|
42
|
+
<CopyButton
|
43
|
+
data={{ testid: 'text-test' }}
|
44
|
+
text={"text"}
|
45
|
+
tooltipPlacement="right"
|
46
|
+
tooltipText="Text copied!"
|
47
|
+
value="copy"
|
48
|
+
/>
|
49
|
+
)
|
50
|
+
|
51
|
+
const content = screen.getByText("text")
|
52
|
+
expect(content).toHaveTextContent("text")
|
53
|
+
|
54
|
+
const kit = screen.getByTestId('text-test')
|
55
|
+
const button = kit.querySelector('.pb_button_kit_primary_inline_enabled')
|
56
|
+
expect(button).toBeInTheDocument()
|
57
|
+
|
58
|
+
fireEvent.click(button)
|
59
|
+
const tooltipContent = screen.getByText("Text copied!")
|
60
|
+
expect(tooltipContent).toHaveTextContent("Text copied!")
|
61
|
+
|
62
|
+
const tooltip = kit.querySelector('.pb_tooltip_kit')
|
63
|
+
expect(tooltip).toBeInTheDocument()
|
64
|
+
})
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import { CopyButton, Textarea } from 'playbook-ui'
|
3
|
+
|
4
|
+
const CopyButtonDefault = (props) => (
|
5
|
+
<div>
|
6
|
+
<CopyButton
|
7
|
+
{...props}
|
8
|
+
text="Copy Text"
|
9
|
+
tooltipPlacement="right"
|
10
|
+
tooltipText="Text copied!"
|
11
|
+
value="Playbook makes it easy to support bleeding edge, or legacy systems. Use Playbook’s 200+ components and end-to-end design language to create simple, intuitive and beautiful experiences with ease."
|
12
|
+
/>
|
13
|
+
|
14
|
+
<Textarea
|
15
|
+
{...props}
|
16
|
+
placeholder="Copy and paste here"
|
17
|
+
/>
|
18
|
+
</div>
|
19
|
+
)
|
20
|
+
|
21
|
+
export default CopyButtonDefault
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import React, { useState } from 'react'
|
2
|
+
import { CopyButton, Body, TextInput, Textarea } from 'playbook-ui'
|
3
|
+
|
4
|
+
const CopyButtonFrom = (props) => {
|
5
|
+
const [text, setText] = useState("Copy this text input text")
|
6
|
+
|
7
|
+
const handleChange = (event) => {
|
8
|
+
setText(event.target.value);
|
9
|
+
}
|
10
|
+
|
11
|
+
return (<div>
|
12
|
+
<Body id="body">Copy this body text!</Body>
|
13
|
+
<CopyButton
|
14
|
+
{...props}
|
15
|
+
from="body"
|
16
|
+
marginBottom="sm"
|
17
|
+
text="Copy Body text"
|
18
|
+
tooltipPlacement="right"
|
19
|
+
tooltipText="Body text copied!"
|
20
|
+
/>
|
21
|
+
|
22
|
+
<TextInput
|
23
|
+
{...props}
|
24
|
+
id="textinput"
|
25
|
+
onChange={handleChange}
|
26
|
+
value={text}
|
27
|
+
/>
|
28
|
+
<CopyButton
|
29
|
+
{...props}
|
30
|
+
from="textinput"
|
31
|
+
marginBottom="sm"
|
32
|
+
text="Copy Text Input"
|
33
|
+
tooltipPlacement="right"
|
34
|
+
tooltipText="Text input copied!"
|
35
|
+
/>
|
36
|
+
|
37
|
+
<Textarea
|
38
|
+
{...props}
|
39
|
+
placeholder="Copy and paste here"
|
40
|
+
/>
|
41
|
+
</div>
|
42
|
+
)
|
43
|
+
}
|
44
|
+
|
45
|
+
export default CopyButtonFrom
|
@@ -0,0 +1 @@
|
|
1
|
+
Provide an element's ID as the `from` parameter, and its text will be copied. If the element is an input, its `value` will be copied; otherwise, the `innerText` will be used. Additionally, if a `value` prop is provided, it will override the content from the `from` element and be copied instead.
|
@@ -1,24 +1,15 @@
|
|
1
1
|
import PbEnhancedElement from '../pb_enhanced_element'
|
2
2
|
|
3
|
-
const TOAST_WRAPPER_SELECTOR = '[data-pb-toast-wrapper]'
|
4
|
-
const TOAST_AUTO_CLOSE_CLASS = 'auto_close'
|
5
|
-
const TOAST_REMOVE_CLASS = 'remove_toast'
|
6
|
-
|
7
3
|
export default class PbFixedConfirmationToast extends PbEnhancedElement {
|
8
4
|
static get selector() {
|
9
|
-
return
|
5
|
+
return '.auto_close, .remove_toast'
|
10
6
|
}
|
11
7
|
|
12
8
|
connect() {
|
13
9
|
this.self = this.element
|
10
|
+
this.autoCloseToast(this.self)
|
14
11
|
|
15
|
-
if (this.self.classList.contains(
|
16
|
-
this.self.hasAttribute('data-pb-auto-close')) {
|
17
|
-
this.autoCloseToast(this.self)
|
18
|
-
}
|
19
|
-
|
20
|
-
if (this.self.classList.contains(TOAST_REMOVE_CLASS) ||
|
21
|
-
this.self.hasAttribute('data-pb-remove-toast')) {
|
12
|
+
if (this.self.classList.contains('remove_toast')) {
|
22
13
|
this.self.addEventListener('click', () => {
|
23
14
|
this.removeToast(this.self)
|
24
15
|
})
|
@@ -35,35 +26,21 @@ export default class PbFixedConfirmationToast extends PbEnhancedElement {
|
|
35
26
|
}
|
36
27
|
|
37
28
|
autoCloseToast(element) {
|
38
|
-
|
29
|
+
const hasAutoCloseClass = element.classList.contains('auto_close')
|
39
30
|
|
40
|
-
if (
|
41
|
-
const autoCloseClass = Array.from(element.classList)
|
42
|
-
.find(cls => cls.startsWith('auto_close_'))
|
43
|
-
|
31
|
+
if (hasAutoCloseClass) {
|
32
|
+
const autoCloseClass = Array.from(element.classList).find(cls => cls.startsWith('auto_close_'))
|
44
33
|
if (autoCloseClass) {
|
45
|
-
duration = parseInt(autoCloseClass.split('_')[2])
|
46
|
-
}
|
47
|
-
}
|
34
|
+
const duration = parseInt(autoCloseClass.split('_')[2])
|
48
35
|
|
49
|
-
|
50
|
-
|
51
|
-
|
36
|
+
if (element.autoCloseTimeout) {
|
37
|
+
clearTimeout(element.autoCloseTimeout)
|
38
|
+
}
|
52
39
|
|
53
|
-
|
54
|
-
|
55
|
-
|
40
|
+
element.autoCloseTimeout = setTimeout(() => {
|
41
|
+
this.removeToast(element)
|
42
|
+
}, duration)
|
56
43
|
}
|
57
|
-
|
58
|
-
element.autoCloseTimeout = setTimeout(() => {
|
59
|
-
this.removeToast(element)
|
60
|
-
}, duration)
|
61
|
-
}
|
62
|
-
}
|
63
|
-
|
64
|
-
disconnect() {
|
65
|
-
if (this.element.autoCloseTimeout) {
|
66
|
-
clearTimeout(this.element.autoCloseTimeout)
|
67
44
|
}
|
68
45
|
}
|
69
46
|
}
|
@@ -8,27 +8,31 @@ const TableWithCollapsibleWithCustomContent = (props) => {
|
|
8
8
|
<Card
|
9
9
|
borderNone
|
10
10
|
borderRadius="none"
|
11
|
-
color="light"
|
11
|
+
color="light"
|
12
12
|
paddingX="xl"
|
13
13
|
paddingY="md"
|
14
14
|
{...props}
|
15
15
|
>
|
16
|
-
<Body paddingBottom="sm"
|
16
|
+
<Body paddingBottom="sm"
|
17
17
|
text="Expanded Custom Layout"
|
18
18
|
{...props}
|
19
19
|
/>
|
20
20
|
<Flex justify="between">
|
21
21
|
<Image
|
22
|
-
|
22
|
+
size="sm"
|
23
|
+
url="https://unsplash.it/500/400/?image=634"
|
23
24
|
/>
|
24
25
|
<Image
|
25
|
-
|
26
|
+
size="sm"
|
27
|
+
url="https://unsplash.it/500/400/?image=634"
|
26
28
|
/>
|
27
29
|
<Image
|
28
|
-
|
30
|
+
size="sm"
|
31
|
+
url="https://unsplash.it/500/400/?image=634"
|
29
32
|
/>
|
30
33
|
<Image
|
31
|
-
|
34
|
+
size="sm"
|
35
|
+
url="https://unsplash.it/500/400/?image=634"
|
32
36
|
/>
|
33
37
|
</Flex>
|
34
38
|
</Card>
|
@@ -52,7 +56,7 @@ const TableWithCollapsibleWithCustomContent = (props) => {
|
|
52
56
|
|
53
57
|
</Table.Head>
|
54
58
|
<Table.Body>
|
55
|
-
<Table.Row collapsible
|
59
|
+
<Table.Row collapsible
|
56
60
|
collapsibleContent={<Content/>}
|
57
61
|
{...props}
|
58
62
|
>
|
@@ -61,7 +65,7 @@ const TableWithCollapsibleWithCustomContent = (props) => {
|
|
61
65
|
<Table.Cell>{'Value 3'}</Table.Cell>
|
62
66
|
<Table.Cell>{'Value 4'}</Table.Cell>
|
63
67
|
<Table.Cell>{'Value 5'}</Table.Cell>
|
64
|
-
<Table.Cell textAlign="right">{
|
68
|
+
<Table.Cell textAlign="right">{
|
65
69
|
<Icon
|
66
70
|
color="primary"
|
67
71
|
fixedWidth
|