playbook_ui 15.2.0 → 15.3.0.pre.alpha.PLAY2012currencyallownonstring11930
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/_playbook.scss +5 -5
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +3 -1
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableActions.ts +18 -3
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +71 -14
- data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableHeader.tsx +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +12 -3
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +59 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_background_control_rails.html.erb +39 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_background_control_rails.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta.md +3 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_sort.html.erb +3 -3
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_subrow_headers.html.erb +3 -3
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_collapsible_trail_rails.html.erb +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.md +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers_rails.html.erb +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_rails.html.erb +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_rails.md +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_inline_row_loading.jsx +28 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_inline_row_loading.md +11 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_padding_control_per_row_rails.html.erb +51 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_padding_control_per_row_rails.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_padding_control_rails.html.erb +40 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_padding_control_rails.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pagination_with_props.jsx +4 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pagination_with_props.md +3 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling_rails.md +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling_react.md +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_rails.html.erb +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_mock_data_inline_loading_empty_children.js +42 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/index.js +5 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +6 -6
- data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +6 -6
- data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +3 -2
- data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +49 -5
- data/app/pb_kits/playbook/pb_bread_crumbs/docs/_bread_crumbs_default.html.erb +4 -4
- data/app/pb_kits/playbook/pb_bread_crumbs/docs/_bread_crumbs_default.jsx +4 -0
- data/app/pb_kits/playbook/pb_button/_button.scss +6 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_loading.html.erb +7 -3
- data/app/pb_kits/playbook/pb_button/docs/_button_loading.jsx +29 -0
- data/app/pb_kits/playbook/pb_currency/_currency.tsx +17 -7
- data/app/pb_kits/playbook/pb_currency/currency.rb +20 -8
- data/app/pb_kits/playbook/pb_currency/currency.test.js +42 -0
- data/app/pb_kits/playbook/pb_currency/docs/_currency_variants.html.erb +1 -1
- data/app/pb_kits/playbook/pb_currency/docs/_currency_variants.jsx +1 -1
- data/app/pb_kits/playbook/pb_currency/docs/_currency_variants.md +1 -0
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +2 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range_pattern.jsx +1 -1
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_quick_pick_styles.scss +11 -30
- data/app/pb_kits/playbook/pb_draggable/_draggable.scss +8 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.scss +0 -1
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.tsx +5 -3
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_description.md +2 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.rb +4 -1
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.test.js +10 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.html.erb +1 -1
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -1
- data/app/pb_kits/playbook/pb_form/formHelper.js +1 -1
- data/app/pb_kits/playbook/pb_icon_circle/docs/_icon_circle_color.md +1 -1
- data/app/pb_kits/playbook/pb_icon_stat_value/docs/_icon_stat_value_color.html.erb +7 -14
- data/app/pb_kits/playbook/pb_icon_stat_value/docs/_icon_stat_value_color.jsx +6 -15
- data/app/pb_kits/playbook/pb_pb_bar_graph/_pb_bar_graph.tsx +8 -6
- data/app/pb_kits/playbook/pb_pb_bar_graph/docs/_description.md +3 -0
- data/app/pb_kits/playbook/pb_pb_bar_graph/pb_bar_graph.rb +7 -10
- data/app/pb_kits/playbook/pb_pb_bar_graph/pbbargraph.test.jsx +73 -1
- data/app/pb_kits/playbook/pb_pb_circle_chart/_pb_circle_chart.tsx +1 -1
- data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_description.md +3 -0
- data/app/pb_kits/playbook/pb_pb_circle_chart/pb_circle_chart.rb +7 -10
- data/app/pb_kits/playbook/pb_pb_circle_chart/pb_circle_chart.test.jsx +47 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/_pb_gauge_chart.scss +3 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/_pb_gauge_chart.tsx +69 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_description.md +3 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_color.html.erb +12 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_color.jsx +24 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_color.md +5 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_complex.html.erb +45 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_complex.jsx +119 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_complex.md +1 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_default.html.erb +5 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_default.jsx +17 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_disable_animation.html.erb +12 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_disable_animation.jsx +24 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_full_circle.html.erb +23 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_full_circle.jsx +37 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_height.html.erb +40 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_height.jsx +56 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_live_data.jsx +64 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_min_max.html.erb +27 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_min_max.jsx +40 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_min_max.md +1 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_sizing.html.erb +19 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_sizing.jsx +65 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_sizing.md +3 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_title.html.erb +14 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_title.jsx +27 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_units.html.erb +39 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_units.jsx +58 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/_pb_gauge_chart_units.md +1 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/example.yml +29 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/docs/index.js +11 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/pbGaugeGraphTheme.ts +91 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/pb_gauge_chart.html.erb +1 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/pb_gauge_chart.rb +25 -0
- data/app/pb_kits/playbook/pb_pb_gauge_chart/pb_gauge_chart.test.jsx +80 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/_pb_line_graph.scss +3 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/_pb_line_graph.tsx +61 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_description.md +3 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_colors.html.erb +34 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_colors.jsx +52 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_colors.md +5 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_default.html.erb +34 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_default.jsx +45 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_height.html.erb +47 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_height.jsx +64 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_height.md +3 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_legend.html.erb +24 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_legend.jsx +37 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_legend_nonclickable.html.erb +39 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_legend_nonclickable.jsx +45 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_legend_position.html.erb +86 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_legend_position.jsx +116 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/_pb_line_graph_legend_position.md +11 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/example.yml +20 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/docs/index.js +6 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/pbLineGraphTheme.ts +125 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/pb_line_graph.html.erb +1 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/pb_line_graph.rb +25 -0
- data/app/pb_kits/playbook/pb_pb_line_graph/pb_line_graph.test.jsx +110 -0
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +130 -28
- data/app/pb_kits/playbook/pb_popover/_popover.tsx +69 -34
- data/app/pb_kits/playbook/pb_popover/docs/_popover_append_to.jsx +68 -0
- data/app/pb_kits/playbook/pb_popover/docs/_popover_append_to_react.md +1 -0
- data/app/pb_kits/playbook/pb_popover/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_popover/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_popover/popover.test.js +80 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx +41 -2
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +60 -20
- data/app/pb_kits/playbook/pb_rich_text_editor/_tiptap_styles.scss +36 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_attributes.jsx +38 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_attributes.md +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_focus.jsx +34 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_focus.md +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_inline.jsx +37 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_inline.md +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_simple.jsx +37 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_sticky.jsx +38 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_sticky.md +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_templates.jsx +69 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_templates.md +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +8 -2
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/index.js +6 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.test.js +127 -1
- data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.scss +29 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_dynamic_collapsible.html.erb +63 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_dynamic_collapsible.jsx +89 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_dynamic_collapsible_rails.md +4 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_dynamic_collapsible_react.md +3 -0
- data/app/pb_kits/playbook/pb_table/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_table/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_text_input/text_input.rb +2 -2
- data/app/pb_kits/playbook/pb_timeline/_timeline.scss +250 -233
- data/app/pb_kits/playbook/pb_timeline/_timeline.tsx +1 -1
- data/app/pb_kits/playbook/pb_timeline/timeline.test.js +2 -2
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +76 -1
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +85 -2
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_custom_options.html.erb +64 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_custom_options.jsx +70 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_custom_options.md +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default_options.html.erb +102 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default_options.md +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default_value.jsx +103 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default_value.md +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +4 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/index.js +2 -0
- data/app/pb_kits/playbook/tokens/_positioning.scss +1 -0
- data/app/pb_kits/playbook/utilities/_positioning.scss +6 -1
- data/app/pb_kits/playbook/utilities/globalProps.ts +3 -1
- data/dist/chunks/{_line_graph-ByLTvO72.js → _line_graph-CqE0-dq5.js} +1 -1
- data/dist/chunks/_typeahead-3ZAbZUqU.js +6 -0
- data/dist/chunks/{_weekday_stacked-CB1Sm0pQ.js → _weekday_stacked-D6fNzH0S.js} +3 -3
- data/dist/chunks/{lib-izYrkvOQ.js → lib-CGxXTQ75.js} +2 -2
- data/dist/chunks/{pb_form_validation-Cah5Z5J3.js → pb_form_validation-DebqlUKZ.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +12 -0
- data/dist/playbook-doc.js +2 -2
- 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_helper.rb +7 -6
- data/lib/playbook/version.rb +2 -2
- data/lib/playbook/z_index.rb +1 -1
- metadata +101 -8
- data/dist/chunks/_typeahead-DXZQU3hC.js +0 -6
- /data/app/pb_kits/playbook/pb_popover/docs/{_popover_append_to.md → _popover_append_to_rails.md} +0 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import colors from '../tokens/exports/_colors.module.scss'
|
|
2
|
+
import typography from '../tokens/exports/_typography.module.scss'
|
|
3
|
+
|
|
4
|
+
const pbLineGraphTheme = {
|
|
5
|
+
title: {
|
|
6
|
+
text: "",
|
|
7
|
+
style: {
|
|
8
|
+
color: colors.text_lt_default,
|
|
9
|
+
fontFamily: typography.font_family_base,
|
|
10
|
+
fontWeight: typography.bold,
|
|
11
|
+
fontSize: typography.heading_3,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
subtitle: {
|
|
15
|
+
text: "" ,
|
|
16
|
+
style: {
|
|
17
|
+
fontFamily: typography.font_family_base,
|
|
18
|
+
color: colors.text_lt_light,
|
|
19
|
+
fontWeight: typography.regular,
|
|
20
|
+
fontSize: typography.text_base,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
chart: {
|
|
24
|
+
type: "line",
|
|
25
|
+
},
|
|
26
|
+
tooltip: {
|
|
27
|
+
backgroundColor: {
|
|
28
|
+
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
|
|
29
|
+
stops: [
|
|
30
|
+
[0, colors.bg_dark],
|
|
31
|
+
[1, colors.bg_dark],
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
followPointer: true,
|
|
35
|
+
shadow: false,
|
|
36
|
+
borderWidth: 0,
|
|
37
|
+
borderRadius: 10,
|
|
38
|
+
style: {
|
|
39
|
+
fontFamily: typography.font_family_base,
|
|
40
|
+
color: colors.text_dk_default,
|
|
41
|
+
fontWeight: typography.regular,
|
|
42
|
+
fontSize: typography.text_smaller,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
plotOptions: {
|
|
46
|
+
line: {
|
|
47
|
+
dataLabels: {
|
|
48
|
+
enabled: false,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
credits: { enabled: false },
|
|
53
|
+
legend: {
|
|
54
|
+
enabled: false,
|
|
55
|
+
itemStyle: {
|
|
56
|
+
fontFamily: typography.font_family_base,
|
|
57
|
+
color: colors.text_lt_light,
|
|
58
|
+
fontWeight: typography.regular,
|
|
59
|
+
fontSize: typography.text_smaller,
|
|
60
|
+
},
|
|
61
|
+
itemHoverStyle: {
|
|
62
|
+
color: colors.text_lt_default,
|
|
63
|
+
},
|
|
64
|
+
itemHiddenStyle: {
|
|
65
|
+
color: colors.text_lt_lighter,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
colors: [
|
|
69
|
+
colors.data_1,
|
|
70
|
+
colors.data_2,
|
|
71
|
+
colors.data_3,
|
|
72
|
+
colors.data_4,
|
|
73
|
+
colors.data_5,
|
|
74
|
+
colors.data_6,
|
|
75
|
+
colors.data_7,
|
|
76
|
+
],
|
|
77
|
+
xAxis: {
|
|
78
|
+
gridLineWidth: 0,
|
|
79
|
+
lineColor: colors.border_light,
|
|
80
|
+
tickColor: colors.border_light,
|
|
81
|
+
labels: {
|
|
82
|
+
style: {
|
|
83
|
+
fontFamily: typography.font_family_base,
|
|
84
|
+
color: colors.text_lt_lighter,
|
|
85
|
+
fontWeight: typography.bold,
|
|
86
|
+
fontSize: typography.text_smaller,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
title: {
|
|
90
|
+
style: {
|
|
91
|
+
color: colors.text_lt_default,
|
|
92
|
+
fontFamily: typography.font_family_base,
|
|
93
|
+
fontWeight: typography.regular,
|
|
94
|
+
fontSize: typography.heading_4,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
yAxis: {
|
|
99
|
+
alternateGridColor: undefined as string | undefined,
|
|
100
|
+
minorTickInterval: null as number | null,
|
|
101
|
+
gridLineColor: colors.border_light,
|
|
102
|
+
minorGridLineColor: colors.border_light,
|
|
103
|
+
lineWidth: 0,
|
|
104
|
+
tickWidth: 0,
|
|
105
|
+
tickPixelInterval: 50,
|
|
106
|
+
labels: {
|
|
107
|
+
style: {
|
|
108
|
+
fontFamily: typography.font_family_base,
|
|
109
|
+
color: colors.text_lt_lighter,
|
|
110
|
+
fontWeight: typography.bold,
|
|
111
|
+
fontSize: typography.text_smaller,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
title: {
|
|
115
|
+
style: {
|
|
116
|
+
fontFamily: typography.font_family_base,
|
|
117
|
+
color: colors.text_lt_lighter,
|
|
118
|
+
fontWeight: typography.bold,
|
|
119
|
+
fontSize: typography.text_smaller,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export default pbLineGraphTheme;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= react_component('PbLineGraph', object.react_props) %>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Playbook
|
|
4
|
+
module PbPbLineGraph
|
|
5
|
+
class PbLineGraph < ::Playbook::KitBase
|
|
6
|
+
prop :options, default: {}
|
|
7
|
+
|
|
8
|
+
def react_props
|
|
9
|
+
{
|
|
10
|
+
className: classname,
|
|
11
|
+
data: data,
|
|
12
|
+
options: options,
|
|
13
|
+
id: id,
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def classname
|
|
18
|
+
# Highcharts react needs classname attached to the container div,
|
|
19
|
+
# we pass an empty string here to avoid conflicts, classname is built in the TSX
|
|
20
|
+
# We still need generate_classnames to retain ability to pass in custom classnames or global props
|
|
21
|
+
generate_classname("")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '../utilities/test-utils'
|
|
3
|
+
|
|
4
|
+
import { PbLineGraph } from 'playbook-ui'
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
// Silences error logs within the test suite.
|
|
8
|
+
jest.spyOn(console, 'error');
|
|
9
|
+
jest.spyOn(console, 'warn');
|
|
10
|
+
console.error.mockImplementation(() => {});
|
|
11
|
+
console.warn.mockImplementation(() => {});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
console.error.mockRestore();
|
|
16
|
+
console.warn.mockRestore();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const seriesData = [{
|
|
20
|
+
name: 'Installation',
|
|
21
|
+
data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175],
|
|
22
|
+
}, {
|
|
23
|
+
name: 'Manufacturing',
|
|
24
|
+
data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434],
|
|
25
|
+
}, {
|
|
26
|
+
name: 'Sales & Distribution',
|
|
27
|
+
data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387],
|
|
28
|
+
}, {
|
|
29
|
+
name: 'Project Development',
|
|
30
|
+
data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227],
|
|
31
|
+
}, {
|
|
32
|
+
name: 'Other',
|
|
33
|
+
data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111],
|
|
34
|
+
}]
|
|
35
|
+
|
|
36
|
+
const categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
|
37
|
+
|
|
38
|
+
const chartOptions = {
|
|
39
|
+
series: seriesData,
|
|
40
|
+
title: { text: "Solar Employment Growth by Sector, 2010-2016" },
|
|
41
|
+
subtitle: { text: "Source: thesolarfoundation.com" },
|
|
42
|
+
xAxis: {
|
|
43
|
+
categories: categories,
|
|
44
|
+
},
|
|
45
|
+
yAxis: {
|
|
46
|
+
title: {
|
|
47
|
+
text: "Number of Employees",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const testId = 'pblinegraph1';
|
|
53
|
+
|
|
54
|
+
test('Kit to exist', () => {
|
|
55
|
+
render(
|
|
56
|
+
<PbLineGraph
|
|
57
|
+
data={{testid: testId}}
|
|
58
|
+
options={chartOptions}
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
expect(screen.getByTestId(testId)).toBeInTheDocument()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('Kit to apply base classname', () => {
|
|
66
|
+
render(
|
|
67
|
+
<PbLineGraph
|
|
68
|
+
data={{testid: testId}}
|
|
69
|
+
options={chartOptions}
|
|
70
|
+
/>
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
expect(screen.getByTestId(testId)).toHaveClass('pb_pb_line_graph')
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
test('Kit to have custom class', () => {
|
|
77
|
+
render(
|
|
78
|
+
<PbLineGraph
|
|
79
|
+
className='custom-class'
|
|
80
|
+
data={{testid: testId}}
|
|
81
|
+
options={chartOptions}
|
|
82
|
+
/>
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
expect(screen.getByTestId(testId)).toHaveClass('custom-class')
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
test('Kit to apply global props', () => {
|
|
89
|
+
render(
|
|
90
|
+
<PbLineGraph
|
|
91
|
+
data={{testid: testId}}
|
|
92
|
+
margin="lg"
|
|
93
|
+
options={chartOptions}
|
|
94
|
+
/>
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
expect(screen.getByTestId(testId)).toHaveClass('m_lg')
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test('kit to apply id', () => {
|
|
101
|
+
render(
|
|
102
|
+
<PbLineGraph
|
|
103
|
+
data={{testid: testId}}
|
|
104
|
+
id='line-graph-id'
|
|
105
|
+
options={chartOptions}
|
|
106
|
+
/>
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
expect(screen.getByTestId(testId)).toHaveAttribute('id', 'line-graph-id')
|
|
110
|
+
})
|
|
@@ -111,7 +111,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
111
111
|
const inputRef = useRef<HTMLInputElement | null>(null)
|
|
112
112
|
const itiRef = useRef<any>(null);
|
|
113
113
|
const [inputValue, setInputValue] = useState(value)
|
|
114
|
-
const [error, setError] = useState(props.error)
|
|
114
|
+
const [error, setError] = useState(props.error || "")
|
|
115
115
|
const [dropDownIsOpen, setDropDownIsOpen] = useState(false)
|
|
116
116
|
const [selectedData, setSelectedData] = useState()
|
|
117
117
|
const [hasTyped, setHasTyped] = useState(false)
|
|
@@ -124,24 +124,6 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
124
124
|
}
|
|
125
125
|
}, [error, onValidate])
|
|
126
126
|
|
|
127
|
-
/*
|
|
128
|
-
useImperativeHandle exposes the kit's input element to a parent component via a ref.
|
|
129
|
-
See the Playbook docs for use cases.
|
|
130
|
-
Read: https://react.dev/reference/react/useImperativeHandle
|
|
131
|
-
*/
|
|
132
|
-
useImperativeHandle(ref, () => {
|
|
133
|
-
return {
|
|
134
|
-
clearField() {
|
|
135
|
-
setInputValue("")
|
|
136
|
-
setError("")
|
|
137
|
-
setHasTyped(false)
|
|
138
|
-
},
|
|
139
|
-
inputNode() {
|
|
140
|
-
return inputRef.current
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
})
|
|
144
|
-
|
|
145
127
|
const unformatNumber = (formattedNumber: any) => {
|
|
146
128
|
return formattedNumber.replace(/\D/g, "")
|
|
147
129
|
}
|
|
@@ -164,6 +146,13 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
164
146
|
|
|
165
147
|
const validateTooShortNumber = (itiInit: any) => {
|
|
166
148
|
if (!itiInit) return
|
|
149
|
+
|
|
150
|
+
// If field is empty, don't show "too short" error
|
|
151
|
+
if (!inputValue || inputValue.trim() === '') {
|
|
152
|
+
setError('')
|
|
153
|
+
return false
|
|
154
|
+
}
|
|
155
|
+
|
|
167
156
|
if (itiInit.getValidationError() === ValidationError.TooShort) {
|
|
168
157
|
return showFormattedError('too short')
|
|
169
158
|
} else {
|
|
@@ -183,7 +172,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
183
172
|
}
|
|
184
173
|
|
|
185
174
|
const validateUnhandledError = (itiInit: any) => {
|
|
186
|
-
if (!
|
|
175
|
+
if (!itiInit) return
|
|
187
176
|
if (itiInit.getValidationError() === ValidationError.SomethingWentWrong) {
|
|
188
177
|
if (inputValue.length === 1) {
|
|
189
178
|
return showFormattedError('too short')
|
|
@@ -206,14 +195,27 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
206
195
|
|
|
207
196
|
const validateRepeatCountryCode = (itiInit: any) => {
|
|
208
197
|
if (!itiInit) return
|
|
209
|
-
const countryDialCode =
|
|
198
|
+
const countryDialCode = itiRef.current.getSelectedCountryData().dialCode;
|
|
210
199
|
if (unformatNumber(inputValue).startsWith(countryDialCode)) {
|
|
211
200
|
return showFormattedError('repeat country code')
|
|
212
201
|
}
|
|
213
202
|
}
|
|
214
203
|
|
|
204
|
+
const validateRequiredField = () => {
|
|
205
|
+
if (!inputValue || inputValue.trim() === '') {
|
|
206
|
+
setError('Missing phone number')
|
|
207
|
+
return true
|
|
208
|
+
}
|
|
209
|
+
return false
|
|
210
|
+
}
|
|
215
211
|
|
|
216
212
|
const validateErrors = () => {
|
|
213
|
+
// If field is empty, show error message
|
|
214
|
+
if (!inputValue || inputValue.trim() === '') {
|
|
215
|
+
if (validateRequiredField()) return
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
|
|
217
219
|
if (!hasTyped && !error) return
|
|
218
220
|
|
|
219
221
|
if (itiRef.current) isValid(itiRef.current.isValidNumber())
|
|
@@ -225,20 +227,105 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
225
227
|
if (validateRepeatCountryCode(itiRef.current)) return
|
|
226
228
|
}
|
|
227
229
|
|
|
230
|
+
/*
|
|
231
|
+
useImperativeHandle exposes the kit's input element to a parent component via a ref.
|
|
232
|
+
See the Playbook docs for use cases.
|
|
233
|
+
Read: https://react.dev/reference/react/useImperativeHandle
|
|
234
|
+
*/
|
|
235
|
+
useImperativeHandle(ref, () => {
|
|
236
|
+
return {
|
|
237
|
+
clearField() {
|
|
238
|
+
setInputValue("")
|
|
239
|
+
setError("")
|
|
240
|
+
setHasTyped(false)
|
|
241
|
+
},
|
|
242
|
+
inputNode() {
|
|
243
|
+
return inputRef.current
|
|
244
|
+
},
|
|
245
|
+
// Expose validation method for React Hook Form
|
|
246
|
+
validate() {
|
|
247
|
+
// Run validation and return error message or true
|
|
248
|
+
const isEmpty = !inputValue || inputValue.trim() === ''
|
|
249
|
+
|
|
250
|
+
if (isEmpty) {
|
|
251
|
+
// Show missing phone number error
|
|
252
|
+
const errorMessage = 'Missing phone number'
|
|
253
|
+
setError(errorMessage)
|
|
254
|
+
setHasTyped(true)
|
|
255
|
+
// Only return error for React Hook Form if field is required
|
|
256
|
+
return required ? errorMessage : true
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (!itiRef.current) {
|
|
260
|
+
return true
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Check for repeat country code first
|
|
264
|
+
const countryDialCode = itiRef.current.getSelectedCountryData().dialCode;
|
|
265
|
+
if (unformatNumber(inputValue).startsWith(countryDialCode)) {
|
|
266
|
+
const countryName = itiRef.current.getSelectedCountryData().name
|
|
267
|
+
const errorMessage = `Invalid ${countryName} phone number (repeat country code)`
|
|
268
|
+
setError(errorMessage)
|
|
269
|
+
setHasTyped(true)
|
|
270
|
+
return errorMessage
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Check if it only contains valid characters
|
|
274
|
+
if (!containOnlyNumbers(inputValue)) {
|
|
275
|
+
const countryName = itiRef.current.getSelectedCountryData().name
|
|
276
|
+
const errorMessage = `Invalid ${countryName} phone number (enter numbers only)`
|
|
277
|
+
setError(errorMessage)
|
|
278
|
+
setHasTyped(true)
|
|
279
|
+
return errorMessage
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Check if valid number
|
|
283
|
+
if (!itiRef.current.isValidNumber()) {
|
|
284
|
+
const countryName = itiRef.current.getSelectedCountryData().name
|
|
285
|
+
const validationError = itiRef.current.getValidationError()
|
|
286
|
+
let errorMessage = ''
|
|
287
|
+
|
|
288
|
+
if (validationError === ValidationError.TooShort) {
|
|
289
|
+
errorMessage = `Invalid ${countryName} phone number (too short)`
|
|
290
|
+
} else if (validationError === ValidationError.TooLong) {
|
|
291
|
+
errorMessage = `Invalid ${countryName} phone number (too long)`
|
|
292
|
+
} else if (validationError === ValidationError.MissingAreaCode) {
|
|
293
|
+
errorMessage = `Invalid ${countryName} phone number (missing area code)`
|
|
294
|
+
} else {
|
|
295
|
+
errorMessage = `Invalid ${countryName} phone number`
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
setError(errorMessage)
|
|
299
|
+
setHasTyped(true)
|
|
300
|
+
|
|
301
|
+
return errorMessage
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Clear error if valid
|
|
305
|
+
setError('')
|
|
306
|
+
return true
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
})
|
|
310
|
+
|
|
228
311
|
const getCurrentSelectedData = (itiInit: any, inputValue: string) => {
|
|
229
312
|
return { ...itiInit.getSelectedCountryData(), number: inputValue }
|
|
230
313
|
}
|
|
231
314
|
|
|
232
315
|
const handleOnChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
|
|
233
316
|
if (!hasTyped) setHasTyped(true)
|
|
317
|
+
|
|
234
318
|
setInputValue(evt.target.value)
|
|
319
|
+
|
|
235
320
|
let phoneNumberData
|
|
321
|
+
|
|
236
322
|
if (formatAsYouType) {
|
|
237
323
|
const formattedPhoneNumberData = getCurrentSelectedData(itiRef.current, evt.target.value)
|
|
238
324
|
phoneNumberData = {...formattedPhoneNumberData, number: unformatNumber(formattedPhoneNumberData.number)}
|
|
239
325
|
} else {
|
|
240
326
|
phoneNumberData = getCurrentSelectedData(itiRef.current, evt.target.value)
|
|
241
327
|
}
|
|
328
|
+
|
|
242
329
|
setSelectedData(phoneNumberData)
|
|
243
330
|
onChange(phoneNumberData)
|
|
244
331
|
isValid(itiRef.current.isValidNumber())
|
|
@@ -287,11 +374,26 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
287
374
|
|
|
288
375
|
inputRef.current.addEventListener("open:countrydropdown", () => setDropDownIsOpen(true))
|
|
289
376
|
inputRef.current.addEventListener("close:countrydropdown", () => setDropDownIsOpen(false))
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
377
|
+
|
|
378
|
+
// Handle formatAsYouType with input event
|
|
379
|
+
if (formatAsYouType) {
|
|
380
|
+
inputRef.current.addEventListener("input", (evt: Event) => {
|
|
381
|
+
const target = evt.target as HTMLInputElement
|
|
382
|
+
const formattedValue = target.value
|
|
383
|
+
|
|
384
|
+
// Update internal state
|
|
385
|
+
setInputValue(formattedValue)
|
|
386
|
+
setHasTyped(true)
|
|
387
|
+
|
|
388
|
+
// Get phone number data with unformatted number
|
|
389
|
+
const formattedPhoneNumberData = getCurrentSelectedData(telInputInit, formattedValue)
|
|
390
|
+
const phoneNumberData = {...formattedPhoneNumberData, number: unformatNumber(formattedPhoneNumberData.number)}
|
|
391
|
+
|
|
392
|
+
setSelectedData(phoneNumberData)
|
|
393
|
+
onChange(phoneNumberData)
|
|
394
|
+
isValid(telInputInit.isValidNumber())
|
|
395
|
+
})
|
|
396
|
+
}
|
|
295
397
|
}
|
|
296
398
|
}, [])
|
|
297
399
|
|
|
@@ -300,13 +402,13 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
|
|
|
300
402
|
dark,
|
|
301
403
|
"data-phone-number": JSON.stringify(selectedData),
|
|
302
404
|
disabled,
|
|
303
|
-
error,
|
|
405
|
+
error: hasTyped ? error : props.error,
|
|
304
406
|
type: 'tel',
|
|
305
407
|
id,
|
|
306
408
|
label,
|
|
307
409
|
name,
|
|
308
410
|
onBlur: validateErrors,
|
|
309
|
-
onChange: handleOnChange,
|
|
411
|
+
onChange: formatAsYouType ? undefined : handleOnChange,
|
|
310
412
|
value: inputValue
|
|
311
413
|
}
|
|
312
414
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable react/no-multi-comp */
|
|
2
|
-
import React, { useEffect, useState } from "react";
|
|
2
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
3
3
|
import ReactDOM from "react-dom";
|
|
4
4
|
import {
|
|
5
5
|
Popper,
|
|
@@ -24,6 +24,7 @@ import { uniqueId } from '../utilities/object';
|
|
|
24
24
|
type ModifiedGlobalProps = Omit<GlobalProps, 'minWidth' | 'maxHeight' | 'minHeight'>
|
|
25
25
|
|
|
26
26
|
type PbPopoverProps = {
|
|
27
|
+
appendTo?: string;
|
|
27
28
|
aria?: { [key: string]: string };
|
|
28
29
|
className?: string;
|
|
29
30
|
closeOnClick?: "outside" | "inside" | "any";
|
|
@@ -62,6 +63,25 @@ const popoverModifiers = ({
|
|
|
62
63
|
return offset ? modifiers.concat([POPOVER_MODIFIERS.offset]) : modifiers;
|
|
63
64
|
};
|
|
64
65
|
|
|
66
|
+
const getAppendTarget = (
|
|
67
|
+
appendTo: string | undefined,
|
|
68
|
+
targetId: string
|
|
69
|
+
): HTMLElement => {
|
|
70
|
+
if (!appendTo || appendTo === "body") return document.body;
|
|
71
|
+
|
|
72
|
+
if (appendTo === "parent") {
|
|
73
|
+
const referenceWrapper = document.querySelector(`#reference-${targetId}`);
|
|
74
|
+
if (referenceWrapper?.parentElement) {
|
|
75
|
+
return referenceWrapper.parentElement;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const selectorMatch = document.querySelector(appendTo);
|
|
80
|
+
if (selectorMatch instanceof HTMLElement) return selectorMatch;
|
|
81
|
+
|
|
82
|
+
return document.body;
|
|
83
|
+
};
|
|
84
|
+
|
|
65
85
|
const Popover = (props: PbPopoverProps) => {
|
|
66
86
|
const {
|
|
67
87
|
aria = {},
|
|
@@ -89,7 +109,7 @@ const Popover = (props: PbPopoverProps) => {
|
|
|
89
109
|
const popoverSpacing =
|
|
90
110
|
filteredGlobalProps.includes("dark") || !filteredGlobalProps
|
|
91
111
|
? "p_sm"
|
|
92
|
-
: filteredGlobalProps
|
|
112
|
+
: filteredGlobalProps
|
|
93
113
|
const overflowHandling = maxHeight || maxWidth ? "overflow_handling" : "";
|
|
94
114
|
const zIndexStyle = zIndex ? { zIndex: zIndex } : {};
|
|
95
115
|
const widthHeightStyles = () => {
|
|
@@ -113,7 +133,7 @@ const Popover = (props: PbPopoverProps) => {
|
|
|
113
133
|
|
|
114
134
|
return (
|
|
115
135
|
<Popper
|
|
116
|
-
modifiers={popoverModifiers({ modifiers, offset })}
|
|
136
|
+
modifiers={popoverModifiers({ modifiers, offset: offset || false })}
|
|
117
137
|
placement={placement}
|
|
118
138
|
referenceElement={referenceElement}
|
|
119
139
|
>
|
|
@@ -154,6 +174,7 @@ const Popover = (props: PbPopoverProps) => {
|
|
|
154
174
|
const PbReactPopover = (props: PbPopoverProps): React.ReactElement => {
|
|
155
175
|
const [targetId] = useState(uniqueId('id-'))
|
|
156
176
|
const {
|
|
177
|
+
appendTo,
|
|
157
178
|
className,
|
|
158
179
|
children,
|
|
159
180
|
modifiers = [],
|
|
@@ -170,42 +191,56 @@ const PbReactPopover = (props: PbPopoverProps): React.ReactElement => {
|
|
|
170
191
|
minHeight,
|
|
171
192
|
minWidth,
|
|
172
193
|
width,
|
|
194
|
+
closeOnClick,
|
|
195
|
+
shouldClosePopover = noop,
|
|
173
196
|
} = props;
|
|
174
197
|
|
|
198
|
+
// Store latest callback in a ref to avoid re-runs
|
|
199
|
+
const shouldClosePopoverRef = useRef(shouldClosePopover);
|
|
200
|
+
|
|
201
|
+
// Update ref on change
|
|
175
202
|
useEffect(() => {
|
|
176
|
-
|
|
203
|
+
shouldClosePopoverRef.current = shouldClosePopover;
|
|
204
|
+
}, [shouldClosePopover]);
|
|
177
205
|
|
|
206
|
+
useEffect(() => {
|
|
178
207
|
if (!closeOnClick) return;
|
|
179
208
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
209
|
+
// Function to handle popover event listener and targetId.
|
|
210
|
+
// Ensure that whenever the component is conditionally rendered
|
|
211
|
+
// that the old listener is removed and the new listener is
|
|
212
|
+
// updated with the targetId.
|
|
213
|
+
const handleClick = (e: MouseEvent) => {
|
|
214
|
+
const target = e.target as HTMLElement
|
|
184
215
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
216
|
+
const targetIsPopover =
|
|
217
|
+
target.closest("#" + targetId) !== null;
|
|
218
|
+
const targetIsReference =
|
|
219
|
+
target.closest("#reference-" + targetId) !== null;
|
|
189
220
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
221
|
+
const shouldClose = () => {
|
|
222
|
+
setTimeout(() => shouldClosePopoverRef.current(true), 0);
|
|
223
|
+
}
|
|
193
224
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
);
|
|
208
|
-
|
|
225
|
+
switch (closeOnClick) {
|
|
226
|
+
case "outside":
|
|
227
|
+
if (!targetIsPopover && !targetIsReference) shouldClose();
|
|
228
|
+
break;
|
|
229
|
+
case "inside":
|
|
230
|
+
if (targetIsPopover) shouldClose();
|
|
231
|
+
break;
|
|
232
|
+
case "any":
|
|
233
|
+
if (targetIsPopover || !targetIsPopover && !targetIsReference) shouldClose();
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
document.body.addEventListener("click", handleClick, { capture: true });
|
|
239
|
+
|
|
240
|
+
return () => {
|
|
241
|
+
document.body.removeEventListener("click", handleClick, { capture: true });
|
|
242
|
+
};
|
|
243
|
+
}, [targetId, closeOnClick]);
|
|
209
244
|
|
|
210
245
|
const popoverComponent = (
|
|
211
246
|
<Popover
|
|
@@ -246,10 +281,10 @@ const PbReactPopover = (props: PbPopoverProps): React.ReactElement => {
|
|
|
246
281
|
{show &&
|
|
247
282
|
(usePortal ? (
|
|
248
283
|
<>
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
284
|
+
{ReactDOM.createPortal(
|
|
285
|
+
popoverComponent,
|
|
286
|
+
getAppendTarget(appendTo, targetId)
|
|
287
|
+
)}
|
|
253
288
|
</>
|
|
254
289
|
) : (
|
|
255
290
|
{ popoverComponent }
|