playbook_ui 15.5.0.pre.rc.4 → 15.6.0.pre.alpha.play265012865
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/_advanced_table.scss +96 -6
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props.html.erb +1 -1
- data/app/pb_kits/playbook/pb_background/_background.tsx +6 -6
- data/app/pb_kits/playbook/pb_background/background.test.js +5 -1
- data/app/pb_kits/playbook/pb_background/docs/_background_light.html.erb +1 -1
- data/app/pb_kits/playbook/pb_background/docs/_background_light.jsx +0 -1
- data/app/pb_kits/playbook/pb_background/docs/_background_light.md +1 -0
- data/app/pb_kits/playbook/pb_background/docs/example.yml +2 -2
- data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +6 -0
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.html.erb +31 -0
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +156 -6
- data/app/pb_kits/playbook/pb_draggable/context/types.ts +8 -3
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_dropzone.jsx +180 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_dropzone.md +22 -0
- data/app/pb_kits/playbook/pb_draggable/docs/example.yml +3 -2
- data/app/pb_kits/playbook/pb_draggable/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +77 -1
- data/app/pb_kits/playbook/pb_file_upload/_file_upload.scss +4 -4
- data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +34 -22
- data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.html.erb +16 -12
- data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_default.html.erb +1 -1
- data/app/pb_kits/playbook/pb_home_address_street/none_emphasis.html.erb +16 -12
- data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.html.erb +16 -12
- data/app/pb_kits/playbook/pb_legend/_legend.tsx +7 -1
- data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.scss +10 -0
- data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.tsx +66 -15
- data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.jsx +42 -0
- data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.md +1 -0
- data/app/pb_kits/playbook/pb_multiple_users/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_multiple_users/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_multiple_users/multiple_users.test.js +25 -0
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +44 -10
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.html.erb +34 -4
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.jsx +16 -7
- data/app/pb_kits/playbook/pb_table/styles/_vertical_border.scss +49 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +15 -0
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +3 -0
- data/app/pb_kits/playbook/pb_typeahead/components/ClearIndicator.tsx +13 -2
- data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +6 -1
- data/app/pb_kits/playbook/pb_typeahead/components/ValueContainer.tsx +34 -7
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.html.erb +30 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.jsx +37 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.md +3 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +6 -1
- data/app/pb_kits/playbook/utilities/DEPRECATION_WARNINGS.md +82 -0
- data/app/pb_kits/playbook/utilities/deprecated.ts +65 -0
- data/dist/chunks/_typeahead-Mjy3POtc.js +6 -0
- data/dist/chunks/vendor.js +2 -2
- data/dist/menu.yml +3 -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 +2 -2
- metadata +13 -4
- data/app/pb_kits/playbook/pb_bar_graph/BarGraphStyles.scss +0 -58
- data/dist/chunks/_typeahead-Cd3O38ts.js +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1f00eed8d72dd338dfb0665fdbc61354194cc91f5cdf0755368f84f909c8d251
|
|
4
|
+
data.tar.gz: 31c851467170e08092848d43f25a82f61ce30c41aba7814eada0d8a663319806
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9ed414cfd8bf2656d273e36c8ad280b64ced9172ae1914b42aaa652b4799738834f0d36206059a892f4cffa272af41ecfeaaeb0325e18f014bce04a78d697388
|
|
7
|
+
data.tar.gz: 2e155137b2e170bc7704c3a3419d61b9ae9da0f21d5505fdff5552e4d175433656e9cd9fe6d7fae829e903999b1917c02de35a382107d38aace4eee21e297581
|
|
@@ -791,6 +791,28 @@
|
|
|
791
791
|
box-shadow: 1px 0px 0px 0px var(--column-border-color) !important;
|
|
792
792
|
}
|
|
793
793
|
|
|
794
|
+
// Override last-header-cell border color in dark mode
|
|
795
|
+
.pb_advanced_table_header {
|
|
796
|
+
> tr:not(:first-child) {
|
|
797
|
+
.last-header-cell {
|
|
798
|
+
border-right: 1px solid $border_dark !important;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
th[colspan]:not([colspan="1"]) {
|
|
803
|
+
border-right: 1px solid $border_dark !important;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// Override last-cell border color in dark mode for body cells
|
|
808
|
+
.pb_advanced_table_body {
|
|
809
|
+
tr {
|
|
810
|
+
.last-cell:not(:last-of-type) {
|
|
811
|
+
border-right: 1px solid $border_dark !important;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
794
816
|
// Apply border colors in dark mode
|
|
795
817
|
&[class*="column-group-border-"] {
|
|
796
818
|
// For top-level column groups (ENROLLMENT DATA, PERFORMANCE DATA)
|
|
@@ -850,7 +872,7 @@
|
|
|
850
872
|
// Restore vertical border styling in dark mode when verticalBorder is true
|
|
851
873
|
.pb_table[data-vertical-border="true"] {
|
|
852
874
|
.pb_advanced_table_header {
|
|
853
|
-
> tr
|
|
875
|
+
> tr {
|
|
854
876
|
th:not(:last-child) {
|
|
855
877
|
border-right: 1px solid $border_dark !important;
|
|
856
878
|
}
|
|
@@ -864,11 +886,17 @@
|
|
|
864
886
|
}
|
|
865
887
|
}
|
|
866
888
|
|
|
889
|
+
tr.virtualized-table-row {
|
|
890
|
+
td:not(:last-child) {
|
|
891
|
+
border-right: 1px solid $border_dark !important;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
|
|
867
895
|
// When both verticalBorder AND columnGroupBorderColor are set in dark mode,
|
|
868
896
|
// override the default border-dark with the custom color
|
|
869
897
|
&.pb_advanced_table[class*="column-group-border-"] {
|
|
870
898
|
.pb_advanced_table_header {
|
|
871
|
-
> tr
|
|
899
|
+
> tr {
|
|
872
900
|
th:not(:last-child) {
|
|
873
901
|
border-right: 1px solid var(--column-border-color) !important;
|
|
874
902
|
}
|
|
@@ -881,6 +909,12 @@
|
|
|
881
909
|
border-right: 1px solid var(--column-border-color) !important;
|
|
882
910
|
}
|
|
883
911
|
}
|
|
912
|
+
|
|
913
|
+
tr.virtualized-table-row {
|
|
914
|
+
td:not(:last-child) {
|
|
915
|
+
border-right: 1px solid var(--column-border-color) !important;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
884
918
|
}
|
|
885
919
|
}
|
|
886
920
|
|
|
@@ -985,34 +1019,90 @@
|
|
|
985
1019
|
// Firefox-specific fix for last-header-cell and last-cell vertical borders
|
|
986
1020
|
@-moz-document url-prefix() {
|
|
987
1021
|
.pb_advanced_table_header {
|
|
988
|
-
|
|
1022
|
+
th[colspan]:not([colspan="1"]):not(:last-child) {
|
|
1023
|
+
border-right: none !important;
|
|
1024
|
+
box-shadow: 1px 0 0 0 $border_light !important;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
.last-header-cell:not(:last-child),
|
|
1028
|
+
> tr:last-child .last-header-cell:not(:last-child) {
|
|
989
1029
|
border-right: none !important;
|
|
990
1030
|
box-shadow: 1px 0 0 0 $border_light !important;
|
|
991
1031
|
}
|
|
992
1032
|
}
|
|
993
1033
|
|
|
994
1034
|
.pb_advanced_table_body {
|
|
995
|
-
.last-cell:not(:last-
|
|
1035
|
+
tr .last-cell:not(:last-of-type),
|
|
1036
|
+
td.last-cell:not(:last-child),
|
|
1037
|
+
.pb_table_td.last-cell:not(:last-child) {
|
|
996
1038
|
border-right: none !important;
|
|
997
1039
|
box-shadow: 1px 0 0 0 $border_light !important;
|
|
998
1040
|
}
|
|
999
1041
|
}
|
|
1000
1042
|
|
|
1043
|
+
&[class*="column-group-border-"] {
|
|
1044
|
+
.pb_advanced_table_header {
|
|
1045
|
+
th[colspan]:not([colspan="1"]):not(:last-child),
|
|
1046
|
+
.last-header-cell:not(:last-child),
|
|
1047
|
+
> tr:last-child .last-header-cell:not(:last-child) {
|
|
1048
|
+
box-shadow: 1px 0 0 0 var(--column-border-color) !important;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
.pb_advanced_table_body {
|
|
1053
|
+
tr .last-cell:not(:last-of-type),
|
|
1054
|
+
td.last-cell:not(:last-child),
|
|
1055
|
+
.pb_table_td.last-cell:not(:last-child) {
|
|
1056
|
+
box-shadow: 1px 0 0 0 var(--column-border-color) !important;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1001
1061
|
// Dark mode Firefox fixes
|
|
1002
1062
|
&.dark {
|
|
1003
1063
|
.pb_advanced_table_header {
|
|
1004
|
-
|
|
1064
|
+
// Convert all colspan headers to box-shadow with dark color
|
|
1065
|
+
th[colspan]:not([colspan="1"]) {
|
|
1066
|
+
border-right: none !important;
|
|
1067
|
+
box-shadow: 1px 0 0 0 $border_dark !important;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
// Convert all last-header-cell borders to box-shadow with dark color
|
|
1071
|
+
.last-header-cell:not(:last-child),
|
|
1072
|
+
> tr:last-child .last-header-cell:not(:last-child),
|
|
1073
|
+
> tr:not(:first-child) .last-header-cell:not(:last-child),
|
|
1074
|
+
> tr:not(:first-child) .last-header-cell:last-child {
|
|
1005
1075
|
border-right: none !important;
|
|
1006
1076
|
box-shadow: 1px 0 0 0 $border_dark !important;
|
|
1007
1077
|
}
|
|
1008
1078
|
}
|
|
1009
1079
|
|
|
1010
1080
|
.pb_advanced_table_body {
|
|
1011
|
-
.last-cell:not(:last-
|
|
1081
|
+
tr .last-cell:not(:last-of-type),
|
|
1082
|
+
td.last-cell:not(:last-child),
|
|
1083
|
+
.pb_table_td.last-cell:not(:last-child) {
|
|
1012
1084
|
border-right: none !important;
|
|
1013
1085
|
box-shadow: 1px 0 0 0 $border_dark !important;
|
|
1014
1086
|
}
|
|
1015
1087
|
}
|
|
1088
|
+
|
|
1089
|
+
&[class*="column-group-border-"] {
|
|
1090
|
+
.pb_advanced_table_header {
|
|
1091
|
+
th[colspan]:not([colspan="1"]):not(:last-child),
|
|
1092
|
+
.last-header-cell:not(:last-child),
|
|
1093
|
+
> tr:last-child .last-header-cell:not(:last-child) {
|
|
1094
|
+
box-shadow: 1px 0 0 0 var(--column-border-color) !important;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
.pb_advanced_table_body {
|
|
1099
|
+
tr .last-cell:not(:last-of-type),
|
|
1100
|
+
td.last-cell:not(:last-child),
|
|
1101
|
+
.pb_table_td.last-cell:not(:last-child) {
|
|
1102
|
+
box-shadow: 1px 0 0 0 var(--column-border-color) !important;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1016
1106
|
}
|
|
1017
1107
|
}
|
|
1018
1108
|
}
|
|
@@ -30,4 +30,4 @@
|
|
|
30
30
|
}
|
|
31
31
|
] %>
|
|
32
32
|
|
|
33
|
-
<%= pb_rails("advanced_table", props: { id: "table_props_table", table_data: @table_data, column_definitions: column_definitions, table_props: { vertical_border: true, container: false }}) %>
|
|
33
|
+
<%= pb_rails("advanced_table", props: { id: "table_props_table", table_data: @table_data, column_definitions: column_definitions, table_props: { vertical_border: true, container: false }}) %>
|
|
@@ -102,16 +102,16 @@ const Background = (props: BackgroundProps): React.ReactElement => {
|
|
|
102
102
|
useEffect(() => {
|
|
103
103
|
const updateResponsiveProps = () => {
|
|
104
104
|
setResponsiveProps({
|
|
105
|
-
backgroundSize: getResponsiveValue(
|
|
106
|
-
backgroundPosition: getResponsiveValue(
|
|
107
|
-
backgroundRepeat: getResponsiveValue(
|
|
108
|
-
backgroundColor: getResponsiveValue(
|
|
109
|
-
imageUrl: getResponsiveValue(
|
|
105
|
+
backgroundSize: getResponsiveValue(backgroundSize),
|
|
106
|
+
backgroundPosition: getResponsiveValue(backgroundPosition),
|
|
107
|
+
backgroundRepeat: getResponsiveValue(backgroundRepeat),
|
|
108
|
+
backgroundColor: getResponsiveValue(backgroundColor),
|
|
109
|
+
imageUrl: getResponsiveValue(imageUrl),
|
|
110
110
|
});
|
|
111
111
|
};
|
|
112
112
|
window.addEventListener('resize', updateResponsiveProps);
|
|
113
113
|
return () => window.removeEventListener('resize', updateResponsiveProps);
|
|
114
|
-
}, [
|
|
114
|
+
}, [backgroundSize, backgroundPosition, backgroundRepeat, backgroundColor, imageUrl]);
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
// Extract currently applicable responsive values.
|
|
@@ -4,7 +4,6 @@ import Background from './_background'
|
|
|
4
4
|
|
|
5
5
|
const props = {
|
|
6
6
|
data: { testid: 'background' },
|
|
7
|
-
backgroundColor: null,
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
it('Should be accessible', async () => {
|
|
@@ -42,3 +41,8 @@ test('applies correct overlay class when imageOverlay prop is provided', () => {
|
|
|
42
41
|
const kit = renderKit(Background, props, { imageOverlay: 'opacity_6' });
|
|
43
42
|
expect(kit).toHaveClass('imageoverlay_opacity_6');
|
|
44
43
|
});
|
|
44
|
+
|
|
45
|
+
test('Sets backgroundColor to light as default when no backgroundColor prop is provided', () => {
|
|
46
|
+
const kit = renderKit(Background, props);
|
|
47
|
+
expect(kit).toHaveClass('pb_background_color_light');
|
|
48
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
By default, the Background kit sets background color to 'light' as seen here.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
examples:
|
|
2
2
|
|
|
3
3
|
rails:
|
|
4
|
-
- background_light:
|
|
4
|
+
- background_light: Default
|
|
5
5
|
- background_white: White
|
|
6
6
|
- background_gradient: Gradient
|
|
7
7
|
- background_image: Image
|
|
@@ -11,7 +11,7 @@ examples:
|
|
|
11
11
|
- background_size: Size
|
|
12
12
|
|
|
13
13
|
react:
|
|
14
|
-
- background_light:
|
|
14
|
+
- background_light: Default
|
|
15
15
|
- background_white: White
|
|
16
16
|
- background_gradient: Gradient
|
|
17
17
|
- background_image: Image
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useState, useEffect } from "react";
|
|
2
2
|
import { globalProps } from "../utilities/globalProps";
|
|
3
3
|
import { buildAriaProps, buildDataProps, buildHtmlProps } from "../utilities/props";
|
|
4
|
+
import { deprecatedKitWarning } from "../utilities/deprecated";
|
|
4
5
|
|
|
5
6
|
import HighchartsReact from "highcharts-react-official";
|
|
6
7
|
import Highcharts from "highcharts";
|
|
@@ -168,6 +169,11 @@ if (Array.isArray(axisTitle) && axisTitle.length > 1 && axisTitle[1].name) {
|
|
|
168
169
|
|
|
169
170
|
const [options, setOptions] = useState({});
|
|
170
171
|
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
// Warn about deprecated kit (only once per page load, dev mode only)
|
|
174
|
+
deprecatedKitWarning('BarGraph', '[Playbook] The "BarGraph" kit is deprecated. Please use "PbBarGraph" instead.');
|
|
175
|
+
}, []);
|
|
176
|
+
|
|
171
177
|
useEffect(() => {
|
|
172
178
|
setOptions(merge(staticOptions, customOptions));
|
|
173
179
|
}, [chartData]);
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
<%
|
|
2
|
+
options = [
|
|
3
|
+
{
|
|
4
|
+
label: "United States",
|
|
5
|
+
value: "unitedStates",
|
|
6
|
+
id: "us"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
label: "United Kingdom",
|
|
10
|
+
value: "unitedKingdom",
|
|
11
|
+
id: "gb"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
label: "Pakistan",
|
|
15
|
+
value: "pakistan",
|
|
16
|
+
id: "pk"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
%>
|
|
20
|
+
|
|
21
|
+
|
|
1
22
|
<%= pb_rails("button", props: { text: "Open Complex Dialog", data:{"open-dialog": "dialog-complex"} }) %>
|
|
2
23
|
|
|
3
24
|
<%= pb_rails("dialog", props: { id:"dialog-complex", size: "lg", full_height: true }) do %>
|
|
@@ -10,6 +31,16 @@
|
|
|
10
31
|
<%= pb_rails("rich_text_editor", props: {id: "default", value: "Add your text here"}) %>
|
|
11
32
|
<%= pb_rails("caption", props: { text: "Type in a word or term too help find tickets later. ex. training, phone setup, hr", margin_bottom: "xs", margin_top: "sm" }) %>
|
|
12
33
|
<%= pb_rails("typeahead", props: { placeholder: "Tags.."}) %>
|
|
34
|
+
<%= pb_rails("dropdown", props: {options: options, autocomplete: true}) %>
|
|
35
|
+
<%= pb_rails("typeahead", props: {
|
|
36
|
+
id: "typeahead-default",
|
|
37
|
+
placeholder: "Select one...",
|
|
38
|
+
options: options,
|
|
39
|
+
name: :foo,
|
|
40
|
+
margin_top: "sm",
|
|
41
|
+
is_multi: false
|
|
42
|
+
})
|
|
43
|
+
%>
|
|
13
44
|
|
|
14
45
|
<% end %>
|
|
15
46
|
<%= pb_rails("dialog/dialog_footer", props: {cancel_button: "Back", confirm_button: "Send my Issue", confirm_button_id:"confirm-complex", id: "dialog-complex"}) %>
|
|
@@ -39,6 +39,59 @@ const reducer = (state: InitialStateType, action: ActionType) => {
|
|
|
39
39
|
|
|
40
40
|
return { ...state, items: newItems };
|
|
41
41
|
}
|
|
42
|
+
|
|
43
|
+
// Used only when enableCrossContainerPreview is true
|
|
44
|
+
case "REORDER_ITEMS_CROSS_CONTAINER": {
|
|
45
|
+
const { dragId, targetId, newContainer } = action.payload;
|
|
46
|
+
const newItems = [...state.items];
|
|
47
|
+
const draggedItem = newItems.find((item) => item && item.id === dragId);
|
|
48
|
+
|
|
49
|
+
if (!draggedItem) return state;
|
|
50
|
+
|
|
51
|
+
const draggedIndex = newItems.indexOf(draggedItem);
|
|
52
|
+
const targetIndex = newItems.findIndex(
|
|
53
|
+
(item) => item && item.id === targetId
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
if (draggedIndex === -1 || targetIndex === -1) return state;
|
|
57
|
+
|
|
58
|
+
const updatedItem = { ...draggedItem, container: newContainer };
|
|
59
|
+
newItems.splice(draggedIndex, 1);
|
|
60
|
+
newItems.splice(targetIndex, 0, updatedItem);
|
|
61
|
+
|
|
62
|
+
return { ...state, items: newItems };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Used only when enableCrossContainerPreview is true
|
|
66
|
+
case "MOVE_TO_CONTAINER_END": {
|
|
67
|
+
const { dragId, newContainer } = action.payload;
|
|
68
|
+
const newItems = [...state.items];
|
|
69
|
+
const draggedItem = newItems.find((item) => item && item.id === dragId);
|
|
70
|
+
|
|
71
|
+
if (!draggedItem) return state;
|
|
72
|
+
|
|
73
|
+
const draggedIndex = newItems.indexOf(draggedItem);
|
|
74
|
+
if (draggedIndex === -1) return state;
|
|
75
|
+
|
|
76
|
+
const updatedItem = { ...draggedItem, container: newContainer };
|
|
77
|
+
|
|
78
|
+
// Remove from current position
|
|
79
|
+
newItems.splice(draggedIndex, 1);
|
|
80
|
+
|
|
81
|
+
// Insert at end of target container
|
|
82
|
+
const lastIndexInContainer = newItems
|
|
83
|
+
.map((item) => item && item.container)
|
|
84
|
+
.lastIndexOf(newContainer);
|
|
85
|
+
|
|
86
|
+
if (lastIndexInContainer === -1) {
|
|
87
|
+
newItems.push(updatedItem);
|
|
88
|
+
} else {
|
|
89
|
+
newItems.splice(lastIndexInContainer + 1, 0, updatedItem);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return { ...state, items: newItems };
|
|
93
|
+
}
|
|
94
|
+
|
|
42
95
|
default:
|
|
43
96
|
return state;
|
|
44
97
|
}
|
|
@@ -61,7 +114,9 @@ export const DraggableProvider = ({
|
|
|
61
114
|
onDrop,
|
|
62
115
|
onDragOver,
|
|
63
116
|
dropZone = { type: 'ghost', color: 'neutral', direction: 'vertical' },
|
|
64
|
-
providerId = 'default', // fallback provided for backward compatibility
|
|
117
|
+
providerId = 'default', // fallback provided for backward compatibility
|
|
118
|
+
// Opt-in flag for cross-container preview
|
|
119
|
+
enableCrossContainerPreview = false,
|
|
65
120
|
}: DraggableProviderType) => {
|
|
66
121
|
const [state, dispatch] = useReducer(reducer, initialState);
|
|
67
122
|
|
|
@@ -103,17 +158,74 @@ export const DraggableProvider = ({
|
|
|
103
158
|
if (state.dragData.originId !== providerId) return; // Ignore drag events from other providers
|
|
104
159
|
|
|
105
160
|
if (state.dragData.id !== id) {
|
|
106
|
-
|
|
107
|
-
|
|
161
|
+
if (enableCrossContainerPreview) {
|
|
162
|
+
// Used only when enableCrossContainerPreview is true
|
|
163
|
+
const draggedItem = state.items.find(
|
|
164
|
+
(item) => item && item.id === state.dragData.id
|
|
165
|
+
);
|
|
166
|
+
const currentContainer =
|
|
167
|
+
draggedItem && draggedItem.container
|
|
168
|
+
? draggedItem.container
|
|
169
|
+
: state.dragData.initialGroup;
|
|
170
|
+
|
|
171
|
+
const isCrossContainer =
|
|
172
|
+
currentContainer !== container &&
|
|
173
|
+
(currentContainer !== undefined || container !== undefined);
|
|
174
|
+
|
|
175
|
+
if (isCrossContainer) {
|
|
176
|
+
dispatch({
|
|
177
|
+
type: "REORDER_ITEMS_CROSS_CONTAINER",
|
|
178
|
+
payload: {
|
|
179
|
+
dragId: state.dragData.id,
|
|
180
|
+
targetId: id,
|
|
181
|
+
newContainer: container,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
} else {
|
|
185
|
+
// Same container: keep original behavior
|
|
186
|
+
dispatch({
|
|
187
|
+
type: "REORDER_ITEMS",
|
|
188
|
+
payload: { dragId: state.dragData.id, targetId: id },
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
// Original behavior (no preview across containers)
|
|
193
|
+
dispatch({type: "REORDER_ITEMS", payload: { dragId: state.dragData.id, targetId: id }});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
dispatch({type: "SET_DRAG_DATA",payload: {id: state.dragData.id, initialGroup: container, originId: providerId}});
|
|
108
197
|
}
|
|
109
198
|
if (onDragEnter) onDragEnter(id, container);
|
|
110
199
|
};
|
|
111
200
|
|
|
112
201
|
const handleDragEnd = () => {
|
|
202
|
+
const draggedItemId = state.dragData.id;
|
|
203
|
+
const originalContainer = state.dragData.initialGroup;
|
|
204
|
+
|
|
113
205
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
114
206
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
115
207
|
dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
|
|
116
|
-
if (onDragEnd)
|
|
208
|
+
if (onDragEnd) {
|
|
209
|
+
if (!enableCrossContainerPreview) {
|
|
210
|
+
onDragEnd();
|
|
211
|
+
} else {
|
|
212
|
+
const draggedItem = state.items.find(item => item && item.id === draggedItemId);
|
|
213
|
+
const finalContainer = draggedItem ? draggedItem.container : originalContainer;
|
|
214
|
+
|
|
215
|
+
const itemsInContainer = state.items.filter(item => item && item.container === finalContainer);
|
|
216
|
+
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
|
|
217
|
+
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
218
|
+
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
219
|
+
|
|
220
|
+
onDragEnd(
|
|
221
|
+
draggedItemId,
|
|
222
|
+
finalContainer,
|
|
223
|
+
originalContainer,
|
|
224
|
+
itemAbove,
|
|
225
|
+
itemBelow
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
117
229
|
};
|
|
118
230
|
|
|
119
231
|
const changeCategory = (itemId: string, container: string) => {
|
|
@@ -123,10 +235,34 @@ export const DraggableProvider = ({
|
|
|
123
235
|
const handleDrop = (container: string) => {
|
|
124
236
|
if (state.dragData.originId !== providerId) return; // Ignore drop events from other providers
|
|
125
237
|
|
|
238
|
+
const draggedItemId = state.dragData.id;
|
|
239
|
+
const originalContainer = state.dragData.initialGroup;
|
|
240
|
+
|
|
126
241
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
127
242
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
128
243
|
changeCategory(state.dragData.id, container);
|
|
129
|
-
if (onDrop)
|
|
244
|
+
if (onDrop) {
|
|
245
|
+
if (!enableCrossContainerPreview) {
|
|
246
|
+
onDrop(container);
|
|
247
|
+
} else {
|
|
248
|
+
const draggedItem = state.items.find(item => item && item.id === draggedItemId);
|
|
249
|
+
const updatedItem = draggedItem ? { ...draggedItem, container } : null;
|
|
250
|
+
|
|
251
|
+
const itemsInContainer = state.items.filter(item => item && item.container === container);
|
|
252
|
+
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
|
|
253
|
+
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
254
|
+
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
255
|
+
|
|
256
|
+
onDrop(
|
|
257
|
+
draggedItemId,
|
|
258
|
+
container,
|
|
259
|
+
originalContainer,
|
|
260
|
+
updatedItem,
|
|
261
|
+
itemAbove,
|
|
262
|
+
itemBelow
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
130
266
|
};
|
|
131
267
|
|
|
132
268
|
const handleDragOver = (e: Event, container: string) => {
|
|
@@ -134,6 +270,20 @@ export const DraggableProvider = ({
|
|
|
134
270
|
|
|
135
271
|
e.preventDefault();
|
|
136
272
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: container });
|
|
273
|
+
|
|
274
|
+
if (enableCrossContainerPreview && state.dragData.id) {
|
|
275
|
+
// Only when enableCrossContainerPreview is true: when hovering over a different container, move item to end
|
|
276
|
+
const draggedItem = state.items.find(
|
|
277
|
+
(item) => item && item.id === state.dragData.id
|
|
278
|
+
);
|
|
279
|
+
if (draggedItem && draggedItem.container !== container) {
|
|
280
|
+
dispatch({
|
|
281
|
+
type: "MOVE_TO_CONTAINER_END",
|
|
282
|
+
payload: { dragId: state.dragData.id, newContainer: container },
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
137
287
|
if (onDragOver) onDragOver(e, container);
|
|
138
288
|
};
|
|
139
289
|
|
|
@@ -157,4 +307,4 @@ export const DraggableProvider = ({
|
|
|
157
307
|
return (
|
|
158
308
|
<DragContext.Provider value={contextValue}>{children}</DragContext.Provider>
|
|
159
309
|
);
|
|
160
|
-
};
|
|
310
|
+
};
|
|
@@ -18,8 +18,12 @@ export type ActionType =
|
|
|
18
18
|
} }
|
|
19
19
|
| { type: 'SET_IS_DRAGGING'; payload: string }
|
|
20
20
|
| { type: 'SET_ACTIVE_CONTAINER'; payload: string }
|
|
21
|
+
| { type: 'SET_CROSS_CONTAINER_PREVIEW'; payload: boolean }
|
|
21
22
|
| { type: 'CHANGE_CATEGORY'; payload: { itemId: string; container: string } }
|
|
22
|
-
| { type: 'REORDER_ITEMS'; payload: { dragId: string; targetId: string } }
|
|
23
|
+
| { type: 'REORDER_ITEMS'; payload: { dragId: string; targetId: string } }
|
|
24
|
+
| { type: 'REORDER_ITEMS_CROSS_CONTAINER'; payload: { dragId: string; targetId: string; newContainer: string } }
|
|
25
|
+
| { type: 'MOVE_TO_CONTAINER_END'; payload: { dragId: string; newContainer: string } }
|
|
26
|
+
| { type: 'RESET_DRAG_CONTAINER'; payload: { itemId: string; originalContainer: string } };
|
|
23
27
|
|
|
24
28
|
export interface DropZoneConfig {
|
|
25
29
|
type?: 'ghost' | 'outline' | 'shadow' | 'line';
|
|
@@ -33,9 +37,10 @@ export type ActionType =
|
|
|
33
37
|
onReorder: (items: ItemType[]) => void;
|
|
34
38
|
onDragStart?: (id: string, container: string) => void;
|
|
35
39
|
onDragEnter?: (id: string, container: string) => void;
|
|
36
|
-
onDragEnd?: () => void;
|
|
37
|
-
onDrop?: (
|
|
40
|
+
onDragEnd?: (...args: any[]) => void;
|
|
41
|
+
onDrop?: (...args: any[]) => void;
|
|
38
42
|
onDragOver?: (e: Event, container: string) => void;
|
|
39
43
|
dropZone?: DropZoneConfig | string; // Can accept string for backward compatibility
|
|
40
44
|
providerId?: string;
|
|
45
|
+
enableCrossContainerPreview?: boolean;
|
|
41
46
|
}
|