playbook_ui 14.8.0.pre.alpha.PLAY16254545 → 14.8.0.pre.alpha.pbntr661createstickyleftprop4612

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b2b5ad03216b06c9f37e1792a0b208efbfd3d44b79f73696e1a3b006f89228c
4
- data.tar.gz: 282f44cd7aee29b4bc0ca84396be2a914a3786e91c8b308c5e7f284b84d4d74c
3
+ metadata.gz: 447188fd32d5d83aeaf14c246e24bbb2ded7d4ef68ec21db96a48fc115a50d49
4
+ data.tar.gz: 4c1d2183a6df9ebefcb605e8aaeb52c097cdc1726c672a234237aa194b67c475
5
5
  SHA512:
6
- metadata.gz: 0b14587326a80d3f8a7663ab14df6c51720aae8ad3a3492370dd853a956292a7b80901b2782e6ea04fbdb37b38d7810490234b4396bc9c891158432c208578f4
7
- data.tar.gz: a1f50ae88764cf79258478662bd9cd294b394d8c3cbd3c96580045ba2a5a67c3d924d9ee0170daf134ca9400078c4709c18dff06ea98927392f412343b5d7216
6
+ metadata.gz: 99ea4d44f89369d8d928c441c86ebac5261bd849fda00bdb2490b209fb906232be43c480d49101c24f56c2fcacd23f662025e1dba331dd9472275e5d67040df5
7
+ data.tar.gz: b5e4d90132d0d728c6fb9c023b9ceeaf8ac64a017cdac314b5d85c774917a806540eb97dab62d7690112cbff97a395e794c271fb7375d4a3c50e6e13afe1abbc
@@ -6,12 +6,12 @@
6
6
  ) do %>
7
7
  <%= content.presence || object.input %>
8
8
  <% if object.indeterminate %>
9
- <span class="pb_checkbox_indeterminate">
9
+ <span data-pb-checkbox-icon-span="true" class="pb_checkbox_indeterminate">
10
10
  <%= pb_rails("icon", props: { icon: "minus", classname: "indeterminate_icon", fixed_width: true}) %>
11
11
  <%= pb_rails("icon", props: { icon: "check", classname: "check_icon hidden", fixed_width: true}) %>
12
12
  </span>
13
13
  <% else %>
14
- <span class="pb_checkbox_checkmark">
14
+ <span data-pb-checkbox-icon-span="true" class="pb_checkbox_checkmark">
15
15
  <%= pb_rails("icon", props: { icon: "check", classname: "check_icon", fixed_width: true}) %>
16
16
  <%= pb_rails("icon", props: { icon: "minus", classname: "indeterminate_icon hidden", fixed_width: true}) %>
17
17
  </span>
@@ -18,10 +18,6 @@ module Playbook
18
18
  prop :form_spacing, type: Playbook::Props::Boolean,
19
19
  default: false
20
20
 
21
- def checked_html
22
- checked ? "checked='true'" : nil
23
- end
24
-
25
21
  def classname
26
22
  generate_classname("pb_checkbox_kit", checked_class) + indeterminate_class + error_class
27
23
  end
@@ -1,7 +1,84 @@
1
- <%= pb_rails("checkbox" , props: {
2
- text: "Select ",
3
- value: "checkbox-value",
4
- name: "main",
5
- indeterminate: true,
6
- id: "test-indeterminate-js"
7
- }) %>
1
+ <% checkboxes = [
2
+ { name: 'Coffee', id: 'coffee', checked: false },
3
+ { name: 'Ice Cream', id: 'ice-cream', checked: false },
4
+ { name: 'Chocolate', id: 'chocolate', checked: true }
5
+ ] %>
6
+
7
+ <%= pb_rails("table", props: { container: false, size: "md" }) do %>
8
+ <thead>
9
+ <tr>
10
+ <th>
11
+ <%= pb_rails("checkbox", props: {
12
+ checked: true,
13
+ text: "Uncheck All",
14
+ value: "checkbox-value",
15
+ name: "main-checkbox",
16
+ indeterminate: true,
17
+ id: "indeterminate-checkbox"
18
+ }) %>
19
+ </th>
20
+ </tr>
21
+ </thead>
22
+
23
+ <tbody>
24
+ <% checkboxes.each do |checkbox| %>
25
+ <tr>
26
+ <td>
27
+ <%= pb_rails("checkbox", props: {
28
+ checked: checkbox[:checked],
29
+ text: checkbox[:name],
30
+ value: checkbox[:id],
31
+ name: "#{checkbox[:id]}-indeterminate-checkbox",
32
+ id: "#{checkbox[:id]}-indeterminate-checkbox",
33
+ }) %>
34
+ </td>
35
+ </tr>
36
+ <% end %>
37
+ </tbody>
38
+ <% end %>
39
+
40
+ <script>
41
+ document.addEventListener('DOMContentLoaded', function() {
42
+ const mainCheckboxWrapper = document.getElementById('indeterminate-checkbox');
43
+ const mainCheckbox = document.getElementsByName("main-checkbox")[0];
44
+ const childCheckboxes = document.querySelectorAll('input[type="checkbox"][id$="indeterminate-checkbox"]');
45
+
46
+ const updateMainCheckbox = () => {
47
+ // Count the number of checked child checkboxes
48
+ const checkedCount = Array.from(childCheckboxes).filter(cb => cb.checked).length;
49
+ // Determine if the main checkbox should be in an indeterminate state
50
+ const indeterminate = checkedCount > 0 && checkedCount < childCheckboxes.length;
51
+
52
+ // Set the main checkbox states
53
+ mainCheckbox.indeterminate = indeterminate;
54
+ mainCheckbox.checked = checkedCount > 0;
55
+
56
+ // Determine the main checkbox label based on the number of checked checkboxes
57
+ const text = checkedCount === 0 ? 'Check All' : 'Uncheck All';
58
+
59
+ // Determine the icon class to add and remove based on the number of checked checkboxes
60
+ const iconClassToAdd = checkedCount === 0 ? 'pb_checkbox_checkmark' : 'pb_checkbox_indeterminate';
61
+ const iconClassToRemove = checkedCount === 0 ? 'pb_checkbox_indeterminate' : 'pb_checkbox_checkmark';
62
+
63
+ // Update main checkbox label
64
+ mainCheckboxWrapper.getElementsByClassName('pb_body_kit')[0].textContent = text;
65
+
66
+ // Add and remove the icon class to the main checkbox wrapper
67
+ mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.add(iconClassToAdd);
68
+ mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.remove(iconClassToRemove);
69
+
70
+ // Toggle the visibility of the checkbox icon based on the indeterminate state
71
+ mainCheckboxWrapper.getElementsByClassName("indeterminate_icon")[0].classList.toggle('hidden', !indeterminate);
72
+ mainCheckboxWrapper.getElementsByClassName("check_icon")[0].classList.toggle('hidden', indeterminate);
73
+ };
74
+
75
+ mainCheckbox.addEventListener('change', function() {
76
+ childCheckboxes.forEach(cb => cb.checked = this.checked);
77
+ updateMainCheckbox();
78
+ });
79
+
80
+ childCheckboxes.forEach(cb => {
81
+ cb.addEventListener('change', updateMainCheckbox);
82
+ });
83
+ });
84
+ </script>
@@ -53,6 +53,7 @@
53
53
  }
54
54
 
55
55
  .pb_dropdown_container {
56
+ position: absolute;
56
57
  background-color: $white;
57
58
  overflow: hidden;
58
59
  box-shadow: $shadow_deep;
@@ -3,7 +3,6 @@
3
3
  class: object.classname,
4
4
  data: object.data,
5
5
  id: object.id,
6
- style: object.container_style,
7
6
  **combined_html_options) do %>
8
7
  <%= pb_rails("list", props: {ordered: false, borderless: false}) do %>
9
8
  <% if content.present? %>
@@ -7,10 +7,6 @@ module Playbook
7
7
  generate_classname("pb_dropdown_container", "close", separator: " ")
8
8
  end
9
9
 
10
- def container_style
11
- "position: absolute"
12
- end
13
-
14
10
  def data
15
11
  Hash(prop(:data)).merge(dropdown_container: true)
16
12
  end
@@ -4,11 +4,11 @@ import { buildAriaProps, buildDataProps, buildHtmlProps } from '../utilities/pro
4
4
  import { globalProps, GlobalProps } from '../utilities/globalProps'
5
5
  import PbTable from '.'
6
6
  import {
7
- TableHead,
8
- TableHeader,
9
- TableBody,
10
- TableRow,
11
- TableCell,
7
+ TableHead,
8
+ TableHeader,
9
+ TableBody,
10
+ TableRow,
11
+ TableCell,
12
12
  } from "./subcomponents";
13
13
 
14
14
  type TableProps = {
@@ -28,6 +28,7 @@ type TableProps = {
28
28
  singleLine?: boolean,
29
29
  size?: "sm" | "md" | "lg",
30
30
  sticky?: boolean,
31
+ stickyLeftcolumn?: string[],
31
32
  striped?: boolean,
32
33
  tag?: "table" | "div",
33
34
  verticalBorder?: boolean,
@@ -51,6 +52,7 @@ const Table = (props: TableProps): React.ReactElement => {
51
52
  singleLine = false,
52
53
  size = 'sm',
53
54
  sticky = false,
55
+ stickyLeftcolumn = [],
54
56
  striped = false,
55
57
  tag = 'table',
56
58
  verticalBorder = false,
@@ -76,6 +78,7 @@ const Table = (props: TableProps): React.ReactElement => {
76
78
  'single-line': singleLine,
77
79
  'no-hover': disableHover,
78
80
  'sticky-header': sticky,
81
+ 'sticky-left-column': stickyLeftcolumn,
79
82
  'striped': striped,
80
83
  [outerPaddingCss]: outerPadding !== '',
81
84
  },
@@ -85,6 +88,56 @@ const Table = (props: TableProps): React.ReactElement => {
85
88
  className
86
89
  )
87
90
 
91
+ useEffect(() => {
92
+ const handleStickyColumns = () => {
93
+ let accumulatedWidth = 0;
94
+
95
+ stickyLeftcolumn.forEach((colId, index) => {
96
+ const isLastColumn = index === stickyLeftcolumn.length - 1;
97
+ const header = document.querySelector(`th[id="${colId}"]`);
98
+ const cells = document.querySelectorAll(`td[id="${colId}"]`);
99
+
100
+ if (header) {
101
+ header.classList.add('sticky');
102
+ (header as HTMLElement).style.left = `${accumulatedWidth}px`;
103
+
104
+ if (!isLastColumn) {
105
+ header.classList.add('with-border');
106
+ header.classList.remove('sticky-shadow');
107
+ } else {
108
+ header.classList.remove('with-border');
109
+ header.classList.add('sticky-shadow');
110
+ }
111
+
112
+ accumulatedWidth += (header as HTMLElement).offsetWidth;
113
+ }
114
+
115
+ cells.forEach((cell) => {
116
+ cell.classList.add('sticky');
117
+ (cell as HTMLElement).style.left = `${accumulatedWidth - (header as HTMLElement).offsetWidth}px`;
118
+
119
+ if (!isLastColumn) {
120
+ cell.classList.add('with-border');
121
+ cell.classList.remove('sticky-shadow');
122
+ } else {
123
+ cell.classList.remove('with-border');
124
+ cell.classList.add('sticky-shadow');
125
+ }
126
+ });
127
+ });
128
+ };
129
+
130
+ setTimeout(() => {
131
+ handleStickyColumns();
132
+ }, 10);
133
+
134
+ window.addEventListener('resize', handleStickyColumns);
135
+
136
+ return () => {
137
+ window.removeEventListener('resize', handleStickyColumns);
138
+ };
139
+ }, [stickyLeftcolumn]);
140
+
88
141
  useEffect(() => {
89
142
  const instance = new PbTable()
90
143
  instance.connect()
@@ -92,26 +145,52 @@ const Table = (props: TableProps): React.ReactElement => {
92
145
 
93
146
  return (
94
147
  <>
95
- {isTableTag ? (
96
- <table
97
- {...ariaProps}
98
- {...dataProps}
99
- {...htmlProps}
100
- className={classNames}
101
- id={id}
102
- >
103
- {children}
104
- </table>
105
- ) : (
106
- <div
107
- {...ariaProps}
108
- {...dataProps}
109
- {...htmlProps}
110
- className={classNames}
111
- id={id}
112
- >
113
- {children}
148
+ {responsive === 'scroll' ? (
149
+ <div className='table-responsive-scroll'>
150
+ {isTableTag ? (
151
+ <table
152
+ {...ariaProps}
153
+ {...dataProps}
154
+ {...htmlProps}
155
+ className={classNames}
156
+ id={id}
157
+ >
158
+ {children}
159
+ </table>
160
+ ) : (
161
+ <div
162
+ {...ariaProps}
163
+ {...dataProps}
164
+ {...htmlProps}
165
+ className={classNames}
166
+ id={id}
167
+ >
168
+ {children}
169
+ </div>
170
+ )}
114
171
  </div>
172
+ ) : (
173
+ isTableTag ? (
174
+ <table
175
+ {...ariaProps}
176
+ {...dataProps}
177
+ {...htmlProps}
178
+ className={classNames}
179
+ id={id}
180
+ >
181
+ {children}
182
+ </table>
183
+ ) : (
184
+ <div
185
+ {...ariaProps}
186
+ {...dataProps}
187
+ {...htmlProps}
188
+ className={classNames}
189
+ id={id}
190
+ >
191
+ {children}
192
+ </div>
193
+ )
115
194
  )}
116
195
  </>
117
196
  )
@@ -0,0 +1,87 @@
1
+ import React from 'react'
2
+ import Table from '../_table'
3
+
4
+ const TableStickyLeftColumns = () => {
5
+ return (
6
+ <Table
7
+ responsive="scroll"
8
+ size="md"
9
+ stickyLeftcolumn={["1", "2", "3"]}
10
+ >
11
+ <thead>
12
+ <tr>
13
+ <th id="1">{'Column 1'}</th>
14
+ <th id="2">{'Column 2'}</th>
15
+ <th id="3">{'Column 3'}</th>
16
+ <th>{'Column 4'}</th>
17
+ <th>{'Column 5'}</th>
18
+ <th>{'Column 6'}</th>
19
+ <th>{'Column 7'}</th>
20
+ <th>{'Column 8'}</th>
21
+ <th>{'Column 9'}</th>
22
+ <th>{'Column 10'}</th>
23
+ <th>{'Column 11'}</th>
24
+ <th>{'Column 12'}</th>
25
+ <th>{'Column 13'}</th>
26
+ <th>{'Column 14'}</th>
27
+ <th>{'Column 15'}</th>
28
+ </tr>
29
+ </thead>
30
+ <tbody>
31
+ <tr>
32
+ <td id="1">{'Value 1'}</td>
33
+ <td id="2">{'Value 2'}</td>
34
+ <td id="3">{'Value 3'}</td>
35
+ <td>{'Value 4'}</td>
36
+ <td>{'Value 5'}</td>
37
+ <td>{'Value 6'}</td>
38
+ <td>{'Value 7'}</td>
39
+ <td>{'Value 8'}</td>
40
+ <td>{'Value 9'}</td>
41
+ <td>{'Value 10'}</td>
42
+ <td>{'Value 11'}</td>
43
+ <td>{'Value 12'}</td>
44
+ <td>{'Value 13'}</td>
45
+ <td>{'Value 14'}</td>
46
+ <td>{'Value 15'}</td>
47
+ </tr>
48
+ <tr>
49
+ <td id="1">{'Value 1'}</td>
50
+ <td id="2">{'Value 2'}</td>
51
+ <td id="3">{'Value 3'}</td>
52
+ <td>{'Value 4'}</td>
53
+ <td>{'Value 5'}</td>
54
+ <td>{'Value 6'}</td>
55
+ <td>{'Value 7'}</td>
56
+ <td>{'Value 8'}</td>
57
+ <td>{'Value 9'}</td>
58
+ <td>{'Value 10'}</td>
59
+ <td>{'Value 11'}</td>
60
+ <td>{'Value 12'}</td>
61
+ <td>{'Value 13'}</td>
62
+ <td>{'Value 14'}</td>
63
+ <td>{'Value 15'}</td>
64
+ </tr>
65
+ <tr>
66
+ <td id="1">{'Value 1'}</td>
67
+ <td id="2">{'Value 2'}</td>
68
+ <td id="3">{'Value 3'}</td>
69
+ <td>{'Value 4'}</td>
70
+ <td>{'Value 5'}</td>
71
+ <td>{'Value 6'}</td>
72
+ <td>{'Value 7'}</td>
73
+ <td>{'Value 8'}</td>
74
+ <td>{'Value 9'}</td>
75
+ <td>{'Value 10'}</td>
76
+ <td>{'Value 11'}</td>
77
+ <td>{'Value 12'}</td>
78
+ <td>{'Value 13'}</td>
79
+ <td>{'Value 14'}</td>
80
+ <td>{'Value 15'}</td>
81
+ </tr>
82
+ </tbody>
83
+ </Table>
84
+ )
85
+ }
86
+
87
+ export default TableStickyLeftColumns
@@ -0,0 +1,2 @@
1
+ The `stickyLeftColumn` prop expects an array of the column ids you want to be sticky. Make sure to add the corresponding id to the `<th>` and `<td>`.
2
+ If you are using the sub-component variant, then you will pass the id to `<Table.Header>` and `<Table.Cell>`
@@ -33,6 +33,7 @@ examples:
33
33
  - table_md: Medium
34
34
  - table_lg: Large
35
35
  - table_sticky: Sticky Header
36
+ - table_sticky_left_columns: Sticky Left Column
36
37
  - table_alignment_row: Row Alignment
37
38
  - table_alignment_column: Cell Alignment
38
39
  - table_alignment_shift_row: Row Shift
@@ -25,3 +25,4 @@ export { default as TableDiv } from './_table_div.jsx'
25
25
  export { default as TableWithSubcomponents } from './_table_with_subcomponents.jsx'
26
26
  export { default as TableWithSubcomponentsAsDivs } from './_table_with_subcomponents_as_divs.jsx'
27
27
  export { default as TableOuterPadding } from './_table_outer_padding.jsx'
28
+ export { default as TableStickyLeftColumns } from './_table_sticky_left_columns.jsx'
@@ -20,3 +20,5 @@
20
20
  @import "table_header";
21
21
  @import "striped";
22
22
  @import "outer_padding";
23
+ @import "sticky_columns";
24
+ @import "scroll";
@@ -0,0 +1,4 @@
1
+ .table-responsive-scroll {
2
+ display: block;
3
+ overflow-x: auto;
4
+ }
@@ -0,0 +1,18 @@
1
+ @import "../../tokens/colors";
2
+
3
+ [class^="pb_table"] {
4
+ .sticky {
5
+ position: sticky !important;
6
+ left: 0;
7
+ z-index: 1;
8
+ background-color: white;
9
+ }
10
+
11
+ .with-border {
12
+ border-right: 1px solid $border_light !important;
13
+ }
14
+
15
+ .sticky-shadow {
16
+ box-shadow: 4px 0 10px rgba(60, 106, 172, 0.16) !important;
17
+ }
18
+ }