playbook_ui 14.17.0.pre.rc.1 → 14.17.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_advanced_table/Utilities/types.ts +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +70 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +83 -2
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +20 -7
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_fullscreen.jsx +90 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_fullscreen.md +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +2 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +14 -7
- data/app/pb_kits/playbook/pb_contact/contact.test.js +7 -7
- data/app/pb_kits/playbook/pb_date_range_inline/date_range_inline.test.js +2 -2
- data/app/pb_kits/playbook/pb_date_range_stacked/date_range_stacked.test.js +1 -1
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +58 -17
- data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +6 -6
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.jsx +6 -6
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +6 -6
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +8 -8
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +3 -3
- data/app/pb_kits/playbook/pb_form_group/_form_group.scss +22 -0
- data/app/pb_kits/playbook/pb_icon/icon.test.js +9 -9
- data/app/pb_kits/playbook/pb_icon_circle/icon_circle.test.js +1 -1
- data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.test.js +1 -1
- data/app/pb_kits/playbook/pb_icon_value/icon_value.test.js +1 -1
- data/app/pb_kits/playbook/pb_label_value/label_value.test.js +1 -1
- data/app/pb_kits/playbook/pb_layout/_layout.scss +58 -0
- data/app/pb_kits/playbook/pb_layout/_layout.tsx +20 -7
- data/app/pb_kits/playbook/pb_layout/docs/_layout_bracket.jsx +190 -0
- data/app/pb_kits/playbook/pb_layout/docs/_layout_bracket.md +5 -0
- data/app/pb_kits/playbook/pb_layout/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_layout/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_layout/layout.test.js +4 -0
- data/app/pb_kits/playbook/pb_layout/subcomponents/_game.tsx +90 -0
- data/app/pb_kits/playbook/pb_layout/subcomponents/_round.tsx +57 -0
- data/app/pb_kits/playbook/pb_link/link.test.jsx +2 -2
- data/app/pb_kits/playbook/pb_nav/_nav_item.test.js +5 -3
- data/app/pb_kits/playbook/pb_section_separator/docs/_section_separator_vertical.md +1 -0
- data/app/pb_kits/playbook/pb_stat_change/stat_change.test.js +8 -4
- data/app/pb_kits/playbook/pb_table/styles/_striped.scss +3 -3
- data/app/pb_kits/playbook/pb_tooltip/tooltip.html.erb +2 -5
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.jsx +4 -4
- data/app/pb_kits/playbook/pb_typeahead/typeahead.html.erb +2 -5
- data/app/pb_kits/playbook/pb_user/user.html.erb +1 -6
- data/app/pb_kits/playbook/pb_user_badge/user_badge.html.erb +1 -6
- data/dist/chunks/{_typeahead-Djo6qCne.js → _typeahead-CPM091Hj.js} +2 -2
- data/dist/chunks/_weekday_stacked-BzIANIYX.js +45 -0
- data/dist/chunks/lazysizes-DHz07jlL.js +1 -0
- data/dist/chunks/lib-Bg2KFzpz.js +29 -0
- data/dist/chunks/{pb_form_validation-BvNy9Bd6.js → pb_form_validation-BiHyZedy.js} +1 -1
- data/dist/chunks/vendor.js +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/kit_base.rb +4 -4
- data/lib/playbook/version.rb +1 -1
- metadata +14 -7
- data/dist/chunks/_weekday_stacked-DIIHW0OV.js +0 -45
- data/dist/chunks/lazysizes-B7xYodB-.js +0 -1
- data/dist/chunks/lib-BGzBzFZX.js +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13874566f1f6c12cde0929976d074965455ec07aec5f90e4bea2b2ae0e7e3b0e
|
4
|
+
data.tar.gz: 2d6fae64049b09f78c419089d563bd15daa6d3cd8857c7743264c78367eb6f00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88ec472b7d3b00f5359abad8596f1ecdc32f2308c02d0eb4a27c31259b2f563fabdf2458f9fc741865f7c05d99cc11ae55bf747c49f1db16b8b991010ee6ea41
|
7
|
+
data.tar.gz: 181523ec91b70cca9e242a1b5679afb5bee4f77da05391e58618e9269b3d9709cdcbbb18a00d7f0ca221050fec168bb03c984a4cda6980382645c5da9f397ee8
|
@@ -7,6 +7,7 @@
|
|
7
7
|
@import "./scss_partials/chrome_styles";
|
8
8
|
@import "../tokens/screen_sizes";
|
9
9
|
@import "../tokens/shadows";
|
10
|
+
@import "../tokens/positioning";
|
10
11
|
|
11
12
|
.pb_advanced_table {
|
12
13
|
$border-color: 1px solid $border_light;
|
@@ -229,6 +230,53 @@
|
|
229
230
|
max-height: 1920px;
|
230
231
|
overflow-y: auto;
|
231
232
|
}
|
233
|
+
|
234
|
+
// Fullscreen
|
235
|
+
&.advanced-table-allow-fullscreen {
|
236
|
+
transition: all 0.3s ease;
|
237
|
+
}
|
238
|
+
|
239
|
+
&.advanced-table-fullscreen {
|
240
|
+
background-color: $bg_light;
|
241
|
+
box-sizing: border-box;
|
242
|
+
height: 100vh;
|
243
|
+
left: 0;
|
244
|
+
overflow: auto;
|
245
|
+
position: fixed;
|
246
|
+
top: 0;
|
247
|
+
width: 100%;
|
248
|
+
z-index: $z_10;
|
249
|
+
|
250
|
+
.pb_table {
|
251
|
+
th, td, div, button {
|
252
|
+
font-size: calc(100%);
|
253
|
+
}
|
254
|
+
box-sizing: border-box;
|
255
|
+
margin: $space_lg;
|
256
|
+
max-width: calc(100% - 64px);
|
257
|
+
width: calc(100% - 64px);
|
258
|
+
}
|
259
|
+
|
260
|
+
.pb_table.sticky-header {
|
261
|
+
thead,
|
262
|
+
.pb_advanced_table_header {
|
263
|
+
position: sticky !important;
|
264
|
+
top: 44px !important;
|
265
|
+
z-index: $z_10;
|
266
|
+
}
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
.advanced-table-fullscreen-header {
|
271
|
+
background-color: $white;
|
272
|
+
height: 44px;
|
273
|
+
padding: 13px 20px;
|
274
|
+
position: sticky;
|
275
|
+
top: 0;
|
276
|
+
width: 100%;
|
277
|
+
z-index: $z_10;
|
278
|
+
}
|
279
|
+
|
232
280
|
// Icons
|
233
281
|
.button-icon {
|
234
282
|
display: flex;
|
@@ -277,6 +325,16 @@
|
|
277
325
|
}
|
278
326
|
}
|
279
327
|
|
328
|
+
.fullscreen-icon {
|
329
|
+
@extend .button-icon;
|
330
|
+
@extend %primary-color-pseudo;
|
331
|
+
padding: 2px 0;
|
332
|
+
|
333
|
+
&:focus-visible {
|
334
|
+
border-radius: $border_rad_lighter;
|
335
|
+
}
|
336
|
+
}
|
337
|
+
|
280
338
|
// Vertical separator
|
281
339
|
.table-header-cells:first-child,
|
282
340
|
.table-header-cells-custom:first-child,
|
@@ -466,6 +524,18 @@
|
|
466
524
|
box-shadow: 1px 0px 0px 0px $border_dark !important;
|
467
525
|
}
|
468
526
|
|
527
|
+
// Fullscreen
|
528
|
+
&.advanced-table-fullscreen {
|
529
|
+
background: $bg_dark;
|
530
|
+
}
|
531
|
+
|
532
|
+
.advanced-table-fullscreen-header {
|
533
|
+
background-color: $bg_dark_card;
|
534
|
+
position: sticky;
|
535
|
+
top: 0;
|
536
|
+
z-index: $z_10;
|
537
|
+
}
|
538
|
+
|
469
539
|
// Dark Mode Responsive Styles
|
470
540
|
@media only screen and (max-width: $screen-xl-min) {
|
471
541
|
&[class*="advanced-table-responsive-scroll"] {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { useRef, useEffect } from "react";
|
1
|
+
import React, { useRef, useEffect, useState, useCallback } from "react";
|
2
2
|
import classnames from "classnames";
|
3
3
|
|
4
4
|
import { GenericObject } from "../types";
|
@@ -19,6 +19,15 @@ import TableActionBar from "./Components/TableActionBar";
|
|
19
19
|
import { useTableState } from "./Hooks/useTableState";
|
20
20
|
import { useTableActions } from "./Hooks/useTableActions";
|
21
21
|
|
22
|
+
import Card from "../pb_card/_card"
|
23
|
+
import Flex from "../pb_flex/_flex"
|
24
|
+
import Icon from "../pb_icon/_icon"
|
25
|
+
|
26
|
+
type FullscreenControls = {
|
27
|
+
toggleFullscreen: () => void;
|
28
|
+
isFullscreen: boolean;
|
29
|
+
};
|
30
|
+
|
22
31
|
type AdvancedTableProps = {
|
23
32
|
aria?: { [key: string]: string }
|
24
33
|
actions?: React.ReactNode[] | React.ReactNode
|
@@ -49,6 +58,8 @@ type AdvancedTableProps = {
|
|
49
58
|
toggleExpansionIcon?: string | string[]
|
50
59
|
onRowSelectionChange?: (arg: RowSelectionState) => void
|
51
60
|
virtualizedRows?: boolean
|
61
|
+
allowFullScreen?: boolean
|
62
|
+
fullScreenControl?: (controls: FullscreenControls) => void
|
52
63
|
} & GlobalProps;
|
53
64
|
|
54
65
|
const AdvancedTable = (props: AdvancedTableProps) => {
|
@@ -82,6 +93,8 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
82
93
|
toggleExpansionIcon = "arrows-from-line",
|
83
94
|
onRowSelectionChange,
|
84
95
|
virtualizedRows = false,
|
96
|
+
allowFullScreen = false,
|
97
|
+
fullScreenControl,
|
85
98
|
} = props;
|
86
99
|
|
87
100
|
// Component refs
|
@@ -146,6 +159,68 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
146
159
|
);
|
147
160
|
}, [fetchMoreOnBottomReached, fetchNextPage, isFetching, totalFetched, fullData.length]);
|
148
161
|
|
162
|
+
// Fullscreen
|
163
|
+
const [isFullscreen, setIsFullscreen] = useState(false)
|
164
|
+
|
165
|
+
const toggleFullscreen = useCallback(() => {
|
166
|
+
setIsFullscreen(prevState => !prevState)
|
167
|
+
}, [])
|
168
|
+
|
169
|
+
useEffect(() => {
|
170
|
+
if (allowFullScreen && fullScreenControl) {
|
171
|
+
fullScreenControl({
|
172
|
+
toggleFullscreen,
|
173
|
+
isFullscreen
|
174
|
+
})
|
175
|
+
}
|
176
|
+
}, [allowFullScreen, fullScreenControl, toggleFullscreen, isFullscreen])
|
177
|
+
|
178
|
+
const renderFullscreenHeader = () => {
|
179
|
+
if (!isFullscreen) return null
|
180
|
+
|
181
|
+
const defaultMinimizeIcon = (
|
182
|
+
<button
|
183
|
+
className="gray-icon fullscreen-icon"
|
184
|
+
onClick={toggleFullscreen}
|
185
|
+
>
|
186
|
+
<Icon
|
187
|
+
cursor="pointer"
|
188
|
+
fixedWidth
|
189
|
+
icon="arrow-down-left-and-arrow-up-right-to-center"
|
190
|
+
{...props}
|
191
|
+
/>
|
192
|
+
</button>
|
193
|
+
)
|
194
|
+
|
195
|
+
return (
|
196
|
+
<Card
|
197
|
+
borderNone
|
198
|
+
borderRadius="none"
|
199
|
+
className="advanced-table-fullscreen-header"
|
200
|
+
{...props}
|
201
|
+
>
|
202
|
+
<Flex justify="end">
|
203
|
+
{defaultMinimizeIcon}
|
204
|
+
</Flex>
|
205
|
+
</Card>
|
206
|
+
)
|
207
|
+
}
|
208
|
+
|
209
|
+
useEffect(() => {
|
210
|
+
if (!allowFullScreen) return
|
211
|
+
|
212
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
213
|
+
if (event.key === 'Escape' && isFullscreen) {
|
214
|
+
event.preventDefault()
|
215
|
+
toggleFullscreen()
|
216
|
+
}
|
217
|
+
}
|
218
|
+
document.addEventListener('keydown', handleKeyDown)
|
219
|
+
return () => {
|
220
|
+
document.removeEventListener('keydown', handleKeyDown)
|
221
|
+
}
|
222
|
+
}, [allowFullScreen, toggleFullscreen, isFullscreen])
|
223
|
+
|
149
224
|
// Build CSS classes and props
|
150
225
|
const ariaProps = buildAriaProps(aria);
|
151
226
|
const dataProps = buildDataProps(data);
|
@@ -154,6 +229,10 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
154
229
|
buildCss("pb_advanced_table"),
|
155
230
|
`advanced-table-responsive-${responsive}`,
|
156
231
|
maxHeight ? `advanced-table-max-height-${maxHeight}` : '',
|
232
|
+
{
|
233
|
+
'advanced-table-fullscreen': isFullscreen,
|
234
|
+
'advanced-table-allow-fullscreen': allowFullScreen
|
235
|
+
},
|
157
236
|
globalProps(props),
|
158
237
|
className
|
159
238
|
);
|
@@ -194,6 +273,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
194
273
|
ref={tableWrapperRef}
|
195
274
|
style={tableWrapperStyle as React.CSSProperties}
|
196
275
|
>
|
276
|
+
{renderFullscreenHeader()}
|
197
277
|
<AdvancedTableProvider
|
198
278
|
columnDefinitions={columnDefinitions}
|
199
279
|
enableToggleExpansion={enableToggleExpansion}
|
@@ -204,6 +284,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
204
284
|
hasAnySubRows={hasAnySubRows}
|
205
285
|
inlineRowLoading={inlineRowLoading}
|
206
286
|
isActionBarVisible={isActionBarVisible}
|
287
|
+
isFullscreen={isFullscreen}
|
207
288
|
loading={loading}
|
208
289
|
responsive={responsive}
|
209
290
|
selectableRows={selectableRows}
|
@@ -246,7 +327,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
246
327
|
</AdvancedTableProvider>
|
247
328
|
|
248
329
|
</div>
|
249
|
-
|
330
|
+
{/* Bottom Pagination */}
|
250
331
|
{pagination && (
|
251
332
|
<TablePagination
|
252
333
|
onChange={onPageChange}
|
@@ -149,7 +149,7 @@ return (
|
|
149
149
|
data={{testid: testId}}
|
150
150
|
sortControl={sortControl}
|
151
151
|
tableData={MOCK_DATA}
|
152
|
-
|
152
|
+
>
|
153
153
|
<AdvancedTable.Header enableSorting />
|
154
154
|
<AdvancedTable.Body />
|
155
155
|
</AdvancedTable>
|
@@ -338,8 +338,8 @@ test("enableExpansionIcon changes icon", () => {
|
|
338
338
|
|
339
339
|
const kit = screen.getByTestId(testId)
|
340
340
|
const tableHead = kit.querySelector('table')
|
341
|
-
const toggleIcon= tableHead.querySelector(".
|
342
|
-
expect(toggleIcon).
|
341
|
+
const toggleIcon = tableHead.querySelector(".pb_custom_icon")
|
342
|
+
expect(toggleIcon).toBeInTheDocument()
|
343
343
|
})
|
344
344
|
|
345
345
|
test("sortIcon changes icon", () => {
|
@@ -360,8 +360,8 @@ test("sortIcon changes icon", () => {
|
|
360
360
|
|
361
361
|
const kit = screen.getByTestId(testId)
|
362
362
|
const sortIcon = kit.querySelector('.sort-button-icon')
|
363
|
-
const icon= sortIcon.querySelector(".
|
364
|
-
expect(icon).
|
363
|
+
const icon = sortIcon.querySelector(".pb_custom_icon")
|
364
|
+
expect(icon).toBeInTheDocument()
|
365
365
|
})
|
366
366
|
|
367
367
|
test("Sort icon renders with enableSorting + sortControl works as expected", () => {
|
@@ -452,7 +452,7 @@ test("inlineRowLoading prop renders inline loading if true", () => {
|
|
452
452
|
const rowButton = kit.querySelector(".gray-icon.expand-toggle-icon")
|
453
453
|
expect(rowButton).toBeInTheDocument()
|
454
454
|
rowButton.click()
|
455
|
-
const inlineLoading = kit.querySelector(".
|
455
|
+
const inlineLoading = kit.querySelector(".pb_custom_icon")
|
456
456
|
expect(inlineLoading).toBeInTheDocument()
|
457
457
|
})
|
458
458
|
|
@@ -498,4 +498,17 @@ test("customRenderer prop functions as expected", () => {
|
|
498
498
|
const kit = screen.getByTestId(testId)
|
499
499
|
const pill = kit.querySelector(".pb_pill_kit_success_lowercase")
|
500
500
|
expect(pill).toBeInTheDocument()
|
501
|
-
})
|
501
|
+
})
|
502
|
+
|
503
|
+
test("allowFullScreen prop adds fullscreen class", () => {
|
504
|
+
render(
|
505
|
+
<AdvancedTable
|
506
|
+
allowFullScreen
|
507
|
+
columnDefinitions={columnDefinitions}
|
508
|
+
tableData={MOCK_DATA}
|
509
|
+
/>
|
510
|
+
)
|
511
|
+
|
512
|
+
const tableContainer = screen.getByRole("table").closest("div")
|
513
|
+
expect(tableContainer).toHaveClass("advanced-table-allow-fullscreen")
|
514
|
+
})
|
@@ -0,0 +1,90 @@
|
|
1
|
+
import React, { useState } from "react"
|
2
|
+
import { AdvancedTable, Button, Flex } from "playbook-ui"
|
3
|
+
import MOCK_DATA from "./advanced_table_mock_data.json"
|
4
|
+
import PAGINATION_MOCK_DATA from "./advanced_table_pagination_mock_data.json"
|
5
|
+
|
6
|
+
const AdvancedTableFullscreen = (props) => {
|
7
|
+
const [fullscreenToggleSmall, setFullscreenToggleSmall] = useState(null)
|
8
|
+
const [fullscreenToggleLarge, setFullscreenToggleLarge] = useState(null)
|
9
|
+
|
10
|
+
const columnDefinitions = [
|
11
|
+
{
|
12
|
+
accessor: "year",
|
13
|
+
label: "Year",
|
14
|
+
cellAccessors: ["quarter", "month", "day"],
|
15
|
+
},
|
16
|
+
{
|
17
|
+
accessor: "newEnrollments",
|
18
|
+
label: "New Enrollments",
|
19
|
+
},
|
20
|
+
{
|
21
|
+
accessor: "scheduledMeetings",
|
22
|
+
label: "Scheduled Meetings",
|
23
|
+
},
|
24
|
+
{
|
25
|
+
accessor: "attendanceRate",
|
26
|
+
label: "Attendance Rate",
|
27
|
+
},
|
28
|
+
{
|
29
|
+
accessor: "completedClasses",
|
30
|
+
label: "Completed Classes",
|
31
|
+
},
|
32
|
+
{
|
33
|
+
accessor: "classCompletionRate",
|
34
|
+
label: "Class Completion Rate",
|
35
|
+
},
|
36
|
+
{
|
37
|
+
accessor: "graduatedStudents",
|
38
|
+
label: "Graduated Students",
|
39
|
+
},
|
40
|
+
]
|
41
|
+
|
42
|
+
const tableProps = {
|
43
|
+
sticky: true
|
44
|
+
}
|
45
|
+
|
46
|
+
return (
|
47
|
+
<div>
|
48
|
+
<Flex justify="end">
|
49
|
+
<Button
|
50
|
+
marginBottom="sm"
|
51
|
+
onClick={() => fullscreenToggleSmall?.()}
|
52
|
+
text="Fullscreen Small Table"
|
53
|
+
variant="secondary"
|
54
|
+
/>
|
55
|
+
</Flex>
|
56
|
+
<AdvancedTable
|
57
|
+
allowFullScreen
|
58
|
+
columnDefinitions={columnDefinitions}
|
59
|
+
fullScreenControl={({ toggleFullscreen }) => setFullscreenToggleSmall(() => toggleFullscreen)}
|
60
|
+
tableData={MOCK_DATA}
|
61
|
+
{...props}
|
62
|
+
>
|
63
|
+
<AdvancedTable.Header enableSorting />
|
64
|
+
<AdvancedTable.Body />
|
65
|
+
</AdvancedTable>
|
66
|
+
<Flex justify="end">
|
67
|
+
<Button
|
68
|
+
marginY="sm"
|
69
|
+
onClick={() => fullscreenToggleLarge?.()}
|
70
|
+
text="Fullscreen Large Table"
|
71
|
+
variant="secondary"
|
72
|
+
/>
|
73
|
+
</Flex>
|
74
|
+
<AdvancedTable
|
75
|
+
allowFullScreen
|
76
|
+
columnDefinitions={columnDefinitions}
|
77
|
+
fullScreenControl={({ toggleFullscreen }) => setFullscreenToggleLarge(() => toggleFullscreen)}
|
78
|
+
responsive="none"
|
79
|
+
tableData={PAGINATION_MOCK_DATA}
|
80
|
+
tableProps={tableProps}
|
81
|
+
{...props}
|
82
|
+
>
|
83
|
+
<AdvancedTable.Header enableSorting />
|
84
|
+
<AdvancedTable.Body />
|
85
|
+
</AdvancedTable>
|
86
|
+
</div>
|
87
|
+
)
|
88
|
+
}
|
89
|
+
|
90
|
+
export default AdvancedTableFullscreen
|
@@ -0,0 +1,3 @@
|
|
1
|
+
Trigger Fullscreen mode with the `allowFullScreen`and `fullScreenControl` props. `allowFullScreen` is a boolean that enables Fullscreen functionality for an Advanced Table. `fullScreenControl` is a callback function that receives an object containing the table's internal `toggleFullscreen` function, allowing you to store and trigger Fullscreen from the parent component. An external trigger (like a button) must be used to activate Fullscreen mode.
|
2
|
+
|
3
|
+
Exit Fullscreen mode by clicking the minimize top-right-corner icon or by pressing the "Escape" keyboard key.
|
@@ -39,4 +39,5 @@ examples:
|
|
39
39
|
- advanced_table_selectable_rows_no_subrows: Selectable Rows (No Subrows)
|
40
40
|
- advanced_table_selectable_rows_actions: Selectable Rows (With Actions)
|
41
41
|
- advanced_table_selectable_rows_header: Selectable Rows (No Actions Bar)
|
42
|
-
- advanced_table_inline_editing: Inline Cell Editing
|
42
|
+
- advanced_table_inline_editing: Inline Cell Editing
|
43
|
+
- advanced_table_fullscreen: Fullscreen
|
@@ -21,4 +21,5 @@ export { default as AdvancedTableSelectableRowsHeader } from './_advanced_table_
|
|
21
21
|
export { default as AdvancedTableSelectableRowsActions } from './_advanced_table_selectable_rows_actions.jsx'
|
22
22
|
export { default as AdvancedTableTablePropsStickyHeader } from './_advanced_table_table_props_sticky_header.jsx'
|
23
23
|
export { default as AdvancedTableColumnHeadersCustomCell } from './_advanced_table_column_headers_custom_cell.jsx'
|
24
|
-
export { default as AdvancedTableInlineEditing } from './_advanced_table_inline_editing.jsx'
|
24
|
+
export { default as AdvancedTableInlineEditing } from './_advanced_table_inline_editing.jsx'
|
25
|
+
export { default as AdvancedTableFullscreen } from './_advanced_table_fullscreen.jsx'
|
@@ -27,13 +27,20 @@ exports[`html structure is correct 1`] = `
|
|
27
27
|
class="icon_wrapper"
|
28
28
|
style="vertical-align: middle; color: rgb(193, 205, 214);"
|
29
29
|
>
|
30
|
-
<
|
31
|
-
class="
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
<svg
|
31
|
+
class="pb_custom_icon svg-inline--fa svg_lg svg_fw"
|
32
|
+
color="currentColor"
|
33
|
+
fill="none"
|
34
|
+
height="auto"
|
35
|
+
viewBox="0 0 30 25"
|
36
|
+
width="auto"
|
37
|
+
xmlns="http://www.w3.org/2000/svg"
|
38
|
+
>
|
39
|
+
<path
|
40
|
+
d="M14.203 19.297l-9-9c-.469-.422-.469-1.125 0-1.594.422-.422 1.125-.422 1.594 0L15 16.953l8.203-8.203c.422-.469 1.125-.469 1.594 0a1.103 1.103 0 010 1.547l-9.047 9a1.027 1.027 0 01-1.547 0z"
|
41
|
+
fill="#242B42"
|
42
|
+
/>
|
43
|
+
</svg>
|
37
44
|
</div>
|
38
45
|
</div>
|
39
46
|
</div>
|
@@ -75,15 +75,15 @@ test('returns correct icon', () => {
|
|
75
75
|
</>
|
76
76
|
)
|
77
77
|
|
78
|
-
expect(screen.getByTestId('test-cell').querySelector('.
|
79
|
-
expect(screen.getByTestId('test-home').querySelector('.
|
78
|
+
expect(screen.getByTestId('test-cell').querySelector('.pb_custom_icon')).toBeInTheDocument()
|
79
|
+
expect(screen.getByTestId('test-home').querySelector('.pb_custom_icon')).toBeInTheDocument()
|
80
80
|
expect(screen.getByTestId('test-work').querySelector('.pb_icon_kit')).toHaveClass('fa-phone-office')
|
81
|
-
expect(screen.getByTestId('test-work-cell').querySelector('.
|
82
|
-
expect(screen.getByTestId('test-email').querySelector('.pb_custom_icon')).
|
83
|
-
expect(screen.getByTestId('test-wrong-phone').querySelector('.
|
84
|
-
expect(screen.getByTestId('test-wrong-type').querySelector('.
|
81
|
+
expect(screen.getByTestId('test-work-cell').querySelector('.pb_custom_icon')).toBeInTheDocument()
|
82
|
+
expect(screen.getByTestId('test-email').querySelector('.pb_custom_icon')).toBeInTheDocument()
|
83
|
+
expect(screen.getByTestId('test-wrong-phone').querySelector('.pb_custom_icon')).toBeInTheDocument()
|
84
|
+
expect(screen.getByTestId('test-wrong-type').querySelector('.pb_custom_icon')).toBeInTheDocument()
|
85
85
|
expect(screen.getByTestId('test-extension').querySelector('.pb_icon_kit')).toHaveClass('fa-phone-plus')
|
86
|
-
expect(screen.getByTestId('test-empty').querySelector('.
|
86
|
+
expect(screen.getByTestId('test-empty').querySelector('.pb_custom_icon')).toBeInTheDocument()
|
87
87
|
})
|
88
88
|
|
89
89
|
test("not compliant values return null in phone related contact types", () => {
|
@@ -62,7 +62,7 @@ describe("DateRangeInline Kit", () => {
|
|
62
62
|
)
|
63
63
|
|
64
64
|
const kit = screen.getByTestId(testId)
|
65
|
-
const arrow = kit.querySelector('.
|
65
|
+
const arrow = kit.querySelector('.pb_custom_icon')
|
66
66
|
expect(arrow).toBeInTheDocument()
|
67
67
|
})
|
68
68
|
|
@@ -93,7 +93,7 @@ describe("DateRangeInline Kit", () => {
|
|
93
93
|
)
|
94
94
|
|
95
95
|
const kit = screen.getByTestId(testId)
|
96
|
-
const calendar = kit.querySelector('.
|
96
|
+
const calendar = kit.querySelector('.pb_custom_icon')
|
97
97
|
expect(calendar).toBeInTheDocument()
|
98
98
|
})
|
99
99
|
|
@@ -58,7 +58,7 @@ describe("DateRangeStacked Kit", () => {
|
|
58
58
|
)
|
59
59
|
|
60
60
|
const kit = screen.getByTestId(testId)
|
61
|
-
const arrowicon = kit.querySelector('.
|
61
|
+
const arrowicon = kit.querySelector('.pb_custom_icon')
|
62
62
|
expect(arrowicon).toBeInTheDocument()
|
63
63
|
})
|
64
64
|
|
@@ -1,11 +1,11 @@
|
|
1
|
-
import React, { createContext, useReducer, useContext, useEffect, useMemo } from "react";
|
1
|
+
import React, { createContext, useReducer, useContext, useEffect, useMemo, useRef, useState } from "react";
|
2
2
|
import { InitialStateType, ActionType, DraggableProviderType } from "./types";
|
3
3
|
|
4
4
|
const initialState: InitialStateType = {
|
5
5
|
items: [],
|
6
6
|
dragData: { id: "", initialGroup: "" },
|
7
7
|
isDragging: "",
|
8
|
-
activeContainer: ""
|
8
|
+
activeContainer: "",
|
9
9
|
};
|
10
10
|
|
11
11
|
const reducer = (state: InitialStateType, action: ActionType) => {
|
@@ -31,9 +31,23 @@ const reducer = (state: InitialStateType, action: ActionType) => {
|
|
31
31
|
const { dragId, targetId } = action.payload;
|
32
32
|
const newItems = [...state.items];
|
33
33
|
const draggedItem = newItems.find(item => item.id === dragId);
|
34
|
-
const
|
34
|
+
const targetItem = newItems.find(item => item.id === targetId);
|
35
|
+
|
36
|
+
if (!draggedItem || !targetItem || draggedItem.container !== targetItem.container) {
|
37
|
+
return state;
|
38
|
+
}
|
39
|
+
|
40
|
+
if (dragId === targetId) {
|
41
|
+
return state;
|
42
|
+
}
|
43
|
+
|
44
|
+
const draggedIndex = newItems.findIndex(item => item.id === dragId);
|
35
45
|
const targetIndex = newItems.findIndex(item => item.id === targetId);
|
36
46
|
|
47
|
+
if (draggedIndex === -1 || targetIndex === -1) {
|
48
|
+
return state;
|
49
|
+
}
|
50
|
+
|
37
51
|
newItems.splice(draggedIndex, 1);
|
38
52
|
newItems.splice(targetIndex, 0, draggedItem);
|
39
53
|
|
@@ -48,7 +62,11 @@ const reducer = (state: InitialStateType, action: ActionType) => {
|
|
48
62
|
const DragContext = createContext<any>({});
|
49
63
|
|
50
64
|
export const DraggableContext = () => {
|
51
|
-
|
65
|
+
const context = useContext(DragContext);
|
66
|
+
if (context === undefined) {
|
67
|
+
throw new Error('DraggableContext must be used within a DraggableProvider');
|
68
|
+
}
|
69
|
+
return context;
|
52
70
|
};
|
53
71
|
|
54
72
|
export const DraggableProvider = ({
|
@@ -63,7 +81,11 @@ export const DraggableProvider = ({
|
|
63
81
|
dropZone = { type: 'ghost', color: 'neutral', direction: 'vertical' }
|
64
82
|
}: DraggableProviderType) => {
|
65
83
|
const [state, dispatch] = useReducer(reducer, initialState);
|
66
|
-
|
84
|
+
|
85
|
+
// Store initial items in a ref to use if needed (for consistency when needed in future updates)
|
86
|
+
const initialItemsRef = useRef(initialItems);
|
87
|
+
const [isDragging, setIsDragging] = useState(false);
|
88
|
+
|
67
89
|
// Parse dropZone prop - handle both string format (backward compatibility) and object format
|
68
90
|
let dropZoneType = 'ghost';
|
69
91
|
let dropZoneColor = 'neutral';
|
@@ -86,45 +108,64 @@ export const DraggableProvider = ({
|
|
86
108
|
|
87
109
|
useEffect(() => {
|
88
110
|
dispatch({ type: 'SET_ITEMS', payload: initialItems });
|
111
|
+
initialItemsRef.current = initialItems;
|
89
112
|
}, [initialItems]);
|
90
113
|
|
91
114
|
useEffect(() => {
|
92
|
-
onReorder
|
93
|
-
|
115
|
+
if (onReorder) {
|
116
|
+
onReorder(state.items);
|
117
|
+
}
|
118
|
+
}, [state.items, onReorder]);
|
94
119
|
|
95
120
|
const handleDragStart = (id: string, container: string) => {
|
96
|
-
|
121
|
+
setIsDragging(true);
|
122
|
+
dispatch({ type: 'SET_DRAG_DATA', payload: { id, initialGroup: container } });
|
97
123
|
dispatch({ type: 'SET_IS_DRAGGING', payload: id });
|
124
|
+
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
|
98
125
|
if (onDragStart) onDragStart(id, container);
|
99
126
|
};
|
100
127
|
|
101
128
|
const handleDragEnter = (id: string, container: string) => {
|
102
|
-
if (
|
103
|
-
|
104
|
-
|
129
|
+
if (!isDragging || container !== state.activeContainer) return;
|
130
|
+
|
131
|
+
if (state.dragData.id === id) return;
|
132
|
+
|
133
|
+
const draggedItem = state.items.find(item => item.id === state.dragData.id);
|
134
|
+
const targetItem = state.items.find(item => item.id === id);
|
135
|
+
|
136
|
+
if (!draggedItem || !targetItem || draggedItem.container !== targetItem.container) {
|
137
|
+
return;
|
105
138
|
}
|
139
|
+
|
140
|
+
dispatch({ type: 'REORDER_ITEMS', payload: { dragId: state.dragData.id, targetId: id } });
|
141
|
+
|
106
142
|
if (onDragEnter) onDragEnter(id, container);
|
107
143
|
};
|
108
144
|
|
109
145
|
const handleDragEnd = () => {
|
146
|
+
setIsDragging(false);
|
110
147
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
111
148
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
112
149
|
if (onDragEnd) onDragEnd();
|
113
150
|
};
|
114
151
|
|
115
|
-
const changeCategory = (itemId: string, container: string) => {
|
116
|
-
dispatch({ type: 'CHANGE_CATEGORY', payload: { itemId, container } });
|
117
|
-
};
|
118
|
-
|
119
152
|
const handleDrop = (container: string) => {
|
153
|
+
const draggedItem = state.items.find(item => item.id === state.dragData.id);
|
154
|
+
|
155
|
+
if (draggedItem && draggedItem.container !== container) {
|
156
|
+
dispatch({ type: 'CHANGE_CATEGORY', payload: { itemId: state.dragData.id, container } });
|
157
|
+
}
|
158
|
+
|
120
159
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
121
160
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
122
|
-
|
161
|
+
|
162
|
+
setIsDragging(false);
|
123
163
|
if (onDrop) onDrop(container);
|
124
164
|
};
|
125
165
|
|
126
166
|
const handleDragOver = (e: Event, container: string) => {
|
127
167
|
e.preventDefault();
|
168
|
+
e.stopPropagation();
|
128
169
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
|
129
170
|
if (onDragOver) onDragOver(e, container);
|
130
171
|
};
|
@@ -144,7 +185,7 @@ export const DraggableProvider = ({
|
|
144
185
|
handleDragEnd,
|
145
186
|
handleDrop,
|
146
187
|
handleDragOver
|
147
|
-
}), [state, dropZoneType, dropZoneColor, dropZoneDirection]);
|
188
|
+
}), [state, dropZoneType, dropZoneColor, dropZoneDirection, handleDragStart, handleDragEnter, handleDragEnd, handleDrop, handleDragOver]);
|
148
189
|
|
149
190
|
return (
|
150
191
|
<DragContext.Provider value={contextValue}>{children}</DragContext.Provider>
|