playbook_ui 18.2.0.pre.rc.2 → 18.2.0
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_background/_background.tsx +3 -1
- data/app/pb_kits/playbook/pb_background/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_caption/_caption.tsx +3 -1
- data/app/pb_kits/playbook/pb_caption/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_container/_container.tsx +3 -1
- data/app/pb_kits/playbook/pb_container/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_currency/_currency.tsx +3 -1
- data/app/pb_kits/playbook/pb_currency/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_dashboard_value/_dashboard_value.tsx +3 -1
- data/app/pb_kits/playbook/pb_dashboard_value/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_detail/_detail.tsx +3 -1
- data/app/pb_kits/playbook/pb_detail/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +6 -5
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_custom.md +7 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_custom_rails.md +7 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_enable_time.html.erb +33 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_enable_time.jsx +42 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_enable_time.md +24 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_highlight.jsx +101 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_highlight.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -0
- data/app/pb_kits/playbook/pb_dropdown/index.js +19 -10
- data/app/pb_kits/playbook/pb_dropdown/quickpick/index.ts +60 -18
- data/app/pb_kits/playbook/pb_dropdown/quickpick_helper.rb +92 -3
- data/app/pb_kits/playbook/pb_dropdown/utilities/index.ts +8 -1
- data/app/pb_kits/playbook/pb_dropdown/utilities/quickpickDateSync.ts +137 -0
- data/app/pb_kits/playbook/pb_filter/Filter/InteractiveFilter.tsx +1 -1
- data/app/pb_kits/playbook/pb_highlight/_highlight.tsx +3 -1
- data/app/pb_kits/playbook/pb_highlight/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_icon_stat_value/_icon_stat_value.tsx +3 -1
- data/app/pb_kits/playbook/pb_icon_stat_value/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_icon_value/_icon_value.tsx +3 -1
- data/app/pb_kits/playbook/pb_icon_value/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_label_value/_label_value.tsx +3 -1
- data/app/pb_kits/playbook/pb_label_value/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_map/docs/_map_default.md +3 -3
- data/app/pb_kits/playbook/pb_message/_message.tsx +3 -1
- data/app/pb_kits/playbook/pb_message/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.tsx +3 -1
- data/app/pb_kits/playbook/pb_multiple_users/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.tsx +4 -2
- data/app/pb_kits/playbook/pb_multiple_users_stacked/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/MoreExtensionsDropdown.tsx +10 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx +16 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.json +2 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.overrides.json +2 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_attributes.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.md +2 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_focus.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_height.jsx +3 -13
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_inline.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_label.jsx +2 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_markdown_support.jsx +1 -2
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_min_height.jsx +3 -13
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_preview.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_required_indicator.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_simple.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_sticky.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_templates.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_more_extensions.jsx +3 -8
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_more_extensions.md +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.md +2 -2
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.test.js +2 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_advanced.test.js +7 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_rails.js +15 -4
- data/app/pb_kits/playbook/pb_stat_value/_stat_value.tsx +3 -1
- data/app/pb_kits/playbook/pb_stat_value/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_table/_table.tsx +70 -197
- data/app/pb_kits/playbook/pb_table/index.ts +53 -122
- data/app/pb_kits/playbook/pb_table/styles/_sticky_columns.scss +26 -3
- data/app/pb_kits/playbook/pb_table/utilities/stickyColumns.test.ts +266 -0
- data/app/pb_kits/playbook/pb_table/utilities/stickyColumns.ts +145 -0
- data/app/pb_kits/playbook/pb_title_count/_title_count.tsx +3 -1
- data/app/pb_kits/playbook/pb_title_count/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_title_detail/_title_detail.tsx +3 -1
- data/app/pb_kits/playbook/pb_title_detail/kit.schema.json +1 -0
- data/app/pb_kits/playbook/utilities/test/globalProps/onClick.test.js +237 -0
- data/dist/ai/all-schemas.json +16 -0
- data/dist/ai/forms.json +1 -1
- data/dist/ai/index.json +2 -2
- data/dist/ai/kits/background.schema.json +1 -0
- data/dist/ai/kits/caption.schema.json +1 -0
- data/dist/ai/kits/container.schema.json +1 -0
- data/dist/ai/kits/currency.schema.json +1 -0
- data/dist/ai/kits/dashboard_value.schema.json +1 -0
- data/dist/ai/kits/detail.schema.json +1 -0
- data/dist/ai/kits/highlight.schema.json +1 -0
- data/dist/ai/kits/icon_stat_value.schema.json +1 -0
- data/dist/ai/kits/icon_value.schema.json +1 -0
- data/dist/ai/kits/label_value.schema.json +1 -0
- data/dist/ai/kits/message.schema.json +1 -0
- data/dist/ai/kits/multiple_users.schema.json +1 -0
- data/dist/ai/kits/multiple_users_stacked.schema.json +1 -0
- data/dist/ai/kits/stat_value.schema.json +1 -0
- data/dist/ai/kits/title_count.schema.json +1 -0
- data/dist/ai/kits/title_detail.schema.json +1 -0
- data/dist/ai/playgrounds/rich_text_editor.json +1 -1
- data/dist/chunks/{_detail-BqqzPTNr.js → _detail-Bsvl694i.js} +2 -2
- data/dist/chunks/{_pb_line_graph-BGyCJjgG.js → _pb_line_graph-Du7xE9vl.js} +1 -1
- data/dist/chunks/_table-Bf6LGyL9.js +1 -0
- data/dist/chunks/_typeahead-w6S5Vx4b.js +1 -0
- data/dist/chunks/{globalProps-K1DCn3il.js → globalProps-B120NbSJ.js} +1 -1
- data/dist/chunks/{lib-7vm9BMqp.js → lib-Buo6zHEw.js} +1 -1
- data/dist/chunks/quickpickDateSync-DLDx4zce.js +1 -0
- data/dist/chunks/{time_picker_helper-BZutIzB3.js → time_picker_helper-CYGg0UQ0.js} +1 -1
- data/dist/chunks/vendor.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/version.rb +1 -1
- metadata +19 -13
- data/dist/chunks/_table-CEZU0qUK.js +0 -1
- data/dist/chunks/_typeahead-C7iPR5ZF.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect } from 'react'
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react'
|
|
2
2
|
import classnames from 'classnames'
|
|
3
3
|
import { buildAriaProps, buildDataProps, buildHtmlProps } from '../utilities/props'
|
|
4
4
|
import { globalProps, GlobalProps, globalInlineProps } from '../utilities/globalProps'
|
|
@@ -10,6 +10,10 @@ import {
|
|
|
10
10
|
TableCell,
|
|
11
11
|
} from "./subcomponents";
|
|
12
12
|
import { addDataTitle } from './utilities/addDataTitle'
|
|
13
|
+
import {
|
|
14
|
+
applyStickyColumns,
|
|
15
|
+
scheduleStickyColumns,
|
|
16
|
+
} from './utilities/stickyColumns'
|
|
13
17
|
import Card from '../pb_card/_card'
|
|
14
18
|
import Flex from '../pb_flex/_flex'
|
|
15
19
|
import Title from '../pb_title/_title'
|
|
@@ -102,7 +106,13 @@ const Table = (props: TableProps): React.ReactElement => {
|
|
|
102
106
|
const outerPaddingCss = outerPadding ? `outer_padding_${spaceCssName}${outerPadding}` : ''
|
|
103
107
|
const isTableTag = tag === 'table'
|
|
104
108
|
const dynamicInlineProps = globalInlineProps(props)
|
|
105
|
-
const
|
|
109
|
+
const [tableNode, setTableNode] = useState<HTMLElement | null>(null)
|
|
110
|
+
const setTableRef = useCallback(
|
|
111
|
+
(node: HTMLTableElement | HTMLDivElement | null) => {
|
|
112
|
+
setTableNode((current) => (current === node ? current : node))
|
|
113
|
+
},
|
|
114
|
+
[]
|
|
115
|
+
)
|
|
106
116
|
|
|
107
117
|
const isFilterVariant = variant === 'withFilter'
|
|
108
118
|
const effectiveContainer = isFilterVariant ? false : container
|
|
@@ -132,224 +142,87 @@ const Table = (props: TableProps): React.ReactElement => {
|
|
|
132
142
|
)
|
|
133
143
|
|
|
134
144
|
useEffect(() => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
stickyLeftColumn.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
(header as HTMLElement).style.left = `${accumulatedWidth}px`;
|
|
147
|
-
|
|
148
|
-
if (!isLastColumn) {
|
|
149
|
-
header.classList.add('with-border-right');
|
|
150
|
-
header.classList.remove('sticky-left-shadow');
|
|
151
|
-
} else {
|
|
152
|
-
header.classList.remove('with-border-right');
|
|
153
|
-
header.classList.add('sticky-left-shadow');
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const headerWidth = (header as HTMLElement).offsetWidth;
|
|
157
|
-
accumulatedWidth += headerWidth;
|
|
158
|
-
|
|
159
|
-
cells.forEach((cell) => {
|
|
160
|
-
cell.classList.add('sticky');
|
|
161
|
-
(cell as HTMLElement).style.left = `${accumulatedWidth - headerWidth}px`;
|
|
162
|
-
|
|
163
|
-
if (!isLastColumn) {
|
|
164
|
-
cell.classList.add('with-border-right');
|
|
165
|
-
cell.classList.remove('sticky-left-shadow');
|
|
166
|
-
} else {
|
|
167
|
-
cell.classList.remove('with-border-right');
|
|
168
|
-
cell.classList.add('sticky-left-shadow');
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
setTimeout(() => {
|
|
176
|
-
handleStickyLeftColumns();
|
|
177
|
-
}, 10);
|
|
178
|
-
|
|
179
|
-
window.addEventListener('resize', handleStickyLeftColumns);
|
|
180
|
-
|
|
181
|
-
return () => {
|
|
182
|
-
window.removeEventListener('resize', handleStickyLeftColumns);
|
|
183
|
-
};
|
|
184
|
-
}, [stickyLeftColumn]);
|
|
185
|
-
|
|
186
|
-
useEffect(() => {
|
|
187
|
-
const handleStickyRightColumns = () => {
|
|
188
|
-
if (!stickyRightColumn.length) return;
|
|
189
|
-
let accumulatedWidth = 0;
|
|
190
|
-
|
|
191
|
-
stickyRightColumnReversed.forEach((colId, index) => {
|
|
192
|
-
const isLastColumn = index === stickyRightColumn.length - 1;
|
|
193
|
-
const header = document.querySelector(`th[data-sticky-id="${colId}"]`);
|
|
194
|
-
const cells = document.querySelectorAll(`td[data-sticky-id="${colId}"]`);
|
|
195
|
-
|
|
196
|
-
if (header) {
|
|
197
|
-
header.classList.add('sticky');
|
|
198
|
-
(header as HTMLElement).style.right = `${accumulatedWidth}px`;
|
|
199
|
-
|
|
200
|
-
if (!isLastColumn) {
|
|
201
|
-
header.classList.add('with-border-left');
|
|
202
|
-
header.classList.remove('sticky-right-shadow');
|
|
203
|
-
} else {
|
|
204
|
-
header.classList.remove('with-border-left');
|
|
205
|
-
header.classList.add('sticky-right-shadow');
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const headerWidth = (header as HTMLElement).offsetWidth;
|
|
209
|
-
accumulatedWidth += headerWidth;
|
|
210
|
-
|
|
211
|
-
cells.forEach((cell) => {
|
|
212
|
-
cell.classList.add('sticky');
|
|
213
|
-
(cell as HTMLElement).style.right = `${accumulatedWidth - headerWidth}px`;
|
|
214
|
-
|
|
215
|
-
if (!isLastColumn) {
|
|
216
|
-
cell.classList.add('with-border-left');
|
|
217
|
-
cell.classList.remove('sticky-right-shadow');
|
|
218
|
-
} else {
|
|
219
|
-
cell.classList.remove('with-border-left');
|
|
220
|
-
cell.classList.add('sticky-right-shadow');
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
};
|
|
145
|
+
if (!tableNode) return
|
|
146
|
+
if (!stickyLeftColumn.length && !stickyRightColumn.length) return
|
|
147
|
+
|
|
148
|
+
const applyStickyOffsets = () => {
|
|
149
|
+
if (stickyLeftColumn.length) {
|
|
150
|
+
applyStickyColumns(tableNode, stickyLeftColumn, 'left')
|
|
151
|
+
}
|
|
152
|
+
if (stickyRightColumn.length) {
|
|
153
|
+
applyStickyColumns(tableNode, stickyRightColumn, 'right')
|
|
154
|
+
}
|
|
155
|
+
}
|
|
226
156
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}, 10);
|
|
157
|
+
const cancelSchedule = scheduleStickyColumns(applyStickyOffsets)
|
|
158
|
+
window.addEventListener('resize', applyStickyOffsets)
|
|
230
159
|
|
|
231
|
-
|
|
160
|
+
let resizeObserver: ResizeObserver | undefined
|
|
161
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
162
|
+
resizeObserver = new ResizeObserver(applyStickyOffsets)
|
|
163
|
+
resizeObserver.observe(tableNode)
|
|
164
|
+
}
|
|
232
165
|
|
|
233
166
|
return () => {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
167
|
+
cancelSchedule()
|
|
168
|
+
window.removeEventListener('resize', applyStickyOffsets)
|
|
169
|
+
resizeObserver?.disconnect()
|
|
170
|
+
}
|
|
171
|
+
}, [tableNode, stickyLeftColumn, stickyRightColumn])
|
|
237
172
|
|
|
238
173
|
useEffect(() => {
|
|
239
174
|
addDataTitle()
|
|
240
175
|
}, [])
|
|
241
176
|
|
|
177
|
+
const tableElementProps = {
|
|
178
|
+
...ariaProps,
|
|
179
|
+
...dataProps,
|
|
180
|
+
...htmlProps,
|
|
181
|
+
className: classNames,
|
|
182
|
+
id,
|
|
183
|
+
style: dynamicInlineProps,
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const renderTableElement = () => (
|
|
187
|
+
isTableTag ? (
|
|
188
|
+
<table
|
|
189
|
+
{...tableElementProps}
|
|
190
|
+
ref={setTableRef}
|
|
191
|
+
>
|
|
192
|
+
{children}
|
|
193
|
+
</table>
|
|
194
|
+
) : (
|
|
195
|
+
<div
|
|
196
|
+
{...tableElementProps}
|
|
197
|
+
ref={setTableRef}
|
|
198
|
+
>
|
|
199
|
+
{children}
|
|
200
|
+
</div>
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
|
|
242
204
|
// ------------ Default Table (non-filter variant rendering) ------------
|
|
243
205
|
const renderTable = () => {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
{...ariaProps}
|
|
249
|
-
{...dataProps}
|
|
250
|
-
{...htmlProps}
|
|
251
|
-
className={classNames}
|
|
252
|
-
id={id}
|
|
253
|
-
style={dynamicInlineProps}
|
|
254
|
-
>
|
|
255
|
-
{children}
|
|
256
|
-
</table>
|
|
257
|
-
) : (
|
|
258
|
-
<div
|
|
259
|
-
{...ariaProps}
|
|
260
|
-
{...dataProps}
|
|
261
|
-
{...htmlProps}
|
|
262
|
-
className={classNames}
|
|
263
|
-
id={id}
|
|
264
|
-
style={dynamicInlineProps}
|
|
265
|
-
>
|
|
266
|
-
{children}
|
|
267
|
-
</div>
|
|
268
|
-
)}
|
|
269
|
-
</div>
|
|
270
|
-
) : (
|
|
271
|
-
isTableTag ? (
|
|
272
|
-
<table
|
|
273
|
-
{...ariaProps}
|
|
274
|
-
{...dataProps}
|
|
275
|
-
{...htmlProps}
|
|
276
|
-
className={classNames}
|
|
277
|
-
id={id}
|
|
278
|
-
style={dynamicInlineProps}
|
|
279
|
-
>
|
|
280
|
-
{children}
|
|
281
|
-
</table>
|
|
282
|
-
) : (
|
|
283
|
-
<div
|
|
284
|
-
{...ariaProps}
|
|
285
|
-
{...dataProps}
|
|
286
|
-
{...htmlProps}
|
|
287
|
-
className={classNames}
|
|
288
|
-
id={id}
|
|
289
|
-
style={dynamicInlineProps}
|
|
290
|
-
>
|
|
291
|
-
{children}
|
|
206
|
+
if (responsive === 'scroll') {
|
|
207
|
+
return (
|
|
208
|
+
<div className='table-responsive-scroll'>
|
|
209
|
+
{renderTableElement()}
|
|
292
210
|
</div>
|
|
293
211
|
)
|
|
294
|
-
|
|
212
|
+
}
|
|
295
213
|
|
|
296
|
-
return
|
|
214
|
+
return renderTableElement()
|
|
297
215
|
}
|
|
298
216
|
// ------------ End Default Table (non-filter variant rendering) ------------
|
|
299
217
|
|
|
300
218
|
// ------------ variant = 'withFilter' rendering ------------
|
|
301
219
|
const renderCardVariant = () => {
|
|
302
|
-
// Render table element
|
|
303
220
|
const tableElement = responsive === 'scroll' ? (
|
|
304
221
|
<div className='table-responsive-scroll'>
|
|
305
|
-
{
|
|
306
|
-
<table
|
|
307
|
-
{...ariaProps}
|
|
308
|
-
{...dataProps}
|
|
309
|
-
{...htmlProps}
|
|
310
|
-
className={classNames}
|
|
311
|
-
id={id}
|
|
312
|
-
style={dynamicInlineProps}
|
|
313
|
-
>
|
|
314
|
-
{children}
|
|
315
|
-
</table>
|
|
316
|
-
) : (
|
|
317
|
-
<div
|
|
318
|
-
{...ariaProps}
|
|
319
|
-
{...dataProps}
|
|
320
|
-
{...htmlProps}
|
|
321
|
-
className={classNames}
|
|
322
|
-
id={id}
|
|
323
|
-
style={dynamicInlineProps}
|
|
324
|
-
>
|
|
325
|
-
{children}
|
|
326
|
-
</div>
|
|
327
|
-
)}
|
|
222
|
+
{renderTableElement()}
|
|
328
223
|
</div>
|
|
329
224
|
) : (
|
|
330
|
-
|
|
331
|
-
<table
|
|
332
|
-
{...ariaProps}
|
|
333
|
-
{...dataProps}
|
|
334
|
-
{...htmlProps}
|
|
335
|
-
className={classNames}
|
|
336
|
-
id={id}
|
|
337
|
-
style={dynamicInlineProps}
|
|
338
|
-
>
|
|
339
|
-
{children}
|
|
340
|
-
</table>
|
|
341
|
-
) : (
|
|
342
|
-
<div
|
|
343
|
-
{...ariaProps}
|
|
344
|
-
{...dataProps}
|
|
345
|
-
{...htmlProps}
|
|
346
|
-
className={classNames}
|
|
347
|
-
id={id}
|
|
348
|
-
style={dynamicInlineProps}
|
|
349
|
-
>
|
|
350
|
-
{children}
|
|
351
|
-
</div>
|
|
352
|
-
)
|
|
225
|
+
renderTableElement()
|
|
353
226
|
)
|
|
354
227
|
|
|
355
228
|
// Default filter props that CAN be overridden (All props from Filter kit CAN be used, but these are the ones we set as defaults)
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import PbEnhancedElement from '../pb_enhanced_element'
|
|
2
|
+
import {
|
|
3
|
+
applyStickyColumns,
|
|
4
|
+
scheduleStickyColumns,
|
|
5
|
+
} from './utilities/stickyColumns'
|
|
2
6
|
|
|
3
7
|
const TABLE_WRAPPER_SELECTOR = "[data-pb-table-wrapper]";
|
|
4
8
|
const TABLE_COLLAPSIBLE_WRAPPER_SELECTOR = "[data-pb-table-collapsible-wrapper]";
|
|
@@ -7,7 +11,10 @@ const TABLE_COLLAPSIBLE_CELL_SELECTOR = "[data-pb-table-collapsible-cell-id]";
|
|
|
7
11
|
export default class PbTable extends PbEnhancedElement {
|
|
8
12
|
stickyLeftColumns: string[] = [];
|
|
9
13
|
stickyRightColumns: string[] = [];
|
|
10
|
-
|
|
14
|
+
private stickyTable: Element | null = null;
|
|
15
|
+
private cancelStickySchedule: (() => void) | null = null;
|
|
16
|
+
private stickyResizeObserver: ResizeObserver | null = null;
|
|
17
|
+
private boundApplyStickyOffsets = () => this.applyStickyOffsets();
|
|
11
18
|
|
|
12
19
|
static get selector(): string {
|
|
13
20
|
return TABLE_WRAPPER_SELECTOR;
|
|
@@ -31,133 +38,59 @@ export default class PbTable extends PbEnhancedElement {
|
|
|
31
38
|
})
|
|
32
39
|
}
|
|
33
40
|
|
|
34
|
-
this.
|
|
35
|
-
this.initStickyRightColumns();
|
|
41
|
+
this.initStickyColumns();
|
|
36
42
|
this.handleCollapsibleClick();
|
|
37
43
|
this.handleCollapsibleRow();
|
|
38
44
|
}
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
const table =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
46
|
+
initStickyColumns() {
|
|
47
|
+
const table =
|
|
48
|
+
this.element.querySelector('.sticky-left-column, .sticky-right-column') ||
|
|
49
|
+
(this.element.classList.contains('sticky-left-column') ||
|
|
50
|
+
this.element.classList.contains('sticky-right-column')
|
|
51
|
+
? this.element
|
|
52
|
+
: null);
|
|
53
|
+
|
|
54
|
+
if (!table) return;
|
|
55
|
+
|
|
56
|
+
this.stickyTable = table;
|
|
57
|
+
const classList = Array.from(table.classList);
|
|
58
|
+
const stickyLeftClass = classList.find(cls => cls.startsWith('sticky-left-columns-ids-'));
|
|
59
|
+
const stickyRightClass = classList.find(cls => cls.startsWith('sticky-right-columns-ids-'));
|
|
60
|
+
|
|
61
|
+
if (stickyLeftClass) {
|
|
62
|
+
this.stickyLeftColumns = stickyLeftClass
|
|
63
|
+
.replace('sticky-left-columns-ids-', '')
|
|
64
|
+
.split('-');
|
|
59
65
|
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
handleStickyLeftColumns() {
|
|
63
|
-
let accumulatedWidth = 0;
|
|
64
|
-
|
|
65
|
-
this.stickyLeftColumns.forEach((colId, index) => {
|
|
66
|
-
const isLastColumn = index === this.stickyLeftColumns.length - 1;
|
|
67
|
-
const header = this.element.querySelector(`th[data-sticky-id="${colId}"]`);
|
|
68
|
-
const cells = this.element.querySelectorAll(`td[data-sticky-id="${colId}"]`);
|
|
69
|
-
|
|
70
|
-
if (header) {
|
|
71
|
-
header.classList.add('sticky');
|
|
72
|
-
(header as HTMLElement).style.left = `${accumulatedWidth}px`;
|
|
73
|
-
|
|
74
|
-
if (!isLastColumn) {
|
|
75
|
-
header.classList.add('with-border-right');
|
|
76
|
-
header.classList.remove('sticky-left-shadow');
|
|
77
|
-
} else {
|
|
78
|
-
header.classList.remove('with-border-right');
|
|
79
|
-
header.classList.add('sticky-left-shadow');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const headerWidth = (header as HTMLElement).offsetWidth;
|
|
83
|
-
accumulatedWidth += headerWidth;
|
|
84
|
-
|
|
85
|
-
cells.forEach((cell) => {
|
|
86
|
-
cell.classList.add('sticky');
|
|
87
|
-
(cell as HTMLElement).style.left = `${accumulatedWidth - headerWidth}px`;
|
|
88
|
-
|
|
89
|
-
if (!isLastColumn) {
|
|
90
|
-
cell.classList.add('with-border-right');
|
|
91
|
-
cell.classList.remove('sticky-left-shadow');
|
|
92
|
-
} else {
|
|
93
|
-
cell.classList.remove('with-border-right');
|
|
94
|
-
cell.classList.add('sticky-left-shadow');
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
66
|
|
|
101
|
-
|
|
102
|
-
|
|
67
|
+
if (stickyRightClass) {
|
|
68
|
+
this.stickyRightColumns = stickyRightClass
|
|
69
|
+
.replace('sticky-right-columns-ids-', '')
|
|
70
|
+
.split('-');
|
|
71
|
+
}
|
|
103
72
|
|
|
104
|
-
if (
|
|
105
|
-
const classList = Array.from(table.classList);
|
|
106
|
-
const stickyColumnClass = classList.find(cls => cls.startsWith('sticky-right-columns-ids-'));
|
|
73
|
+
if (!this.stickyLeftColumns.length && !this.stickyRightColumns.length) return;
|
|
107
74
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
.replace('sticky-right-columns-ids-', '')
|
|
111
|
-
.split('-');
|
|
112
|
-
this.stickyRightColumnsReversed = this.stickyRightColumns.reverse();
|
|
75
|
+
this.cancelStickySchedule = scheduleStickyColumns(this.boundApplyStickyOffsets);
|
|
76
|
+
window.addEventListener('resize', this.boundApplyStickyOffsets);
|
|
113
77
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
window.addEventListener('resize', () => this.handleStickyRightColumns());
|
|
118
|
-
}, 10);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
78
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
79
|
+
this.stickyResizeObserver = new ResizeObserver(this.boundApplyStickyOffsets);
|
|
80
|
+
this.stickyResizeObserver.observe(table);
|
|
121
81
|
}
|
|
122
82
|
}
|
|
123
83
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
this.stickyRightColumnsReversed.forEach((colId, index) => {
|
|
128
|
-
const isLastColumn = index === this.stickyRightColumns.length - 1;
|
|
129
|
-
const header = this.element.querySelector(`th[data-sticky-id="${colId}"]`);
|
|
130
|
-
const cells = this.element.querySelectorAll(`td[data-sticky-id="${colId}"]`);
|
|
131
|
-
|
|
132
|
-
if (header) {
|
|
133
|
-
header.classList.add('sticky');
|
|
134
|
-
(header as HTMLElement).style.right = `${accumulatedWidth}px`;
|
|
135
|
-
|
|
136
|
-
if (!isLastColumn) {
|
|
137
|
-
header.classList.add('with-border-left');
|
|
138
|
-
header.classList.remove('sticky-right-shadow');
|
|
139
|
-
} else {
|
|
140
|
-
header.classList.remove('with-border-right');
|
|
141
|
-
header.classList.add('sticky-right-shadow');
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const headerWidth = (header as HTMLElement).offsetWidth;
|
|
145
|
-
accumulatedWidth += headerWidth;
|
|
84
|
+
applyStickyOffsets() {
|
|
85
|
+
if (!this.stickyTable) return;
|
|
146
86
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
87
|
+
if (this.stickyLeftColumns.length) {
|
|
88
|
+
applyStickyColumns(this.stickyTable, this.stickyLeftColumns, 'left');
|
|
89
|
+
}
|
|
150
90
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
} else {
|
|
155
|
-
cell.classList.remove('with-border-left');
|
|
156
|
-
cell.classList.add('sticky-right-shadow');
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
});
|
|
91
|
+
if (this.stickyRightColumns.length) {
|
|
92
|
+
applyStickyColumns(this.stickyTable, this.stickyRightColumns, 'right');
|
|
93
|
+
}
|
|
161
94
|
}
|
|
162
95
|
|
|
163
96
|
handleCollapsibleClick() {
|
|
@@ -228,14 +161,12 @@ export default class PbTable extends PbEnhancedElement {
|
|
|
228
161
|
}
|
|
229
162
|
}
|
|
230
163
|
|
|
231
|
-
// Cleanup method to remove event listener
|
|
232
164
|
disconnect() {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
165
|
+
this.cancelStickySchedule?.();
|
|
166
|
+
this.cancelStickySchedule = null;
|
|
167
|
+
window.removeEventListener('resize', this.boundApplyStickyOffsets);
|
|
168
|
+
this.stickyResizeObserver?.disconnect();
|
|
169
|
+
this.stickyResizeObserver = null;
|
|
170
|
+
this.stickyTable = null;
|
|
240
171
|
}
|
|
241
172
|
}
|
|
@@ -1,13 +1,38 @@
|
|
|
1
1
|
@import "../../tokens/colors";
|
|
2
2
|
|
|
3
3
|
[class^="pb_table"] {
|
|
4
|
+
// Collapsed borders + sticky columns leave subpixel seams at some zoom/sizes.
|
|
5
|
+
// Separate borders keep sticky offsets aligned with painted cell edges.
|
|
6
|
+
&.table-sm,
|
|
7
|
+
&.table-md,
|
|
8
|
+
&.table-lg {
|
|
9
|
+
&.sticky-left-column,
|
|
10
|
+
&.sticky-right-column {
|
|
11
|
+
border-collapse: separate;
|
|
12
|
+
border-spacing: 0;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
4
16
|
.sticky {
|
|
5
17
|
position: sticky !important;
|
|
6
18
|
z-index: 1;
|
|
7
19
|
background-color: white;
|
|
20
|
+
background-clip: padding-box;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Corner cells (sticky header + sticky column) must sit above scrolling
|
|
24
|
+
// header siblings in multi-row theads.
|
|
25
|
+
&.sticky-header {
|
|
26
|
+
thead .sticky,
|
|
27
|
+
.pb_table_thead .sticky {
|
|
28
|
+
z-index: 2;
|
|
29
|
+
}
|
|
8
30
|
}
|
|
9
31
|
|
|
10
|
-
// For use with sticky left columns
|
|
32
|
+
// For use with sticky left columns.
|
|
33
|
+
// Default left/right keep single sticky edge (and Nitro colspan corner cells
|
|
34
|
+
// that use these classes without data-sticky-id) pinned. Multi-column JS
|
|
35
|
+
// offsets override via inline style.
|
|
11
36
|
.sticky-left-shadow {
|
|
12
37
|
box-shadow: 4px 0 10px rgba(60, 106, 172, 0.16) !important;
|
|
13
38
|
left: 0;
|
|
@@ -15,7 +40,6 @@
|
|
|
15
40
|
|
|
16
41
|
.with-border-right {
|
|
17
42
|
border-right: 1px solid var(--table-border-color, #{$border_light}) !important;
|
|
18
|
-
left: 0;
|
|
19
43
|
}
|
|
20
44
|
|
|
21
45
|
// For use with sticky right columns
|
|
@@ -26,6 +50,5 @@
|
|
|
26
50
|
|
|
27
51
|
.with-border-left {
|
|
28
52
|
border-left: 1px solid var(--table-border-color, #{$border_light}) !important;
|
|
29
|
-
right: 0;
|
|
30
53
|
}
|
|
31
54
|
}
|