@visns-studio/visns-components 6.3.11 → 6.3.13
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.
package/package.json
CHANGED
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
92
92
|
},
|
|
93
93
|
"name": "@visns-studio/visns-components",
|
|
94
|
-
"version": "6.3.
|
|
94
|
+
"version": "6.3.13",
|
|
95
95
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
96
96
|
"main": "src/index.js",
|
|
97
97
|
"files": [
|
|
@@ -976,6 +976,19 @@ const DataGrid = forwardRef(
|
|
|
976
976
|
},
|
|
977
977
|
}));
|
|
978
978
|
|
|
979
|
+
// First matching `rowColours` rule for a row, shared by getRowStyle
|
|
980
|
+
// (which paints it) and rowClassName (which marks the row so the
|
|
981
|
+
// zebra banding stands down — see .tintedRow in the module styles).
|
|
982
|
+
const findRowColour = useCallback(
|
|
983
|
+
(data) =>
|
|
984
|
+
ajaxSetting?.rowColours?.length > 0 && data
|
|
985
|
+
? ajaxSetting.rowColours.find(
|
|
986
|
+
(config) => data[config.id] === config.value
|
|
987
|
+
)
|
|
988
|
+
: undefined,
|
|
989
|
+
[ajaxSetting]
|
|
990
|
+
);
|
|
991
|
+
|
|
979
992
|
const getRowStyle = useCallback(
|
|
980
993
|
(rowProps) => {
|
|
981
994
|
const { data } = rowProps;
|
|
@@ -995,19 +1008,14 @@ const DataGrid = forwardRef(
|
|
|
995
1008
|
style.fontWeight = 600;
|
|
996
1009
|
}
|
|
997
1010
|
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
);
|
|
1002
|
-
|
|
1003
|
-
if (colorConfig) {
|
|
1004
|
-
style.backgroundColor = colorConfig.colour;
|
|
1005
|
-
}
|
|
1011
|
+
const colorConfig = findRowColour(data);
|
|
1012
|
+
if (colorConfig) {
|
|
1013
|
+
style.backgroundColor = colorConfig.colour;
|
|
1006
1014
|
}
|
|
1007
1015
|
|
|
1008
1016
|
return Object.keys(style).length > 0 ? style : null;
|
|
1009
1017
|
},
|
|
1010
|
-
[ajaxSetting]
|
|
1018
|
+
[ajaxSetting, findRowColour]
|
|
1011
1019
|
);
|
|
1012
1020
|
|
|
1013
1021
|
/**
|
|
@@ -1104,10 +1112,14 @@ const DataGrid = forwardRef(
|
|
|
1104
1112
|
'vs-datagrid--row',
|
|
1105
1113
|
treeRowClassName(rowProps?.data),
|
|
1106
1114
|
getRowClassName(rowProps),
|
|
1115
|
+
// A rowColours tint is an inline background on the row
|
|
1116
|
+
// element; the class lets the stylesheet clear the zebra
|
|
1117
|
+
// band that would otherwise paint over it on odd rows.
|
|
1118
|
+
findRowColour(rowProps?.data) ? styles.tintedRow : '',
|
|
1107
1119
|
]
|
|
1108
1120
|
.filter(Boolean)
|
|
1109
1121
|
.join(' '),
|
|
1110
|
-
[getRowClassName, treeRowClassName]
|
|
1122
|
+
[getRowClassName, treeRowClassName, findRowColour]
|
|
1111
1123
|
);
|
|
1112
1124
|
|
|
1113
1125
|
const handleDownload = async (d) => {
|
package/src/components/Field.jsx
CHANGED
|
@@ -152,6 +152,9 @@ function Field({
|
|
|
152
152
|
const editorRef = useRef(null);
|
|
153
153
|
const fileImageInputRef = useRef(null);
|
|
154
154
|
const containerRef = useRef(null);
|
|
155
|
+
// Wrapper for the `colour` field's popup picker — used by the
|
|
156
|
+
// click-outside handler below to tell inside clicks from outside ones
|
|
157
|
+
const colorPickerRef = useRef(null);
|
|
155
158
|
const [autoValue, setAutoValue] = useState('');
|
|
156
159
|
const [colorPickerShow, setColorPickerShow] = useState(false);
|
|
157
160
|
const [counter, setCounter] = useState(0);
|
|
@@ -163,6 +166,42 @@ function Field({
|
|
|
163
166
|
const [emailSuggestions, setEmailSuggestions] = useState([]);
|
|
164
167
|
const [showEmailSuggestions, setShowEmailSuggestions] = useState(false);
|
|
165
168
|
|
|
169
|
+
/**
|
|
170
|
+
* `colour` field popup picker: dismiss the popover when the user clicks
|
|
171
|
+
* anywhere outside it or presses Escape. Picking a colour inside the
|
|
172
|
+
* popover deliberately keeps it open (users drag around the gradient).
|
|
173
|
+
* Declared here — top level of the component — because the field itself
|
|
174
|
+
* is rendered from a switch further down.
|
|
175
|
+
*/
|
|
176
|
+
useEffect(() => {
|
|
177
|
+
if (!colorPickerShow) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const onMouseDown = (event) => {
|
|
182
|
+
if (
|
|
183
|
+
colorPickerRef.current &&
|
|
184
|
+
!colorPickerRef.current.contains(event.target)
|
|
185
|
+
) {
|
|
186
|
+
setColorPickerShow(false);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const onKeyDown = (event) => {
|
|
191
|
+
if (event.key === 'Escape') {
|
|
192
|
+
setColorPickerShow(false);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
document.addEventListener('mousedown', onMouseDown);
|
|
197
|
+
document.addEventListener('keydown', onKeyDown);
|
|
198
|
+
|
|
199
|
+
return () => {
|
|
200
|
+
document.removeEventListener('mousedown', onMouseDown);
|
|
201
|
+
document.removeEventListener('keydown', onKeyDown);
|
|
202
|
+
};
|
|
203
|
+
}, [colorPickerShow]);
|
|
204
|
+
|
|
166
205
|
/**
|
|
167
206
|
* Conflict warnings (opt-in via `settings.conflict`): the field polls
|
|
168
207
|
* `conflict.url` for a map of {optionId: info} describing options that
|
|
@@ -1069,46 +1108,77 @@ function Field({
|
|
|
1069
1108
|
))}
|
|
1070
1109
|
</div>
|
|
1071
1110
|
);
|
|
1072
|
-
case 'colour':
|
|
1111
|
+
case 'colour': {
|
|
1112
|
+
const hasColour = inputValue && inputValue !== 'null';
|
|
1113
|
+
const toggleColorPicker = () => {
|
|
1114
|
+
if (isFieldReadOnly) {
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
setColorPickerShow((show) => !show);
|
|
1119
|
+
};
|
|
1120
|
+
|
|
1073
1121
|
return (
|
|
1074
|
-
<div
|
|
1075
|
-
|
|
1122
|
+
<div
|
|
1123
|
+
className="cpicker-inline cpicker-popup"
|
|
1124
|
+
ref={colorPickerRef}
|
|
1125
|
+
>
|
|
1126
|
+
<div
|
|
1127
|
+
className="cpicker-trigger"
|
|
1128
|
+
role="button"
|
|
1129
|
+
tabIndex={isFieldReadOnly ? -1 : 0}
|
|
1130
|
+
aria-haspopup="dialog"
|
|
1131
|
+
aria-expanded={colorPickerShow}
|
|
1132
|
+
aria-disabled={isFieldReadOnly}
|
|
1133
|
+
onClick={toggleColorPicker}
|
|
1134
|
+
onKeyDown={(event) => {
|
|
1135
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
1136
|
+
event.preventDefault();
|
|
1137
|
+
toggleColorPicker();
|
|
1138
|
+
}
|
|
1139
|
+
}}
|
|
1140
|
+
>
|
|
1076
1141
|
<div
|
|
1077
1142
|
className="cpicker__box"
|
|
1078
|
-
data-color={
|
|
1143
|
+
data-color={
|
|
1144
|
+
hasColour ? inputValue : 'No colour selected'
|
|
1145
|
+
}
|
|
1079
1146
|
style={
|
|
1080
|
-
|
|
1147
|
+
hasColour
|
|
1081
1148
|
? { backgroundColor: inputValue }
|
|
1082
1149
|
: {}
|
|
1083
1150
|
}
|
|
1084
|
-
title={
|
|
1151
|
+
title={
|
|
1152
|
+
hasColour
|
|
1153
|
+
? `Current colour: ${inputValue}`
|
|
1154
|
+
: 'No colour selected'
|
|
1155
|
+
}
|
|
1085
1156
|
></div>
|
|
1086
1157
|
<span className="cpicker-value">
|
|
1087
|
-
{
|
|
1158
|
+
{hasColour ? inputValue : 'No colour selected'}
|
|
1088
1159
|
</span>
|
|
1089
1160
|
</div>
|
|
1090
|
-
|
|
1091
|
-
<
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
/>
|
|
1109
|
-
</div>
|
|
1161
|
+
{colorPickerShow && (
|
|
1162
|
+
<div className="cpicker-popover" role="dialog">
|
|
1163
|
+
<Sketch
|
|
1164
|
+
color={hasColour ? inputValue : '#000000'}
|
|
1165
|
+
onChange={(color) => {
|
|
1166
|
+
onChangeColour(
|
|
1167
|
+
{ target: { value: color.hex } },
|
|
1168
|
+
{ hex: color.hex },
|
|
1169
|
+
settings.id
|
|
1170
|
+
);
|
|
1171
|
+
}}
|
|
1172
|
+
style={{
|
|
1173
|
+
boxShadow: 'none',
|
|
1174
|
+
border: 'none'
|
|
1175
|
+
}}
|
|
1176
|
+
/>
|
|
1177
|
+
</div>
|
|
1178
|
+
)}
|
|
1110
1179
|
</div>
|
|
1111
1180
|
);
|
|
1181
|
+
}
|
|
1112
1182
|
case 'copytoclipboard':
|
|
1113
1183
|
return (
|
|
1114
1184
|
<>
|
|
@@ -83,6 +83,17 @@
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
// A `rowColours` tint arrives as an inline background on the ROW element,
|
|
87
|
+
// but the banding above paints the cell-wrap CHILD, which sits on top — so
|
|
88
|
+
// on odd rows the stripe swallowed the tint and only even rows showed their
|
|
89
|
+
// urgency colour. A tinted row (marked by rowClassName in DataGrid.jsx)
|
|
90
|
+
// clears its cell-wrap so the row's own colour reads on every row. Must
|
|
91
|
+
// stay AFTER the banding rule: same specificity, order decides. Hover is
|
|
92
|
+
// unaffected — its background is `!important` on the hover target.
|
|
93
|
+
.tintedRow :global(.InovuaReactDataGrid__row-cell-wrap) {
|
|
94
|
+
background: transparent;
|
|
95
|
+
}
|
|
96
|
+
|
|
86
97
|
.InovuaReactDataGrid__row-hover-target:hover {
|
|
87
98
|
color: var(--primary-color) !important;
|
|
88
99
|
background: var(--hover-color, rgb(230, 240, 250)) !important;
|
|
@@ -807,6 +807,69 @@ form div:has(.react-toggle) input[type='checkbox'] {
|
|
|
807
807
|
}
|
|
808
808
|
}
|
|
809
809
|
|
|
810
|
+
/* Popup (click-to-open) variant of the colour picker — the collapsed
|
|
811
|
+
trigger row plus the floating Sketch popover. Additive: the inline
|
|
812
|
+
rules above are left as-is for any consumer still using them. */
|
|
813
|
+
.cpicker-popup {
|
|
814
|
+
position: relative;
|
|
815
|
+
gap: 0;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
.cpicker-trigger {
|
|
819
|
+
display: flex;
|
|
820
|
+
align-items: center;
|
|
821
|
+
gap: 8px;
|
|
822
|
+
width: 100%;
|
|
823
|
+
box-sizing: border-box;
|
|
824
|
+
min-height: 42px;
|
|
825
|
+
padding: 0.4rem 0.65rem;
|
|
826
|
+
font-size: 0.85rem;
|
|
827
|
+
color: var(--paragraph-color);
|
|
828
|
+
background: #ffffff;
|
|
829
|
+
border: 1px solid rgba(var(--paragraph-color-rgb, 0, 0, 0), 0.15);
|
|
830
|
+
border-radius: var(--br, 6px);
|
|
831
|
+
cursor: pointer;
|
|
832
|
+
transition: border 0.15s linear;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
.cpicker-trigger:hover,
|
|
836
|
+
.cpicker-trigger:focus-visible {
|
|
837
|
+
border: 1px solid rgba(var(--paragraph-color-rgb, 0, 0, 0), 0.85);
|
|
838
|
+
outline: none;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
.cpicker-trigger[aria-disabled='true'] {
|
|
842
|
+
cursor: not-allowed;
|
|
843
|
+
opacity: 0.7;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/* The value chip styling only makes sense on the old inline preview —
|
|
847
|
+
inside the trigger it should read as plain input text */
|
|
848
|
+
.cpicker-trigger .cpicker-value {
|
|
849
|
+
background: transparent;
|
|
850
|
+
border: none;
|
|
851
|
+
padding: 0;
|
|
852
|
+
font-weight: 500;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
.cpicker-popover {
|
|
856
|
+
position: absolute;
|
|
857
|
+
top: calc(100% + 4px);
|
|
858
|
+
left: 0;
|
|
859
|
+
z-index: 1100;
|
|
860
|
+
padding: 8px;
|
|
861
|
+
background: #ffffff;
|
|
862
|
+
border: 1px solid #dee2e6;
|
|
863
|
+
border-radius: 6px;
|
|
864
|
+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
.cpicker-popover .w-color-sketch {
|
|
868
|
+
box-shadow: none !important;
|
|
869
|
+
border: none !important;
|
|
870
|
+
border-radius: 6px !important;
|
|
871
|
+
}
|
|
872
|
+
|
|
810
873
|
/* Safari-specific fixes for form elements */
|
|
811
874
|
@supports (-webkit-touch-callout: none) {
|
|
812
875
|
/* Safari-specific styles */
|