playbook_ui 16.5.0.pre.rc.4 → 16.5.0.pre.rc.5
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/Context/AdvancedTableContext.tsx +5 -2
- data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableHeader.tsx +9 -11
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_grouped_headers_composition.jsx +235 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_grouped_headers_composition.md +17 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/advanced_table_grouped_headers_composition_mock_data.json +98 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_attributes.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_blank.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_custom_select.html.erb +1 -1
- data/app/pb_kits/playbook/pb_select/docs/_select_custom_select_subheaders.html.erb +1 -1
- data/app/pb_kits/playbook/pb_select/docs/_select_default.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_disabled.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_disabled_options.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_error.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_inline.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_inline_compact.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_inline_show_arrow.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_multiple.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_required.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_required_indicator.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_value_text_same.html.erb +1 -0
- data/app/pb_kits/playbook/pb_select/select.html.erb +5 -5
- data/app/pb_kits/playbook/pb_select/select.rb +5 -0
- data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.scss +39 -0
- data/dist/chunks/vendor.js +2 -2
- data/dist/menu.yml +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c32d51cfd82ea85173431252ee253925ee58870d14cd99ec19c3685734dd7cdb
|
|
4
|
+
data.tar.gz: d44a53d1fb2030fb3d90e5af717f7e967266832676ee62c34135fc70ff76313b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cb9a2f2707fa909d99f3215fa0c4a826cb6138f4b8d3418023652e44b0e8e9f8183fbdfc21d43bdf0c95627f6ccf8be301ad80676d7dd45de1bdeac5dec9576f
|
|
7
|
+
data.tar.gz: 32170dae149912ff60302959a1f2f3033ab3b43d48fddc6c22ad2b30576b740191c4e28b70cd52cb9e4f1d643cd88bf7e67e865e3c1d2d5ca00669de83610285
|
|
@@ -33,7 +33,8 @@ export const AdvancedTableProvider = ({ children, ...props }: {
|
|
|
33
33
|
|
|
34
34
|
const measureHeights = useCallback(() => {
|
|
35
35
|
if (headerRef.current) {
|
|
36
|
-
const
|
|
36
|
+
const headerElement = headerRef.current as HTMLElement;
|
|
37
|
+
const headerRect = headerElement.getBoundingClientRect();
|
|
37
38
|
if (headerRect.height > 0) {
|
|
38
39
|
setHeaderHeight(headerRect.height);
|
|
39
40
|
}
|
|
@@ -67,9 +68,11 @@ export const AdvancedTableProvider = ({ children, ...props }: {
|
|
|
67
68
|
};
|
|
68
69
|
}, [measureHeights]);
|
|
69
70
|
|
|
71
|
+
const headerGroupCount = table?.getHeaderGroups()?.length ?? 0;
|
|
72
|
+
|
|
70
73
|
useEffect(() => {
|
|
71
74
|
measureHeights();
|
|
72
|
-
}, [table?.getRowModel().rows.length, measureHeights]);
|
|
75
|
+
}, [table?.getRowModel().rows.length, headerGroupCount, measureHeights]);
|
|
73
76
|
|
|
74
77
|
|
|
75
78
|
// Create a flattened data array that includes ALL components for virtualization
|
|
@@ -64,14 +64,12 @@ export const TableHeader = ({
|
|
|
64
64
|
);
|
|
65
65
|
|
|
66
66
|
const renderRegularTableHeader = () => (
|
|
67
|
-
<thead className={classes}
|
|
67
|
+
<thead className={classes}
|
|
68
68
|
id={id}
|
|
69
|
+
ref={headerRef}
|
|
69
70
|
>
|
|
70
|
-
{table.getHeaderGroups().map((headerGroup: HeaderGroup<GenericObject
|
|
71
|
-
<tr
|
|
72
|
-
key={`${headerGroup.id}-headerGroup`}
|
|
73
|
-
ref={index === 0 ? headerRef : null}
|
|
74
|
-
>
|
|
71
|
+
{table.getHeaderGroups().map((headerGroup: HeaderGroup<GenericObject>) => (
|
|
72
|
+
<tr key={`${headerGroup.id}-headerGroup`}>
|
|
75
73
|
{!hasAnySubRows && selectableRows && (
|
|
76
74
|
<th className={customCellClassnames}>
|
|
77
75
|
<Checkbox
|
|
@@ -105,16 +103,16 @@ export const TableHeader = ({
|
|
|
105
103
|
);
|
|
106
104
|
|
|
107
105
|
const renderVirtualizedTableHeader = () => (
|
|
108
|
-
<thead
|
|
109
|
-
className={classes}
|
|
106
|
+
<thead
|
|
107
|
+
className={classes}
|
|
110
108
|
data-virtualized="true"
|
|
111
109
|
id={id}
|
|
110
|
+
ref={headerRef}
|
|
112
111
|
>
|
|
113
|
-
{table.getHeaderGroups().map((headerGroup: HeaderGroup<GenericObject
|
|
114
|
-
<tr
|
|
112
|
+
{table.getHeaderGroups().map((headerGroup: HeaderGroup<GenericObject>) => (
|
|
113
|
+
<tr
|
|
115
114
|
className="virtualized-header-row-header"
|
|
116
115
|
key={`${headerGroup.id}-headerGroup-virtualized`}
|
|
117
|
-
ref={index === 0 ? headerRef : null}
|
|
118
116
|
>
|
|
119
117
|
{!hasAnySubRows && selectableRows && (
|
|
120
118
|
<th className={classnames(customCellClassnames, "virtualized-header-cell")}>
|
data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_grouped_headers_composition.jsx
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/* eslint-disable react/no-multi-comp, react/prop-types */
|
|
2
|
+
import React, { useCallback, useState } from "react"
|
|
3
|
+
|
|
4
|
+
import AdvancedTable from "../_advanced_table"
|
|
5
|
+
import Flex from "../../pb_flex/_flex"
|
|
6
|
+
import Icon from "../../pb_icon/_icon"
|
|
7
|
+
import List from "../../pb_list/_list"
|
|
8
|
+
import ListItem from "../../pb_list/_list_item"
|
|
9
|
+
import PbReactPopover from "../../pb_popover/_popover"
|
|
10
|
+
import SectionSeparator from "../../pb_section_separator/_section_separator"
|
|
11
|
+
import StarRating from "../../pb_star_rating/_star_rating"
|
|
12
|
+
import COMPOSITION_MOCK_DATA from "./advanced_table_grouped_headers_composition_mock_data.json"
|
|
13
|
+
|
|
14
|
+
const LEAF_COUNT = "newEnrollments"
|
|
15
|
+
const LEAF_SCHEDULED = "scheduledMeetings"
|
|
16
|
+
|
|
17
|
+
const ICON_UNSORTED = "arrow-up-arrow-down"
|
|
18
|
+
const iconSorted = (desc) => (desc ? "arrow-up-wide-short" : "arrow-down-short-wide")
|
|
19
|
+
|
|
20
|
+
const STAR_MENU = [
|
|
21
|
+
{ id: LEAF_COUNT, label: "Count" },
|
|
22
|
+
{ id: LEAF_SCHEDULED, label: "Scheduled" },
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
const MENU_BTN = {
|
|
26
|
+
alignItems: "center",
|
|
27
|
+
background: "transparent",
|
|
28
|
+
border: "none",
|
|
29
|
+
cursor: "pointer",
|
|
30
|
+
display: "flex",
|
|
31
|
+
font: "inherit",
|
|
32
|
+
gap: 12,
|
|
33
|
+
justifyContent: "space-between",
|
|
34
|
+
padding: "8px 14px",
|
|
35
|
+
textAlign: "left",
|
|
36
|
+
width: "100%",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const labelStyle = (active) => ({
|
|
40
|
+
color: active ? "#0056cf" : "#242930",
|
|
41
|
+
flex: 1,
|
|
42
|
+
fontSize: 14,
|
|
43
|
+
fontWeight: active ? 600 : 400,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
/** Hooks + popover; `header` callback cannot use hooks directly. */
|
|
47
|
+
const StarMetricGroupHeader = ({ table }) => {
|
|
48
|
+
const [open, setOpen] = useState(false)
|
|
49
|
+
const menuId = "playbook-star-metric-sort-menu"
|
|
50
|
+
|
|
51
|
+
const sort0 = table.getState().sorting[0]
|
|
52
|
+
const groupActive =
|
|
53
|
+
sort0?.id === LEAF_COUNT || sort0?.id === LEAF_SCHEDULED
|
|
54
|
+
|
|
55
|
+
const close = useCallback((shouldClose) => setOpen(!shouldClose), [])
|
|
56
|
+
const toggle = useCallback((e) => {
|
|
57
|
+
e.stopPropagation()
|
|
58
|
+
setOpen((v) => !v)
|
|
59
|
+
}, [])
|
|
60
|
+
|
|
61
|
+
const applySort = useCallback(
|
|
62
|
+
(columnId, e) => {
|
|
63
|
+
e.stopPropagation()
|
|
64
|
+
const cur = table.getState().sorting[0]
|
|
65
|
+
const nextDesc = cur?.id === columnId ? !cur.desc : true
|
|
66
|
+
table.setSorting([{ desc: nextDesc, id: columnId }])
|
|
67
|
+
setOpen(false)
|
|
68
|
+
},
|
|
69
|
+
[table]
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<PbReactPopover
|
|
74
|
+
closeOnClick="outside"
|
|
75
|
+
offset
|
|
76
|
+
padding="none"
|
|
77
|
+
placement="bottom-start"
|
|
78
|
+
reference={
|
|
79
|
+
<button
|
|
80
|
+
aria-controls={menuId}
|
|
81
|
+
aria-expanded={open}
|
|
82
|
+
aria-haspopup="menu"
|
|
83
|
+
aria-label="Sort by Count or Scheduled"
|
|
84
|
+
onClick={toggle}
|
|
85
|
+
style={{
|
|
86
|
+
background: open ? "rgba(115, 134, 169, 0.14)" : "transparent",
|
|
87
|
+
border: "none",
|
|
88
|
+
borderRadius: 6,
|
|
89
|
+
cursor: "pointer",
|
|
90
|
+
font: "inherit",
|
|
91
|
+
margin: 0,
|
|
92
|
+
padding: "2px 4px",
|
|
93
|
+
}}
|
|
94
|
+
title="Open menu to sort by Count or Scheduled"
|
|
95
|
+
type="button"
|
|
96
|
+
>
|
|
97
|
+
<Flex alignItems="center"
|
|
98
|
+
gap="xs"
|
|
99
|
+
justifyContent="center"
|
|
100
|
+
>
|
|
101
|
+
<StarRating
|
|
102
|
+
backgroundType="outline"
|
|
103
|
+
colorOption="primary"
|
|
104
|
+
justifyContent="center"
|
|
105
|
+
maxWidth="102px"
|
|
106
|
+
rating={5}
|
|
107
|
+
/>
|
|
108
|
+
<Icon
|
|
109
|
+
color={groupActive ? "primary" : "default"}
|
|
110
|
+
fixedWidth
|
|
111
|
+
icon={
|
|
112
|
+
groupActive
|
|
113
|
+
? iconSorted(Boolean(sort0?.desc))
|
|
114
|
+
: ICON_UNSORTED
|
|
115
|
+
}
|
|
116
|
+
size="md"
|
|
117
|
+
/>
|
|
118
|
+
</Flex>
|
|
119
|
+
</button>
|
|
120
|
+
}
|
|
121
|
+
shouldClosePopover={close}
|
|
122
|
+
show={open}
|
|
123
|
+
zIndex={1200}
|
|
124
|
+
>
|
|
125
|
+
<Flex id={menuId}
|
|
126
|
+
minWidth="220px"
|
|
127
|
+
orientation="column"
|
|
128
|
+
>
|
|
129
|
+
<List borderless
|
|
130
|
+
padding="none"
|
|
131
|
+
>
|
|
132
|
+
{STAR_MENU.map(({ id, label }, i) => {
|
|
133
|
+
const active = sort0?.id === id
|
|
134
|
+
return (
|
|
135
|
+
<React.Fragment key={id}>
|
|
136
|
+
{i > 0 ? <SectionSeparator margin="none" /> : null}
|
|
137
|
+
<ListItem padding="none">
|
|
138
|
+
<button
|
|
139
|
+
onClick={(e) => applySort(id, e)}
|
|
140
|
+
style={MENU_BTN}
|
|
141
|
+
type="button"
|
|
142
|
+
>
|
|
143
|
+
<span style={labelStyle(active)}>{label}</span>
|
|
144
|
+
<Icon
|
|
145
|
+
color={active ? "primary" : "default"}
|
|
146
|
+
fixedWidth
|
|
147
|
+
icon={
|
|
148
|
+
active
|
|
149
|
+
? iconSorted(Boolean(sort0?.desc))
|
|
150
|
+
: ICON_UNSORTED
|
|
151
|
+
}
|
|
152
|
+
size="md"
|
|
153
|
+
/>
|
|
154
|
+
</button>
|
|
155
|
+
</ListItem>
|
|
156
|
+
</React.Fragment>
|
|
157
|
+
)
|
|
158
|
+
})}
|
|
159
|
+
</List>
|
|
160
|
+
</Flex>
|
|
161
|
+
</PbReactPopover>
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const AdvancedTableGroupedHeadersComposition = (props) => {
|
|
166
|
+
const [pinnedRows, setPinnedRows] = useState({ top: ["12"] })
|
|
167
|
+
|
|
168
|
+
const columnDefinitions = [
|
|
169
|
+
{
|
|
170
|
+
accessor: "year",
|
|
171
|
+
cellAccessors: ["quarter", "month", "day"],
|
|
172
|
+
label: "Year",
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
columns: [
|
|
176
|
+
{
|
|
177
|
+
columns: [
|
|
178
|
+
{
|
|
179
|
+
accessor: "newEnrollments",
|
|
180
|
+
enableSort: true,
|
|
181
|
+
id: LEAF_COUNT,
|
|
182
|
+
label: "Count",
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
accessor: "scheduledMeetings",
|
|
186
|
+
enableSort: true,
|
|
187
|
+
id: LEAF_SCHEDULED,
|
|
188
|
+
label: "Scheduled",
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
id: "starLeafPair",
|
|
192
|
+
label: "Metrics",
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
header: ({ table }) => (
|
|
196
|
+
<Flex justify="center">
|
|
197
|
+
<StarMetricGroupHeader table={table} />
|
|
198
|
+
</Flex>
|
|
199
|
+
),
|
|
200
|
+
id: "starMetricGroup",
|
|
201
|
+
label: "Rating group (custom header)",
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
columns: [
|
|
205
|
+
{ accessor: "attendanceRate", label: "Attendance" },
|
|
206
|
+
{
|
|
207
|
+
accessor: "classCompletionRate",
|
|
208
|
+
enableSort: true,
|
|
209
|
+
id: "classCompletionRate",
|
|
210
|
+
label: "Completion %",
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
label: "Performance",
|
|
214
|
+
},
|
|
215
|
+
]
|
|
216
|
+
|
|
217
|
+
return (
|
|
218
|
+
<div>
|
|
219
|
+
<AdvancedTable
|
|
220
|
+
columnDefinitions={columnDefinitions}
|
|
221
|
+
enableSortingRemoval
|
|
222
|
+
maxHeight="md"
|
|
223
|
+
pinnedRows={{ onChange: setPinnedRows, value: pinnedRows }}
|
|
224
|
+
tableData={COMPOSITION_MOCK_DATA}
|
|
225
|
+
tableProps={{ sticky: true }}
|
|
226
|
+
{...props}
|
|
227
|
+
>
|
|
228
|
+
<AdvancedTable.Header enableSorting />
|
|
229
|
+
<AdvancedTable.Body />
|
|
230
|
+
</AdvancedTable>
|
|
231
|
+
</div>
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export default AdvancedTableGroupedHeadersComposition
|
data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_grouped_headers_composition.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
### Grouped headers, custom UI, sort, and pinned rows
|
|
2
|
+
|
|
3
|
+
This example combines patterns that often show up together in product tables:
|
|
4
|
+
|
|
5
|
+
1. **Multi-level headers** — nested `columns` in `columnDefinitions`.
|
|
6
|
+
2. **Custom group header** — a `header` function returning React (here: `StarRating`, sort icon, `PbReactPopover` menu). Parent groups are not sort targets; **only leaf columns** use `enableSort: true` (see **Enable Sort By Column (Multi-Column)**).
|
|
7
|
+
3. **Programmatic sort** — the group `header` receives TanStack’s **`table`**. Call **`table.setSorting([{ id: "<leafColumnId>", desc: boolean }])`** using the same **`id`** values as your leaf columns. Match **direction icons** to the built-in kit (`arrow-up-arrow-down` unsorted; `arrow-up-wide-short` / `arrow-down-short-wide` when sorted).
|
|
8
|
+
4. **Pinned row + sticky header** — `pinnedRows` with row **`id`**s and `tableProps={{ sticky: true }}` (see **Pinned Rows**).
|
|
9
|
+
|
|
10
|
+
**Implementation notes**
|
|
11
|
+
|
|
12
|
+
- **`header` must be a child component** if you need hooks (e.g. popover open state). Render it from `header: ({ table }) => <YourHeader table={table} />`.
|
|
13
|
+
- **Avoid wrapping the primary control in `Tooltip`** — it can steal the first tap/click. Use a **`title`** on the button or copy in the doc instead.
|
|
14
|
+
- **Popover rows:** use a plain **`<button>`** as `reference`, `closeOnClick="outside"`. Picking the **same** metric again should **toggle** `desc`; switching to another leaf column often defaults to **`desc: true`** to align with **`sortDescFirst`**.
|
|
15
|
+
- **Data:** **`advanced_table_grouped_headers_composition_mock_data.json`** — twelve flat rows (2015–2026) with **varied** Count / Scheduled / % values so sorting is obvious; **`id` `"12"`** is **2026** and is pinned by default.
|
|
16
|
+
|
|
17
|
+
Other building blocks on this kit: **Custom Header with Multiple Headers**, **Sticky Header**.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "1",
|
|
4
|
+
"year": "2015",
|
|
5
|
+
"newEnrollments": "12",
|
|
6
|
+
"scheduledMeetings": "40",
|
|
7
|
+
"attendanceRate": "62%",
|
|
8
|
+
"classCompletionRate": "28%"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": "2",
|
|
12
|
+
"year": "2016",
|
|
13
|
+
"newEnrollments": "88",
|
|
14
|
+
"scheduledMeetings": "12",
|
|
15
|
+
"attendanceRate": "71%",
|
|
16
|
+
"classCompletionRate": "55%"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "3",
|
|
20
|
+
"year": "2017",
|
|
21
|
+
"newEnrollments": "34",
|
|
22
|
+
"scheduledMeetings": "67",
|
|
23
|
+
"attendanceRate": "58%",
|
|
24
|
+
"classCompletionRate": "41%"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "4",
|
|
28
|
+
"year": "2018",
|
|
29
|
+
"newEnrollments": "05",
|
|
30
|
+
"scheduledMeetings": "91",
|
|
31
|
+
"attendanceRate": "44%",
|
|
32
|
+
"classCompletionRate": "73%"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "5",
|
|
36
|
+
"year": "2019",
|
|
37
|
+
"newEnrollments": "61",
|
|
38
|
+
"scheduledMeetings": "19",
|
|
39
|
+
"attendanceRate": "83%",
|
|
40
|
+
"classCompletionRate": "36%"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "6",
|
|
44
|
+
"year": "2020",
|
|
45
|
+
"newEnrollments": "19",
|
|
46
|
+
"scheduledMeetings": "54",
|
|
47
|
+
"attendanceRate": "67%",
|
|
48
|
+
"classCompletionRate": "62%"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "7",
|
|
52
|
+
"year": "2021",
|
|
53
|
+
"newEnrollments": "73",
|
|
54
|
+
"scheduledMeetings": "08",
|
|
55
|
+
"attendanceRate": "52%",
|
|
56
|
+
"classCompletionRate": "49%"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "8",
|
|
60
|
+
"year": "2022",
|
|
61
|
+
"newEnrollments": "50",
|
|
62
|
+
"scheduledMeetings": "50",
|
|
63
|
+
"attendanceRate": "75%",
|
|
64
|
+
"classCompletionRate": "45%"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"id": "9",
|
|
68
|
+
"year": "2023",
|
|
69
|
+
"newEnrollments": "95",
|
|
70
|
+
"scheduledMeetings": "03",
|
|
71
|
+
"attendanceRate": "69%",
|
|
72
|
+
"classCompletionRate": "81%"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"id": "10",
|
|
76
|
+
"year": "2024",
|
|
77
|
+
"newEnrollments": "27",
|
|
78
|
+
"scheduledMeetings": "76",
|
|
79
|
+
"attendanceRate": "91%",
|
|
80
|
+
"classCompletionRate": "22%"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"id": "11",
|
|
84
|
+
"year": "2025",
|
|
85
|
+
"newEnrollments": "41",
|
|
86
|
+
"scheduledMeetings": "33",
|
|
87
|
+
"attendanceRate": "48%",
|
|
88
|
+
"classCompletionRate": "94%"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"id": "12",
|
|
92
|
+
"year": "2026",
|
|
93
|
+
"newEnrollments": "66",
|
|
94
|
+
"scheduledMeetings": "66",
|
|
95
|
+
"attendanceRate": "55%",
|
|
96
|
+
"classCompletionRate": "58%"
|
|
97
|
+
}
|
|
98
|
+
]
|
|
@@ -75,6 +75,7 @@ examples:
|
|
|
75
75
|
- advanced_table_column_visibility_with_state: Column Visibility Control With State
|
|
76
76
|
- advanced_table_column_visibility_custom: Column Visibility Control with Custom Dropdown
|
|
77
77
|
- advanced_table_column_visibility_multi: Column Visibility Control with Multi-Header Columns
|
|
78
|
+
- advanced_table_grouped_headers_composition: Grouped headers, custom headers, sort, and pinned rows
|
|
78
79
|
- advanced_table_scrollbar_none: Advanced Table Scrollbar None
|
|
79
80
|
- advanced_table_row_styling: Row Styling
|
|
80
81
|
- advanced_table_padding_control_per_row: Padding Control using Row Styling
|
|
@@ -42,6 +42,7 @@ export { default as AdvancedTableInfiniteScroll} from './_advanced_table_infinit
|
|
|
42
42
|
export {default as AdvancedTableWithCustomHeader} from './_advanced_table_with_custom_header.jsx'
|
|
43
43
|
export { default as AdvancedTableCustomSort } from './_advanced_table_custom_sort.jsx'
|
|
44
44
|
export { default as AdvancedTableWithCustomHeaderMultiHeader } from './_advanced_table_with_custom_header_multi_header.jsx'
|
|
45
|
+
export { default as AdvancedTableGroupedHeadersComposition } from './_advanced_table_grouped_headers_composition.jsx'
|
|
45
46
|
export { default as AdvancedTableSortPerColumn } from './_advanced_table_sort_per_column.jsx'
|
|
46
47
|
export { default as AdvancedTableSortPerColumnForMultiColumn } from './_advanced_table_sort_per_column_for_multi_column.jsx'
|
|
47
48
|
export { default as AdvancedTablePaddingControl } from './_advanced_table_padding_control.jsx'
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
id: nil,
|
|
3
3
|
class: object.classnames ) do %>
|
|
4
4
|
<% if object.label %>
|
|
5
|
-
|
|
5
|
+
<%= tag.label(class: "pb_select_kit_label", for: object.select_input_id) do %>
|
|
6
6
|
<% if object.required_indicator %>
|
|
7
7
|
<%= pb_rails("caption", props: { color: "lighter", dark: object.dark }) do %>
|
|
8
8
|
<%= object.label %><span style="color: #DA0014;"> *</span>
|
|
9
|
-
<% end %>
|
|
9
|
+
<% end %>
|
|
10
10
|
<% else %>
|
|
11
11
|
<%= pb_rails("caption", props: { color: "lighter", text: object.label, dark: object.dark }) %>
|
|
12
12
|
<% end %>
|
|
13
|
-
|
|
13
|
+
<% end %>
|
|
14
14
|
<% end %>
|
|
15
|
-
|
|
15
|
+
<%= tag.label(class: object.select_wrapper_class, for: object.select_input_id) do %>
|
|
16
16
|
<% if content.present? %>
|
|
17
17
|
<%= content %>
|
|
18
18
|
<%= pb_rails("body", props: { status: "negative", text: object.error }) %>
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
<% if object.multiple != true %>
|
|
33
33
|
<%= pb_rails("icon", props: { custom_icon: Playbook::Engine::root.join(angle_down_path), fixed_width: true, classname: "pb_select_kit_caret"}) %>
|
|
34
34
|
<% end %>
|
|
35
|
-
|
|
35
|
+
<% end %>
|
|
36
36
|
<% end %>
|
|
@@ -46,6 +46,11 @@ module Playbook
|
|
|
46
46
|
}.merge(attributes).merge(input_options)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
# Same resolved id as the native +<select>+ (+all_attributes[:id]+) for label +for+.
|
|
50
|
+
def select_input_id
|
|
51
|
+
all_attributes[:id].presence
|
|
52
|
+
end
|
|
53
|
+
|
|
49
54
|
def classname
|
|
50
55
|
generate_classname("pb_select", select_margin_bottom, separator: " ")
|
|
51
56
|
end
|
|
@@ -165,6 +165,10 @@ $pb_selectable_paddings: (
|
|
|
165
165
|
padding: $space_sm;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
> label .pb_card_kit.dark.pb_card_kit_border_none {
|
|
169
|
+
border-width: 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
168
172
|
&.dark {
|
|
169
173
|
.separator {
|
|
170
174
|
background: $input_border_default_dark;
|
|
@@ -289,6 +293,41 @@ $pb_selectable_paddings: (
|
|
|
289
293
|
}
|
|
290
294
|
}
|
|
291
295
|
|
|
296
|
+
.pb_selectable_card_kit_disabled.display_input,
|
|
297
|
+
.pb_selectable_card_kit_checked_disabled.display_input {
|
|
298
|
+
&:not(.dark) {
|
|
299
|
+
.separator {
|
|
300
|
+
background: $input_border_disabled !important;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.psuedo_separator {
|
|
304
|
+
background-color: $input_border_disabled !important;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
> label > .pb_flex_kit {
|
|
309
|
+
align-items: stretch;
|
|
310
|
+
|
|
311
|
+
> .pb_flex_kit:first-child {
|
|
312
|
+
align-self: center;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
> label .pb_card_kit {
|
|
317
|
+
flex: 1;
|
|
318
|
+
min-width: 0;
|
|
319
|
+
align-self: stretch;
|
|
320
|
+
background-color: $input_background_disabled !important;
|
|
321
|
+
border-width: 0 !important;
|
|
322
|
+
color: $input_text_disabled;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
&.dark > label .pb_card_kit.dark {
|
|
326
|
+
background-color: $input_background_disabled_dark !important;
|
|
327
|
+
color: $input_text_disabled_dark;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
292
331
|
.pb_selectable_card_kit_checked_disabled>label {
|
|
293
332
|
border-color: $input_border_state !important;
|
|
294
333
|
.dark & {
|