playbook_ui 14.20.0.pre.alpha.PLAY2178advancedtablerowpinning7978 → 14.20.0.pre.alpha.PLAY2214checkboxhiddeninput8052
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/pb_advanced_table/Components/RegularTableView.tsx +79 -89
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +4 -1
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +8 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +5 -2
- data/app/pb_kits/playbook/pb_advanced_table/index.js +2 -0
- data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +4 -11
- data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +28 -7
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_custom.html.erb +1 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_custom_rails.md +1 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_form.html.erb +22 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_form.md +5 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate.html.erb +2 -48
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate_rails.md +1 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_options.html.erb +1 -0
- data/app/pb_kits/playbook/pb_checkbox/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_checkbox/index.js +56 -0
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +17 -58
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +12 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_close_on_select.jsx +42 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_close_on_select.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_dropdown/index.js +24 -0
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +14 -10
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +26 -15
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -1
- data/app/pb_kits/playbook/pb_popover/index.ts +9 -4
- data/app/pb_kits/playbook/pb_table/docs/_table_with_selectable_rows.html.erb +3 -51
- data/app/pb_kits/playbook/pb_table/styles/_mobile_collapse.scss +1 -1
- data/dist/chunks/{_typeahead-CRW6dJbW.js → _typeahead-CoOpeYom.js} +1 -1
- data/dist/chunks/_weekday_stacked-BppvLxTS.js +45 -0
- data/dist/chunks/{lib-D5R1BjUn.js → lib-D7Va7yqa.js} +1 -1
- data/dist/chunks/{pb_form_validation-BZ2AVAi_.js → pb_form_validation-DSkdRDMf.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +1 -1
- 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/version.rb +1 -1
- metadata +13 -6
- data/dist/chunks/_weekday_stacked-yWpUc_c0.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: 7ccd5f34dd1f2a70f68d8c16e9209ace9bd33d53b7952e0a01a6923c3f89552e
|
4
|
+
data.tar.gz: 43ebf8006b68996baadd8f823d964ef2908c8890bb5d7914d3102910af7c154a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f36f96c61a5b520710754222b4b8bcc111ac2ee5d5b62137f99e1e033f86601c0fed765c36d6b15a44bf40f345b3f299a8e611fd7fc80e40eeebd87ffea9dfa6
|
7
|
+
data.tar.gz: df815bdc4cdac84fc2fcb215e0c304f7656a01eb9e4260677fe3eff97ede106c2ff586ce428cb4fc9b1f5ccf5f044a645da5796ad4131276d54899ed650d2041
|
@@ -19,6 +19,71 @@ type RegularTableViewProps = {
|
|
19
19
|
subRowHeaders?: string[]
|
20
20
|
}
|
21
21
|
|
22
|
+
// Helper function for Table Rendering
|
23
|
+
const TableCellRenderer = ({
|
24
|
+
row,
|
25
|
+
collapsibleTrail = true,
|
26
|
+
loading = false,
|
27
|
+
stickyLeftColumn,
|
28
|
+
columnPinning
|
29
|
+
}: {
|
30
|
+
row: Row<GenericObject>
|
31
|
+
collapsibleTrail?: boolean
|
32
|
+
loading?: boolean | string
|
33
|
+
stickyLeftColumn?: string[]
|
34
|
+
columnPinning: { left: string[] }
|
35
|
+
}) => {
|
36
|
+
return (
|
37
|
+
<>
|
38
|
+
{row.getVisibleCells().map((cell: Cell<GenericObject, unknown>, i: number) => {
|
39
|
+
const isPinnedLeft = columnPinning.left.includes(cell.column.id);
|
40
|
+
const isLastCell = (() => {
|
41
|
+
const parent = cell.column.parent;
|
42
|
+
if (!parent) {
|
43
|
+
const last = row.getVisibleCells().at(-1);
|
44
|
+
return last?.column.id === cell.column.id;
|
45
|
+
}
|
46
|
+
|
47
|
+
const visibleSiblings = parent.columns.filter(col => col.getIsVisible());
|
48
|
+
return visibleSiblings.at(-1)?.id === cell.column.id;
|
49
|
+
})();
|
50
|
+
|
51
|
+
const { column } = cell;
|
52
|
+
|
53
|
+
return (
|
54
|
+
<td
|
55
|
+
align="right"
|
56
|
+
className={classnames(
|
57
|
+
`${cell.id}-cell position_relative`,
|
58
|
+
isChrome() ? "chrome-styles" : "",
|
59
|
+
isPinnedLeft && 'pinned-left',
|
60
|
+
stickyLeftColumn && stickyLeftColumn.length > 0 && isPinnedLeft && 'sticky-left',
|
61
|
+
isLastCell && 'last-cell',
|
62
|
+
)}
|
63
|
+
key={`${cell.id}-data`}
|
64
|
+
style={{
|
65
|
+
left: isPinnedLeft
|
66
|
+
? i === 1 // Accounting for set min-width for first column
|
67
|
+
? '180px'
|
68
|
+
: `${column.getStart("left")}px`
|
69
|
+
: undefined,
|
70
|
+
}}
|
71
|
+
>
|
72
|
+
{collapsibleTrail && i === 0 && row.depth > 0 && renderCollapsibleTrail(row.depth)}
|
73
|
+
<span id={`${cell.id}-span`}>
|
74
|
+
{loading ? (
|
75
|
+
<LoadingCell />
|
76
|
+
) : (
|
77
|
+
flexRender(cell.column.columnDef.cell, cell.getContext())
|
78
|
+
)}
|
79
|
+
</span>
|
80
|
+
</td>
|
81
|
+
);
|
82
|
+
})}
|
83
|
+
</>
|
84
|
+
)
|
85
|
+
}
|
86
|
+
|
22
87
|
export const RegularTableView = ({
|
23
88
|
collapsibleTrail = true,
|
24
89
|
subRowHeaders,
|
@@ -70,50 +135,13 @@ export const RegularTableView = ({
|
|
70
135
|
zIndex: '3'
|
71
136
|
}}
|
72
137
|
>
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
}
|
81
|
-
|
82
|
-
const visibleSiblings = parent.columns.filter(col => col.getIsVisible());
|
83
|
-
return visibleSiblings.at(-1)?.id === cell.column.id;
|
84
|
-
})();
|
85
|
-
|
86
|
-
const { column } = cell;
|
87
|
-
return (
|
88
|
-
<td
|
89
|
-
align="right"
|
90
|
-
className={classnames(
|
91
|
-
`${cell.id}-cell position_relative`,
|
92
|
-
isChrome() ? "chrome-styles" : "",
|
93
|
-
isPinnedLeft && 'pinned-left',
|
94
|
-
stickyLeftColumn && stickyLeftColumn.length > 0 && isPinnedLeft && 'sticky-left',
|
95
|
-
isLastCell && 'last-cell',
|
96
|
-
)}
|
97
|
-
key={`${cell.id}-data`}
|
98
|
-
style={{
|
99
|
-
left: isPinnedLeft
|
100
|
-
? i === 1 //Accounting for set min-width for first column
|
101
|
-
? '180px'
|
102
|
-
: `${column.getStart("left")}px`
|
103
|
-
: undefined,
|
104
|
-
}}
|
105
|
-
>
|
106
|
-
{collapsibleTrail && i === 0 && row.depth > 0 && renderCollapsibleTrail(row.depth)}
|
107
|
-
<span id={`${cell.id}-span`}>
|
108
|
-
{loading ? (
|
109
|
-
<LoadingCell />
|
110
|
-
) : (
|
111
|
-
flexRender(cell.column.columnDef.cell, cell.getContext())
|
112
|
-
)}
|
113
|
-
</span>
|
114
|
-
</td>
|
115
|
-
);
|
116
|
-
})}
|
138
|
+
<TableCellRenderer
|
139
|
+
collapsibleTrail={collapsibleTrail}
|
140
|
+
columnPinning={columnPinning}
|
141
|
+
loading={loading}
|
142
|
+
row={row}
|
143
|
+
stickyLeftColumn={stickyLeftColumn}
|
144
|
+
/>
|
117
145
|
</tr>
|
118
146
|
)
|
119
147
|
}
|
@@ -167,51 +195,13 @@ export const RegularTableView = ({
|
|
167
195
|
/>
|
168
196
|
</td>
|
169
197
|
)}
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
return last?.column.id === cell.column.id;
|
178
|
-
}
|
179
|
-
|
180
|
-
const visibleSiblings = parent.columns.filter(col => col.getIsVisible());
|
181
|
-
return visibleSiblings.at(-1)?.id === cell.column.id;
|
182
|
-
})();
|
183
|
-
|
184
|
-
const { column } = cell;
|
185
|
-
return (
|
186
|
-
<td
|
187
|
-
align="right"
|
188
|
-
className={classnames(
|
189
|
-
`${cell.id}-cell position_relative`,
|
190
|
-
isChrome() ? "chrome-styles" : "",
|
191
|
-
isPinnedLeft && 'pinned-left',
|
192
|
-
stickyLeftColumn && stickyLeftColumn.length > 0 && isPinnedLeft && 'sticky-left',
|
193
|
-
isLastCell && 'last-cell',
|
194
|
-
)}
|
195
|
-
key={`${cell.id}-data`}
|
196
|
-
style={{
|
197
|
-
left: isPinnedLeft
|
198
|
-
? i === 1 //Accounting for set min-width for first column
|
199
|
-
? '180px'
|
200
|
-
: `${column.getStart("left")}px`
|
201
|
-
: undefined,
|
202
|
-
}}
|
203
|
-
>
|
204
|
-
{collapsibleTrail && i === 0 && row.depth > 0 && renderCollapsibleTrail(row.depth)}
|
205
|
-
<span id={`${cell.id}-span`}>
|
206
|
-
{loading ? (
|
207
|
-
<LoadingCell />
|
208
|
-
) : (
|
209
|
-
flexRender(cell.column.columnDef.cell, cell.getContext())
|
210
|
-
)}
|
211
|
-
</span>
|
212
|
-
</td>
|
213
|
-
);
|
214
|
-
})}
|
198
|
+
<TableCellRenderer
|
199
|
+
collapsibleTrail={collapsibleTrail}
|
200
|
+
columnPinning={columnPinning}
|
201
|
+
loading={loading}
|
202
|
+
row={row}
|
203
|
+
stickyLeftColumn={stickyLeftColumn}
|
204
|
+
/>
|
215
205
|
</tr>
|
216
206
|
|
217
207
|
{/* Display LoadingInline if Row Data is querying and there are no children already */}
|
@@ -24,7 +24,10 @@ interface UseTableStateProps {
|
|
24
24
|
loading?: boolean | string;
|
25
25
|
pagination?: boolean;
|
26
26
|
paginationProps?: GenericObject;
|
27
|
-
pinnedRows?:
|
27
|
+
pinnedRows?: {
|
28
|
+
value?: RowPinningState;
|
29
|
+
onChange?: (value: RowPinningState) => void;
|
30
|
+
};
|
28
31
|
virtualizedRows?: boolean;
|
29
32
|
tableOptions?: GenericObject;
|
30
33
|
onRowSelectionChange?: (arg: RowSelectionState) => void;
|
@@ -368,6 +368,10 @@
|
|
368
368
|
box-shadow: 1px 0px 0px 0px var(--column-border-color) !important;
|
369
369
|
}
|
370
370
|
|
371
|
+
.pb_table_td:nth-child(2) {
|
372
|
+
box-shadow: inset 1px 0px 0px 0px var(--column-border-color) !important;
|
373
|
+
}
|
374
|
+
|
371
375
|
// Color for collapsible trail
|
372
376
|
.collapsible-trail {
|
373
377
|
background-color: $border_light !important;
|
@@ -564,6 +568,10 @@
|
|
564
568
|
box-shadow: $shadow_deep !important;
|
565
569
|
}
|
566
570
|
|
571
|
+
.pb_table_td:nth-child(2) {
|
572
|
+
box-shadow: 0 0 0 0 !important;
|
573
|
+
}
|
574
|
+
|
567
575
|
.pb_advanced_table_header,
|
568
576
|
.pb_advanced_table_body {
|
569
577
|
th.sticky-left,
|
@@ -2,7 +2,7 @@ import React, { useRef, useEffect, useState, useCallback } from "react";
|
|
2
2
|
import classnames from "classnames";
|
3
3
|
|
4
4
|
import { GenericObject } from "../types";
|
5
|
-
import { Row, RowSelectionState } from "@tanstack/react-table";
|
5
|
+
import { Row, RowSelectionState, RowPinningState } from "@tanstack/react-table";
|
6
6
|
|
7
7
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from "../utilities/props";
|
8
8
|
import { globalProps, GlobalProps } from "../utilities/globalProps";
|
@@ -52,7 +52,10 @@ type AdvancedTableProps = {
|
|
52
52
|
onToggleExpansionClick?: (arg: Row<GenericObject>) => void
|
53
53
|
pagination?: boolean,
|
54
54
|
paginationProps?: GenericObject,
|
55
|
-
pinnedRows?:
|
55
|
+
pinnedRows?: {
|
56
|
+
value?: RowPinningState;
|
57
|
+
onChange?: (value: RowPinningState) => void;
|
58
|
+
};
|
56
59
|
responsive?: "scroll" | "none",
|
57
60
|
selectableRows?: boolean,
|
58
61
|
showActionsBar?: boolean,
|
@@ -569,6 +569,8 @@ class PbAdvancedTableActionBar {
|
|
569
569
|
actionBar.style.height = 'auto';
|
570
570
|
actionBar.style.overflow = 'visible';
|
571
571
|
actionBar.style.opacity = '1';
|
572
|
+
actionBar.style.transitionProperty = 'all';
|
573
|
+
actionBar.style.transitionTimingFunction = 'ease-in-out';
|
572
574
|
actionBar.classList.remove("p_none");
|
573
575
|
actionBar.classList.add("p_xs", "is-visible", "show-action-card");
|
574
576
|
|
@@ -1,16 +1,9 @@
|
|
1
1
|
<%= pb_content_tag(:label) do %>
|
2
2
|
<%= content.presence || object.input %>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
</span>
|
8
|
-
<% else %>
|
9
|
-
<span data-pb-checkbox-icon-span="true" class="pb_checkbox_checkmark">
|
10
|
-
<%= pb_rails("icon", props: { icon: "check", classname: "check_icon", fixed_width: true}) %>
|
11
|
-
<%= pb_rails("icon", props: { icon: "minus", classname: "indeterminate_icon hidden", fixed_width: true}) %>
|
12
|
-
</span>
|
13
|
-
<% end %>
|
3
|
+
<span data-pb-checkbox-icon-span="true" class="pb_checkbox_checkmark">
|
4
|
+
<%= pb_rails("icon", props: { icon: "check", classname: "check_icon", fixed_width: true}) %>
|
5
|
+
<%= pb_rails("icon", props: { icon: "minus", classname: "indeterminate_icon hidden", fixed_width: true}) %>
|
6
|
+
</span>
|
14
7
|
<span class="pb_checkbox_label">
|
15
8
|
<%= pb_rails("body", props: { status: object.checkbox_label_status, text: object.text, dark: object.dark, margin_right: object.form_spacing ? "xs" : "" }) %>
|
16
9
|
</span>
|
@@ -5,7 +5,8 @@ module Playbook
|
|
5
5
|
class Checkbox < Playbook::KitBase
|
6
6
|
prop :error, type: Playbook::Props::Boolean, default: false
|
7
7
|
prop :checked, type: Playbook::Props::Boolean, default: false
|
8
|
-
prop :
|
8
|
+
prop :indeterminate_main, type: Playbook::Props::Boolean, default: false
|
9
|
+
prop :indeterminate_parent
|
9
10
|
prop :text
|
10
11
|
prop :value
|
11
12
|
prop :name
|
@@ -17,19 +18,43 @@ module Playbook
|
|
17
18
|
default: false
|
18
19
|
prop :form_spacing, type: Playbook::Props::Boolean,
|
19
20
|
default: false
|
21
|
+
prop :hidden_input, type: Playbook::Props::Boolean,
|
22
|
+
default: false
|
23
|
+
prop :hidden_value
|
20
24
|
|
21
25
|
def classname
|
22
|
-
generate_classname("pb_checkbox_kit", checked_class) +
|
26
|
+
generate_classname("pb_checkbox_kit", checked_class) + error_class
|
23
27
|
end
|
24
28
|
|
25
29
|
def input
|
26
|
-
|
30
|
+
inputs = []
|
31
|
+
effective_name = name || input_options[:name]
|
32
|
+
effective_value = value || input_options[:value] || "1"
|
33
|
+
is_checked = checked || input_options[:checked]
|
34
|
+
|
35
|
+
inputs << hidden_field_tag(effective_name, hidden_value || "0") if hidden_input && effective_name.present?
|
36
|
+
|
37
|
+
inputs << check_box_tag(
|
38
|
+
effective_name,
|
39
|
+
effective_value,
|
40
|
+
is_checked,
|
41
|
+
input_options.merge(disabled: disabled)
|
42
|
+
)
|
43
|
+
|
44
|
+
safe_join(inputs)
|
27
45
|
end
|
28
46
|
|
29
47
|
def checkbox_label_status
|
30
48
|
error ? "negative" : nil
|
31
49
|
end
|
32
50
|
|
51
|
+
def data
|
52
|
+
Hash(prop(:data)).merge(
|
53
|
+
pb_checkbox_indeterminate_main: indeterminate_main,
|
54
|
+
pb_checkbox_indeterminate_parent: indeterminate_parent
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
33
58
|
private
|
34
59
|
|
35
60
|
def error_class
|
@@ -39,10 +64,6 @@ module Playbook
|
|
39
64
|
def checked_class
|
40
65
|
checked ? "on" : "off"
|
41
66
|
end
|
42
|
-
|
43
|
-
def indeterminate_class
|
44
|
-
indeterminate ? " indeterminate" : ""
|
45
|
-
end
|
46
67
|
end
|
47
68
|
end
|
48
69
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
When using a custom checkbox wrapped in the Checkbox kit, hidden inputs are not automatically included and cannot be prop enabled. Manually add a hidden input before the checkbox if necessary to submit a value when the checkbox is unchecked (as is standard in Rails forms).
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
<%= pb_form_with(scope: :example, url: "", method: :get) do |form| %>
|
3
|
+
<%=pb_rails("flex", props: { gap: "sm", orientation: "column"}) do %>
|
4
|
+
<%= pb_rails("checkbox" , props: {
|
5
|
+
text: "1. pb_rails(\"checkbox\") Checkbox from kit",
|
6
|
+
value: "checkbox-value",
|
7
|
+
name: "checkbox-name",
|
8
|
+
hidden_input: true
|
9
|
+
}) %>
|
10
|
+
<%= form.check_box :example_checkbox,
|
11
|
+
data: { field1: "value1", field2: "value2" },
|
12
|
+
props: { text: "2. form.check_box Checkbox from Form Builder" },
|
13
|
+
unchecked_value: "no",
|
14
|
+
id: "checkbox-id",
|
15
|
+
name: "checkbox-name",
|
16
|
+
class: "checkbox-class"
|
17
|
+
%>
|
18
|
+
<%= form.actions do |action| %>
|
19
|
+
<%= action.button props: { type: "submit", text: "Submit", variant: "primary" } %>
|
20
|
+
<% end %>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
The way to access hidden inputs for form submission depends on which version of the kit being used within the form context.
|
2
|
+
|
3
|
+
If using the Rails Checkbox version of the kit, set `hidden_input: true`. Inspect Checkbox #1 in the example above to see the hidden input in the DOM.
|
4
|
+
|
5
|
+
If using the Form Builder version of the kit (reference the [Form kit page](https://playbook.powerapp.cloud/kits/form) for more on these), the hidden input will appear if the input has a set `unchecked_value`. Inspect Checkbox #2 in the example above (and the two checkbox examples on the Form kit page) to see the hidden input in the DOM. See the [Rails check_box FormHelper docs](https://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-check_box) for more.
|
@@ -9,11 +9,10 @@
|
|
9
9
|
<tr>
|
10
10
|
<th>
|
11
11
|
<%= pb_rails("checkbox", props: {
|
12
|
-
checked: true,
|
13
12
|
text: "Uncheck All",
|
14
13
|
value: "checkbox-value",
|
15
14
|
name: "main-checkbox",
|
16
|
-
|
15
|
+
indeterminate_main: true,
|
17
16
|
id: "indeterminate-checkbox"
|
18
17
|
}) %>
|
19
18
|
</th>
|
@@ -30,55 +29,10 @@
|
|
30
29
|
value: checkbox[:id],
|
31
30
|
name: "#{checkbox[:id]}-indeterminate-checkbox",
|
32
31
|
id: "#{checkbox[:id]}-indeterminate-checkbox",
|
32
|
+
indeterminate_parent: "indeterminate-checkbox",
|
33
33
|
}) %>
|
34
34
|
</td>
|
35
35
|
</tr>
|
36
36
|
<% end %>
|
37
37
|
</tbody>
|
38
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>
|
@@ -0,0 +1 @@
|
|
1
|
+
If you want to use indeterminate, "check/uncheck all" checkboxes, add `indeterminate_main: true` and an `id` to the main checkbox. Then, add an `indeterminate_parent` prop with the main checkbox's `id` to the children checkboxes.
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import PbEnhancedElement from "../pb_enhanced_element"
|
2
|
+
|
3
|
+
const INDETERMINATE_MAIN_CHECKBOX_SELECTOR = "[data-pb-checkbox-indeterminate-main='true']"
|
4
|
+
|
5
|
+
export default class PbCheckbox extends PbEnhancedElement {
|
6
|
+
static get selector() {
|
7
|
+
return INDETERMINATE_MAIN_CHECKBOX_SELECTOR
|
8
|
+
}
|
9
|
+
|
10
|
+
connect() {
|
11
|
+
const mainCheckboxWrapper = this.element;
|
12
|
+
const mainCheckbox = mainCheckboxWrapper.querySelector('input')
|
13
|
+
const childCheckboxes = document.querySelectorAll(`[data-pb-checkbox-indeterminate-parent="${this.element.id}"] input[type="checkbox"]`);
|
14
|
+
|
15
|
+
const updateMainCheckbox = () => {
|
16
|
+
// Count the number of checked child checkboxes
|
17
|
+
const checkedCount = Array.from(childCheckboxes).filter(cb => cb.checked).length;
|
18
|
+
// Determine if the main checkbox should be in an indeterminate state
|
19
|
+
const indeterminate = checkedCount > 0 && checkedCount < childCheckboxes.length;
|
20
|
+
|
21
|
+
// Set the main checkbox states
|
22
|
+
mainCheckbox.indeterminate = indeterminate;
|
23
|
+
mainCheckbox.checked = checkedCount > 0;
|
24
|
+
|
25
|
+
// Determine the main checkbox label based on the number of checked checkboxes
|
26
|
+
const text = checkedCount === 0 ? 'Check All' : 'Uncheck All';
|
27
|
+
|
28
|
+
// Determine the icon class to add and remove based on the number of checked checkboxes
|
29
|
+
const iconClassToAdd = checkedCount === 0 ? 'pb_checkbox_checkmark' : 'pb_checkbox_indeterminate';
|
30
|
+
const iconClassToRemove = checkedCount === 0 ? 'pb_checkbox_indeterminate' : 'pb_checkbox_checkmark';
|
31
|
+
|
32
|
+
// Update main checkbox label
|
33
|
+
mainCheckboxWrapper.getElementsByClassName('pb_body_kit')[0].textContent = text;
|
34
|
+
|
35
|
+
// Add and remove the icon class to the main checkbox wrapper
|
36
|
+
mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.add(iconClassToAdd);
|
37
|
+
mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.remove(iconClassToRemove);
|
38
|
+
|
39
|
+
// Toggle the visibility of the checkbox icon based on the indeterminate state
|
40
|
+
mainCheckboxWrapper.getElementsByClassName("indeterminate_icon")[0].classList.toggle('hidden', !indeterminate);
|
41
|
+
mainCheckboxWrapper.getElementsByClassName("check_icon")[0].classList.toggle('hidden', indeterminate);
|
42
|
+
};
|
43
|
+
|
44
|
+
// Set indeterminate icon on main checkbox if initial children checkboxes are checked
|
45
|
+
updateMainCheckbox();
|
46
|
+
|
47
|
+
this.element.querySelector('input').addEventListener('change', function() {
|
48
|
+
childCheckboxes.forEach(cb => cb.checked = this.checked);
|
49
|
+
updateMainCheckbox();
|
50
|
+
});
|
51
|
+
|
52
|
+
childCheckboxes.forEach(cb => {
|
53
|
+
cb.addEventListener('change', updateMainCheckbox);
|
54
|
+
});
|
55
|
+
}
|
56
|
+
}
|