playbook_ui 16.9.0.pre.rc.2 → 16.9.0.pre.rc.3

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 (25) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_scroll_limitation.jsx +68 -0
  3. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_scroll_limitation.md +7 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -0
  5. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +1 -0
  6. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +36 -21
  7. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_dialog_submission.jsx +2 -2
  8. data/app/pb_kits/playbook/pb_icon/_icon.scss +2 -1
  9. data/app/pb_kits/playbook/pb_icon/docs/example.yml +0 -2
  10. data/app/pb_kits/playbook/pb_icon/docs/index.js +0 -1
  11. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_centered_data.html.erb +90 -0
  12. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_centered_data.jsx +100 -0
  13. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_centered_data.md +1 -0
  14. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_default.jsx +1 -1
  15. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/example.yml +2 -0
  16. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/index.js +2 -1
  17. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_external_filter_rails.md +1 -1
  18. data/app/pb_kits/playbook/pb_text_input/_text_input.scss +37 -0
  19. data/dist/menu.yml +1 -1
  20. data/dist/playbook.css +1 -1
  21. data/lib/playbook/version.rb +1 -1
  22. metadata +7 -5
  23. data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.html.erb +0 -1
  24. data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.jsx +0 -21
  25. data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.md +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 767e8550794164361093c1a0d6af22791b7a0a1662e680535494704ba4c08210
4
- data.tar.gz: 83c41c8410774f11eb7e314e140a25a6b0f016120fa6b5fb73fe3e24af84e376
3
+ metadata.gz: d9aa05ce18cdb9f381d5d2c4a2e18a63d9513a3641eb081d672d6613cfdbf07b
4
+ data.tar.gz: 68d67cb7ac4c1af97301482014d063f795ecee5c97f8a3927788edb770e3d8b5
5
5
  SHA512:
6
- metadata.gz: 8d45b541fb4afce34a9e6c14dc71dff2426a3a802e02ac56fd1923a226abbfd706e1c8ca2ad5f58a35efdc1f370f2d46852f9ee70da3aec57ceb9c1330a87348
7
- data.tar.gz: 17987cc62b5d10f84cbacacd4f9759641e6fa0d362131ac373771b9e51e896ade7e5fb70846c969df926564195f5f7da9e1d8d59a1ef752667fcfd6b8bb276cf
6
+ metadata.gz: 100d25619305677ab8bc5ce3642bca116ae21421224300bc9de0d1deeb0225d2c694ee516e1d18c6fc5a4c7d711538d5e6092e53b4d09857800c15e7084f5096
7
+ data.tar.gz: 596fd4c60ea8792268c8e64c0a6c598c8e19e6533a8b82d86c41c08d293f8e6885ede170f0418d83c201e97d182104dd246eb226439e1396808d5b9768848b50
@@ -0,0 +1,68 @@
1
+ import React from "react"
2
+ import AdvancedTable from "../../pb_advanced_table/_advanced_table"
3
+ import Title from "../../pb_title/_title"
4
+
5
+ const COLUMN_COUNT = 10
6
+ const ROW_COUNT = 40
7
+
8
+ const columnDefinitions = [
9
+ {
10
+ accessor: "region",
11
+ label: "Region",
12
+ id: "region",
13
+ columnStyling: { minWidth: 160 },
14
+ },
15
+ ...Array.from({ length: COLUMN_COUNT }, (_, index) => ({
16
+ accessor: `metric${index + 1}`,
17
+ label: `Metric ${index + 1}`,
18
+ id: `metric${index + 1}`,
19
+ columnStyling: { minWidth: 180 },
20
+ })),
21
+ ]
22
+
23
+ const tableData = Array.from({ length: ROW_COUNT }, (_, row) => ({
24
+ region: `Region ${row + 1}`,
25
+ ...Object.fromEntries(
26
+ Array.from({ length: COLUMN_COUNT }, (_, col) => [
27
+ `metric${col + 1}`,
28
+ String((row + 1) * (col + 1)),
29
+ ])
30
+ ),
31
+ }))
32
+
33
+ const tableProps = { sticky: true }
34
+
35
+ const AdvancedTableStickyScrollLimitation = (props) => (
36
+ <div>
37
+ <Title
38
+ size={4}
39
+ text="Without maxHeight"
40
+ {...props}
41
+ />
42
+ <AdvancedTable
43
+ columnDefinitions={columnDefinitions}
44
+ responsive="none"
45
+ stickyLeftColumn={["region"]}
46
+ tableData={tableData}
47
+ tableProps={tableProps}
48
+ {...props}
49
+ />
50
+ <Title
51
+ paddingTop="sm"
52
+ size={4}
53
+ text="With maxHeight"
54
+ {...props}
55
+ />
56
+ <AdvancedTable
57
+ columnDefinitions={columnDefinitions}
58
+ maxHeight="sm"
59
+ responsive="none"
60
+ stickyLeftColumn={["region"]}
61
+ tableData={tableData}
62
+ tableProps={tableProps}
63
+ {...props}
64
+ />
65
+ </div>
66
+ )
67
+
68
+ export default AdvancedTableStickyScrollLimitation
@@ -0,0 +1,7 @@
1
+ `stickyLeftColumn` adds horizontal overflow to the table wrapper. Without `maxHeight`, the page scrolls vertically while the table scrolls horizontally — two scroll containers.
2
+
3
+ Sticky columns work in that setup, but the sticky header cannot stick to the page. Scroll down on the page, then scroll the first table horizontally to see the conflict.
4
+
5
+ The second table uses `maxHeight` so both axes share one scroll container. The header sticks to the top of the table box instead of the page.
6
+
7
+ For a typical implementation with subrows, see [Sticky Columns with Sticky Header](#sticky-columns-with-sticky-header).
@@ -52,6 +52,7 @@ examples:
52
52
  - advanced_table_table_props_sticky_header: Sticky Header for Responsive Table
53
53
  - advanced_table_sticky_columns: Sticky Columns
54
54
  - advanced_table_sticky_columns_and_header: Sticky Columns with Sticky Header
55
+ - advanced_table_sticky_scroll_limitation: Sticky Header and Column Scroll Limitation
55
56
  - advanced_table_responsive: Responsive Tables
56
57
  - advanced_table_custom_cell: Custom Components for Cells
57
58
  - advanced_table_with_custom_header: Custom Header Cell
@@ -27,6 +27,7 @@ export { default as AdvancedTableFullscreen } from './_advanced_table_fullscreen
27
27
  export { default as AdvancedTableStickyColumns } from './_advanced_table_sticky_columns.jsx'
28
28
  export { default as AdvancedTableStickyHeader } from './_advanced_table_sticky_header.jsx'
29
29
  export { default as AdvancedTableStickyColumnsAndHeader } from './_advanced_table_sticky_columns_and_header.jsx'
30
+ export { default as AdvancedTableStickyScrollLimitation } from './_advanced_table_sticky_scroll_limitation.jsx'
30
31
  export { default as AdvancedTableExpandByDepth } from './_advanced_table_expand_by_depth.jsx'
31
32
  export { default as AdvancedTableColumnBorderColor} from './_advanced_table_column_border_color.jsx'
32
33
  export { default as AdvancedTableColumnVisibility } from './_advanced_table_column_visibility.jsx'
@@ -79,42 +79,57 @@
79
79
 
80
80
  <%= javascript_tag do %>
81
81
  (function() {
82
+ const initQuickPickChangeListener = (input) => {
83
+ if (!<%= object.selection_type == "quickpick" %>) return
84
+ if (input.dataset.quickpickInitialized) return
85
+
86
+ input.dataset.quickpickInitialized = "true"
87
+ input.addEventListener("change", ({ target }) => {
88
+ const startDate = document.getElementById("<%= object.start_date_id %>")
89
+ const endDate = document.getElementById("<%= object.end_date_id %>")
90
+ const splittedValue = target.value.split(" to ")
91
+ startDate.value = splittedValue[0]
92
+ endDate.value = splittedValue[1] ? splittedValue[1] : splittedValue[0]
93
+ })
94
+ }
95
+
82
96
  const loadDatePicker = () => {
83
- const input = document.getElementById("<%= object.picker_id %>");
84
- if (input && !input._flatpickr) {
85
- datePickerHelper(<%= object.date_picker_config %>, "<%= object.scroll_container %>")
97
+ const input = document.getElementById("<%= object.picker_id %>")
98
+
99
+ if (!input || input._flatpickr) return true
100
+ if (typeof window.datePickerHelper !== "function") return false
86
101
 
87
- if (<%= object.selection_type == "quickpick" %>) {
88
- document.getElementById("<%= object.picker_id %>").addEventListener("change", ({ target }) => {
89
- const startDate = document.getElementById("<%= object.start_date_id %>")
90
- const endDate = document.getElementById("<%= object.end_date_id %>")
91
- const splittedValue = target.value.split(" to ")
92
- startDate.value = splittedValue[0]
93
- endDate.value = splittedValue[1] ? splittedValue[1] : splittedValue[0]
94
- })
95
- }
102
+ window.datePickerHelper(<%= object.date_picker_config %>, "<%= object.scroll_container %>")
103
+ initQuickPickChangeListener(input)
104
+
105
+ return true
106
+ }
107
+
108
+ let attempts = 0
109
+ const retryLoad = () => {
110
+ if (loadDatePicker()) return
111
+
112
+ if (attempts++ < 20) {
113
+ setTimeout(retryLoad, 100)
96
114
  }
97
115
  }
98
116
 
99
- // Try to initialize immediately if DOM is ready
100
117
  if (document.readyState === "loading") {
101
- window.addEventListener("DOMContentLoaded", loadDatePicker)
118
+ window.addEventListener("DOMContentLoaded", retryLoad)
102
119
  } else {
103
- loadDatePicker()
120
+ retryLoad()
104
121
  }
105
122
 
106
123
  // For dynamically added content (modals, etc.), check again after a brief delay
107
124
  setTimeout(() => {
108
- const input = document.getElementById("<%= object.picker_id %>");
125
+ const input = document.getElementById("<%= object.picker_id %>")
109
126
  if (input && !input._flatpickr) {
110
- loadDatePicker();
127
+ retryLoad()
111
128
  }
112
- }, 100);
129
+ }, 100)
113
130
 
114
131
  if (<%= !object.custom_event_type.empty? %>) {
115
- window.addEventListener("<%= object.custom_event_type %>", () => {
116
- loadDatePicker()
117
- })
132
+ window.addEventListener("<%= object.custom_event_type %>", retryLoad)
118
133
  }
119
134
  })()
120
135
  <% end %>
@@ -36,10 +36,10 @@ const DatePickerDialogSubmission = () => {
36
36
  <Dialog.Body>
37
37
  <DatePicker
38
38
  defaultDate={dateFixed || undefined}
39
- key={`fixed-${pickerInstance}`}
39
+ key={"fixed-" + pickerInstance}
40
40
  label="Date"
41
41
  onChange={(dateStr) => setDateFixed(dateStr || "")}
42
- pickerId={`datePickerFixed-${pickerInstance}`}
42
+ pickerId={"datePickerFixed-" + pickerInstance}
43
43
  staticPosition={false}
44
44
  />
45
45
  </Dialog.Body>
@@ -69,9 +69,10 @@ svg {
69
69
  transform: scaleX(-1) scaleY(-1);
70
70
  }
71
71
  &.svg-inline--fa {
72
+ box-sizing: content-box;
72
73
  height: 1em;
73
74
  overflow: visible;
74
- vertical-align: -.125em
75
+ vertical-align: -.125em;
75
76
  }
76
77
  &.svg_inverse {
77
78
  color: #fff;
@@ -8,7 +8,6 @@ examples:
8
8
  - icon_border: Icon Border
9
9
  - icon_sizes: Icon Sizes
10
10
  - icon_custom: Icon Custom
11
- - icon_fa_kit: Icon with FontAwesome Kit
12
11
  - icon_color: Icon Color
13
12
 
14
13
  react:
@@ -20,7 +19,6 @@ examples:
20
19
  - icon_border: Icon Border
21
20
  - icon_sizes: Icon Sizes
22
21
  - icon_custom: Icon Custom
23
- - icon_fa_kit: Icon with FontAwesome Kit
24
22
  - icon_color: Icon Color
25
23
 
26
24
  swift:
@@ -6,5 +6,4 @@ export { default as IconPull } from './_icon_pull.jsx'
6
6
  export { default as IconBorder } from './_icon_border.jsx'
7
7
  export { default as IconSizes } from './_icon_sizes.jsx'
8
8
  export { default as IconCustom } from './_icon_custom.jsx'
9
- export { default as IconFaKit} from './_icon_fa_kit.jsx'
10
9
  export { default as IconColor } from './_icon_color.jsx'
@@ -0,0 +1,90 @@
1
+ <% data = [
2
+ {
3
+ name: "EV",
4
+ y: 23.9,
5
+ },
6
+ {
7
+ name: "Hybrids",
8
+ y: 12.6,
9
+ },
10
+ {
11
+ name: "Diesel",
12
+ y: 37.0,
13
+ },
14
+ {
15
+ name: "Petrol",
16
+ y: 26.4,
17
+ },
18
+ ] %>
19
+
20
+ <% total = data.sum { |point| point[:y] } %>
21
+ <% subtitle_rows = data.map { |point| "#{point[:name]}: #{point[:y]}%" }.join("<br>") %>
22
+
23
+ <% chart_options = {
24
+ chart: {
25
+ type: "pie",
26
+ },
27
+ accessibility: {
28
+ point: {
29
+ valueSuffix: "%",
30
+ },
31
+ },
32
+ title: {
33
+ text: "2023 Norway car registrations",
34
+ floating: true,
35
+ align: "center",
36
+ verticalAlign: "top",
37
+ y: 8,
38
+ },
39
+ subtitle: {
40
+ text: "Total<br><strong>#{total.round(1)}</strong><br><br>#{subtitle_rows}",
41
+ useHTML: true,
42
+ floating: true,
43
+ align: "center",
44
+ verticalAlign: "middle",
45
+ y: 8,
46
+ style: {
47
+ textAlign: "center",
48
+ },
49
+ },
50
+ tooltip: {
51
+ pointFormat: "{series.name}: <b>{point.percentage:.0f}%</b>",
52
+ },
53
+ legend: {
54
+ enabled: false,
55
+ },
56
+ plotOptions: {
57
+ series: {
58
+ allowPointSelect: true,
59
+ cursor: "pointer",
60
+ borderRadius: 8,
61
+ dataLabels: [
62
+ {
63
+ enabled: true,
64
+ distance: 20,
65
+ format: "{point.name}",
66
+ },
67
+ {
68
+ enabled: true,
69
+ distance: -15,
70
+ format: "{point.percentage:.0f}%",
71
+ style: {
72
+ fontSize: "0.9em",
73
+ },
74
+ },
75
+ ],
76
+ showInLegend: true,
77
+ },
78
+ },
79
+ series: [
80
+ {
81
+ name: "Registrations",
82
+ colorByPoint: true,
83
+ center: ["50%", "50%"],
84
+ innerSize: "75%",
85
+ data: data,
86
+ },
87
+ ],
88
+ } %>
89
+
90
+ <%= pb_rails("pb_circle_chart", props: { options: chart_options }) %>
@@ -0,0 +1,100 @@
1
+ import React from "react";
2
+ import PbCircleChart from "../_pb_circle_chart";
3
+
4
+ const data = [
5
+ {
6
+ name: "EV",
7
+ y: 23.9,
8
+ },
9
+ {
10
+ name: "Hybrids",
11
+ y: 12.6,
12
+ },
13
+ {
14
+ name: "Diesel",
15
+ y: 37.0,
16
+ },
17
+ {
18
+ name: "Petrol",
19
+ y: 26.4,
20
+ },
21
+ ];
22
+
23
+ const total = data.reduce((sum, point) => sum + point.y, 0);
24
+ const subtitleRows = data.map((point) => `${point.name}: ${point.y}%`).join("<br>");
25
+
26
+ const chartOptions = {
27
+ chart: {
28
+ type: "pie",
29
+ },
30
+ accessibility: {
31
+ point: {
32
+ valueSuffix: "%",
33
+ },
34
+ },
35
+ title: {
36
+ text: "2023 Norway car registrations",
37
+ floating: true,
38
+ align: "center",
39
+ verticalAlign: "top",
40
+ y: 8,
41
+ },
42
+ subtitle: {
43
+ text: `Total<br><strong>${total.toFixed(1)}</strong><br><br>${subtitleRows}`,
44
+ useHTML: true,
45
+ floating: true,
46
+ align: "center",
47
+ verticalAlign: "middle",
48
+ y: 8,
49
+ style: {
50
+ textAlign: "center",
51
+ },
52
+ },
53
+ tooltip: {
54
+ pointFormat: "{series.name}: <b>{point.percentage:.0f}%</b>",
55
+ },
56
+ legend: {
57
+ enabled: false,
58
+ },
59
+ plotOptions: {
60
+ series: {
61
+ allowPointSelect: true,
62
+ cursor: "pointer",
63
+ borderRadius: 8,
64
+ dataLabels: [
65
+ {
66
+ enabled: true,
67
+ distance: 20,
68
+ format: "{point.name}",
69
+ },
70
+ {
71
+ enabled: true,
72
+ distance: -15,
73
+ format: "{point.percentage:.0f}%",
74
+ style: {
75
+ fontSize: "0.9em",
76
+ },
77
+ },
78
+ ],
79
+ showInLegend: true,
80
+ },
81
+ },
82
+ series: [
83
+ {
84
+ name: "Registrations",
85
+ colorByPoint: true,
86
+ center: ["50%", "50%"],
87
+ innerSize: "75%",
88
+ data,
89
+ },
90
+ ],
91
+ };
92
+
93
+ const PbCircleChartCenteredData = (props) => (
94
+ <PbCircleChart
95
+ options={chartOptions}
96
+ {...props}
97
+ />
98
+ );
99
+
100
+ export default PbCircleChartCenteredData;
@@ -0,0 +1 @@
1
+ This example shows how to achieve centered data. This data will remain in the center of all screen sizes.
@@ -30,4 +30,4 @@ const PbCircleChartDefault = (props) => (
30
30
  </div>
31
31
  );
32
32
 
33
- export default PbCircleChartDefault;
33
+ export default PbCircleChartDefault;
@@ -11,6 +11,7 @@ examples:
11
11
  - pb_circle_chart_with_title: With Title
12
12
  - pb_circle_chart_inner_sizes: Inner Circle Size Options
13
13
  - pb_circle_chart_custom_tooltip: Tooltip Customization
14
+ - pb_circle_chart_centered_data: Centered Data
14
15
 
15
16
 
16
17
  react:
@@ -25,5 +26,6 @@ examples:
25
26
  - pb_circle_chart_with_title: With Title
26
27
  - pb_circle_chart_inner_sizes: Inner Circle Size Options
27
28
  - pb_circle_chart_custom_tooltip: Tooltip Customization
29
+ - pb_circle_chart_centered_data: Centered Data
28
30
 
29
31
 
@@ -8,4 +8,5 @@ export { default as PbCircleChartDataWithLegend } from './_pb_circle_chart_data_
8
8
  export { default as PbCircleChartDataLegendPosition } from './_pb_circle_chart_data_legend_position.jsx'
9
9
  export { default as PbCircleChartWithTitle } from './_pb_circle_chart_with_title.jsx'
10
10
  export { default as PbCircleChartInnerSizes } from './_pb_circle_chart_inner_sizes.jsx'
11
- export { default as PbCircleChartCustomTooltip } from './_pb_circle_chart_custom_tooltip.jsx'
11
+ export { default as PbCircleChartCustomTooltip } from './_pb_circle_chart_custom_tooltip.jsx'
12
+ export { default as PbCircleChartCenteredData } from './_pb_circle_chart_centered_data.jsx'
@@ -36,4 +36,4 @@ When `filter` is present, `filter_content` and `filter_props` are ignored.
36
36
  <% end %>
37
37
  ```
38
38
 
39
- For Nitro apps that use a shared search/filter pattern, reference the example on Alpha for implementation details.
39
+ For Nitro apps that use a shared search/filter pattern, reference the [example on Alpha](https://github.com/powerhome/nitro-web/pull/56859/changes/aa2afcdc97d39d74beb65cf53eb3bb2517eb2181) for implementation details.
@@ -100,6 +100,29 @@
100
100
  color: $input_text_disabled_dark;
101
101
  }
102
102
  }
103
+
104
+ .text_input_wrapper_add_on {
105
+ &:has(input:disabled),
106
+ &:has(.text_input:disabled) {
107
+ .add-on-card,
108
+ .add-on-card-dark {
109
+ border-color: $input_border_disabled_dark;
110
+ background-color: $input_background_disabled_dark;
111
+ }
112
+
113
+ .add-on-icon {
114
+ color: $input_text_disabled_dark;
115
+ }
116
+
117
+ .text_input:focus ~ .add-on-card-dark,
118
+ input:focus ~ .add-on-card-dark {
119
+ background-color: $input_background_disabled_dark;
120
+ border-color: $input_border_disabled_dark;
121
+ border-width: 1px;
122
+ }
123
+ }
124
+ }
125
+
103
126
  &.error {
104
127
  .text_input_wrapper {
105
128
  // The `:not` here prevents error styling from affecting the country search input in the Phone Number Input Kit.
@@ -192,6 +215,20 @@
192
215
  }
193
216
  }
194
217
  }
218
+ &:not(.dark) .text_input_wrapper_add_on {
219
+ &:has(input:disabled),
220
+ &:has(.text_input:disabled) {
221
+ .add-on-card {
222
+ border-color: $input_border_disabled;
223
+ background-color: $input_background_disabled;
224
+ }
225
+
226
+ .add-on-icon {
227
+ color: $input_text_disabled;
228
+ }
229
+ }
230
+ }
231
+
195
232
  &.inline {
196
233
  .text_input_wrapper input::placeholder,
197
234
  .text_input_wrapper .text_input .placeholder {
data/dist/menu.yml CHANGED
@@ -80,7 +80,7 @@ kits:
80
80
  - name: layout_&_positioning
81
81
  description: Scroll, sticky headers/columns, responsive layout, fullscreen modes.
82
82
  parent: advanced_table
83
- kit_section: ["Sticky Header", "Sticky Header for Responsive Table", "Sticky Columns", "Sticky Columns with Sticky Header", "Responsive Tables", "Fullscreen", "Advanced Table Scrollbar None"]
83
+ kit_section: ["Sticky Header", "Sticky Header for Responsive Table", "Sticky Columns", "Sticky Columns with Sticky Header", "Sticky Header and Column Scroll Limitation", "Responsive Tables", "Fullscreen", "Advanced Table Scrollbar None"]
84
84
  platforms: *1
85
85
  status: stable
86
86
  icons_used: true